diff --git a/.gitattributes b/.gitattributes
index 2588229e05..83897cba6e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -17,3 +17,5 @@
*.png binary
*.jpg binary
*.fon binary
+*.bin binary
+*.woff binary
diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index b228783799..7549e3defc 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -36,9 +36,11 @@ jobs:
# Base Environments
- DUE
+ - DUE_archim
- esp32
- linux_native
- mega2560
+ - at90usb1286_dfu
- teensy31
- teensy35
- teensy41
@@ -46,13 +48,13 @@ jobs:
# Extended AVR Environments
- - FYSETC_F6_13
+ - FYSETC_F6
- mega1280
- rambo
- sanguino1284p
- sanguino644p
- # Extended STM32 Environments
+ # STM32F1 (Maple) Environments
- STM32F103RC_btt
- STM32F103RC_btt_USB
@@ -62,39 +64,39 @@ jobs:
- STM32F103RC_meeb
- jgaurora_a5s_a1
- STM32F103VE_longer
+ - mks_robin
+ - mks_robin_lite
+ - mks_robin_pro
+ - STM32F103RET6_creality
+ - mks_robin_nano35
+
+ # STM32 (ST) Environments
+
- STM32F407VE_black
- STM32F401VE_STEVAL
- BIGTREE_BTT002
- BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0
- - mks_robin
- mks_robin_stm32
- ARMED
- FYSETC_S6
- STM32F070CB_malyan
- STM32F070RB_malyan
- malyan_M300
- - mks_robin_lite
- FLYF407ZG
- rumba32
- - mks_robin_pro
- - STM32F103RET6_creality
- LERDGEX
- - mks_robin_nano35
+ - mks_robin_nano35_stm32
+ - NUCLEO_F767ZI
+ - REMRAM_V1
# 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
#- at90usb1286_cdc
- #- at90usb1286_dfu
#- STM32F103CB_malyan
#- mks_robin_mini
@@ -116,8 +118,4 @@ jobs:
- name: Run ${{ matrix.test-platform }} Tests
run: |
- # Inline tests script
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
- export PATH=./buildroot/bin/:./buildroot/tests/:${PATH}
- run_tests . ${{ matrix.test-platform }}
+ make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
diff --git a/.gitignore b/.gitignore
index c163d339df..f7d49cc1ed 100755
--- a/.gitignore
+++ b/.gitignore
@@ -19,9 +19,9 @@
# along with this program. If not, see .
#
-# Our automatic versioning scheme generates the following file
-# NEVER put it in the repository
+# Generated files
_Version.h
+bdf2u8g
#
# OS
@@ -77,7 +77,6 @@ tags
*.out
*.app
-
#
# C
#
@@ -149,7 +148,7 @@ Marlin/*/*/*/*/readme.txt
# Secure Credentials
Configuration_Secure.h
-#Visual Studio
+# Visual Studio
*.sln
*.vcxproj
*.vcxproj.user
@@ -160,27 +159,34 @@ __vm/
.vs/
vc-fileutils.settings
-#Visual Studio Code
+# Visual Studio Code
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
-#cmake
+# cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
-#CLion
+# CLion
cmake-build-*
-#Eclipse
+# Eclipse
.project
.cproject
.pydevproject
.settings
.classpath
-#Python
+# Python
__pycache__
+
+# IOLogger logs
+*_log.csv
+
+# Simulation / Native
+eeprom.dat
+imgui.ini
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..ebcdf25e2d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,52 @@
+help:
+ @echo "Tasks for local development:"
+ @echo "* tests-single-ci: Run a single test from inside the CI"
+ @echo "* tests-single-local: Run a single test locally"
+ @echo "* tests-single-local-docker: Run a single test locally, using docker-compose"
+ @echo "* tests-all-local: Run all tests locally"
+ @echo "* tests-all-local-docker: Run all tests locally, using docker-compose"
+ @echo "* setup-local-docker: Setup local docker-compose"
+ @echo ""
+ @echo "Options for testing:"
+ @echo " TEST_TARGET Set when running tests-single-*, to select the"
+ @echo " test. If you set it to ALL it will run all "
+ @echo " tests, but some of them are broken: use "
+ @echo " tests-all-* instead to run only the ones that "
+ @echo " run on GitHub CI"
+ @echo " ONLY_TEST Limit tests to only those that contain this, or"
+ @echo " the index of the test (1-based)"
+ @echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
+ @echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
+ @echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
+.PHONY: help
+
+tests-single-ci:
+ export GIT_RESET_HARD=true
+ $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET)
+.PHONY: tests-single-ci
+
+tests-single-local:
+ @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET= or use make tests-all-local" ; return 1; fi
+ export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
+ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
+ && run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
+.PHONY: tests-single-local
+
+tests-single-local-docker:
+ @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET= or use make tests-all-local-docker" ; return 1; fi
+ docker-compose run --rm marlin $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
+.PHONY: tests-single-local-docker
+
+tests-all-local:
+ export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
+ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
+ && for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
+.PHONY: tests-all-local
+
+tests-all-local-docker:
+ docker-compose run --rm marlin $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
+.PHONY: tests-all-local-docker
+
+setup-local-docker:
+ docker-compose build
+.PHONY: setup-local-docker
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index a44b70a8d0..d408738e81 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -44,9 +44,8 @@
* - Extra features
*
* Advanced settings can be found in Configuration_adv.h
- *
*/
-#define CONFIGURATION_H_VERSION 020006
+#define CONFIGURATION_H_VERSION 020008
//===========================================================================
//============================= Getting Started =============================
@@ -67,15 +66,15 @@
//===========================================================================
//============================= DELTA Printer ===============================
//===========================================================================
-// For a Delta printer start with one of the configuration files in the
-// config/examples/delta directory and customize for your machine.
+// For a Delta printer, start with one of the configuration files in the config/examples/delta directory
+// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
//===========================================================================
//============================= SCARA Printer ===============================
//===========================================================================
-// For a SCARA printer start with the configuration files in
-// config/examples/SCARA and customize for your machine.
+// For a SCARA printer, start with one of the configuration files in the config/examples/SCARA directory
+// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
// @section info
@@ -123,7 +122,8 @@
/**
* Select a secondary serial port on the board to use for communication with the host.
- * :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
+ * Currently Ethernet (-2) is only supported on Teensy 4.1 boards.
+ * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
#if ENABLED(SKR13)
#define SERIAL_PORT_2 0
@@ -179,33 +179,19 @@
#endif
/**
- * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants.
+ * Multi-Material Unit
+ * Set to one of these predefined models:
*
- * This device allows one stepper driver on a control board to drive
- * two to eight stepper motors, one at a time, in a manner suitable
- * for extruders.
- *
- * This option only allows the multiplexer to switch on tool-change.
- * Additional options to configure custom E moves are pending.
- */
-//#define MK2_MULTIPLEXER
-#if ENABLED(MK2_MULTIPLEXER)
- // Override the default DIO selector pins here, if needed.
- // Some pins files may provide defaults for these pins.
- //#define E_MUX0_PIN 40 // Always Required
- //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
- //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
-#endif
-
-/**
- * Průša Multi-Material Unit v2
+ * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version)
+ * PRUSA_MMU2 : Průša MMU2
+ * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
+ * SMUFF_EMU_MMU2 : Technik Gegg SMUFF (Průša MMU2 emulation mode)
+ * SMUFF_EMU_MMU2S : Technik Gegg SMUFF (Průša MMU2S emulation mode)
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
- * Requires EXTRUDERS = 5
- *
- * For additional configuration see Configuration_adv.h
+ * See additional options in Configuration_adv.h.
*/
-//#define PRUSA_MMU2
+//#define MMU_MODEL PRUSA_MMU2
// A dual extruder that uses a single stepper motor
//#define SWITCHING_EXTRUDER
@@ -356,23 +342,26 @@
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
+ //#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
+ //#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)
+
//#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_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
- //#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU over this temperature
- //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU over this temperature
- #define POWER_TIMEOUT 30
+ //#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
+ //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
+ #define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
+ //#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#endif
-// @section temperature
-
//===========================================================================
//============================= Thermal Settings ============================
//===========================================================================
+// @section temperature
/**
* --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
@@ -407,10 +396,13 @@
* 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
* 15 : 100k thermistor calibration for JGAurora A5 hotend
* 18 : ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327
- * 20 : Pt100 with circuit in the Ultimainboard V2.x with 5v excitation (AVR)
- * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v excitation (STM32 \ LPC176x....)
+ * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
+ * NOTES: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
+ * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply.
+ * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C.
* 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB)
* 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB)
+ * 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup)
* 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x
* 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
* 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup
@@ -454,9 +446,15 @@
#define TEMP_SENSOR_CHAMBER 0
// Dummy thermistor constant temperature readings, for use with 998 and 999
-#define DUMMY_THERMISTOR_998_VALUE 25
+#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 100
+// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
+//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
+//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for AdaFruit PT100; 4300 for AdaFruit PT1000
+//#define MAX31865_SENSOR_OHMS_1 100
+//#define MAX31865_CALIBRATION_OHMS_1 430
+
// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings
// from the two sensors differ too much the print will be aborted.
//#define TEMP_SENSOR_1_AS_REDUNDANT
@@ -513,12 +511,13 @@
#endif
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
+
#if ENABLED(PID_PARAMS_PER_HOTEND)
// Specify between 1 and HOTENDS values per array.
// If fewer than EXTRUDER values are provided, the last element will be repeated.
- #define DEFAULT_Kp_LIST { 22.20, 20.0 }
- #define DEFAULT_Ki_LIST { 1.08, 1.0 }
- #define DEFAULT_Kd_LIST { 114.00, 112.0 }
+ #define DEFAULT_Kp_LIST { 22.20, 22.20 }
+ #define DEFAULT_Ki_LIST { 1.08, 1.08 }
+ #define DEFAULT_Kd_LIST { 114.00, 114.00 }
#else
#define DEFAULT_Kp 14.58
#define DEFAULT_Ki 1.14
@@ -564,18 +563,6 @@
#define DEFAULT_bedKi 45.87
#define DEFAULT_bedKd 325.08
- //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
- //from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
- //#define DEFAULT_bedKp 10.00
- //#define DEFAULT_bedKi .023
- //#define DEFAULT_bedKd 305.4
-
- //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
- //from pidautotune
- //#define DEFAULT_bedKp 97.1
- //#define DEFAULT_bedKi 1.41
- //#define DEFAULT_bedKd 1675.16
-
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
@@ -706,6 +693,8 @@
*
* A4988 is assumed for unspecified drivers.
*
+ * Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
+ *
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,
* TB6560, TB6600, TMC2100,
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
@@ -914,7 +903,6 @@
* - For simple switches connect...
* - normally-closed switches to GND and D32.
* - normally-open switches to 5V and D32.
- *
*/
//#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default
@@ -956,11 +944,6 @@
*/
#define BLTOUCH
-/**
- * Pressure sensor with a BLTouch-like interface
- */
-//#define CREALITY_TOUCH
-
/**
* Touch-MI Probe by hotends.fr
*
@@ -1014,10 +997,20 @@
/**
* Nozzle-to-Probe offsets { X, Y, Z }
*
- * - Use a caliper or ruler to measure the distance from the tip of
+ * X and Y offset
+ * Use a caliper or ruler to measure the distance from the tip of
* the Nozzle to the center-point of the Probe in the X and Y axes.
+ *
+ * Z offset
* - For the Z offset use your best known value and adjust at runtime.
- * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
+ * - Common probes trigger below the nozzle and have negative values for Z offset.
+ * - Probes triggering above the nozzle height are uncommon but do exist. When using
+ * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES
+ * to avoid collisions during probing.
+ *
+ * Tune and Adjust
+ * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
+ * - PROBE_OFFSET_WIZARD (configuration_adv.h) can be used for setting the Z offset.
*
* Assuming the typical work area orientation:
* - Probe to RIGHT of the Nozzle has a Positive X offset
@@ -1051,11 +1044,38 @@
#define XY_PROBE_SPEED (133*60)
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
-#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
+#define Z_PROBE_SPEED_FAST (4*60)
// Feedrate (mm/min) for the "accurate" probe of each point
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
+/**
+ * Probe Activation Switch
+ * A switch indicating proper deployment, or an optical
+ * switch triggered when the carriage is near the bed.
+ */
+//#define PROBE_ACTIVATION_SWITCH
+#if ENABLED(PROBE_ACTIVATION_SWITCH)
+ #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active
+ //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin
+#endif
+
+/**
+ * Tare Probe (determine zero-point) prior to each probe.
+ * Useful for a strain gauge or piezo sensor that needs to factor out
+ * elements such as cables pulling on the carriage.
+ */
+//#define PROBE_TARE
+#if ENABLED(PROBE_TARE)
+ #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin
+ #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before
+ #define PROBE_TARE_STATE HIGH // State to write pin for tare
+ //#define PROBE_TARE_PIN PA5 // Override default pin
+ #if ENABLED(PROBE_ACTIVATION_SWITCH)
+ //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active
+ #endif
+#endif
+
/**
* Multiple Probing
*
@@ -1119,6 +1139,13 @@
//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors
+// Require minimum nozzle and/or bed temperature for probing
+//#define PREHEAT_BEFORE_PROBING
+#if ENABLED(PREHEAT_BEFORE_PROBING)
+ #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
+ #define PROBING_BED_TEMP 50
+#endif
+
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
// :{ 0:'Low', 1:'High' }
#define X_ENABLE_ON 0
@@ -1187,9 +1214,9 @@
#endif
// @section homing
-//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed
-
-//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
+//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety.
+//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety.
+//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
//#define Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
// Be sure you have this distance over your Z_MAX_POS in case.
@@ -1249,6 +1276,12 @@
* Filament Runout Sensors
* Mechanical or opto endstops are used to check for the presence of filament.
*
+ * IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running.
+ * Marlin knows a print job is running when:
+ * 1. Running a print job from media started with M24.
+ * 2. The Print Job Timer has been started with M75.
+ * 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled.
+ *
* RAMPS-based boards use SERVO3_PIN for the first runout sensor.
* For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc.
*/
@@ -1258,11 +1291,45 @@
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500.
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
+
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
#define FIL_RUNOUT_PIN 2 //X-Max
+ // Override individually if the runout sensors vary
+ //#define FIL_RUNOUT1_STATE LOW
+ //#define FIL_RUNOUT1_PULLUP
+ //#define FIL_RUNOUT1_PULLDOWN
+
+ //#define FIL_RUNOUT2_STATE LOW
+ //#define FIL_RUNOUT2_PULLUP
+ //#define FIL_RUNOUT2_PULLDOWN
+
+ //#define FIL_RUNOUT3_STATE LOW
+ //#define FIL_RUNOUT3_PULLUP
+ //#define FIL_RUNOUT3_PULLDOWN
+
+ //#define FIL_RUNOUT4_STATE LOW
+ //#define FIL_RUNOUT4_PULLUP
+ //#define FIL_RUNOUT4_PULLDOWN
+
+ //#define FIL_RUNOUT5_STATE LOW
+ //#define FIL_RUNOUT5_PULLUP
+ //#define FIL_RUNOUT5_PULLDOWN
+
+ //#define FIL_RUNOUT6_STATE LOW
+ //#define FIL_RUNOUT6_PULLUP
+ //#define FIL_RUNOUT6_PULLDOWN
+
+ //#define FIL_RUNOUT7_STATE LOW
+ //#define FIL_RUNOUT7_PULLUP
+ //#define FIL_RUNOUT7_PULLDOWN
+
+ //#define FIL_RUNOUT8_STATE LOW
+ //#define FIL_RUNOUT8_PULLUP
+ //#define FIL_RUNOUT8_PULLDOWN
+
// Set one or more commands to execute on filament runout.
// (After 'M412 H' Marlin will ask the host to handle the process.)
#define FILAMENT_RUNOUT_SCRIPT "M600"
@@ -1329,10 +1396,21 @@
//#define AUTO_BED_LEVELING_LINEAR
/**
- * Normally G28 leaves leveling disabled on completion. Enable
- * this option to have G28 restore the prior leveling state.
+ * Normally G28 leaves leveling disabled on completion. Enable one of
+ * these options to restore the prior leveling state or to always enable
+ * leveling immediately after G28.
*/
#define RESTORE_LEVELING_AFTER_G28
+//#define ENABLE_LEVELING_AFTER_G28
+
+/**
+ * Auto-leveling needs preheating
+ */
+//#define PREHEAT_BEFORE_LEVELING
+#if ENABLED(PREHEAT_BEFORE_LEVELING)
+ #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
+ #define LEVELING_BED_TEMP 50
+#endif
/**
* Enable detailed logging of G28, G29, M48, etc.
@@ -1346,6 +1424,9 @@
// at which point movement will be level to the machine's XY plane.
// The height can be set with M420 Z
#define ENABLE_LEVELING_FADE_HEIGHT
+ #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
+ #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height.
+ #endif
// For Cartesian machines, instead of dividing moves on mesh boundaries,
// split up moves into short segments like a Delta. This follows the
@@ -1359,10 +1440,11 @@
#define G26_MESH_VALIDATION
#if ENABLED(G26_MESH_VALIDATION)
#define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle.
- #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for the G26 Mesh Validation Tool.
- #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
- #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for the G26 Mesh Validation Tool.
- #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for XY Moves for the G26 Mesh Validation Tool.
+ #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26.
+ #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26.
+ #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26.
+ #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves.
+ #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves.
#define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements.
#endif
@@ -1449,6 +1531,31 @@
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
#define LEVEL_CENTER_TOO // Move to the center after the last corner
+ //#define LEVEL_CORNERS_USE_PROBE
+ #if ENABLED(LEVEL_CORNERS_USE_PROBE)
+ #define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
+ #define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
+ //#define LEVEL_CORNERS_AUDIO_FEEDBACK
+ #endif
+
+ /**
+ * Corner Leveling Order
+ *
+ * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge.
+ *
+ * LF Left-Front RF Right-Front
+ * LB Left-Back RB Right-Back
+ *
+ * Examples:
+ *
+ * Default {LF,RB,LB,RF} {LF,RF} {LB,LF}
+ * LB --------- RB LB --------- RB LB --------- RB LB --------- RB
+ * | 4 3 | | 3 2 | | <3> | | 1 |
+ * | | | | | | | <3>|
+ * | 1 2 | | 1 4 | | 1 2 | | 2 |
+ * LF --------- RF LF --------- RF LF --------- RF LF --------- RF
+ */
+ #define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, RB, LB }
#endif
/**
@@ -1485,8 +1592,7 @@
#endif
// Homing speeds (mm/min)
-#define HOMING_FEEDRATE_XY (50*60)
-#define HOMING_FEEDRATE_Z (8*60)
+#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (8*60) }
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -1663,7 +1769,6 @@
*
* Caveats: The ending Z should be the same as starting Z.
* Attention: EXPERIMENTAL. G-code arguments may change.
- *
*/
//#define NOZZLE_CLEAN_FEATURE
@@ -1695,6 +1800,10 @@
// For a purge/clean station mounted on the X axis
//#define NOZZLE_CLEAN_NO_Y
+ // Require a minimum hotend temperature for cleaning
+ #define NOZZLE_CLEAN_MIN_TEMP 170
+ //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe
+
// Explicit wipe G-code script applies to a G12 with no arguments.
//#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0"
@@ -1730,6 +1839,9 @@
* View the current statistics with M78.
*/
//#define PRINTCOUNTER
+#if ENABLED(PRINTCOUNTER)
+ #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
+#endif
/**
* Password
@@ -1774,9 +1886,9 @@
* Select the language to display on the LCD. These languages are available:
*
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it,
- * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
+ * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW
*
- * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
+ * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' }
*/
#define LCD_LANGUAGE en
@@ -1816,22 +1928,11 @@
*
* SD Card support is disabled by default. If your controller has an SD slot,
* you must uncomment the following option or it won't work.
- *
*/
#if ENABLED(GraphicalLCD)
#define SDSUPPORT
#endif
-/**
- * SD CARD: SPI SPEED
- *
- * Enable one of the following items for a slower SPI transfer speed.
- * This may be required to resolve "volume init" errors.
- */
-//#define SPI_SPEED SPI_HALF_SPEED
-//#define SPI_SPEED SPI_QUARTER_SPEED
-//#define SPI_SPEED SPI_EIGHTH_SPEED
-
/**
* SD CARD: ENABLE CRC
*
@@ -2055,6 +2156,14 @@
//
//#define FF_INTERFACEBOARD
+//
+// TFT GLCD Panel with Marlin UI
+// Panel connected to main board by SPI or I2C interface.
+// See https://github.com/Serhiy-K/TFTGLCDAdapter
+//
+//#define TFTGLCD_PANEL_SPI
+//#define TFTGLCD_PANEL_I2C
+
//=============================================================================
//======================= LCD / Controller Selection =======================
//========================= (Graphical LCDs) ========================
@@ -2173,9 +2282,10 @@
//
// Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6
// A clone of the RepRapDiscount full graphics display but with
-// different pins/wiring (see pins_ANET_10.h).
+// different pins/wiring (see pins_ANET_10.h). Enable one of these.
//
//#define ANET_FULL_GRAPHICS_LCD
+//#define ANET_FULL_GRAPHICS_LCD_ALT_WIRING
//
// AZSMZ 12864 LCD with SD
@@ -2282,7 +2392,7 @@
//
// Third-party or vendor-customized controller interfaces.
-// Sources should be installed in 'src/lcd/extensible_ui'.
+// Sources should be installed in 'src/lcd/extui'.
//
//#define EXTENSIBLE_UI
@@ -2294,43 +2404,122 @@
//=============================== Graphical TFTs ==============================
//=============================================================================
-//
-// TFT display with optional touch screen
-// Color Marlin UI with standard menu system
-//
-//#define TFT_320x240
-//#define TFT_320x240_SPI
-//#define TFT_480x320
-//#define TFT_480x320_SPI
+/**
+ * Specific TFT Model Presets. Enable one of the following options
+ * or enable TFT_GENERIC and set sub-options.
+ */
//
-// Skip autodetect and force specific TFT driver
-// Mandatory for SPI screens with no MISO line
-// Available drivers are: ST7735, ST7789, ST7796, R61505, ILI9328, ILI9341, ILI9488
+// 480x320, 3.5", SPI Display From MKS
+// Normally used in MKS Robin Nano V2
//
-//#define TFT_DRIVER AUTO
+//#define MKS_TS35_V2_0
//
-// SPI display (MKS Robin Nano V2.0, MKS Gen L V2.0)
-// Upscaled 128x64 Marlin UI
+// 320x240, 2.4", FSMC Display From MKS
+// Normally used in MKS Robin Nano V1.2
//
-//#define SPI_GRAPHICAL_TFT
+//#define MKS_ROBIN_TFT24
//
-// FSMC display (MKS Robin, Alfawise U20, JGAurora A5S, REXYZ A1, etc.)
-// Upscaled 128x64 Marlin UI
+// 320x240, 2.8", FSMC Display From MKS
+// Normally used in MKS Robin Nano V1.2
//
-//#define FSMC_GRAPHICAL_TFT
+//#define MKS_ROBIN_TFT28
//
-// TFT LVGL UI
+// 320x240, 3.2", FSMC Display From MKS
+// Normally used in MKS Robin Nano V1.2
//
-// Using default MKS icons and fonts from: https://git.io/JJvzK
-// Just copy the 'assets' folder from the build directory to the
-// root of your SD card, together with the compiled firmware.
+//#define MKS_ROBIN_TFT32
+
//
-//#define TFT_LVGL_UI_FSMC // Robin nano v1.2 uses FSMC
-//#define TFT_LVGL_UI_SPI // Robin nano v2.0 uses SPI
+// 480x320, 3.5", FSMC Display From MKS
+// Normally used in MKS Robin Nano V1.2
+//
+//#define MKS_ROBIN_TFT35
+
+//
+// 480x272, 4.3", FSMC Display From MKS
+//
+//#define MKS_ROBIN_TFT43
+
+//
+// 320x240, 3.2", FSMC Display From MKS
+// Normally used in MKS Robin
+//
+//#define MKS_ROBIN_TFT_V1_1R
+
+//
+// 480x320, 3.5", FSMC Stock Display from TronxXY
+//
+//#define TFT_TRONXY_X5SA
+
+//
+// 480x320, 3.5", FSMC Stock Display from AnyCubic
+//
+//#define ANYCUBIC_TFT35
+
+//
+// 320x240, 2.8", FSMC Stock Display from Longer/Alfawise
+//
+//#define LONGER_LK_TFT28
+
+//
+// 320x240, 2.8", FSMC Stock Display from ET4
+//
+//#define ANET_ET4_TFT28
+
+//
+// 480x320, 3.5", FSMC Stock Display from ET5
+//
+//#define ANET_ET5_TFT35
+
+//
+// Generic TFT with detailed options
+//
+//#define TFT_GENERIC
+#if ENABLED(TFT_GENERIC)
+ // :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ]
+ #define TFT_DRIVER AUTO
+
+ // Interface. Enable one of the following options:
+ //#define TFT_INTERFACE_FSMC
+ //#define TFT_INTERFACE_SPI
+
+ // TFT Resolution. Enable one of the following options:
+ //#define TFT_RES_320x240
+ //#define TFT_RES_480x272
+ //#define TFT_RES_480x320
+#endif
+
+/**
+ * TFT UI - User Interface Selection. Enable one of the following options:
+ *
+ * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled
+ * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities
+ * TFT_LVGL_UI - A Modern UI using LVGL
+ *
+ * For LVGL_UI also copy the 'assets' folder from the build directory to the
+ * root of your SD card, together with the compiled firmware.
+ */
+//#define TFT_CLASSIC_UI
+//#define TFT_COLOR_UI
+//#define TFT_LVGL_UI
+
+#if ENABLED(TFT_LVGL_UI)
+ //#define MKS_WIFI_MODULE // MKS WiFi module
+#endif
+
+/**
+ * TFT Rotation. Set to one of the following values:
+ *
+ * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y,
+ * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y,
+ * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y,
+ * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION
+ */
+//#define TFT_ROTATION TFT_NO_ROTATION
//=============================================================================
//============================ Other Controllers ============================
@@ -2351,10 +2540,15 @@
#define TOUCH_SCREEN_CALIBRATION
- //#define XPT2046_X_CALIBRATION 12316
- //#define XPT2046_Y_CALIBRATION -8981
- //#define XPT2046_X_OFFSET -43
- //#define XPT2046_Y_OFFSET 257
+ //#define TOUCH_CALIBRATION_X 12316
+ //#define TOUCH_CALIBRATION_Y -8981
+ //#define TOUCH_OFFSET_X -43
+ //#define TOUCH_OFFSET_Y 257
+ //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE
+
+ #if ENABLED(TFT_COLOR_UI)
+ //#define SINGLE_TOUCH_NAVIGATION
+ #endif
#endif
//
@@ -2400,9 +2594,6 @@
// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis)
//#define TEMP_STAT_LEDS
-// SkeinForge sends the wrong arc G-codes when using Arc Point as fillet procedure
-//#define SF_ARC_FIX
-
// Support for the BariCUDA Paste Extruder
//#define BARICUDA
@@ -2435,7 +2626,6 @@
* *** CAUTION ***
*
* LED Type. Enable only one of the following two options.
- *
*/
#if DISABLED(ABL_BLTOUCH) || ENABLED(RELOCATE_LED) && DISABLED(SKR13)
#define RGB_LED
@@ -2491,17 +2681,12 @@
#define PRINTER_EVENT_LEDS
#endif
-/**
- * R/C SERVO support
- * Sponsored by TrinityLabs, Reworked by codexmas
- */
-
/**
* Number of servos
*
* For some servo-related options NUM_SERVOS will be set automatically.
* Set this manually if there are extra servos needing manual control.
- * Leave undefined or set to 0 to entirely disable the servo subsystem.
+ * Set to 0 to turn off servo support.
*/
//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
@@ -2513,5 +2698,5 @@
// Only power servos during movement, otherwise leave off to prevent jitter
//#define DEACTIVATE_SERVOS_AFTER_MOVE
-// Allow servo angle to be edited and saved to EEPROM
+// Edit servo angles with M281 and save to EEPROM with M500
//#define EDITABLE_SERVO_ANGLES
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index c3f508ca19..dde0677021 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -29,15 +29,13 @@
* Some of these settings can damage your printer if improperly set!
*
* Basic settings can be found in Configuration.h
- *
*/
-#define CONFIGURATION_ADV_H_VERSION 020006
-
-// @section temperature
+#define CONFIGURATION_ADV_H_VERSION 020008
//===========================================================================
//============================= Thermal Settings ============================
//===========================================================================
+// @section temperature
/**
* Thermocouple sensors are quite sensitive to noise. Any noise induced in
@@ -126,9 +124,19 @@
#define HEATER_BED_INVERTING true
#endif
-/**
- * Heated Chamber settings
- */
+//
+// Heated Bed Bang-Bang options
+//
+#if DISABLED(PIDTEMPBED)
+ #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control
+ #if ENABLED(BED_LIMIT_SWITCHING)
+ #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS
+ #endif
+#endif
+
+//
+// Heated Chamber options
+//
#if TEMP_SENSOR_CHAMBER
#define CHAMBER_MINTEMP 5
#define CHAMBER_MAXTEMP 60
@@ -136,12 +144,28 @@
//#define CHAMBER_LIMIT_SWITCHING
//#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin
//#define HEATER_CHAMBER_INVERTING false
-#endif
-#if DISABLED(PIDTEMPBED)
- #define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control
- #if ENABLED(BED_LIMIT_SWITCHING)
- #define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS
+ //#define CHAMBER_FAN // Enable a fan on the chamber
+ #if ENABLED(CHAMBER_FAN)
+ #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve.
+ #if CHAMBER_FAN_MODE == 0
+ #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255)
+ #elif CHAMBER_FAN_MODE == 1
+ #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target
+ #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target
+ #elif CHAMBER_FAN_MODE == 2
+ #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255)
+ #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target
+ #endif
+ #endif
+
+ //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber
+ #if ENABLED(CHAMBER_VENT)
+ #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo
+ #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber
+ #define LOW_EXCESS_HEAT_LIMIT 3
+ #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
+ #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
#endif
#endif
@@ -182,7 +206,7 @@
* and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set
* below 2.
*/
- #define WATCH_TEMP_PERIOD 20 // Seconds
+ #define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
#endif
@@ -260,8 +284,8 @@
// 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 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
@@ -532,7 +556,7 @@
//#define X_DUAL_STEPPER_DRIVERS
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
- #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions
+ //#define INVERT_X2_VS_X_DIR // Enable if X2 direction signal is opposite to X
//#define X_DUAL_ENDSTOPS
#if ENABLED(X_DUAL_ENDSTOPS)
#define X2_USE_ENDSTOP _XMAX_
@@ -542,7 +566,7 @@
//#define Y_DUAL_STEPPER_DRIVERS
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
- #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions
+ //#define INVERT_Y2_VS_Y_DIR // Enable if Y2 direction signal is opposite to Y
//#define Y_DUAL_ENDSTOPS
#if ENABLED(Y_DUAL_ENDSTOPS)
#define Y2_USE_ENDSTOP _YMAX_
@@ -556,6 +580,11 @@
#define NUM_Z_STEPPER_DRIVERS 2 // (1-4) Z options change based on how many
#if NUM_Z_STEPPER_DRIVERS > 1
+ // Enable if Z motor direction signals are the opposite of Z1
+ //#define INVERT_Z2_VS_Z_DIR
+ //#define INVERT_Z3_VS_Z_DIR
+ //#define INVERT_Z4_VS_Z_DIR
+
//#define Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z2_USE_ENDSTOP _XMAX_
@@ -617,6 +646,9 @@
// Default x offset in duplication mode (typically set to half print bed width)
#define DEFAULT_DUPLICATION_X_OFFSET 100
+
+ // Default action to execute following M605 mode change commands. Typically G28X to apply new mode.
+ //#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
#endif
// Activate a solenoid on the active extruder with M380. Disable all with M381.
@@ -640,6 +672,7 @@
#define QUICK_HOME // If G28 contains XY do a diagonal move first
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
+//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe).
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
// @section bltouch
@@ -744,7 +777,6 @@
* | 4 3 | 1 4 | 2 1 | 3 2 |
* | | | | |
* | 1 2 | 2 3 | 3 4 | 4 1 |
- *
*/
#ifndef Z_STEPPER_ALIGN_XY
//#define Z_STEPPERS_ORIENTATION 0
@@ -779,20 +811,22 @@
//
//#define ASSISTED_TRAMMING
#if ENABLED(ASSISTED_TRAMMING)
- // Define positions for probing points, use the hotend as reference not the sensor.
- #define TRAMMING_POINT_XY { { 20, 20 }, { 200, 20 }, { 200, 200 }, { 20, 200 } }
- // Define positions names for probing points.
+ // Define positions for probe points.
+ #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } }
+
+ // Define position names for probe points.
#define TRAMMING_POINT_NAME_1 "Front-Left"
#define TRAMMING_POINT_NAME_2 "Front-Right"
#define TRAMMING_POINT_NAME_3 "Back-Right"
#define TRAMMING_POINT_NAME_4 "Back-Left"
- // Enable to restore leveling setup after operation
- #define RESTORE_LEVELING_AFTER_G35
+ #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation
+ //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first
- // Add a menu item for Assisted Tramming
- //#define ASSISTED_TRAMMING_MENU_ITEM
+ //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu
+
+ //#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment
/**
* Screw thread:
@@ -801,6 +835,7 @@
* M5: 50 = Clockwise, 51 = Counter-Clockwise
*/
#define TRAMMING_SCREW_THREAD 30
+
#endif
// @section motion
@@ -830,8 +865,6 @@
// If the Nozzle or Bed falls when the Z stepper is disabled, set its resting position here.
//#define Z_AFTER_DEACTIVATE Z_HOME_POS
-//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated
-
// Default Minimum Feedrates for printing and travel moves
#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S.
#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T.
@@ -1000,7 +1033,7 @@
/**
* I2C-based DIGIPOTs (e.g., Azteeg X3 Pro)
*/
-//#define DIGIPOT_MCP4018 // Requires https://github.com/stawel/SlowSoftI2CMaster
+//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster
//#define DIGIPOT_MCP4451
#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5
@@ -1031,10 +1064,10 @@
// @section lcd
-#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
+#if EITHER(IS_ULTIPANEL, EXTENSIBLE_UI)
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
- #define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm)
- #if ENABLED(ULTIPANEL)
+ #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
+ #if IS_ULTIPANEL
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen
#endif
@@ -1056,6 +1089,22 @@
#if HAS_LCD_MENU
+ // Add Probe Z Offset calibration to the Z Probe Offsets menu
+ #if HAS_BED_PROBE
+ //#define PROBE_OFFSET_WIZARD
+ #if ENABLED(PROBE_OFFSET_WIZARD)
+ //
+ // Enable to init the Probe Z-Offset when starting the Wizard.
+ // Use a height slightly above the estimated nozzle-to-probe Z offset.
+ // For example, with an offset of -5, consider a starting height of -4.
+ //
+ //#define PROBE_OFFSET_WIZARD_START_Z -4.0
+
+ // Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
+ //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
+ #endif
+ #endif
+
// Include a page of printer information in the LCD Main Menu
#define LCD_INFO_MENU
#if ENABLED(LCD_INFO_MENU)
@@ -1065,6 +1114,9 @@
// BACK menu items keep the highlight at the top
//#define TURBO_BACK_MENU_ITEM
+ // Add a mute option to the LCD menu
+ //#define SOUND_MENU_ITEM
+
/**
* LED Control Menu
* Add LED Control to the LCD menu
@@ -1093,38 +1145,42 @@
#endif // HAS_LCD_MENU
-// Scroll a longer status message into view
-#define STATUS_MESSAGE_SCROLLING
+#if HAS_DISPLAY
+ // The timeout (in ms) to return to the status screen from sub-menus
+ #define LCD_TIMEOUT_TO_STATUS 15000
-// On the Info Screen, display XY with one decimal place when possible
-//#define LCD_DECIMAL_SMALL_XY
+ #if ENABLED(SHOW_BOOTSCREEN)
+ #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
+ #if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI)
+ #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
+ #endif
+ #endif
-// The timeout (in ms) to return to the status screen from sub-menus
-#define LCD_TIMEOUT_TO_STATUS 15000
+ // Scroll a longer status message into view
+ #define STATUS_MESSAGE_SCROLLING
-// Add an 'M73' G-code to set the current percentage
-#if ENABLED(GraphicalLCD)
+ // On the Info Screen, display XY with one decimal place when possible
+ //#define LCD_DECIMAL_SMALL_XY
+
+ // Add an 'M73' G-code to set the current percentage
#define LCD_SET_PROGRESS_MANUALLY
-#endif
-// Show the E position (filament used) during printing
-//#define LCD_SHOW_E_TOTAL
-#if ENABLED(SHOW_BOOTSCREEN)
- #define BOOTSCREEN_TIMEOUT 2000 // (ms) Total Duration to display the boot screen(s)
+ // Show the E position (filament used) during printing
+ //#define LCD_SHOW_E_TOTAL
#endif
-#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && (HAS_GRAPHICAL_LCD || HAS_CHARACTER_LCD)
+#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, EXTENSIBLE_UI)
//#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
- #if HAS_GRAPHICAL_LCD
+ #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
#endif
- #if HAS_CHARACTER_LCD
+ #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
//#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
#if ENABLED(LCD_PROGRESS_BAR)
#define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar
@@ -1137,13 +1193,26 @@
#endif
#if ENABLED(SDSUPPORT)
+ /**
+ * SD Card SPI Speed
+ * May be required to resolve "volume init" errors.
+ *
+ * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED
+ * otherwise full speed will be applied.
+ *
+ * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED']
+ */
+ //#define SD_SPI_SPEED SPI_HALF_SPEED
// The standard SD detect circuit reads LOW when media is inserted and HIGH when empty.
// Enable this option and set to HIGH if your SD cards are incorrectly detected.
#define SD_DETECT_STATE HIGH
+ //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up
//#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash)
+ //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping
+
#define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls
#define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished
@@ -1155,8 +1224,11 @@
#define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing
+ //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM
//#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files
+ //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted
+
#define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27")
#if ENABLED(PRINTER_EVENT_LEDS)
@@ -1175,10 +1247,12 @@
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
+ //#define POWER_LOSS_RECOVER_ZHOME // Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#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. Set to -1 to disable default pin on boards without module.
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
- //#define POWER_LOSS_PULL // Set pullup / pulldown as appropriate
+ //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
+ //#define POWER_LOSS_PULLDOWN
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
@@ -1225,6 +1299,10 @@
// Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
#endif
+ // Allow international symbols in long filenames. To display correctly, the
+ // LCD's font must contain the characters. Check your selected LCD language.
+ //#define UTF_FILENAME_SUPPORT
+
// This allows hosts to request long names for files and folders with M33
#define LONG_FILENAME_HOST_SUPPORT
@@ -1269,9 +1347,6 @@
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
- #define USB_CS_PIN SDSS
- #define USB_INTR_PIN SD_DETECT_PIN
-
/**
* USB Host Shield Library
*
@@ -1282,7 +1357,18 @@
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
+ //#define USE_UHS2_USB
//#define USE_UHS3_USB
+
+ /**
+ * Native USB Host supported by some boards (USB OTG)
+ */
+ //#define USE_OTG_USB_HOST
+
+ #if DISABLED(USE_OTG_USB_HOST)
+ #define USB_CS_PIN SDSS
+ #define USB_INTR_PIN SD_DETECT_PIN
+ #endif
#endif
/**
@@ -1308,13 +1394,16 @@
* Set this option to one of the following (or the board's defaults apply):
*
* LCD - Use the SD drive in the external LCD controller.
- * ONBOARD - Use the SD drive on the control board. (No SD_DETECT_PIN. M21 to init.)
+ * ONBOARD - Use the SD drive on the control board.
* CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file).
*
* :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ]
*/
//#define SDCARD_CONNECTION LCD
+ // Enable if SD detect is rendered useless (e.g., by using an SD extender)
+ //#define NO_SD_DETECT
+
#endif // SDSUPPORT
/**
@@ -1335,7 +1424,7 @@
* controller events, as there is a trade-off between reliable
* printing performance versus fast display updates.
*/
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
// Show SD percentage next to the progress bar
//#define DOGM_SD_PERCENT
@@ -1350,7 +1439,7 @@
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
#define USE_BIG_EDIT_FONT
- // A smaller font may be used on the Info Screen. Costs 2300 bytes of PROGMEM.
+ // A smaller font may be used on the Info Screen. Costs 2434 bytes of PROGMEM.
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
//#define USE_SMALL_INFOFONT
@@ -1410,7 +1499,7 @@
#endif
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
//
// Additional options for DGUS / DWIN displays
@@ -1449,6 +1538,19 @@
#endif
#endif // HAS_DGUS_LCD
+//
+// Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
+//
+#if EITHER(DOGLCD, TOUCH_UI_FTDI_EVE)
+ //#define LCD_LANGUAGE_2 fr
+ //#define LCD_LANGUAGE_3 de
+ //#define LCD_LANGUAGE_4 es
+ //#define LCD_LANGUAGE_5 it
+ #ifdef LCD_LANGUAGE_2
+ //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change
+ #endif
+#endif
+
//
// Touch UI for the FTDI Embedded Video Engine (EVE)
//
@@ -1516,18 +1618,14 @@
//#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾
//#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬
#endif
+
+ // Cyrillic character set, costs about 27KiB of flash
+ //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET
#endif
// Use a smaller font when labels don't fit buttons
#define TOUCH_UI_FIT_TEXT
- // Allow language selection from menu at run-time (otherwise use LCD_LANGUAGE)
- //#define LCD_LANGUAGE_1 en
- //#define LCD_LANGUAGE_2 fr
- //#define LCD_LANGUAGE_3 de
- //#define LCD_LANGUAGE_4 es
- //#define LCD_LANGUAGE_5 it
-
// Use a numeric passcode for "Screen lock" keypad.
// (recommended for smaller displays)
//#define TOUCH_UI_PASSCODE
@@ -1540,10 +1638,9 @@
#endif
//
-// FSMC / SPI Graphical TFT
+// Classic UI Options
//
#if TFT_SCALED_DOGLCD
- //#define GRAPHICAL_TFT_ROTATE_180
//#define TFT_MARLINUI_COLOR 0xFFFF // White
//#define TFT_MARLINBG_COLOR 0x0000 // Black
//#define TFT_DISABLED_COLOR 0x0003 // Almost black
@@ -1694,6 +1791,10 @@
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
#endif
+#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS)
+ //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space
+#endif
+
/**
* Repeatedly attempt G29 leveling until it succeeds.
* Stop after G29_MAX_RETRIES attempts.
@@ -1787,6 +1888,7 @@
#define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections
//#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles
//#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes
+ //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure
#endif
// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes.
@@ -1976,27 +2078,26 @@
* Be sure to turn off auto-retract during filament change.
*
* Note that M207 / M208 / M209 settings are saved to EEPROM.
- *
*/
#if !ENABLED(ABL_UBL, GraphicalLCD, TMC_2209) || ENABLED(SKR13)
#define FWRETRACT
#endif
#if ENABLED(FWRETRACT)
- #define FWRETRACT_AUTORETRACT // Override slicer retractions
+ #define FWRETRACT_AUTORETRACT // Override slicer retractions
#if ENABLED(FWRETRACT_AUTORETRACT)
- #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
- #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
+ #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
+ #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
#endif
- #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
- #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
- #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
- #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
- #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
- #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
- #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
- #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
+ #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
+ #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
+ #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
+ #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
+ #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
+ #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
+ #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
+ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
#if ENABLED(MIXING_EXTRUDER)
- //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
+ //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
#endif
#endif
@@ -2254,14 +2355,20 @@
#if HAS_TRINAMIC_CONFIG
#define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current
- #define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256
+
+ /**
+ * Interpolate microsteps to 256
+ * Override for each driver with _INTERPOLATE settings below
+ */
+ #define INTERPOLATE true
#if AXIS_IS_TMC(X)
#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_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_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
+ //#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis
#endif
#if AXIS_IS_TMC(X2)
@@ -2270,6 +2377,7 @@
#define X2_MICROSTEPS 16
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
+ //#define X2_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Y)
@@ -2278,6 +2386,7 @@
#define Y_MICROSTEPS 16
#define Y_RSENSE 0.11
#define Y_CHAIN_POS -1
+ //#define Y_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Y2)
@@ -2286,6 +2395,7 @@
#define Y2_MICROSTEPS 16
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
+ //#define Y2_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Z)
@@ -2294,6 +2404,7 @@
#define Z_MICROSTEPS 16
#define Z_RSENSE 0.11
#define Z_CHAIN_POS -1
+ //#define Z_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Z2)
@@ -2302,6 +2413,7 @@
#define Z2_MICROSTEPS 16
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
+ //#define Z2_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Z3)
@@ -2310,6 +2422,7 @@
#define Z3_MICROSTEPS 16
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
+ //#define Z3_INTERPOLATE true
#endif
#if AXIS_IS_TMC(Z4)
@@ -2318,6 +2431,7 @@
#define Z4_MICROSTEPS 16
#define Z4_RSENSE 0.11
#define Z4_CHAIN_POS -1
+ //#define Z4_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E0)
@@ -2325,6 +2439,7 @@
#define E0_MICROSTEPS 16
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
+ //#define E0_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E1)
@@ -2332,6 +2447,7 @@
#define E1_MICROSTEPS 16
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
+ //#define E1_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E2)
@@ -2339,6 +2455,7 @@
#define E2_MICROSTEPS 16
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
+ //#define E2_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E3)
@@ -2346,6 +2463,7 @@
#define E3_MICROSTEPS 16
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
+ //#define E3_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E4)
@@ -2353,6 +2471,7 @@
#define E4_MICROSTEPS 16
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
+ //#define E4_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E5)
@@ -2360,6 +2479,7 @@
#define E5_MICROSTEPS 16
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
+ //#define E5_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E6)
@@ -2367,6 +2487,7 @@
#define E6_MICROSTEPS 16
#define E6_RSENSE 0.11
#define E6_CHAIN_POS -1
+ //#define E6_INTERPOLATE true
#endif
#if AXIS_IS_TMC(E7)
@@ -2374,6 +2495,7 @@
#define E7_MICROSTEPS 16
#define E7_RSENSE 0.11
#define E7_CHAIN_POS -1
+ //#define E7_INTERPOLATE true
#endif
/**
@@ -2494,10 +2616,26 @@
* CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V)
* CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9
*
- * Define you own with
+ * Define your own with:
* { , , hysteresis_start[1..8] }
*/
- #define CHOPPER_TIMING CHOPPER_DEFAULT_24V
+ #define CHOPPER_TIMING CHOPPER_DEFAULT_24V // All axes (override below)
+ //#define CHOPPER_TIMING_X CHOPPER_DEFAULT_12V // For X Axes (override below)
+ //#define CHOPPER_TIMING_X2 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_12V // For Y Axes (override below)
+ //#define CHOPPER_TIMING_Y2 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_Z CHOPPER_DEFAULT_12V // For Z Axes (override below)
+ //#define CHOPPER_TIMING_Z2 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_Z3 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_Z4 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E CHOPPER_DEFAULT_12V // For Extruders (override below)
+ //#define CHOPPER_TIMING_E1 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E2 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E3 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E4 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E5 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E6 CHOPPER_DEFAULT_12V
+ //#define CHOPPER_TIMING_E7 CHOPPER_DEFAULT_12V
/**
* Monitor Trinamic drivers
@@ -2926,11 +3064,18 @@
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
+ //#define SPINDLE_SERVO // A servo converting an angle to spindle power
+ #ifdef SPINDLE_SERVO
+ #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control
+ #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle
+ #endif
+
/**
* Speed / Power can be set ('M3 S') and displayed in terms of:
* - PWM255 (S0 - S255)
* - PERCENT (S0 - S100)
* - RPM (S0 - S50000) Best for use with a spindle
+ * - SERVO (S0 - S180)
*/
#define CUTTER_POWER_UNIT PWM255
@@ -2973,6 +3118,10 @@
#define SPEED_POWER_MAX 100 // (%) 0-100
#define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ // Define the minimum and maximum test pulse time values for a laser test fire function
+ #define LASER_TEST_PULSE_MIN 1 // Used with Laser Control Menu
+ #define LASER_TEST_PULSE_MAX 999 // Caution: Menu may not show more than 3 characters
+
/**
* Enable inline laser power to be handled in the planner / stepper routines.
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
@@ -2981,7 +3130,7 @@
* This allows the laser to keep in perfect sync with the planner and removes
* the powerup/down delay since lasers require negligible time.
*/
- #define LASER_POWER_INLINE
+ //#define LASER_POWER_INLINE
#if ENABLED(LASER_POWER_INLINE)
/**
@@ -3206,6 +3355,8 @@
//#define GCODE_QUOTED_STRINGS // Support for quoted string parameters
#endif
+//#define MEATPACK // Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack)
+
//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase
//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW
@@ -3405,6 +3556,25 @@
//#define JOYSTICK_DEBUG
#endif
+/**
+ * Mechanical Gantry Calibration
+ * Modern replacement for the Prusa TMC_Z_CALIBRATION.
+ * Adds capability to work with any adjustable current drivers.
+ * Implemented as G34 because M915 is deprecated.
+ */
+//#define MECHANICAL_GANTRY_CALIBRATION
+#if ENABLED(MECHANICAL_GANTRY_CALIBRATION)
+ #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma
+ #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move
+ #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move
+ //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction
+
+ //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle
+ //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM
+ //#define GANTRY_CALIBRATION_COMMANDS_PRE ""
+ #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position
+#endif
+
/**
* MAX7219 Debug Matrix
*
@@ -3451,6 +3621,13 @@
// Default behavior is limited to Z axis only.
#endif
+/**
+ * Ethernet. Use M552 to enable and set the IP address.
+ */
+#if HAS_ETHERNET
+ #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network
+#endif
+
/**
* WiFi Support (Espressif ESP32 WiFi)
*/
@@ -3474,16 +3651,26 @@
#endif
/**
- * Průša Multi-Material Unit v2
+ * Průša Multi-Material Unit (MMU)
* Enable in Configuration.h
+ *
+ * These devices allow a single stepper driver on the board to drive
+ * multi-material feeders with any number of stepper motors.
*/
-#if ENABLED(PRUSA_MMU2)
-
+#if HAS_PRUSA_MMU1
+ /**
+ * This option only allows the multiplexer to switch on tool-change.
+ * Additional options to configure custom E moves are pending.
+ *
+ * Override the default DIO selector pins here, if needed.
+ * Some pins files may provide defaults for these pins.
+ */
+ //#define E_MUX0_PIN 40 // Always Required
+ //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
+ //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
+#elif HAS_PRUSA_MMU2
// Serial port used for communication with MMU2.
- // For AVR enable the UART port used for the MMU. (e.g., mmuSerial)
- // For 32-bit boards check your HAL for available serial ports. (e.g., Serial2)
#define MMU2_SERIAL_PORT 2
- #define MMU2_SERIAL mmuSerial
// Use hardware reset for MMU if a pin is defined for it
//#define MMU2_RST_PIN 23
@@ -3496,7 +3683,7 @@
// Add an LCD menu for MMU2
//#define MMU2_MENUS
- #if ENABLED(MMU2_MENUS)
+ #if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S)
// Settings for filament load / unload from the LCD menu.
// This is for Průša MK3-style extruders. Customize for your hardware.
#define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
@@ -3521,29 +3708,12 @@
{ -50.0, 2000 }
#endif
- /**
- * MMU Extruder Sensor
- *
- * Support for a Průša (or other) IR Sensor to detect filament near the extruder
- * and make loading more reliable. Suitable for an extruder equipped with a filament
- * sensor less than 38mm from the gears.
- *
- * During loading the extruder will stop when the sensor is triggered, then do a last
- * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
- * If all attempts fail, a filament runout will be triggered.
- */
- //#define MMU_EXTRUDER_SENSOR
- #if ENABLED(MMU_EXTRUDER_SENSOR)
- #define MMU_LOADING_ATTEMPTS_NR 5 //max. number of attempts to load filament if first load fail
- #endif
-
/**
* Using a sensor like the MMU2S
* This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S.
* See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11
*/
- //#define PRUSA_MMU2_S_MODE
- #if ENABLED(PRUSA_MMU2_S_MODE)
+ #if HAS_PRUSA_MMU2S
#define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries)
#define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min)
@@ -3559,11 +3729,29 @@
#define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \
{ -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE }
+ #else
+
+ /**
+ * MMU1 Extruder Sensor
+ *
+ * Support for a Průša (or other) IR Sensor to detect filament near the extruder
+ * and make loading more reliable. Suitable for an extruder equipped with a filament
+ * sensor less than 38mm from the gears.
+ *
+ * During loading the extruder will stop when the sensor is triggered, then do a last
+ * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
+ * If all attempts fail, a filament runout will be triggered.
+ */
+ //#define MMU_EXTRUDER_SENSOR
+ #if ENABLED(MMU_EXTRUDER_SENSOR)
+ #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
+ #endif
+
#endif
//#define MMU2_DEBUG // Write debug info to serial output
-#endif // PRUSA_MMU2
+#endif // HAS_PRUSA_MMU2
/**
* Advanced Print Counter settings
@@ -3586,6 +3774,11 @@
//
//#define M100_FREE_MEMORY_WATCHER
+//
+// M42 - Set pin states
+//
+//#define DIRECT_PIN_CONTROL
+
//
// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe
//
diff --git a/Marlin/Makefile b/Marlin/Makefile
index 68dd05bdfb..49cb960b92 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -22,8 +22,10 @@
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
# changes, you can use * as a wild card (e.g. UPLOAD_PORT = /dev/tty.usb*).
#
-# 3. Set the line containing "MCU" to match your board's processor.
-# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
+# 3. Set the line containing "MCU" to match your board's processor. Set
+# "PROG_MCU" as the AVR part name corresponding to "MCU". You can use the
+# following command to get a list of correspondences: `avrdude -c alf -p x`
+# Older boards are atmega8 based, newer ones like Arduino Mini, Bluetooth
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
# change F_CPU to 8000000. If you are using Gen7 electronics, you
# probably need to use 20000000. Either way, you must regenerate
@@ -34,18 +36,18 @@
# 5. Type "make upload", reset your Arduino board, and press enter to
# upload your program to the Arduino board.
#
-# Note that all settings at the top of this file can be overriden from
+# Note that all settings at the top of this file can be overridden from
# the command line with, for example, "make HARDWARE_MOTHERBOARD=71"
#
# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
-# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino
+# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino
#
# To compile and upload simply add "upload" to the end of the line...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
-# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino upload
+# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino upload
#
# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or
# start upload manually (using stk500) like so:
@@ -57,7 +59,26 @@
#
# This defines the board to compile for (see boards.h for your board's ID)
-HARDWARE_MOTHERBOARD ?= 11
+HARDWARE_MOTHERBOARD ?= 1020
+
+ifeq ($(OS),Windows_NT)
+ # Windows
+ ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino
+ ARDUINO_USER_DIR ?= ${HOME}/Arduino
+else
+ UNAME_S := $(shell uname -s)
+ ifeq ($(UNAME_S),Linux)
+ # Linux
+ ARDUINO_INSTALL_DIR ?= /usr/share/arduino
+ ARDUINO_USER_DIR ?= ${HOME}/Arduino
+ endif
+ ifeq ($(UNAME_S),Darwin)
+ # Darwin (macOS)
+ ARDUINO_INSTALL_DIR ?= /Applications/Arduino.app/Contents/Java
+ ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino
+ AVR_TOOLS_PATH ?= /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/
+ endif
+endif
# Arduino source install directory, and version number
# On most linuxes this will be /usr/share/arduino
@@ -67,32 +88,38 @@ ARDUINO_VERSION ?= 106
# The installed Libraries are in the User folder
ARDUINO_USER_DIR ?= ${HOME}/Arduino
-# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin)
+# You can optionally set a path to the avr-gcc tools.
+# Requires a trailing slash. For example, /usr/local/avr-gcc/bin/
AVR_TOOLS_PATH ?=
-#Programmer configuration
+# Programmer configuration
UPLOAD_RATE ?= 57600
AVRDUDE_PROGRAMMER ?= arduino
-# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
+# On most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
UPLOAD_PORT ?= /dev/ttyUSB0
-#Directory used to build files in, contains all the build files, from object files to the final hex file
-#on linux it is best to put an absolute path like /home/username/tmp .
+# Directory used to build files in, contains all the build files, from object
+# files to the final hex file on linux it is best to put an absolute path
+# like /home/username/tmp .
BUILD_DIR ?= applet
# This defines whether Liquid_TWI2 support will be built
LIQUID_TWI2 ?= 0
-# this defines if Wire is needed
+# This defines if Wire is needed
WIRE ?= 0
-# this defines if U8GLIB is needed (may require RELOC_WORKAROUND)
-U8GLIB ?= 1
+# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h)
+# Disabling this (and SPEAKER) saves approximatively 350 bytes of memory.
+TONE ?= 1
-# this defines whether to include the Trinamic TMCStepper library
-TMC ?= 1
+# This defines if U8GLIB is needed (may require RELOC_WORKAROUND)
+U8GLIB ?= 0
-# this defines whether to include the AdaFruit NeoPixel library
+# This defines whether to include the Trinamic TMCStepper library
+TMC ?= 0
+
+# This defines whether to include the AdaFruit NeoPixel library
NEOPIXEL ?= 0
############
@@ -208,7 +235,8 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1119)
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
- MCU ?= atmega1280
+ MCU ?= atmega1280
+ PROG_MCU ?= m1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
@@ -350,9 +378,11 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1320)
# Minitronics v1.0/1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1400)
MCU ?= atmega1281
+ PROG_MCU ?= m1281
# Silvergate v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1401)
MCU ?= atmega1281
+ PROG_MCU ?= m1281
#
# Sanguinololu and Derivatives - ATmega644P, ATmega1284P
@@ -362,46 +392,57 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1401)
else ifeq ($(HARDWARE_MOTHERBOARD),1500)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Sanguinololu 1.2 and above
else ifeq ($(HARDWARE_MOTHERBOARD),1501)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Melzi
else ifeq ($(HARDWARE_MOTHERBOARD),1502)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Melzi V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1503)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Melzi with ATmega1284 (MaKr3d version)
else ifeq ($(HARDWARE_MOTHERBOARD),1504)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Melzi Creality3D board (for CR-10 etc)
else ifeq ($(HARDWARE_MOTHERBOARD),1505)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Melzi Malyan M150 board
else ifeq ($(HARDWARE_MOTHERBOARD),1506)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Tronxy X5S
else ifeq ($(HARDWARE_MOTHERBOARD),1507)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# STB V1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1508)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Azteeg X1
else ifeq ($(HARDWARE_MOTHERBOARD),1509)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
# Anet 1.0 (Melzi clone)
else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
@@ -411,50 +452,61 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1510)
else ifeq ($(HARDWARE_MOTHERBOARD),1600)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Gen3+
else ifeq ($(HARDWARE_MOTHERBOARD),1601)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Gen6
else ifeq ($(HARDWARE_MOTHERBOARD),1602)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Gen6 deluxe
else ifeq ($(HARDWARE_MOTHERBOARD),1603)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Gen7 custom (Alfons3 Version)
else ifeq ($(HARDWARE_MOTHERBOARD),1604)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644
+ PROG_MCU ?= m644
F_CPU ?= 20000000
# Gen7 v1.1, v1.2
else ifeq ($(HARDWARE_MOTHERBOARD),1605)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
+ PROG_MCU ?= m644p
F_CPU ?= 20000000
# Gen7 v1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1606)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
+ PROG_MCU ?= m644p
F_CPU ?= 20000000
# Gen7 v1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1607)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
F_CPU ?= 20000000
# Alpha OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),1608)
HARDWARE_VARIANT ?= SanguinoA
MCU ?= atmega644
+ PROG_MCU ?= m644
# Final OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),1609)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
# Sethi 3D_1
else ifeq ($(HARDWARE_MOTHERBOARD),1610)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
+ PROG_MCU ?= m644p
#
# Teensyduino - AT90USB1286, AT90USB1286P
@@ -464,51 +516,60 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1610)
else ifeq ($(HARDWARE_MOTHERBOARD),1700)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# Printrboard (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1701)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# Printrboard Revision F (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1702)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# Brainwave (AT90USB646)
else ifeq ($(HARDWARE_MOTHERBOARD),1703)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb646
+ PROG_MCU ?= usb646
# Brainwave Pro (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1704)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# SAV Mk-I (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1705)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# Teensy++2.0 (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1706)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# 5DPrint D8 Driver Board
else ifeq ($(HARDWARE_MOTHERBOARD),1707)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
+ PROG_MCU ?= usb1286
# UltiMachine Archim1 (with DRV8825 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
HARDWARE_VARIANT ?= archim
MCPU = cortex-m3
- F_CPU = 84000000L
+ F_CPU = 84000000
IS_MCU = 0
# UltiMachine Archim2 (with TMC2130 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3024)
HARDWARE_VARIANT ?= archim
MCPU = cortex-m3
- F_CPU = 84000000L
+ F_CPU = 84000000
IS_MCU = 0
endif
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
# if you are setting this to something other than 16MHz
+# Do not put the UL suffix, it's done later on.
# Set to 16Mhz if not yet set.
F_CPU ?= 16000000
@@ -518,7 +579,8 @@ IS_MCU ?= 1
ifeq ($(IS_MCU),1)
# Set to arduino, ATmega2560 if not yet set.
HARDWARE_VARIANT ?= arduino
- MCU ?= atmega2560
+ MCU ?= atmega2560
+ PROG_MCU ?= m2560
TOOL_PREFIX = avr
MCU_FLAGS = -mmcu=$(MCU)
@@ -549,27 +611,36 @@ VPATH += $(BUILD_DIR)
VPATH += $(HARDWARE_SRC)
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI
+ # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8)
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
+ # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
endif
ifeq ($(IS_MCU),1)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
+ # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial
+ # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
endif
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
+
ifeq ($(LIQUID_TWI2), 1)
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
+ WIRE = 1
+ VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
endif
ifeq ($(WIRE), 1)
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
+ # Old libraries (avr-core 1.6.21 / Arduino < 1.6.8)
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/utility
+ # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src
+ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src/utility
endif
ifeq ($(NEOPIXEL), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
@@ -641,13 +712,23 @@ ifeq ($(WIRE), 1)
LIB_CXXSRC += Wire.cpp
endif
+ifeq ($(TONE), 1)
+ LIB_CXXSRC += Tone.cpp
+endif
+
ifeq ($(U8GLIB), 1)
LIB_CXXSRC += U8glib.cpp
- LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
+ LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c \
+ u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c \
+ u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
endif
ifeq ($(TMC), 1)
- LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
+ LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp \
+ CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp \
+ DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp \
+ SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp \
+ TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
endif
ifeq ($(RELOC_WORKAROUND), 1)
@@ -689,17 +770,23 @@ REMOVE = rm -f
MV = mv -f
# Place -D or -U options here
-CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
+CDEFS = -DF_CPU=$(F_CPU)UL ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
CXXDEFS = $(CDEFS)
ifeq ($(HARDWARE_VARIANT), Teensy)
- CDEFS += -DUSB_SERIAL
+ CDEFS += -DUSB_SERIAL
LIB_SRC += usb.c pins_teensy.c
LIB_CXXSRC += usb_api.cpp
else ifeq ($(HARDWARE_VARIANT), archim)
- CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"'
- LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp USBCore.cpp
+ CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__
+ CDEFS += -DUSB_VID=0x27B1 -DUSB_PID=0x0001 -DUSBCON
+ CDEFS += '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"'
+
+ LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp \
+ UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp \
+ PluggableUSB.cpp USBCore.cpp
+
LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
ifeq ($(U8GLIB), 1)
@@ -725,16 +812,20 @@ CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
endif
+
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD)
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD)
ASFLAGS := $(CDEFS)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+
ifeq ($(HARDWARE_VARIANT), archim)
LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align
LD_SUFFIX = $(LDLIBS)
- LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
+
+ LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty
+ LDFLAGS += -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
else
LD_PREFIX = -Wl,--gc-sections,--relax
LDFLAGS = -lm
@@ -750,7 +841,7 @@ else
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
endif
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
- -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
+ -p$(PROG_MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
-b$(UPLOAD_RATE)
# Since Marlin 2.0, the source files may be distributed into several
@@ -851,7 +942,7 @@ extcoff: $(TARGET).elf
.elf.eep:
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
- --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
.elf.lss:
@@ -865,7 +956,7 @@ extcoff: $(TARGET).elf
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
$(Pecho) " CXX $@"
- $P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
+ $P $(CXX) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
# Object files that were found in "src" will be stored in $(BUILD_DIR)
# in directories that mirror the structure of "src"
diff --git a/Marlin/Version.h b/Marlin/Version.h
index fe0724fbfc..eb2f9f9a14 100644
--- a/Marlin/Version.h
+++ b/Marlin/Version.h
@@ -54,7 +54,7 @@
* 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"
+//#define SOURCE_CODE_URL "github.com/MarlinFirmware/Marlin"
/**
* Default generic printer UUID.
@@ -65,7 +65,7 @@
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
-//#define WEBSITE_URL "https://marlinfw.org"
+//#define WEBSITE_URL "marlinfw.org"
/**
* Set the vendor info the serial USB interface, if changable
diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp
index 58d57c8ee5..4c45a5d78e 100644
--- a/Marlin/src/HAL/AVR/HAL.cpp
+++ b/Marlin/src/HAL/AVR/HAL.cpp
@@ -24,6 +24,13 @@
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
+#ifdef USBCON
+ DefaultSerial MSerial(false, Serial);
+ #ifdef BLUETOOTH
+ BTSerial btSerial(false, bluetoothSerial);
+ #endif
+#endif
+
// ------------------------
// Public Variables
// ------------------------
diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h
index 41f1acd32f..2b565bbe13 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
@@ -81,7 +82,15 @@ typedef int8_t pin_t;
// Serial ports
#ifdef USBCON
- #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
+ #include "../../core/serial_hook.h"
+ typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
+ extern DefaultSerial MSerial;
+ #ifdef BLUETOOTH
+ typedef ForwardSerial0Type< decltype(bluetoothSerial) > BTSerial;
+ extern BTSerial btSerial;
+ #endif
+
+ #define MYSERIAL0 TERN(BLUETOOTH, btSerial, MSerial)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
@@ -96,6 +105,13 @@ typedef int8_t pin_t;
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
+ #error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #endif
+ #define MMU2_SERIAL mmuSerial
+#endif
+
#ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
@@ -119,12 +135,18 @@ void HAL_init();
inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- int freeMemory();
-}
-#pragma GCC diagnostic pop
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+extern "C" int freeMemory();
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
// ADC
#ifdef DIDR2
diff --git a/Marlin/src/HAL/AVR/HAL_SPI.cpp b/Marlin/src/HAL/AVR/HAL_SPI.cpp
index 31e589746c..3e5572e559 100644
--- a/Marlin/src/HAL/AVR/HAL_SPI.cpp
+++ b/Marlin/src/HAL/AVR/HAL_SPI.cpp
@@ -34,17 +34,17 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
- OUT_WRITE(SS_PIN, HIGH);
- SET_OUTPUT(SCK_PIN);
- SET_INPUT(MISO_PIN);
- SET_OUTPUT(MOSI_PIN);
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ SET_OUTPUT(SD_SCK_PIN);
+ SET_INPUT(SD_MISO_PIN);
+ SET_OUTPUT(SD_MOSI_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
- //SET_OUTPUT(SS_PIN);
+ //SET_OUTPUT(SD_SS_PIN);
// set SS high - may be chip select for another SPI device
//#if SET_SPI_SS_HIGH
- //WRITE(SS_PIN, HIGH);
+ //WRITE(SD_SS_PIN, HIGH);
//#endif
// set a default rate
spiInit(1);
@@ -195,19 +195,19 @@ void spiBegin() {
// no interrupts during byte receive - about 8µs
cli();
// output pin high - like sending 0xFF
- WRITE(MOSI_PIN, HIGH);
+ WRITE(SD_MOSI_PIN, HIGH);
LOOP_L_N(i, 8) {
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
nop; // adjust so SCK is nice
nop;
data <<= 1;
- if (READ(MISO_PIN)) data |= 1;
+ if (READ(SD_MISO_PIN)) data |= 1;
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
}
sei();
@@ -225,10 +225,10 @@ void spiBegin() {
// no interrupts during byte send - about 8µs
cli();
LOOP_L_N(i, 8) {
- WRITE(SCK_PIN, LOW);
- WRITE(MOSI_PIN, data & 0x80);
+ WRITE(SD_SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, data & 0x80);
data <<= 1;
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
}
nop; // hold SCK high for a few ns
@@ -236,7 +236,7 @@ void spiBegin() {
nop;
nop;
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
sei();
}
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp
index 63599efd41..904395de1d 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.cpp
+++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp
@@ -454,7 +454,7 @@ void MarlinSerial::flush() {
}
template
-void MarlinSerial::write(const uint8_t c) {
+size_t MarlinSerial::write(const uint8_t c) {
if (Cfg::TX_SIZE == 0) {
_written = true;
@@ -480,7 +480,7 @@ void MarlinSerial::write(const uint8_t c) {
// location". This makes sure flush() won't return until the bytes
// actually got written
B_TXC = 1;
- return;
+ return 1;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
@@ -510,6 +510,7 @@ void MarlinSerial::write(const uint8_t c) {
// Enable TX ISR - Non atomic, but it will eventually enable TX ISR
B_UDRIE = 1;
}
+ return 1;
}
template
@@ -556,161 +557,6 @@ void MarlinSerial::flushTX() {
}
}
-/**
- * Imports from print.h
- */
-
-template
-void MarlinSerial::print(char c, int base) {
- print((long)c, base);
-}
-
-template
-void MarlinSerial::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-template
-void MarlinSerial::print(int n, int base) {
- print((long)n, base);
-}
-
-template
-void MarlinSerial::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-template
-void MarlinSerial::print(long n, int base) {
- if (base == 0) write(n);
- else if (base == 10) {
- if (n < 0) { print('-'); n = -n; }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-template
-void MarlinSerial::println() {
- print('\r');
- print('\n');
-}
-
-template
-void MarlinSerial::println(const String& s) {
- print(s);
- println();
-}
-
-template
-void MarlinSerial::println(const char c[]) {
- print(c);
- println();
-}
-
-template
-void MarlinSerial::println(char c, int base) {
- print(c, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-template
-void MarlinSerial::println(int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-
-template
-void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-template
-void MarlinSerial::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits) rounding *= 0.1;
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
-}
-
// Hookup ISR handlers
ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) {
MarlinSerial>::store_rxd_char();
@@ -720,11 +566,9 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
MarlinSerial>::_tx_udr_empty_irq();
}
-// Preinstantiate
-template class MarlinSerial>;
-
-// Instantiate
-MarlinSerial> customizedSerial1;
+// Because of the template definition above, it's required to instantiate the template to have all method generated
+template class MarlinSerial< MarlinSerialCfg >;
+MSerialT customizedSerial1(MSerialT::HasEmergencyParser);
#ifdef SERIAL_PORT_2
@@ -737,12 +581,8 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> customizedSerial2;
-
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT2 customizedSerial2(MSerialT2::HasEmergencyParser);
#endif
#ifdef MMU2_SERIAL_PORT
@@ -755,12 +595,8 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> mmuSerial;
-
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT3 mmuSerial(MSerialT3::HasEmergencyParser);
#endif
#ifdef LCD_SERIAL_PORT
@@ -773,12 +609,9 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> lcdSerial;
-
+ template class MarlinSerial< LCDSerialCfg >;
+ MSerialT4 lcdSerial(MSerialT4::HasEmergencyParser);
+
#if HAS_DGUS_LCD
template
typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() {
@@ -796,7 +629,7 @@ MarlinSerial> customizedSerial1;
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
- HardwareSerial bluetoothSerial;
+ MSerialT5 bluetoothSerial(false);
#endif
#endif // __AVR__
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h
index 8a0423d143..93a3fb84d1 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.h
+++ b/Marlin/src/HAL/AVR/MarlinSerial.h
@@ -34,6 +34,7 @@
#include
#include "../../inc/MarlinConfigPre.h"
+#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -135,10 +136,6 @@
UART_DECL(3);
#endif
- #define DEC 10
- #define HEX 16
- #define OCT 8
- #define BIN 2
#define BYTE 0
// Templated type selector
@@ -202,60 +199,30 @@
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
- public:
-
+ public:
FORCE_INLINE static void store_rxd_char();
FORCE_INLINE static void _tx_udr_empty_irq();
- public:
- MarlinSerial() {};
- static void begin(const long);
- static void end();
- static int peek();
- static int read();
- static void flush();
- static ring_buffer_pos_t available();
- static void write(const uint8_t c);
- static void flushTX();
- #if HAS_DGUS_LCD
- static ring_buffer_pos_t get_tx_buffer_free();
- #endif
+ public:
+ static void begin(const long);
+ static void end();
+ static int peek();
+ static int read();
+ static void flush();
+ static ring_buffer_pos_t available();
+ static size_t write(const uint8_t c);
+ static void flushTX();
+ #if HAS_DGUS_LCD
+ static ring_buffer_pos_t get_tx_buffer_free();
+ #endif
- static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
+ enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
+ static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
- FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
- FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
- FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
- FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = BYTE);
- static void print(unsigned char, int = BYTE);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = BYTE);
- static void println(unsigned char, int = BYTE);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
- private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
+ FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
+ FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
+ FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
+ FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
};
template
@@ -270,12 +237,13 @@
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
- extern MarlinSerial> customizedSerial1;
+
+ typedef Serial0Type< MarlinSerial< MarlinSerialCfg > > MSerialT;
+ extern MSerialT customizedSerial1;
#ifdef SERIAL_PORT_2
-
- extern MarlinSerial> customizedSerial2;
-
+ typedef Serial0Type< MarlinSerial< MarlinSerialCfg > > MSerialT2;
+ extern MSerialT2 customizedSerial2;
#endif
#endif // !USBCON
@@ -294,7 +262,8 @@
static constexpr bool RX_OVERRUNS = false;
};
- extern MarlinSerial> mmuSerial;
+ typedef Serial0Type< MarlinSerial< MMU2SerialCfg > > MSerialT3;
+ extern MSerial3 mmuSerial;
#endif
#ifdef LCD_SERIAL_PORT
@@ -322,11 +291,13 @@
#endif
};
- extern MarlinSerial> lcdSerial;
+ typedef Serial0Type< MarlinSerial< LCDSerialCfg > > MSerialT4;
+ extern MSerialT4 lcdSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
- extern HardwareSerial bluetoothSerial;
+ typedef Serial0Type MSerialT5;
+ extern MSerialT5 bluetoothSerial;
#endif
diff --git a/Marlin/src/HAL/AVR/Servo.cpp b/Marlin/src/HAL/AVR/Servo.cpp
index 66ed993c6f..526352b773 100644
--- a/Marlin/src/HAL/AVR/Servo.cpp
+++ b/Marlin/src/HAL/AVR/Servo.cpp
@@ -48,7 +48,6 @@
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
* attached() - Return true if a servo is attached.
* detach() - Stop an attached servo from pulsing its i/o pin.
- *
*/
#ifdef __AVR__
diff --git a/Marlin/src/HAL/AVR/eeprom.cpp b/Marlin/src/HAL/AVR/eeprom.cpp
index c7906985eb..ee2a73e410 100644
--- a/Marlin/src/HAL/AVR/eeprom.cpp
+++ b/Marlin/src/HAL/AVR/eeprom.cpp
@@ -59,7 +59,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/AVR/endstop_interrupts.h b/Marlin/src/HAL/AVR/endstop_interrupts.h
index ae9a605acc..9fd9c38b86 100644
--- a/Marlin/src/HAL/AVR/endstop_interrupts.h
+++ b/Marlin/src/HAL/AVR/endstop_interrupts.h
@@ -124,7 +124,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MAX_PIN);
#endif
#endif
@@ -132,7 +132,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MIN_PIN);
#endif
#endif
@@ -140,7 +140,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MAX_PIN);
#endif
#endif
@@ -148,7 +148,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MIN_PIN);
#endif
#endif
@@ -156,7 +156,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MAX_PIN);
#endif
#endif
@@ -164,7 +164,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PIN);
#endif
#endif
@@ -172,7 +172,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MAX_PIN);
#endif
#endif
@@ -180,7 +180,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MIN_PIN);
#endif
#endif
@@ -188,7 +188,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MAX_PIN);
#endif
#endif
@@ -196,7 +196,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MIN_PIN);
#endif
#endif
@@ -204,7 +204,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MAX_PIN);
#endif
#endif
@@ -212,7 +212,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MIN_PIN);
#endif
#endif
@@ -220,7 +220,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MAX_PIN);
#endif
#endif
@@ -228,7 +228,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MIN_PIN);
#endif
#endif
@@ -236,7 +236,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MAX_PIN);
#endif
#endif
@@ -244,7 +244,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MIN_PIN);
#endif
#endif
@@ -252,7 +252,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PROBE_PIN);
#else
- static_assert(digitalPinHasPCICR(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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
diff --git a/Marlin/src/HAL/AVR/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp
index 29866bccf9..238c1124ad 100644
--- a/Marlin/src/HAL/AVR/fast_pwm.cpp
+++ b/Marlin/src/HAL/AVR/fast_pwm.cpp
@@ -185,8 +185,8 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
res_temp_phase_correct = rtf / 2;
}
- LIMIT(res_temp_fast, 1u, size);
- LIMIT(res_temp_phase_correct, 1u, size);
+ LIMIT(res_temp_fast, 1U, size);
+ LIMIT(res_temp_phase_correct, 1U, size);
// Calculate frequencies of test prescaler and resolution values
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h
index 2cf740a559..dac6b1b150 100644
--- a/Marlin/src/HAL/AVR/pinsDebug.h
+++ b/Marlin/src/HAL/AVR/pinsDebug.h
@@ -26,7 +26,7 @@
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
-#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H)
+#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
#define AVR_ATmega2560_FAMILY_PLUS_70 1
#endif
diff --git a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
index 46c03088d2..db3fdf1f76 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
@@ -22,15 +22,12 @@
* Structures for 2560 family boards that use more than 70 pins
*/
-#undef NUM_DIGITAL_PINS
-#if MB(BQ_ZUM_MEGA_3D)
+#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
+ #undef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 85
#elif MB(MIGHTYBOARD_REVE)
+ #undef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 80
-#elif MB(MINIRAMBO)
- #define NUM_DIGITAL_PINS 85
-#elif MB(SCOOVO_X9H)
- #define NUM_DIGITAL_PINS 85
#endif
#define PA 1
diff --git a/Marlin/src/HAL/AVR/spi_pins.h b/Marlin/src/HAL/AVR/spi_pins.h
index f3fa78e2bf..831972938a 100644
--- a/Marlin/src/HAL/AVR/spi_pins.h
+++ b/Marlin/src/HAL/AVR/spi_pins.h
@@ -51,15 +51,15 @@
#define AVR_SS_PIN 16
#endif
-#ifndef SCK_PIN
- #define SCK_PIN AVR_SCK_PIN
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN AVR_SCK_PIN
#endif
-#ifndef MISO_PIN
- #define MISO_PIN AVR_MISO_PIN
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN AVR_MISO_PIN
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN AVR_MOSI_PIN
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN AVR_MOSI_PIN
#endif
-#ifndef SS_PIN
- #define SS_PIN AVR_SS_PIN
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN AVR_SS_PIN
#endif
diff --git a/Marlin/src/HAL/AVR/timers.h b/Marlin/src/HAL/AVR/timers.h
index 6c40d32209..82eb8b14b1 100644
--- a/Marlin/src/HAL/AVR/timers.h
+++ b/Marlin/src/HAL/AVR/timers.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
diff --git a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
index c29b195578..cb95a48ccc 100644
--- a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
+++ b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include "../shared/Marduino.h"
#include "../shared/Delay.h"
@@ -189,5 +189,5 @@ uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL.cpp b/Marlin/src/HAL/DUE/HAL.cpp
index 4b9260c359..2ae70843f0 100644
--- a/Marlin/src/HAL/DUE/HAL.cpp
+++ b/Marlin/src/HAL/DUE/HAL.cpp
@@ -19,9 +19,7 @@
*/
/**
- * Description: HAL for Arduino Due and compatible (SAM3X8E)
- *
- * For ARDUINO_ARCH_SAM
+ * HAL for Arduino Due and compatible (SAM3X8E)
*/
#ifdef ARDUINO_ARCH_SAM
@@ -104,4 +102,11 @@ uint16_t HAL_adc_get_result() {
return HAL_adc_result;
}
+// Forward the default serial port
+DefaultSerial MSerial(false, Serial);
+
+DefaultSerial1 MSerial1(false, Serial1);
+DefaultSerial2 MSerial2(false, Serial2);
+DefaultSerial3 MSerial3(false, Serial3);
+
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h
index 7a057fdae4..78c8a800b9 100644
--- a/Marlin/src/HAL/DUE/HAL.h
+++ b/Marlin/src/HAL/DUE/HAL.h
@@ -22,9 +22,7 @@
#pragma once
/**
- * Description: HAL for Arduino Due and compatible (SAM3X8E)
- *
- * For ARDUINO_ARCH_SAM
+ * HAL for Arduino Due and compatible (SAM3X8E)
*/
#define CPU_32_BIT
@@ -38,9 +36,20 @@
#include
-#define _MSERIAL(X) Serial##X
+#include "../../core/serial_hook.h"
+typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
+extern DefaultSerial MSerial;
+
+typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
+typedef ForwardSerial0Type< decltype(Serial2) > DefaultSerial2;
+typedef ForwardSerial0Type< decltype(Serial3) > DefaultSerial3;
+extern DefaultSerial1 MSerial1;
+extern DefaultSerial2 MSerial2;
+extern DefaultSerial3 MSerial3;
+
+#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define Serial0 Serial
+#define MSerial0 MSerial
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
@@ -61,6 +70,14 @@
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL lcdSerial
@@ -77,16 +94,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*((void**)(addr)))
-#undef pgm_read_word
-#define pgm_read_word(addr) (*((uint16_t*)(addr)))
-
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
@@ -107,13 +114,15 @@ void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
//
// ADC
//
extern uint16_t HAL_adc_result; // result of last ADC conversion
#ifndef analogInputToDigitalPin
- #define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1)
+ #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
#endif
#define HAL_ANALOG_SELECT(ch)
@@ -153,10 +162,16 @@ void HAL_init();
//
void _delay_ms(const int delay);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/DUE/HAL_SPI.cpp b/Marlin/src/HAL/DUE/HAL_SPI.cpp
index 97d69f0d72..342c373735 100644
--- a/Marlin/src/HAL/DUE/HAL_SPI.cpp
+++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp
@@ -30,7 +30,7 @@
*/
/**
- * Description: HAL for Arduino Due and compatible (SAM3X8E)
+ * HAL for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
*/
@@ -69,10 +69,10 @@
// run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0
- uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
- uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
+ uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t idx = 0;
/* Negate bout, as the assembler requires a negated value */
@@ -154,9 +154,9 @@
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
uint32_t bin = 0;
uint32_t work = 0;
- uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -225,15 +225,15 @@
static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
int bits = 8;
do {
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(125); // 10 cycles @ 84mhz
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
DELAY_NS(125); // 10 cycles @ 84mhz
} while (--bits);
return b;
@@ -245,15 +245,15 @@
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
int bits = 8;
do {
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
__delay_4cycles(spiDelayCyclesX4);
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
__delay_4cycles(spiDelayCyclesX4);
} while (--bits);
return b;
@@ -271,10 +271,10 @@
// Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
static void spiTxBlock0(const uint8_t* ptr, uint32_t todo) {
- uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
- uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
+ uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t work = 0;
uint32_t txval = 0;
@@ -352,9 +352,9 @@
static void spiRxBlock0(uint8_t* ptr, uint32_t todo) {
uint32_t bin = 0;
uint32_t work = 0;
- uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -442,22 +442,22 @@
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
#if MB(ALLIGATOR)
- #define _SS_WRITE(S) WRITE(SS_PIN, S)
+ #define _SS_WRITE(S) WRITE(SD_SS_PIN, S)
#else
#define _SS_WRITE(S) NOOP
#endif
void spiBegin() {
- SET_OUTPUT(SS_PIN);
+ SET_OUTPUT(SD_SS_PIN);
_SS_WRITE(HIGH);
- SET_OUTPUT(SCK_PIN);
- SET_INPUT(MISO_PIN);
- SET_OUTPUT(MOSI_PIN);
+ SET_OUTPUT(SD_SCK_PIN);
+ SET_INPUT(SD_MISO_PIN);
+ SET_OUTPUT(SD_MOSI_PIN);
}
uint8_t spiRec() {
_SS_WRITE(LOW);
- WRITE(MOSI_PIN, HIGH); // Output 1s 1
+ WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
uint8_t b = spiTransferRx(0xFF);
_SS_WRITE(HIGH);
return b;
@@ -466,7 +466,7 @@
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte) {
_SS_WRITE(LOW);
- WRITE(MOSI_PIN, HIGH); // Output 1s 1
+ WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
spiRxBlock(buf, nbyte);
_SS_WRITE(HIGH);
}
@@ -519,8 +519,8 @@
}
_SS_WRITE(HIGH);
- WRITE(MOSI_PIN, HIGH);
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, HIGH);
+ WRITE(SD_SCK_PIN, LOW);
}
/** Begin SPI transaction, set clock, bit order, data mode */
@@ -575,20 +575,20 @@
// Configure SPI pins
PIO_Configure(
- g_APinDescription[SCK_PIN].pPort,
- g_APinDescription[SCK_PIN].ulPinType,
- g_APinDescription[SCK_PIN].ulPin,
- g_APinDescription[SCK_PIN].ulPinConfiguration);
+ g_APinDescription[SD_SCK_PIN].pPort,
+ g_APinDescription[SD_SCK_PIN].ulPinType,
+ g_APinDescription[SD_SCK_PIN].ulPin,
+ g_APinDescription[SD_SCK_PIN].ulPinConfiguration);
PIO_Configure(
- g_APinDescription[MOSI_PIN].pPort,
- g_APinDescription[MOSI_PIN].ulPinType,
- g_APinDescription[MOSI_PIN].ulPin,
- g_APinDescription[MOSI_PIN].ulPinConfiguration);
+ g_APinDescription[SD_MOSI_PIN].pPort,
+ g_APinDescription[SD_MOSI_PIN].ulPinType,
+ g_APinDescription[SD_MOSI_PIN].ulPin,
+ g_APinDescription[SD_MOSI_PIN].ulPinConfiguration);
PIO_Configure(
- g_APinDescription[MISO_PIN].pPort,
- g_APinDescription[MISO_PIN].ulPinType,
- g_APinDescription[MISO_PIN].ulPin,
- g_APinDescription[MISO_PIN].ulPinConfiguration);
+ g_APinDescription[SD_MISO_PIN].pPort,
+ g_APinDescription[SD_MISO_PIN].ulPinType,
+ g_APinDescription[SD_MISO_PIN].ulPin,
+ g_APinDescription[SD_MISO_PIN].ulPinConfiguration);
// set master mode, peripheral select, fault detection
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
@@ -606,7 +606,7 @@
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM2_CS, HIGH);
WRITE(SPI_FLASH_CS, HIGH);
- WRITE(SS_PIN, HIGH);
+ WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);
@@ -759,7 +759,6 @@
*
* All of the above can be avoided by defining FORCE_SOFT_SPI to force the
* display to use software SPI.
- *
*/
void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified)
diff --git a/Marlin/src/HAL/DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp
index c9a372eeb1..50b84c0b1d 100644
--- a/Marlin/src/HAL/DUE/MarlinSerial.cpp
+++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp
@@ -382,7 +382,7 @@ void MarlinSerial::flush() {
}
template
-void MarlinSerial::write(const uint8_t c) {
+size_t MarlinSerial::write(const uint8_t c) {
_written = true;
if (Cfg::TX_SIZE == 0) {
@@ -400,7 +400,7 @@ void MarlinSerial::write(const uint8_t c) {
// XOFF char at the RX isr, but it is properly handled there
if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) {
HWUART->UART_THR = c;
- return;
+ return 1;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
@@ -428,6 +428,7 @@ void MarlinSerial::write(const uint8_t c) {
// Enable TX isr - Non atomic, but it will eventually enable TX isr
HWUART->UART_IER = UART_IER_TXRDY;
}
+ return 1;
}
template
@@ -473,169 +474,16 @@ void MarlinSerial::flushTX() {
}
}
-/**
- * Imports from print.h
- */
-
-template
-void MarlinSerial::print(char c, int base) {
- print((long)c, base);
-}
-
-template
-void MarlinSerial::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-template
-void MarlinSerial::print(int n, int base) {
- print((long)n, base);
-}
-
-template
-void MarlinSerial::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-template
-void MarlinSerial::print(long n, int base) {
- if (base == 0) write(n);
- else if (base == 10) {
- if (n < 0) { print('-'); n = -n; }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-template
-void MarlinSerial::println() {
- print('\r');
- print('\n');
-}
-
-template
-void MarlinSerial::println(const String& s) {
- print(s);
- println();
-}
-
-template
-void MarlinSerial::println(const char c[]) {
- print(c);
- println();
-}
-
-template
-void MarlinSerial::println(char c, int base) {
- print(c, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-template
-void MarlinSerial::println(int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-template
-void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-template
-void MarlinSerial::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits) rounding *= 0.1;
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
-}
// If not using the USB port as serial port
#if SERIAL_PORT >= 0
- template class MarlinSerial>; // Define
- MarlinSerial> customizedSerial1; // Instantiate
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT customizedSerial1(MarlinSerialCfg::EMERGENCYPARSER);
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
- template class MarlinSerial>; // Define
- MarlinSerial> customizedSerial2; // Instantiate
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT2 customizedSerial2(MarlinSerialCfg::EMERGENCYPARSER);
#endif
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h
index a194eba2f3..7fc21264bb 100644
--- a/Marlin/src/HAL/DUE/MarlinSerial.h
+++ b/Marlin/src/HAL/DUE/MarlinSerial.h
@@ -30,11 +30,7 @@
#include
#include "../../inc/MarlinConfigPre.h"
-
-#define DEC 10
-#define HEX 16
-#define OCT 8
-#define BIN 2
+#include "../../core/serial_hook.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
@@ -119,7 +115,7 @@ public:
static int read();
static void flush();
static ring_buffer_pos_t available();
- static void write(const uint8_t c);
+ static size_t write(const uint8_t c);
static void flushTX();
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
@@ -128,35 +124,6 @@ public:
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = 0);
- static void print(unsigned char, int = 0);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = 0);
- static void println(unsigned char, int = 0);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
-private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
};
// Serial port configuration
@@ -174,9 +141,11 @@ struct MarlinSerialCfg {
};
#if SERIAL_PORT >= 0
- extern MarlinSerial> customizedSerial1;
+ typedef Serial0Type< MarlinSerial< MarlinSerialCfg > > MSerialT;
+ extern MSerialT customizedSerial1;
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
- extern MarlinSerial> customizedSerial2;
+ typedef Serial0Type< MarlinSerial< MarlinSerialCfg > > MSerialT2;
+ extern MSerialT2 customizedSerial2;
#endif
diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
index a41dbfeb7a..d85aaf14b0 100644
--- a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
+++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
@@ -50,10 +50,6 @@ extern "C" {
// Pending character
static int pending_char = -1;
-#if ENABLED(EMERGENCY_PARSER)
- static EmergencyParser::State emergency_state; // = EP_RESET
-#endif
-
// Public Methods
void MarlinSerialUSB::begin(const long) {}
@@ -111,13 +107,13 @@ bool MarlinSerialUSB::available() {
void MarlinSerialUSB::flush() { }
void MarlinSerialUSB::flushTX() { }
-void MarlinSerialUSB::write(const uint8_t c) {
+size_t MarlinSerialUSB::write(const uint8_t c) {
/* Do not even bother sending anything if USB CDC is not enumerated
or not configured on the PC side or there is no program on the PC
listening to our messages */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
- return;
+ return 0;
/* Wait until the PC has read the pending to be sent data */
while (usb_task_cdc_isenabled() &&
@@ -129,161 +125,20 @@ void MarlinSerialUSB::write(const uint8_t c) {
or not configured on the PC side or there is no program on the PC
listening to our messages at this point */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
- return;
+ return 0;
// Fifo full
// udi_cdc_signal_overrun();
udi_cdc_putc(c);
-}
-
-/**
- * Imports from print.h
- */
-
-void MarlinSerialUSB::print(char c, int base) {
- print((long)c, base);
-}
-
-void MarlinSerialUSB::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-void MarlinSerialUSB::print(int n, int base) {
- print((long)n, base);
-}
-
-void MarlinSerialUSB::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-void MarlinSerialUSB::print(long n, int base) {
- if (base == 0)
- write(n);
- else if (base == 10) {
- if (n < 0) {
- print('-');
- n = -n;
- }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-void MarlinSerialUSB::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-void MarlinSerialUSB::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-void MarlinSerialUSB::println() {
- print('\r');
- print('\n');
-}
-
-void MarlinSerialUSB::println(const String& s) {
- print(s);
- println();
-}
-
-void MarlinSerialUSB::println(const char c[]) {
- print(c);
- println();
-}
-
-void MarlinSerialUSB::println(char c, int base) {
- print(c, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-void MarlinSerialUSB::println(int n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(long n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-
-void MarlinSerialUSB::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits)
- rounding *= 0.1;
-
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
+ return 1;
}
// Preinstantiate
#if SERIAL_PORT == -1
- MarlinSerialUSB customizedSerial1;
+ MSerialT customizedSerial1(TERN0(EMERGENCY_PARSER, true));
#endif
#if SERIAL_PORT_2 == -1
- MarlinSerialUSB customizedSerial2;
+ MSerialT customizedSerial2(TERN0(EMERGENCY_PARSER, true));
#endif
#endif // HAS_USB_SERIAL
diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.h b/Marlin/src/HAL/DUE/MarlinSerialUSB.h
index 2e3622e553..9643a8465a 100644
--- a/Marlin/src/HAL/DUE/MarlinSerialUSB.h
+++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.h
@@ -27,20 +27,13 @@
*/
#include "../../inc/MarlinConfig.h"
-
#if HAS_USB_SERIAL
#include
+#include "../../core/serial_hook.h"
-#define DEC 10
-#define HEX 16
-#define OCT 8
-#define BIN 2
-class MarlinSerialUSB {
-
-public:
- MarlinSerialUSB() {};
+struct MarlinSerialUSB {
static void begin(const long);
static void end();
static int peek();
@@ -48,7 +41,7 @@ public:
static void flush();
static void flushTX();
static bool available();
- static void write(const uint8_t c);
+ static size_t write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE static uint32_t dropped() { return 0; }
@@ -57,43 +50,15 @@ public:
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
FORCE_INLINE static int rxMaxEnqueued() { return 0; }
#endif
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = 0);
- static void print(unsigned char, int = 0);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = 0);
- static void println(unsigned char, int = 0);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
-private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
};
+typedef Serial0Type MSerialT;
#if SERIAL_PORT == -1
- extern MarlinSerialUSB customizedSerial1;
+ extern MSerialT customizedSerial1;
#endif
#if SERIAL_PORT_2 == -1
- extern MarlinSerialUSB customizedSerial2;
+ extern MSerialT customizedSerial2;
#endif
#endif // HAS_USB_SERIAL
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
index 28e82d70d4..d07da15ad8 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
@@ -52,25 +52,23 @@
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#ifdef __SAM3X8E__
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
#include "../../../MarlinCore.h"
-void spiBegin();
-void spiInit(uint8_t spiRate);
-void spiSend(uint8_t b);
-void spiSend(const uint8_t* buf, size_t n);
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_QUARTER_SPEED
+#endif
-#include "../../shared/Marduino.h"
+#include "../../shared/HAL_SPI.h"
#include "../fastio.h"
void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) {
@@ -101,11 +99,7 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
spiBegin();
- #ifndef SPI_SPEED
- #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
- #endif
- spiInit(2);
-
+ spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
@@ -145,6 +139,6 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // __SAM3X8E__
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
index 47060d6a5b..7df180cbaa 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
@@ -145,7 +145,7 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
}
#if ENABLED(LIGHTWEIGHT_UI)
- #include "../../../lcd/ultralcd.h"
+ #include "../../../lcd/marlinui.h"
#include "../../shared/HAL_ST7920.h"
#define ST7920_CS_PIN LCD_PINS_RS
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
index 54c244d4f6..890546af58 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
@@ -57,10 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
-
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -144,5 +141,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
index 960df1bd86..615a386c35 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include "../../shared/Delay.h"
@@ -108,5 +108,5 @@ void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
}
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/eeprom_flash.cpp b/Marlin/src/HAL/DUE/eeprom_flash.cpp
index d98f06039f..209a5161ae 100644
--- a/Marlin/src/HAL/DUE/eeprom_flash.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_flash.cpp
@@ -53,7 +53,6 @@
* per page. We can't emulate EE endurance with FLASH for all
* bytes, but we can emulate endurance for a given percent of
* bytes.
- *
*/
//#define EE_EMU_DEBUG
@@ -61,7 +60,7 @@
#define EEPROMSize 4096
#define PagesPerGroup 128
#define GroupCount 2
-#define PageSize 256u
+#define PageSize 256U
/* Flash storage */
typedef struct FLASH_SECTOR {
@@ -997,7 +996,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = ee_Read(uint32_t(pos));
if (writing) *value = c;
diff --git a/Marlin/src/HAL/DUE/eeprom_wired.cpp b/Marlin/src/HAL/DUE/eeprom_wired.cpp
index 4599d6a7cd..b488c36f16 100644
--- a/Marlin/src/HAL/DUE/eeprom_wired.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_wired.cpp
@@ -62,7 +62,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/DUE/fastio.h b/Marlin/src/HAL/DUE/fastio.h
index 286319302d..f375cb6b29 100644
--- a/Marlin/src/HAL/DUE/fastio.h
+++ b/Marlin/src/HAL/DUE/fastio.h
@@ -50,7 +50,7 @@
#define PWM_PIN(P) WITHIN(P, 2, 13)
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
/**
@@ -163,6 +163,9 @@
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup (wrapper)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
+// Set pin as input with pulldown (substitution)
+#define SET_INPUT_PULLDOWN SET_INPUT
+
// Set pin as output (wrapper) - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
// Set pin as PWM
@@ -477,7 +480,7 @@
#define DIO91_PIN 15
#define DIO91_WPORT PIOB
-#if ARDUINO_SAM_ARCHIM
+#ifdef ARDUINO_SAM_ARCHIM
#define DIO92_PIN 11
#define DIO92_WPORT PIOC
diff --git a/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp b/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp
index 1682faea66..d9fbabce21 100644
--- a/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp
+++ b/Marlin/src/HAL/DUE/fastio/G2_PWM.cpp
@@ -154,7 +154,7 @@ void Stepper::digipot_init() {
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
}
-void Stepper::digipot_current(const uint8_t driver, const int16_t current) {
+void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) {
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
diff --git a/Marlin/src/HAL/DUE/inc/SanityCheck.h b/Marlin/src/HAL/DUE/inc/SanityCheck.h
index 6880696506..26fb44f398 100644
--- a/Marlin/src/HAL/DUE/inc/SanityCheck.h
+++ b/Marlin/src/HAL/DUE/inc/SanityCheck.h
@@ -40,7 +40,7 @@
* Usually the hardware SPI pins are only available to the LCD. This makes the DUE hard SPI used at the same time
* as the TMC2130 soft SPI the most common setup.
*/
-#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == MOSI_PIN || TMC_SW_##P == MISO_PIN || TMC_SW_##P == SCK_PIN))
+#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == SD_MOSI_PIN || TMC_SW_##P == SD_MISO_PIN || TMC_SW_##P == SD_SCK_PIN))
#if ENABLED(SDSUPPORT) && HAS_DRIVER(TMC2130)
#if ENABLED(TMC_USE_SW_SPI)
diff --git a/Marlin/src/HAL/DUE/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h
index 28687ff267..a99ca8ecce 100644
--- a/Marlin/src/HAL/DUE/pinsDebug.h
+++ b/Marlin/src/HAL/DUE/pinsDebug.h
@@ -179,5 +179,4 @@ void pwm_details(int32_t pin) {
* ----------------+--------
* ID | PB11
* VBOF | PB10
- *
*/
diff --git a/Marlin/src/HAL/DUE/spi_pins.h b/Marlin/src/HAL/DUE/spi_pins.h
index e28eaf8270..cec22c2c37 100644
--- a/Marlin/src/HAL/DUE/spi_pins.h
+++ b/Marlin/src/HAL/DUE/spi_pins.h
@@ -43,22 +43,22 @@
#define SPI_PIN 87
#define SPI_CHAN 1
#endif
- #define SCK_PIN 76
- #define MISO_PIN 74
- #define MOSI_PIN 75
+ #define SD_SCK_PIN 76
+ #define SD_MISO_PIN 74
+ #define SD_MOSI_PIN 75
#else
// defaults
#define DUE_SOFTWARE_SPI
- #ifndef SCK_PIN
- #define SCK_PIN 52
+ #ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 52
#endif
- #ifndef MISO_PIN
- #define MISO_PIN 50
+ #ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 50
#endif
- #ifndef MOSI_PIN
- #define MOSI_PIN 51
+ #ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 51
#endif
#endif
/* A.28, A.29, B.21, C.26, C.29 */
-#define SS_PIN SDSS
+#define SD_SS_PIN SDSS
diff --git a/Marlin/src/HAL/DUE/timers.cpp b/Marlin/src/HAL/DUE/timers.cpp
index 795cdad66a..65073c510d 100644
--- a/Marlin/src/HAL/DUE/timers.cpp
+++ b/Marlin/src/HAL/DUE/timers.cpp
@@ -21,9 +21,7 @@
*/
/**
- * Description: HAL for Arduino Due and compatible (SAM3X8E)
- *
- * For ARDUINO_ARCH_SAM
+ * HAL Timers for Arduino Due and compatible (SAM3X8E)
*/
#ifdef ARDUINO_ARCH_SAM
@@ -123,7 +121,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/DUE/timers.h b/Marlin/src/HAL/DUE/timers.h
index 9defe39a0a..0e1ea07cc2 100644
--- a/Marlin/src/HAL/DUE/timers.h
+++ b/Marlin/src/HAL/DUE/timers.h
@@ -21,9 +21,7 @@
#pragma once
/**
- * HAL for Arduino Due and compatible (SAM3X8E)
- *
- * For ARDUINO_ARCH_SAM
+ * HAL Timers for Arduino Due and compatible (SAM3X8E)
*/
#include
diff --git a/Marlin/src/HAL/DUE/upload_extra_script.py b/Marlin/src/HAL/DUE/upload_extra_script.py
index 06c2b914f5..d52a0a3642 100644
--- a/Marlin/src/HAL/DUE/upload_extra_script.py
+++ b/Marlin/src/HAL/DUE/upload_extra_script.py
@@ -14,5 +14,5 @@ if current_OS == 'Windows':
# Use bossac.exe on Windows
env.Replace(
- UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot"
+ UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
)
diff --git a/Marlin/src/HAL/DUE/usb/compiler.h b/Marlin/src/HAL/DUE/usb/compiler.h
index 879007fa2a..f89e554c45 100644
--- a/Marlin/src/HAL/DUE/usb/compiler.h
+++ b/Marlin/src/HAL/DUE/usb/compiler.h
@@ -609,37 +609,37 @@ typedef struct
# define clz(u) ((u) ? __CLZ(u) : 32)
#else
# define clz(u) (((u) == 0) ? 32 : \
- ((u) & (1ul << 31)) ? 0 : \
- ((u) & (1ul << 30)) ? 1 : \
- ((u) & (1ul << 29)) ? 2 : \
- ((u) & (1ul << 28)) ? 3 : \
- ((u) & (1ul << 27)) ? 4 : \
- ((u) & (1ul << 26)) ? 5 : \
- ((u) & (1ul << 25)) ? 6 : \
- ((u) & (1ul << 24)) ? 7 : \
- ((u) & (1ul << 23)) ? 8 : \
- ((u) & (1ul << 22)) ? 9 : \
- ((u) & (1ul << 21)) ? 10 : \
- ((u) & (1ul << 20)) ? 11 : \
- ((u) & (1ul << 19)) ? 12 : \
- ((u) & (1ul << 18)) ? 13 : \
- ((u) & (1ul << 17)) ? 14 : \
- ((u) & (1ul << 16)) ? 15 : \
- ((u) & (1ul << 15)) ? 16 : \
- ((u) & (1ul << 14)) ? 17 : \
- ((u) & (1ul << 13)) ? 18 : \
- ((u) & (1ul << 12)) ? 19 : \
- ((u) & (1ul << 11)) ? 20 : \
- ((u) & (1ul << 10)) ? 21 : \
- ((u) & (1ul << 9)) ? 22 : \
- ((u) & (1ul << 8)) ? 23 : \
- ((u) & (1ul << 7)) ? 24 : \
- ((u) & (1ul << 6)) ? 25 : \
- ((u) & (1ul << 5)) ? 26 : \
- ((u) & (1ul << 4)) ? 27 : \
- ((u) & (1ul << 3)) ? 28 : \
- ((u) & (1ul << 2)) ? 29 : \
- ((u) & (1ul << 1)) ? 30 : \
+ ((u) & (1UL << 31)) ? 0 : \
+ ((u) & (1UL << 30)) ? 1 : \
+ ((u) & (1UL << 29)) ? 2 : \
+ ((u) & (1UL << 28)) ? 3 : \
+ ((u) & (1UL << 27)) ? 4 : \
+ ((u) & (1UL << 26)) ? 5 : \
+ ((u) & (1UL << 25)) ? 6 : \
+ ((u) & (1UL << 24)) ? 7 : \
+ ((u) & (1UL << 23)) ? 8 : \
+ ((u) & (1UL << 22)) ? 9 : \
+ ((u) & (1UL << 21)) ? 10 : \
+ ((u) & (1UL << 20)) ? 11 : \
+ ((u) & (1UL << 19)) ? 12 : \
+ ((u) & (1UL << 18)) ? 13 : \
+ ((u) & (1UL << 17)) ? 14 : \
+ ((u) & (1UL << 16)) ? 15 : \
+ ((u) & (1UL << 15)) ? 16 : \
+ ((u) & (1UL << 14)) ? 17 : \
+ ((u) & (1UL << 13)) ? 18 : \
+ ((u) & (1UL << 12)) ? 19 : \
+ ((u) & (1UL << 11)) ? 20 : \
+ ((u) & (1UL << 10)) ? 21 : \
+ ((u) & (1UL << 9)) ? 22 : \
+ ((u) & (1UL << 8)) ? 23 : \
+ ((u) & (1UL << 7)) ? 24 : \
+ ((u) & (1UL << 6)) ? 25 : \
+ ((u) & (1UL << 5)) ? 26 : \
+ ((u) & (1UL << 4)) ? 27 : \
+ ((u) & (1UL << 3)) ? 28 : \
+ ((u) & (1UL << 2)) ? 29 : \
+ ((u) & (1UL << 1)) ? 30 : \
31)
#endif
#endif
@@ -654,38 +654,38 @@ typedef struct
#if (defined __GNUC__) || (defined __CC_ARM)
# define ctz(u) ((u) ? __builtin_ctz(u) : 32)
#else
-# define ctz(u) ((u) & (1ul << 0) ? 0 : \
- (u) & (1ul << 1) ? 1 : \
- (u) & (1ul << 2) ? 2 : \
- (u) & (1ul << 3) ? 3 : \
- (u) & (1ul << 4) ? 4 : \
- (u) & (1ul << 5) ? 5 : \
- (u) & (1ul << 6) ? 6 : \
- (u) & (1ul << 7) ? 7 : \
- (u) & (1ul << 8) ? 8 : \
- (u) & (1ul << 9) ? 9 : \
- (u) & (1ul << 10) ? 10 : \
- (u) & (1ul << 11) ? 11 : \
- (u) & (1ul << 12) ? 12 : \
- (u) & (1ul << 13) ? 13 : \
- (u) & (1ul << 14) ? 14 : \
- (u) & (1ul << 15) ? 15 : \
- (u) & (1ul << 16) ? 16 : \
- (u) & (1ul << 17) ? 17 : \
- (u) & (1ul << 18) ? 18 : \
- (u) & (1ul << 19) ? 19 : \
- (u) & (1ul << 20) ? 20 : \
- (u) & (1ul << 21) ? 21 : \
- (u) & (1ul << 22) ? 22 : \
- (u) & (1ul << 23) ? 23 : \
- (u) & (1ul << 24) ? 24 : \
- (u) & (1ul << 25) ? 25 : \
- (u) & (1ul << 26) ? 26 : \
- (u) & (1ul << 27) ? 27 : \
- (u) & (1ul << 28) ? 28 : \
- (u) & (1ul << 29) ? 29 : \
- (u) & (1ul << 30) ? 30 : \
- (u) & (1ul << 31) ? 31 : \
+# define ctz(u) ((u) & (1UL << 0) ? 0 : \
+ (u) & (1UL << 1) ? 1 : \
+ (u) & (1UL << 2) ? 2 : \
+ (u) & (1UL << 3) ? 3 : \
+ (u) & (1UL << 4) ? 4 : \
+ (u) & (1UL << 5) ? 5 : \
+ (u) & (1UL << 6) ? 6 : \
+ (u) & (1UL << 7) ? 7 : \
+ (u) & (1UL << 8) ? 8 : \
+ (u) & (1UL << 9) ? 9 : \
+ (u) & (1UL << 10) ? 10 : \
+ (u) & (1UL << 11) ? 11 : \
+ (u) & (1UL << 12) ? 12 : \
+ (u) & (1UL << 13) ? 13 : \
+ (u) & (1UL << 14) ? 14 : \
+ (u) & (1UL << 15) ? 15 : \
+ (u) & (1UL << 16) ? 16 : \
+ (u) & (1UL << 17) ? 17 : \
+ (u) & (1UL << 18) ? 18 : \
+ (u) & (1UL << 19) ? 19 : \
+ (u) & (1UL << 20) ? 20 : \
+ (u) & (1UL << 21) ? 21 : \
+ (u) & (1UL << 22) ? 22 : \
+ (u) & (1UL << 23) ? 23 : \
+ (u) & (1UL << 24) ? 24 : \
+ (u) & (1UL << 25) ? 25 : \
+ (u) & (1UL << 26) ? 26 : \
+ (u) & (1UL << 27) ? 27 : \
+ (u) & (1UL << 28) ? 28 : \
+ (u) & (1UL << 29) ? 29 : \
+ (u) & (1UL << 30) ? 30 : \
+ (u) & (1UL << 31) ? 31 : \
32)
#endif
#endif
diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
index ea2936359d..d92d332c1e 100644
--- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
+++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
@@ -68,7 +68,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDRD: %d @ 0x%08x\n"), nb_sector, addr);
- PORT_REDIRECT(0);
+ PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
@@ -84,7 +84,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
card.getSd2Card().readData(sector_buf);
// RAM -> USB
- if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, NULL)) {
+ if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
card.getSd2Card().readStop();
return CTRL_FAIL;
}
@@ -108,7 +108,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDWR: %d @ 0x%08x\n"), nb_sector, addr);
- PORT_REDIRECT(0);
+ PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
@@ -120,7 +120,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
while (nb_sector--) {
// USB -> RAM
- if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, NULL)) {
+ if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
card.getSd2Card().writeStop();
return CTRL_FAIL;
}
diff --git a/Marlin/src/HAL/DUE/watchdog.cpp b/Marlin/src/HAL/DUE/watchdog.cpp
index 0f46971830..e144db8291 100644
--- a/Marlin/src/HAL/DUE/watchdog.cpp
+++ b/Marlin/src/HAL/DUE/watchdog.cpp
@@ -36,7 +36,7 @@ void watchdogSetup() {
#if ENABLED(USE_WATCHDOG)
// 4 seconds timeout
- uint32_t timeout = 4000;
+ uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000);
// Calculate timeout value in WDT counter ticks: This assumes
// the slow clock is running at 32.768 kHz watchdog
diff --git a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
index d4b2f42c53..cc5a4fc476 100644
--- a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
+++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
@@ -24,10 +24,7 @@
#ifdef ARDUINO_ARCH_ESP32
-FlushableHardwareSerial::FlushableHardwareSerial(int uart_nr)
- : HardwareSerial(uart_nr)
-{}
-FlushableHardwareSerial flushableSerial(0);
+Serial0Type flushableSerial(false, 0);
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
index b43caea13c..27df0be4b6 100644
--- a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
+++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
@@ -24,14 +24,13 @@
#ifdef ARDUINO_ARCH_ESP32
#include
+#include "../../core/serial_hook.h"
class FlushableHardwareSerial : public HardwareSerial {
public:
- FlushableHardwareSerial(int uart_nr);
-
- inline void flushTX() { /* No need to flush the hardware serial, but defined here for compatibility. */ }
+ FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {}
};
-extern FlushableHardwareSerial flushableSerial;
+extern Serial0Type flushableSerial;
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp
index 1e00df5177..6ff1446b1c 100644
--- a/Marlin/src/HAL/ESP32/HAL.cpp
+++ b/Marlin/src/HAL/ESP32/HAL.cpp
@@ -40,6 +40,10 @@
#endif
#endif
+#if ENABLED(ESP3D_WIFISUPPORT)
+ DefaultSerial MSerial(false, Serial2Socket);
+#endif
+
// ------------------------
// Externs
// ------------------------
@@ -86,7 +90,7 @@ volatile int numPWMUsed = 0,
#endif
-void HAL_init() { i2s_init(); }
+void HAL_init() { TERN_(I2S_STEPPER_STREAM, i2s_init()); }
void HAL_init_board() {
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index 5eb84fdc30..3dc27c6493 100644
--- a/Marlin/src/HAL/ESP32/HAL.h
+++ b/Marlin/src/HAL/ESP32/HAL.h
@@ -15,11 +15,12 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
/**
- * Description: HAL for Espressif ESP32 WiFi
+ * HAL for Espressif ESP32 WiFi
*/
#define CPU_32_BIT
@@ -54,7 +55,9 @@ extern portMUX_TYPE spinlock;
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
- #define MYSERIAL1 Serial2Socket
+ typedef ForwardSerial0Type< decltype(Serial2Socket) > DefaultSerial;
+ extern DefaultSerial MSerial;
+ #define MYSERIAL1 MSerial
#else
#define MYSERIAL1 webSocketSerial
#endif
@@ -66,10 +69,6 @@ extern portMUX_TYPE spinlock;
#define ENABLE_ISRS() if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
// ------------------------
// Types
// ------------------------
@@ -89,18 +88,33 @@ extern uint16_t HAL_adc_result;
// Public functions
// ------------------------
+//
+// Tone
+//
+void toneInit();
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
+void noTone(const pin_t _pin);
+
// clear reset reason
void HAL_clear_reset_source();
// reset reason
uint8_t HAL_get_reset_source();
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
void _delay_ms(int delay);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
void analogWrite(pin_t pin, int value);
@@ -154,14 +168,14 @@ FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
if (stop >= start) {
// no overflow, so only loop while in between start and stop:
- // 0x00000000 -----------------start****stop-- 0xffffffff
+ // 0x00000000 -----------------start****stop-- 0xFFFFFFFF
while (ccount >= start && ccount < stop) {
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
}
}
else {
// stop did overflow, so only loop while outside of stop and start:
- // 0x00000000 **stop-------------------start** 0xffffffff
+ // 0x00000000 **stop-------------------start** 0xFFFFFFFF
while (ccount >= start || ccount < stop) {
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
}
diff --git a/Marlin/src/HAL/ESP32/HAL_SPI.cpp b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
index 8e5875fc38..8ee837ba15 100644
--- a/Marlin/src/HAL/ESP32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
@@ -53,11 +53,11 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #if !PIN_EXISTS(SS)
- #error "SS_PIN not defined!"
+ #if !PIN_EXISTS(SD_SS)
+ #error "SD_SS_PIN not defined!"
#endif
- OUT_WRITE(SS_PIN, HIGH);
+ OUT_WRITE(SD_SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
diff --git a/Marlin/src/HAL/ESP32/Servo.h b/Marlin/src/HAL/ESP32/Servo.h
index b0d9294527..8542092d66 100644
--- a/Marlin/src/HAL/ESP32/Servo.h
+++ b/Marlin/src/HAL/ESP32/Servo.h
@@ -30,7 +30,7 @@ class Servo {
MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo
TAU_MSEC = 20,
TAU_USEC = (TAU_MSEC * 1000),
- MAX_COMPARE = ((1 << 16) - 1), // 65535
+ MAX_COMPARE = _BV(16) - 1, // 65535
CHANNEL_MAX_NUM = 16;
public:
diff --git a/Marlin/src/HAL/STM32_F4_F7/Servo.cpp b/Marlin/src/HAL/ESP32/Tone.cpp
similarity index 52%
rename from Marlin/src/HAL/STM32_F4_F7/Servo.cpp
rename to Marlin/src/HAL/ESP32/Tone.cpp
index 7185468f50..376c0f32e1 100644
--- a/Marlin/src/HAL/STM32_F4_F7/Servo.cpp
+++ b/Marlin/src/HAL/ESP32/Tone.cpp
@@ -4,7 +4,8 @@
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
- * Copyright (c) 2017 Victor Perez
+ *
+ * Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,32 +21,39 @@
* along with this program. If not, see .
*
*/
-#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
+
+/**
+ * Description: Tone function for ESP32
+ * Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
+ */
+
+#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
+#include "HAL.h"
-#if HAS_SERVOS
+static pin_t tone_pin;
+volatile static int32_t toggles;
-#include "Servo.h"
-
-int8_t libServo::attach(const int pin) {
- if (servoIndex >= MAX_SERVOS) return -1;
- return super::attach(pin);
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
+ tone_pin = _pin;
+ toggles = 2 * frequency * duration / 1000;
+ HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
}
-int8_t libServo::attach(const int pin, const int min, const int max) {
- return super::attach(pin, min, max);
+void noTone(const pin_t _pin) {
+ HAL_timer_disable_interrupt(TONE_TIMER_NUM);
+ WRITE(_pin, LOW);
}
-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]);
- TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach());
+HAL_TONE_TIMER_ISR() {
+ HAL_timer_isr_prologue(TONE_TIMER_NUM);
+
+ if (toggles) {
+ toggles--;
+ TOGGLE(tone_pin);
}
+ else noTone(tone_pin); // turn off interrupt
}
-#endif // HAS_SERVOS
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
+#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
index ca7f47a1f8..8825742d38 100644
--- a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
+++ b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
@@ -29,7 +29,7 @@
#include "wifi.h"
#include
-WebSocketSerial webSocketSerial;
+MSerialT webSocketSerial(false);
AsyncWebSocket ws("/ws"); // TODO Move inside the class.
// RingBuffer impl
@@ -144,9 +144,5 @@ size_t WebSocketSerial::write(const uint8_t* buffer, size_t size) {
return written;
}
-void WebSocketSerial::flushTX() {
- // No need to do anything as there's no benefit to sending partial lines over the websocket connection.
-}
-
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.h b/Marlin/src/HAL/ESP32/WebSocketSerial.h
index 7a25c6dc5e..c68792c8c1 100644
--- a/Marlin/src/HAL/ESP32/WebSocketSerial.h
+++ b/Marlin/src/HAL/ESP32/WebSocketSerial.h
@@ -22,6 +22,7 @@
#pragma once
#include "../../inc/MarlinConfig.h"
+#include "../../core/serial_hook.h"
#include
@@ -68,12 +69,9 @@ public:
int peek();
int read();
void flush();
- void flushTX();
size_t write(const uint8_t c);
size_t write(const uint8_t* buffer, size_t size);
- operator bool() { return true; }
-
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE uint32_t dropped() { return 0; }
#endif
@@ -83,4 +81,5 @@ public:
#endif
};
-extern WebSocketSerial webSocketSerial;
+typedef Serial0Type MSerialT;
+extern MSerialT webSocketSerial;
diff --git a/Marlin/src/HAL/ESP32/eeprom.cpp b/Marlin/src/HAL/ESP32/eeprom.cpp
index 1bf687c6fe..cb5f881284 100644
--- a/Marlin/src/HAL/ESP32/eeprom.cpp
+++ b/Marlin/src/HAL/ESP32/eeprom.cpp
@@ -44,7 +44,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+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;
diff --git a/Marlin/src/HAL/ESP32/fastio.h b/Marlin/src/HAL/ESP32/fastio.h
index 2ded3a5f62..8db89dca12 100644
--- a/Marlin/src/HAL/ESP32/fastio.h
+++ b/Marlin/src/HAL/ESP32/fastio.h
@@ -52,6 +52,9 @@
// Set pin as input with pullup wrapper
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
+// Set pin as input with pulldown (substitution)
+#define SET_INPUT_PULLDOWN SET_INPUT
+
// Set pin as output wrapper
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0)
diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp
index 99b2f755e5..e8f3806543 100644
--- a/Marlin/src/HAL/ESP32/i2s.cpp
+++ b/Marlin/src/HAL/ESP32/i2s.cpp
@@ -184,7 +184,7 @@ int i2s_init() {
// Allocate the array of pointers to the buffers
dma.buffers = (uint32_t **)malloc(sizeof(uint32_t*) * DMA_BUF_COUNT);
- if (dma.buffers == nullptr) return -1;
+ if (!dma.buffers) return -1;
// Allocate each buffer that can be used by the DMA controller
for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) {
@@ -194,7 +194,7 @@ int i2s_init() {
// Allocate the array of DMA descriptors
dma.desc = (lldesc_t**) malloc(sizeof(lldesc_t*) * DMA_BUF_COUNT);
- if (dma.desc == nullptr) return -1;
+ if (!dma.desc) return -1;
// Allocate each DMA descriptor that will be used by the DMA controller
for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) {
diff --git a/Marlin/src/HAL/ESP32/ota.h b/Marlin/src/HAL/ESP32/ota.h
index 7f9b237aa6..546ace82db 100644
--- a/Marlin/src/HAL/ESP32/ota.h
+++ b/Marlin/src/HAL/ESP32/ota.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
diff --git a/Marlin/src/HAL/ESP32/spi_pins.h b/Marlin/src/HAL/ESP32/spi_pins.h
index 15f8f2ab6b..cfe71eee4a 100644
--- a/Marlin/src/HAL/ESP32/spi_pins.h
+++ b/Marlin/src/HAL/ESP32/spi_pins.h
@@ -18,7 +18,7 @@
*/
#pragma once
-#define SS_PIN SDSS
-#define SCK_PIN 18
-#define MISO_PIN 19
-#define MOSI_PIN 23
+#define SD_SS_PIN SDSS
+#define SD_SCK_PIN 18
+#define SD_MISO_PIN 19
+#define SD_MOSI_PIN 23
diff --git a/Marlin/src/HAL/ESP32/timers.cpp b/Marlin/src/HAL/ESP32/timers.cpp
index 3300aea8a8..57662a6658 100644
--- a/Marlin/src/HAL/ESP32/timers.cpp
+++ b/Marlin/src/HAL/ESP32/timers.cpp
@@ -45,7 +45,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
- { TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3
+ { TIMER_GROUP_1, TIMER_1, TONE_TIMER_PRESCALE, toneTC_Handler }, // 3 - Tone
};
// ------------------------
diff --git a/Marlin/src/HAL/ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h
index d722670f33..a47697113d 100644
--- a/Marlin/src/HAL/ESP32/timers.h
+++ b/Marlin/src/HAL/ESP32/timers.h
@@ -24,15 +24,9 @@
#include
#include
-// Includes needed to get I2S_STEPPER_STREAM. Note that pins.h
-// is included in case this header is being included early.
-#include "../../inc/MarlinConfig.h"
-#include "../../pins/pins.h"
-
// ------------------------
// Defines
// ------------------------
-//
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint64_t hal_timer_t;
@@ -50,6 +44,9 @@ typedef uint64_t hal_timer_t;
#ifndef PWM_TIMER_NUM
#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
#endif
+#ifndef TONE_TIMER_NUM
+ #define TONE_TIMER_NUM 3 // index of timer for beeper tones
+#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -65,6 +62,8 @@ typedef uint64_t hal_timer_t;
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
+#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here
+
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -96,10 +95,16 @@ typedef uint64_t hal_timer_t;
#ifndef HAL_PWM_TIMER_ISR
#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler()
#endif
+#ifndef HAL_TONE_TIMER_ISR
+ #define HAL_TONE_TIMER_ISR() extern "C" void toneTC_Handler()
+#endif
-extern "C" void tempTC_Handler();
-extern "C" void stepTC_Handler();
-extern "C" void pwmTC_Handler();
+extern "C" {
+ void tempTC_Handler();
+ void stepTC_Handler();
+ void pwmTC_Handler();
+ void toneTC_Handler();
+}
// ------------------------
// Types
diff --git a/Marlin/src/HAL/ESP32/watchdog.cpp b/Marlin/src/HAL/ESP32/watchdog.cpp
index f6fcfa3182..5ec03c4607 100644
--- a/Marlin/src/HAL/ESP32/watchdog.cpp
+++ b/Marlin/src/HAL/ESP32/watchdog.cpp
@@ -25,6 +25,8 @@
#if ENABLED(USE_WATCHDOG)
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
#include "watchdog.h"
void watchdogSetup() {
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index 8b6a978d21..9eefda8fb1 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -23,6 +23,10 @@
#include "platforms.h"
+#ifndef GCC_VERSION
+ #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
#include HAL_PATH(.,HAL.h)
#ifdef SERIAL_PORT_2
@@ -34,7 +38,7 @@
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
- #define I2C_ADDRESS(A) (A)
+ #define I2C_ADDRESS(A) uint8_t(A)
#endif
// Needed for AVR sprintf_P PROGMEM extension
diff --git a/Marlin/src/HAL/LINUX/HAL.cpp b/Marlin/src/HAL/LINUX/HAL.cpp
index d7d7c2d2b4..771f1d2a08 100644
--- a/Marlin/src/HAL/LINUX/HAL.cpp
+++ b/Marlin/src/HAL/LINUX/HAL.cpp
@@ -24,21 +24,16 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
-HalSerial usb_serial;
+MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
// U8glib required functions
-extern "C" void u8g_xMicroDelay(uint16_t val) {
- DELAY_US(val);
-}
-extern "C" void u8g_MicroDelay() {
- u8g_xMicroDelay(1);
-}
-extern "C" void u8g_10MicroDelay() {
- u8g_xMicroDelay(10);
-}
-extern "C" void u8g_Delay(uint16_t val) {
- delay(val);
+extern "C" {
+ void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); }
+ void u8g_MicroDelay() { u8g_xMicroDelay(1); }
+ void u8g_10MicroDelay() { u8g_xMicroDelay(10); }
+ void u8g_Delay(uint16_t val) { delay(val); }
}
+
//************************//
// return free heap space
diff --git a/Marlin/src/HAL/LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h
index 778ba2db4d..e4f4dd3fc3 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -23,7 +23,7 @@
#define CPU_32_BIT
-#define F_CPU 100000000
+#define F_CPU 100000000UL
#define SystemCoreClock F_CPU
#include
#include
@@ -60,7 +60,7 @@ uint8_t _getc();
#define SHARED_SERVOS HAS_SERVOS
-extern HalSerial usb_serial;
+extern MSerialT usb_serial;
#define MYSERIAL0 usb_serial
#define ST7920_DELAY_1 DELAY_NS(600)
@@ -79,10 +79,16 @@ extern HalSerial usb_serial;
inline void HAL_init() {}
// Utility functions
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
// ADC
#define HAL_ADC_VREF 5.0
@@ -101,12 +107,9 @@ uint16_t HAL_adc_get_result();
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}
-
-// Add strcmp_P if missing
-#ifndef strcmp_P
- #define strcmp_P(a, b) strcmp((a), (b))
-#endif
diff --git a/Marlin/src/HAL/LINUX/eeprom.cpp b/Marlin/src/HAL/LINUX/eeprom.cpp
index 967ca851ab..532f323c6e 100644
--- a/Marlin/src/HAL/LINUX/eeprom.cpp
+++ b/Marlin/src/HAL/LINUX/eeprom.cpp
@@ -40,7 +40,7 @@ size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;
FILE * eeprom_file = fopen(filename, "rb");
- if (eeprom_file == nullptr) return false;
+ if (!eeprom_file) return false;
fseek(eeprom_file, 0L, SEEK_END);
std::size_t file_size = ftell(eeprom_file);
@@ -59,7 +59,7 @@ bool PersistentStore::access_start() {
bool PersistentStore::access_finish() {
FILE * eeprom_file = fopen(filename, "wb");
- if (eeprom_file == nullptr) return false;
+ if (!eeprom_file) return false;
fwrite(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
fclose(eeprom_file);
return true;
@@ -78,7 +78,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return (bytes_written != size); // 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*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
std::size_t bytes_read = 0;
if (writing) {
for (std::size_t i = 0; i < size; i++) {
diff --git a/Marlin/src/HAL/LINUX/hardware/Gpio.h b/Marlin/src/HAL/LINUX/hardware/Gpio.h
index 9255ec1dfc..2d9b1f29eb 100644
--- a/Marlin/src/HAL/LINUX/hardware/Gpio.h
+++ b/Marlin/src/HAL/LINUX/hardware/Gpio.h
@@ -86,10 +86,10 @@ public:
GpioEvent::Type evt_type = value > 1 ? GpioEvent::SET_VALUE : value > pin_map[pin].value ? GpioEvent::RISE : value < pin_map[pin].value ? GpioEvent::FALL : GpioEvent::NOP;
pin_map[pin].value = value;
GpioEvent evt(Clock::nanos(), pin, evt_type);
- if (pin_map[pin].cb != nullptr) {
+ if (pin_map[pin].cb) {
pin_map[pin].cb->interrupt(evt);
}
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint16_t get(pin_type pin) {
@@ -105,8 +105,8 @@ public:
if (!valid_pin(pin)) return;
pin_map[pin].mode = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETM);
- if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint8_t getMode(pin_type pin) {
@@ -118,8 +118,8 @@ public:
if (!valid_pin(pin)) return;
pin_map[pin].dir = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETD);
- if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint8_t getDir(pin_type pin) {
diff --git a/Marlin/src/HAL/LINUX/include/Arduino.h b/Marlin/src/HAL/LINUX/include/Arduino.h
index e28b474ede..d4086e259a 100644
--- a/Marlin/src/HAL/LINUX/include/Arduino.h
+++ b/Marlin/src/HAL/LINUX/include/Arduino.h
@@ -67,34 +67,14 @@ void cli(); // Disable
void sei(); // Enable
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
void detachInterrupt(uint32_t pin);
-extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
-extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
-// Program Memory
-#define pgm_read_ptr(addr) (*((void**)(addr)))
-#define pgm_read_byte_near(addr) (*((uint8_t*)(addr)))
-#define pgm_read_float_near(addr) (*((float*)(addr)))
-#define pgm_read_word_near(addr) (*((uint16_t*)(addr)))
-#define pgm_read_dword_near(addr) (*((uint32_t*)(addr)))
-#define pgm_read_byte(addr) pgm_read_byte_near(addr)
-#define pgm_read_float(addr) pgm_read_float_near(addr)
-#define pgm_read_word(addr) pgm_read_word_near(addr)
-#define pgm_read_dword(addr) pgm_read_dword_near(addr)
-
-using std::memcpy;
-#define memcpy_P memcpy
-#define sprintf_P sprintf
-#define strstr_P strstr
-#define strncpy_P strncpy
-#define vsnprintf_P vsnprintf
-#define strcpy_P strcpy
-#define snprintf_P snprintf
-#define strlen_P strlen
+extern "C" {
+ void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
+ void GpioDisableInt(uint32_t port, uint32_t pin);
+}
// Time functions
-extern "C" {
- void delay(const int milis);
-}
+extern "C" void delay(const int milis);
void _delay_ms(const int delay);
void delayMicroseconds(unsigned long);
uint32_t millis();
diff --git a/Marlin/src/HAL/LINUX/include/serial.h b/Marlin/src/HAL/LINUX/include/serial.h
index 94e0c758ee..2585be25bf 100644
--- a/Marlin/src/HAL/LINUX/include/serial.h
+++ b/Marlin/src/HAL/LINUX/include/serial.h
@@ -25,6 +25,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../../feature/e_parser.h"
#endif
+#include "../../../core/serial_hook.h"
#include
#include
@@ -33,7 +34,6 @@
* Generic RingBuffer
* T type of the buffer array
* S size of the buffer (must be power of 2)
- *
*/
template class RingBuffer {
public:
@@ -74,19 +74,11 @@ private:
volatile uint32_t index_read;
};
-class HalSerial {
-public:
-
- #if ENABLED(EMERGENCY_PARSER)
- EmergencyParser::State emergency_state;
- static inline bool emergency_parser_enabled() { return true; }
- #endif
-
+struct HalSerial {
HalSerial() { host_connected = true; }
void begin(int32_t) {}
-
- void end() {}
+ void end() {}
int peek() {
uint8_t value;
@@ -101,7 +93,7 @@ public:
return transmit_buffer.write(c);
}
- operator bool() { return host_connected; }
+ bool connected() { return host_connected; }
uint16_t available() {
return (uint16_t)receive_buffer.available();
@@ -118,92 +110,9 @@ public:
while (transmit_buffer.available()) { /* nada */ }
}
- void printf(const char *format, ...) {
- static char buffer[256];
- va_list vArgs;
- va_start(vArgs, format);
- int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
- va_end(vArgs);
- if (length > 0 && length < 256) {
- if (host_connected) {
- for (int i = 0; i < length;) {
- if (transmit_buffer.write(buffer[i])) {
- ++i;
- }
- }
- }
- }
- }
-
- #define DEC 10
- #define HEX 16
- #define OCT 8
- #define BIN 2
-
- void print_bin(uint32_t value, uint8_t num_digits) {
- uint32_t mask = 1 << (num_digits -1);
- for (uint8_t i = 0; i < num_digits; i++) {
- if (!(i % 4) && i) write(' ');
- if (!(i % 16) && i) write(' ');
- if (value & mask) write('1');
- else write('0');
- value <<= 1;
- }
- }
-
- void print(const char value[]) { printf("%s" , value); }
- void print(char value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 8);
- else if (nbase == OCT) printf("%3o", value);
- else if (nbase == HEX) printf("%2X", value);
- else if (nbase == DEC ) printf("%d", value);
- else printf("%c" , value);
- }
- void print(unsigned char value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 8);
- else if (nbase == OCT) printf("%3o", value);
- else if (nbase == HEX) printf("%2X", value);
- else printf("%u" , value);
- }
- void print(int value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 16);
- else if (nbase == OCT) printf("%6o", value);
- else if (nbase == HEX) printf("%4X", value);
- else printf("%d", value);
- }
- void print(unsigned int value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 16);
- else if (nbase == OCT) printf("%6o", value);
- else if (nbase == HEX) printf("%4X", value);
- else printf("%u" , value);
- }
- void print(long value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 32);
- else if (nbase == OCT) printf("%11o", value);
- else if (nbase == HEX) printf("%8X", value);
- else printf("%ld" , value);
- }
- void print(unsigned long value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 32);
- else if (nbase == OCT) printf("%11o", value);
- else if (nbase == HEX) printf("%8X", value);
- else printf("%lu" , value);
- }
- void print(float value, int round = 6) { printf("%f" , value); }
- void print(double value, int round = 6) { printf("%f" , value); }
-
- void println(const char value[]) { printf("%s\n" , value); }
- void println(char value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned char value, int nbase = 0) { print(value, nbase); println(); }
- void println(int value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned int value, int nbase = 0) { print(value, nbase); println(); }
- void println(long value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned long value, int nbase = 0) { print(value, nbase); println(); }
- void println(float value, int round = 6) { printf("%f\n" , value); }
- void println(double value, int round = 6) { printf("%f\n" , value); }
- void println() { print('\n'); }
-
volatile RingBuffer receive_buffer;
volatile RingBuffer transmit_buffer;
volatile bool host_connected;
};
+
+typedef Serial0Type MSerialT;
diff --git a/Marlin/src/HAL/LINUX/main.cpp b/Marlin/src/HAL/LINUX/main.cpp
index 481f059030..c409a83e5d 100644
--- a/Marlin/src/HAL/LINUX/main.cpp
+++ b/Marlin/src/HAL/LINUX/main.cpp
@@ -1,6 +1,5 @@
/**
* Marlin 3D Printer Firmware
- *
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
@@ -19,22 +18,23 @@
*/
#ifdef __PLAT_LINUX__
-extern void setup();
-extern void loop();
-
-#include
-
-#include
-#include
+//#define GPIO_LOGGING // Full GPIO and Positional Logging
#include "../../inc/MarlinConfig.h"
-#include
-#include
#include "../shared/Delay.h"
#include "hardware/IOLoggerCSV.h"
#include "hardware/Heater.h"
#include "hardware/LinearAxis.h"
+#include
+#include
+#include
+#include
+#include
+
+extern void setup();
+extern void loop();
+
// simple stdout / stdin implementation for fake serial port
void write_serial_thread() {
for (;;) {
@@ -64,8 +64,6 @@ void simulation_loop() {
LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN);
LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC);
- //#define GPIO_LOGGING // Full GPIO and Positional Logging
-
#ifdef GPIO_LOGGING
IOLoggerCSV logger("all_gpio_log.csv");
Gpio::attachLogger(&logger);
@@ -88,7 +86,7 @@ void simulation_loop() {
#ifdef GPIO_LOGGING
if (x_axis.position != x || y_axis.position != y || z_axis.position != z) {
- uint64_t update = MAX3(x_axis.last_update, y_axis.last_update, z_axis.last_update);
+ uint64_t update = _MAX(x_axis.last_update, y_axis.last_update, z_axis.last_update);
position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl;
position_log.flush();
x = x_axis.position;
diff --git a/Marlin/src/HAL/LINUX/pinsDebug.h b/Marlin/src/HAL/LINUX/pinsDebug.h
index a93ceddc61..8f8543ef59 100644
--- a/Marlin/src/HAL/LINUX/pinsDebug.h
+++ b/Marlin/src/HAL/LINUX/pinsDebug.h
@@ -26,15 +26,15 @@
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
-#define pwm_details(pin) pin = pin // do nothing // print PWM details
-#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
-#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
+#define pwm_details(pin) NOOP // (do nothing)
+#define pwm_status(pin) false // Print a pin's PWM status. Return true if it's currently a PWM pin.
+#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) digitalRead(p)
#define PRINT_PORT(p)
-#define GET_ARRAY_PIN(p) pin_array[p].pin
+#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("%3d "), p); SERIAL_ECHO(buffer); }while(0)
-#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
// active ADC function/mode/code values for PINSEL registers
constexpr int8_t ADC_pin_mode(pin_t pin) {
diff --git a/Marlin/src/HAL/LINUX/servo_private.h b/Marlin/src/HAL/LINUX/servo_private.h
index 122cfef3ea..bcc8d2037f 100644
--- a/Marlin/src/HAL/LINUX/servo_private.h
+++ b/Marlin/src/HAL/LINUX/servo_private.h
@@ -45,7 +45,6 @@
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
- *
*/
#include
diff --git a/Marlin/src/HAL/LINUX/spi_pins.h b/Marlin/src/HAL/LINUX/spi_pins.h
index a444196f04..33136ac9dd 100644
--- a/Marlin/src/HAL/LINUX/spi_pins.h
+++ b/Marlin/src/HAL/LINUX/spi_pins.h
@@ -24,31 +24,32 @@
#include "../../core/macros.h"
#include "../../inc/MarlinConfigPre.h"
-#if BOTH(HAS_GRAPHICAL_LCD, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
// needed due to the speed and mode required for communicating with each device being different.
// This requirement can be removed if the SPI access to these devices is updated to use
// spiBeginTransaction.
#endif
-/** onboard SD card */
-//#define SCK_PIN P0_07
-//#define MISO_PIN P0_08
-//#define MOSI_PIN P0_09
-//#define SS_PIN P0_06
-/** external */
-#ifndef SCK_PIN
- #define SCK_PIN 50
+// Onboard SD
+//#define SD_SCK_PIN P0_07
+//#define SD_MISO_PIN P0_08
+//#define SD_MOSI_PIN P0_09
+//#define SD_SS_PIN P0_06
+
+// External SD
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 50
#endif
-#ifndef MISO_PIN
- #define MISO_PIN 51
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 51
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN 52
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 52
#endif
-#ifndef SS_PIN
- #define SS_PIN 53
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN 53
#endif
#ifndef SDSS
- #define SDSS SS_PIN
+ #define SDSS SD_SS_PIN
#endif
diff --git a/Marlin/src/HAL/LINUX/watchdog.cpp b/Marlin/src/HAL/LINUX/watchdog.cpp
index c15b0e311c..84202e48b6 100644
--- a/Marlin/src/HAL/LINUX/watchdog.cpp
+++ b/Marlin/src/HAL/LINUX/watchdog.cpp
@@ -27,6 +27,8 @@
#include "watchdog.h"
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
void watchdog_init() {}
void HAL_watchdog_refresh() {}
diff --git a/Marlin/src/HAL/LINUX/watchdog.h b/Marlin/src/HAL/LINUX/watchdog.h
index 472624cc78..49a0d9c631 100644
--- a/Marlin/src/HAL/LINUX/watchdog.h
+++ b/Marlin/src/HAL/LINUX/watchdog.h
@@ -21,7 +21,5 @@
*/
#pragma once
-#define WDT_TIMEOUT 4000000 // 4 second timeout
-
void watchdog_init();
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/LPC1768/HAL.cpp b/Marlin/src/HAL/LPC1768/HAL.cpp
index 939f1e8a94..27aa569fae 100644
--- a/Marlin/src/HAL/LPC1768/HAL.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL.cpp
@@ -29,21 +29,18 @@
#include "watchdog.h"
#endif
+DefaultSerial USBSerial(false, UsbSerial);
+
uint32_t HAL_adc_reading = 0;
// U8glib required functions
-extern "C" void u8g_xMicroDelay(uint16_t val) {
- DELAY_US(val);
-}
-extern "C" void u8g_MicroDelay() {
- u8g_xMicroDelay(1);
-}
-extern "C" void u8g_10MicroDelay() {
- u8g_xMicroDelay(10);
-}
-extern "C" void u8g_Delay(uint16_t val) {
- delay(val);
+extern "C" {
+ void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); }
+ void u8g_MicroDelay() { u8g_xMicroDelay(1); }
+ void u8g_10MicroDelay() { u8g_xMicroDelay(10); }
+ void u8g_Delay(uint16_t val) { delay(val); }
}
+
//************************//
// return free heap space
diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h
index 3118aed1b2..1dc4fe6ff9 100644
--- a/Marlin/src/HAL/LPC1768/HAL.h
+++ b/Marlin/src/HAL/LPC1768/HAL.h
@@ -47,9 +47,6 @@ extern "C" volatile uint32_t _millis;
#include
#include
-// i2c uses 8-bit shifted address
-#define I2C_ADDRESS(A) uint8_t((A) << 1)
-
//
// Default graphical display delays
//
@@ -63,12 +60,15 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
+typedef ForwardSerial0Type< decltype(UsbSerial) > DefaultSerial;
+extern DefaultSerial USBSerial;
+
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
- #define MYSERIAL0 UsbSerial
+ #define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -77,7 +77,7 @@ extern "C" volatile uint32_t _millis;
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
- #define MYSERIAL1 UsbSerial
+ #define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -85,9 +85,19 @@ extern "C" volatile uint32_t _millis;
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if MMU2_SERIAL_PORT == -1
+ #define MMU2_SERIAL USBSerial
+ #elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #endif
+#endif
+
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
- #define LCD_SERIAL UsbSerial
+ #define LCD_SERIAL USBSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -107,10 +117,16 @@ extern "C" volatile uint32_t _millis;
//
// Utility functions
//
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
//
// ADC API
@@ -200,7 +216,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255,
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
-// Add strcmp_P if missing
-#ifndef strcmp_P
- #define strcmp_P(a, b) strcmp((a), (b))
-#endif
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
index b3d2908ac9..dbc89a33f5 100644
--- a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
@@ -55,27 +55,33 @@
#include
#include
+#include "../shared/HAL_SPI.h"
+
// ------------------------
// Public functions
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
- #include
-
// Software SPI
- static uint8_t SPI_speed = 0;
+ #include
+
+ #ifndef HAL_SPI_SPEED
+ #define HAL_SPI_SPEED SPI_FULL_SPEED
+ #endif
+
+ static uint8_t SPI_speed = HAL_SPI_SPEED;
static uint8_t spiTransfer(uint8_t b) {
- return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN);
+ return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiBegin() {
- swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN);
+ swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiInit(uint8_t spiRate) {
- SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN);
+ SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
}
uint8_t spiRec() { return spiTransfer(0xFF); }
@@ -100,14 +106,20 @@
#else
- void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
- spiInit(SPI_SPEED);
- }
+ #ifndef HAL_SPI_SPEED
+ #ifdef SD_SPI_SPEED
+ #define HAL_SPI_SPEED SD_SPI_SPEED
+ #else
+ #define HAL_SPI_SPEED SPI_FULL_SPEED
+ #endif
+ #endif
+
+ void spiBegin() { spiInit(HAL_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
void spiInit(uint8_t spiRate) {
- #if MISO_PIN == BOARD_SPI1_MISO_PIN
+ #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPI.setModule(1);
- #elif MISO_PIN == BOARD_SPI2_MISO_PIN
+ #elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPI.setModule(2);
#endif
SPI.setDataSize(DATA_SIZE_8BIT);
@@ -127,11 +139,9 @@
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
}
- void spiSend(uint32_t chan, byte b) {
- }
+ void spiSend(uint32_t chan, byte b) {}
- void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
- }
+ void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {}
// Read single byte from SPI
uint8_t spiRec() { return doio(0xFF); }
@@ -143,9 +153,7 @@
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
- uint8_t spiTransfer(uint8_t b) {
- return doio(b);
- }
+ uint8_t spiTransfer(uint8_t b) { return doio(b); }
// Write from buffer to SPI
void spiSendBlock(uint8_t token, const uint8_t* buf) {
@@ -154,10 +162,9 @@
(void)spiTransfer(buf[i]);
}
- /** Begin SPI transaction, set clock, bit order, data mode */
+ // Begin SPI transaction, set clock, bit order, data mode
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
- // TODO: to be implemented
-
+ // TODO: Implement this method
}
#endif // LPC_SOFTWARE_SPI
@@ -201,6 +208,15 @@ SPIClass::SPIClass(uint8_t device) {
GPDMA_Init();
}
+SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
+ #if BOARD_NR_SPI >= 1
+ if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
+ #endif
+ #if BOARD_NR_SPI >= 2
+ if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
+ #endif
+}
+
void SPIClass::begin() {
// Init the SPI pins in the first begin call
if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
@@ -263,8 +279,9 @@ uint16_t SPIClass::transfer16(const uint16_t data) {
}
void SPIClass::end() {
- // SSP_Cmd(_currentSetting->spi_d, DISABLE); // stop device or SSP_DeInit?
- SSP_DeInit(_currentSetting->spi_d);
+ // Neither is needed for Marlin
+ //SSP_Cmd(_currentSetting->spi_d, DISABLE);
+ //SSP_DeInit(_currentSetting->spi_d);
}
void SPIClass::send(uint8_t data) {
@@ -330,25 +347,15 @@ void SPIClass::read(uint8_t *buf, uint32_t len) {
for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF);
}
-void SPIClass::setClock(uint32_t clock) {
- _currentSetting->clock = clock;
-}
+void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; }
-void SPIClass::setModule(uint8_t device) {
- _currentSetting = &_settings[device - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed
-}
+void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed
-void SPIClass::setBitOrder(uint8_t bitOrder) {
- _currentSetting->bitOrder = bitOrder;
-}
+void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
-void SPIClass::setDataMode(uint8_t dataMode) {
- _currentSetting->dataMode = dataMode;
-}
+void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
-void SPIClass::setDataSize(uint32_t ds) {
- _currentSetting->dataSize = ds;
-}
+void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
/**
* Set up/tear down
@@ -356,8 +363,8 @@ void SPIClass::setDataSize(uint32_t ds) {
void SPIClass::updateSettings() {
//SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?!
- // divide PCLK by 2 for SSP0
- CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
+ // Divide PCLK by 2 for SSP0
+ //CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
SSP_CFG_Type HW_SPI_init; // data structure to hold init values
SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode
@@ -396,9 +403,9 @@ void SPIClass::updateSettings() {
SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
}
-#if MISO_PIN == BOARD_SPI1_MISO_PIN
+#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIClass SPI(1);
-#elif MISO_PIN == BOARD_SPI2_MISO_PIN
+#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIClass SPI(2);
#endif
diff --git a/Marlin/src/HAL/LPC1768/MarlinSPI.h b/Marlin/src/HAL/LPC1768/MarlinSPI.h
new file mode 100644
index 0000000000..fab245f904
--- /dev/null
+++ b/Marlin/src/HAL/LPC1768/MarlinSPI.h
@@ -0,0 +1,45 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+/**
+ * Marlin currently requires 3 SPI classes:
+ *
+ * SPIClass:
+ * This class is normally provided by frameworks and has a semi-default interface.
+ * This is needed because some libraries reference it globally.
+ *
+ * SPISettings:
+ * Container for SPI configs for SPIClass. As above, libraries may reference it globally.
+ *
+ * These two classes are often provided by frameworks so we cannot extend them to add
+ * useful methods for Marlin.
+ *
+ * MarlinSPI:
+ * Provides the default SPIClass interface plus some Marlin goodies such as a simplified
+ * interface for SPI DMA transfer.
+ *
+ */
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
index 5374e005d3..454ace33b2 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
@@ -25,31 +25,20 @@
#include "MarlinSerial.h"
#if USING_SERIAL_0
- MarlinSerial MSerial(LPC_UART0);
- extern "C" void UART0_IRQHandler() {
- MSerial.IRQHandler();
- }
+ MSerialT MSerial(true, LPC_UART0);
+ extern "C" void UART0_IRQHandler() { MSerial.IRQHandler(); }
#endif
-
#if USING_SERIAL_1
- MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
- extern "C" void UART1_IRQHandler() {
- MSerial1.IRQHandler();
- }
+ MSerialT MSerial1(true, (LPC_UART_TypeDef *) LPC_UART1);
+ extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); }
#endif
-
#if USING_SERIAL_2
- MarlinSerial MSerial2(LPC_UART2);
- extern "C" void UART2_IRQHandler() {
- MSerial2.IRQHandler();
- }
+ MSerialT MSerial2(true, LPC_UART2);
+ extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); }
#endif
-
#if USING_SERIAL_3
- MarlinSerial MSerial3(LPC_UART3);
- extern "C" void UART3_IRQHandler() {
- MSerial3.IRQHandler();
- }
+ MSerialT MSerial3(true, LPC_UART3);
+ extern "C" void UART3_IRQHandler() { MSerial3.IRQHandler(); }
#endif
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.h b/Marlin/src/HAL/LPC1768/MarlinSerial.h
index 8d6b64378a..de0f62f006 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.h
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.h
@@ -28,6 +28,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
+#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -41,27 +42,20 @@
class MarlinSerial : public HardwareSerial {
public:
- MarlinSerial(LPC_UART_TypeDef *UARTx) :
- HardwareSerial(UARTx)
- #if ENABLED(EMERGENCY_PARSER)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
- { }
+ MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial(UARTx) { }
void end() {}
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override {
- emergency_parser.update(emergency_state, c);
+ emergency_parser.update(static_cast *>(this)->emergency_state, c);
return true; // do not discard character
}
-
- EmergencyParser::State emergency_state;
- static inline bool emergency_parser_enabled() { return true; }
#endif
};
-extern MarlinSerial MSerial;
-extern MarlinSerial MSerial1;
-extern MarlinSerial MSerial2;
-extern MarlinSerial MSerial3;
+typedef Serial0Type MSerialT;
+extern MSerialT MSerial;
+extern MSerialT MSerial1;
+extern MSerialT MSerial2;
+extern MSerialT MSerial3;
diff --git a/Marlin/src/HAL/LPC1768/Servo.h b/Marlin/src/HAL/LPC1768/Servo.h
index e953cb9204..eb12fd20f4 100644
--- a/Marlin/src/HAL/LPC1768/Servo.h
+++ b/Marlin/src/HAL/LPC1768/Servo.h
@@ -46,7 +46,6 @@
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
- *
*/
#include
diff --git a/Marlin/src/HAL/LPC1768/eeprom_flash.cpp b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
index 2558486375..38d2705d51 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
@@ -25,7 +25,7 @@
* Emulate EEPROM storage using Flash Memory
*
* Use a single 32K flash sector to store EEPROM data. To reduce the
- * number of erase operations a simple "levelling" scheme is used that
+ * number of erase operations a simple "leveling" scheme is used that
* maintains a number of EEPROM "slots" within the larger flash sector.
* Each slot is used in turn and the entire sector is only erased when all
* slots have been used.
@@ -119,7 +119,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false; // return true for any error
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
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);
diff --git a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
index 9f2475f490..54a64ccd72 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
@@ -143,7 +143,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return bytes_written != size; // 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*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
if (!eeprom_file_open) return true;
UINT bytes_read = 0;
FRESULT s;
diff --git a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
index 16c15eaf00..d94aba6119 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
@@ -64,7 +64,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from external EEPROM
const uint8_t c = eeprom_read_byte((uint8_t*)pos);
diff --git a/Marlin/src/HAL/LPC1768/endstop_interrupts.h b/Marlin/src/HAL/LPC1768/endstop_interrupts.h
index b0d0c0ec5c..126d6e7d5b 100644
--- a/Marlin/src/HAL/LPC1768/endstop_interrupts.h
+++ b/Marlin/src/HAL/LPC1768/endstop_interrupts.h
@@ -46,79 +46,79 @@ void setup_endstop_interrupts() {
#if HAS_X_MAX
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
- #error "X_MAX_PIN is not INTERRUPT-capable."
+ #error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(X_MAX_PIN);
#endif
#if HAS_X_MIN
#if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN)
- #error "X_MIN_PIN is not INTERRUPT-capable."
+ #error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(X_MIN_PIN);
#endif
#if HAS_Y_MAX
#if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN)
- #error "Y_MAX_PIN is not INTERRUPT-capable."
+ #error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Y_MAX_PIN);
#endif
#if HAS_Y_MIN
#if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN)
- #error "Y_MIN_PIN is not INTERRUPT-capable."
+ #error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Y_MIN_PIN);
#endif
#if HAS_Z_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN)
- #error "Z_MAX_PIN is not INTERRUPT-capable."
+ #error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MAX_PIN);
#endif
#if HAS_Z_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN)
- #error "Z_MIN_PIN is not INTERRUPT-capable."
+ #error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MIN_PIN);
#endif
#if HAS_Z2_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN)
- #error "Z2_MAX_PIN is not INTERRUPT-capable."
+ #error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z2_MAX_PIN);
#endif
#if HAS_Z2_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN)
- #error "Z2_MIN_PIN is not INTERRUPT-capable."
+ #error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z2_MIN_PIN);
#endif
#if HAS_Z3_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN)
- #error "Z3_MIN_PIN is not INTERRUPT-capable."
+ #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z3_MAX_PIN);
#endif
#if HAS_Z3_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN)
- #error "Z3_MIN_PIN is not INTERRUPT-capable."
+ #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z3_MIN_PIN);
#endif
#if HAS_Z4_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN)
- #error "Z4_MIN_PIN is not INTERRUPT-capable."
+ #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z4_MAX_PIN);
#endif
#if HAS_Z4_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN)
- #error "Z4_MIN_PIN is not INTERRUPT-capable."
+ #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z4_MIN_PIN);
#endif
#if HAS_Z_MIN_PROBE_PIN
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN)
- #error "Z_MIN_PROBE_PIN is not INTERRUPT-capable."
+ #error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h
index b9bc0bf82e..32ef908d63 100644
--- a/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h
+++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_LCD.h
@@ -24,10 +24,3 @@
#if HAS_FSMC_TFT
#error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768."
#endif
-
-// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
-#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
- #undef TOUCH_SCREEN
- #undef TOUCH_SCREEN_CALIBRATION
- #define HAS_TOUCH_XPT2046 1
-#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
index 5f1c4b1601..8e7cab185f 100644
--- a/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
+++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
@@ -20,3 +20,7 @@
*
*/
#pragma once
+
+#if DISABLED(NO_SD_HOST_DRIVE)
+ #define HAS_SD_HOST_DRIVE 1
+#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
index ce6d3fdde2..94e4ce1341 100644
--- a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
+++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
@@ -26,3 +26,10 @@
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
#define USE_SHARED_EEPROM 1
#endif
+
+// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
+// TODO: Which other boards are incompatible?
+#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0
+ #warning "To prevent step loss, motion will pause for PRINTCOUNTER auto-save."
+ #define PRINTCOUNTER_SYNC 1
+#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
index b6491368cd..14890bcd6e 100644
--- a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
@@ -24,7 +24,7 @@
#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 < 2005
+#if PIO_FRAMEWORK_VERSION < 2006
#error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
#endif
@@ -72,7 +72,7 @@ static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are in
//#endif
#if 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)
- #if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
+ #if IS_RRD_FG_SC && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
#error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI."
#endif
#endif
@@ -97,8 +97,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define IS_RX0(P) (P == P0_03)
#if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
#error "Serial port pins (0) conflict with Trinamic SPI pins!"
- #elif ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
- #error "Serial port pins (0) conflict with MK2 multiplexer pins!"
+ #elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
+ #error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!"
#elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN))
#error "Serial port pins (0) conflict with X/Y axis SPI pins!"
#endif
@@ -113,11 +113,11 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define _IS_RX1_1 IS_RX1
#if IS_TX1(TMC_SW_SCK)
#error "Serial port pins (1) conflict with other pins!"
- #elif HAS_SPI_LCD
+ #elif HAS_WIRED_LCD
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
- #elif ANY_TX(1, SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK) \
- || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, MISO_PIN, DOGLCD_A0, SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
+ #elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
+ || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
#error "Serial port pins (1) conflict with LCD pins!"
#endif
#endif
@@ -191,7 +191,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
//
// Flag any i2c pin conflicts
//
-#if ANY(HAS_I2C_DIGIPOT, DAC_STEPPER_CURRENT, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
+#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
#define USEDI2CDEV_M 1 // /Wire.cpp
#if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1)
@@ -205,8 +205,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "SDA0 overlaps with BEEPER_PIN!"
#elif IS_SCL0(BTN_ENC)
#error "SCL0 overlaps with Encoder Button!"
- #elif IS_SCL0(SS_PIN)
- #error "SCL0 overlaps with SS_PIN!"
+ #elif IS_SCL0(SD_SS_PIN)
+ #error "SCL0 overlaps with SD_SS_PIN!"
#elif IS_SCL0(LCD_SDSS)
#error "SCL0 overlaps with LCD_SDSS!"
#endif
diff --git a/Marlin/src/HAL/LPC1768/include/SPI.h b/Marlin/src/HAL/LPC1768/include/SPI.h
index 9da2a32556..ecd91f6a3b 100644
--- a/Marlin/src/HAL/LPC1768/include/SPI.h
+++ b/Marlin/src/HAL/LPC1768/include/SPI.h
@@ -37,13 +37,14 @@
#define DATA_SIZE_8BIT SSP_DATABIT_8
#define DATA_SIZE_16BIT SSP_DATABIT_16
-#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
-#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
-#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
-#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
-#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
-#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
-#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
+#define SPI_CLOCK_MAX_TFT 30000000UL
+#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
+#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
+#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
+#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
+#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
+#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
+#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
@@ -125,6 +126,11 @@ public:
*/
SPIClass(uint8_t spiPortNumber);
+ /**
+ * Init using pins
+ */
+ SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1);
+
/**
* Select and configure the current selected SPI device to use
*/
diff --git a/Marlin/src/HAL/LPC1768/main.cpp b/Marlin/src/HAL/LPC1768/main.cpp
index 0b4045cb99..f41a576376 100644
--- a/Marlin/src/HAL/LPC1768/main.cpp
+++ b/Marlin/src/HAL/LPC1768/main.cpp
@@ -31,17 +31,18 @@
#include
#include
-extern "C" {
- #include
-}
-
-#include "../../sd/cardreader.h"
#include "../../inc/MarlinConfig.h"
#include "../../core/millis_t.h"
+#include "../../sd/cardreader.h"
+
extern uint32_t MSC_SD_Init(uint8_t pdrv);
-extern "C" int isLPC1769();
-extern "C" void disk_timerproc();
+
+extern "C" {
+ #include
+ extern "C" int isLPC1769();
+ extern "C" void disk_timerproc();
+}
void SysTick_Callback() { disk_timerproc(); }
@@ -89,11 +90,11 @@ void HAL_init() {
//debug_frmwrk_init();
//_DBG("\n\nDebug running\n");
// Initialize the SD card chip select pins as soon as possible
- #if PIN_EXISTS(SS)
- OUT_WRITE(SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
- #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SS_PIN
+ #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
#endif
@@ -122,7 +123,7 @@ void HAL_init() {
delay(1000); // Give OS time to notice
USB_Connect(TRUE);
- #if DISABLED(NO_SD_HOST_DRIVE)
+ #if HAS_SD_HOST_DRIVE
MSC_SD_Init(0); // Enable USB SD card access
#endif
diff --git a/Marlin/src/HAL/LPC1768/spi_pins.h b/Marlin/src/HAL/LPC1768/spi_pins.h
index 2e6749bf57..e7d774742f 100644
--- a/Marlin/src/HAL/LPC1768/spi_pins.h
+++ b/Marlin/src/HAL/LPC1768/spi_pins.h
@@ -23,7 +23,7 @@
#include "../../core/macros.h"
-#if BOTH(SDSUPPORT, HAS_GRAPHICAL_LCD) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
// needed due to the speed and mode required for communicating with each device being different.
// This requirement can be removed if the SPI access to these devices is updated to use
@@ -31,24 +31,24 @@
#endif
/** onboard SD card */
-//#define SCK_PIN P0_07
-//#define MISO_PIN P0_08
-//#define MOSI_PIN P0_09
-//#define SS_PIN P0_06
+//#define SD_SCK_PIN P0_07
+//#define SD_MISO_PIN P0_08
+//#define SD_MOSI_PIN P0_09
+//#define SD_SS_PIN P0_06
/** external */
-#ifndef SCK_PIN
- #define SCK_PIN P0_15
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN P0_15
#endif
-#ifndef MISO_PIN
- #define MISO_PIN P0_17
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN P0_17
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN P0_18
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN P0_18
#endif
-#ifndef SS_PIN
- #define SS_PIN P1_23
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN P1_23
#endif
#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h
#undef SDSS
- #define SDSS SS_PIN
+ #define SDSS SD_SS_PIN
#endif
diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
index 84907acd07..a2cb66ab5b 100644
--- a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
@@ -89,7 +89,7 @@ void TFT_SPI::Init() {
#elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIx.setModule(2);
#endif
- SPIx.setClock(SPI_CLOCK_MAX);
+ SPIx.setClock(SPI_CLOCK_MAX_TFT);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
}
@@ -125,7 +125,7 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
}
DataTransferEnd();
- SPIx.setClock(SPI_CLOCK_MAX);
+ SPIx.setClock(SPI_CLOCK_MAX_TFT);
#endif
return data >> 7;
diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.h b/Marlin/src/HAL/LPC1768/tft/tft_spi.h
index 8d3e3127bb..4753fdbae9 100644
--- a/Marlin/src/HAL/LPC1768/tft/tft_spi.h
+++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.h
@@ -36,7 +36,7 @@
#define DATASIZE_8BIT SSP_DATABIT_8
#define DATASIZE_16BIT SSP_DATABIT_16
-#define TFT_IO TFT_SPI
+#define TFT_IO_DRIVER TFT_SPI
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
index 5f96630043..cf14405484 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
-#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
+#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
#include "xpt2046.h"
#include
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.h b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
index 019f75efce..65602bda0f 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.h
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +28,16 @@
#endif
#ifndef TOUCH_MISO_PIN
- #define TOUCH_MISO_PIN MISO_PIN
+ #define TOUCH_MISO_PIN SD_MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
- #define TOUCH_MOSI_PIN MOSI_PIN
+ #define TOUCH_MOSI_PIN SD_MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
- #define TOUCH_SCK_PIN SCK_PIN
+ #define TOUCH_SCK_PIN SD_SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
- #define TOUCH_CS_PIN CS_PIN
+ #define TOUCH_CS_PIN SD_SS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
diff --git a/Marlin/src/HAL/LPC1768/timers.h b/Marlin/src/HAL/LPC1768/timers.h
index 23dc20e2eb..4b63854685 100644
--- a/Marlin/src/HAL/LPC1768/timers.h
+++ b/Marlin/src/HAL/LPC1768/timers.h
@@ -21,7 +21,6 @@
#pragma once
/**
- *
* HAL For LPC1768
*/
@@ -153,7 +152,7 @@ FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// This function is missing from CMSIS
FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[((uint32_t)IRQn) >> 5] & (1 << ((uint32_t)IRQn) & 0x1F)) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
index befc348fab..b1eea13d57 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
@@ -57,15 +57,18 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
#include "../../shared/HAL_SPI.h"
-void spiBegin();
-void spiInit(uint8_t spiRate);
-void spiSend(uint8_t b);
-void spiSend(const uint8_t* buf, size_t n);
+#ifndef LCD_SPI_SPEED
+ #ifdef SD_SPI_SPEED
+ #define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD
+ #else
+ #define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied
+ #endif
+#endif
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch (msg) {
@@ -81,10 +84,7 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
u8g_SetPIOutput(u8g, U8G_PI_RESET);
u8g_Delay(5);
spiBegin();
- #ifndef SPI_SPEED
- #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
- #endif
- spiInit(SPI_SPEED);
+ spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
@@ -124,6 +124,6 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
index f03be9ab34..6f7efba4ae 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
@@ -77,7 +77,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
@@ -193,6 +193,6 @@ uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_v
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
index 1500c22a0d..592e27f6c0 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
#include "../../shared/HAL_SPI.h"
@@ -133,6 +133,6 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
index 10d8494162..61211d9d88 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
@@ -62,9 +62,11 @@
#include
#include
#include "../../shared/Delay.h"
+#include "../../shared/HAL_SPI.h"
-#undef SPI_SPEED
-#define SPI_SPEED 3 // About 1 MHz
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz
+#endif
static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
static uint8_t SPI_speed = 0;
@@ -92,7 +94,7 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
u8g_Delay(5);
- SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
+ SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index 4f52f7dd01..7f38ec54af 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -57,12 +57,14 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include
+#include "../../shared/HAL_SPI.h"
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz
+#endif
#include
#include
@@ -145,7 +147,7 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
u8g_SetPIOutput(u8g, U8G_PI_CS);
u8g_SetPIOutput(u8g, U8G_PI_A0);
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
- SPI_speed = swSpiInit(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
+ SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
break;
@@ -203,5 +205,5 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/upload_extra_script.py b/Marlin/src/HAL/LPC1768/upload_extra_script.py
index 9b0d0617a0..1daaa883ed 100755
--- a/Marlin/src/HAL/LPC1768/upload_extra_script.py
+++ b/Marlin/src/HAL/LPC1768/upload_extra_script.py
@@ -23,63 +23,50 @@ def print_error(e):
%(e, env.get('PIOENV')))
try:
+ #
+ # Find a disk for upload
+ #
+ upload_disk = 'Disk not found'
+ target_file_found = False
+ target_drive_found = False
if current_OS == 'Windows':
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
- #
-
- #
- # get all drives on this computer
- #
import subprocess
- # typical result (string): 'Drives: C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
- 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: ') <- 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()
+ from ctypes import windll
+ import string
+
+ # getting list of drives
+ # https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
+ drives = []
+ bitmask = windll.kernel32.GetLogicalDrives()
+ for letter in string.ascii_uppercase:
+ if bitmask & 1:
+ drives.append(letter)
+ bitmask >>= 1
- upload_disk = 'Disk not found'
- target_file_found = False
- target_drive_found = False
for drive in drives:
- final_drive_name = drive.strip().rstrip('\\') # typical result (string): 'C:'
+ final_drive_name = drive + ':\\'
+ # print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
+ print ('error:{}'.format(e))
continue
else:
- if target_drive in volume_info and target_file_found == False: # set upload if not found target file yet
+ if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = final_drive_name
if target_filename in volume_info:
- if target_file_found == False:
+ if not target_file_found:
upload_disk = final_drive_name
target_file_found = True
- #
- # set upload_port to drive if found
- #
-
- if target_file_found == True or target_drive_found == True:
- env.Replace(
- UPLOAD_PORT=upload_disk
- )
- print('upload disk: ', upload_disk)
- else:
- print_error('Autodetect Error')
-
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
- upload_disk = 'Disk not found'
- target_file_found = False
- target_drive_found = False
drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
@@ -101,22 +88,15 @@ try:
if target_file_found or target_drive_found:
env.Replace(
- UPLOAD_FLAGS="-P$UPLOAD_PORT",
- UPLOAD_PORT=upload_disk
+ UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
- print('upload disk: ', upload_disk)
- else:
- print_error('Autodetect Error')
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
- upload_disk = 'Disk not found'
drives = os.listdir('/Volumes') # human readable names
- target_file_found = False
- target_drive_found = False
- if target_drive in drives and target_file_found == False: # set upload if not found target file yet
+ if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
@@ -126,20 +106,18 @@ try:
continue
else:
if target_filename in filenames:
- if target_file_found == False:
+ if not target_file_found:
upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
- #
- # set upload_port to drive if found
- #
- if target_file_found == True or target_drive_found == True:
- env.Replace(
- UPLOAD_PORT=upload_disk
- )
- print('\nupload disk: ', upload_disk, '\n')
- else:
- print_error('Autodetect Error')
+ #
+ # Set upload_port to drive if found
+ #
+ if target_file_found or target_drive_found:
+ env.Replace(UPLOAD_PORT=upload_disk)
+ print('\nUpload disk: ', upload_disk, '\n')
+ else:
+ print_error('Autodetect Error')
except Exception as e:
print_error(str(e))
diff --git a/Marlin/src/HAL/LPC1768/watchdog.cpp b/Marlin/src/HAL/LPC1768/watchdog.cpp
index 3cd22d6651..f23ccf5b51 100644
--- a/Marlin/src/HAL/LPC1768/watchdog.cpp
+++ b/Marlin/src/HAL/LPC1768/watchdog.cpp
@@ -28,6 +28,8 @@
#include
#include "watchdog.h"
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
void watchdog_init() {
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
@@ -52,7 +54,7 @@ void watchdog_init() {
#else
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
#endif
- WDT_Start(WDT_TIMEOUT);
+ WDT_Start(WDT_TIMEOUT_US);
}
void HAL_watchdog_refresh() {
diff --git a/Marlin/src/HAL/LPC1768/watchdog.h b/Marlin/src/HAL/LPC1768/watchdog.h
index cc170881f3..c843f0ed55 100644
--- a/Marlin/src/HAL/LPC1768/watchdog.h
+++ b/Marlin/src/HAL/LPC1768/watchdog.h
@@ -21,8 +21,6 @@
*/
#pragma once
-#define WDT_TIMEOUT 4000000 // 4 second timeout
-
void watchdog_init();
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/SAMD51/HAL.cpp b/Marlin/src/HAL/SAMD51/HAL.cpp
index 9f24d30071..a413c4cd80 100644
--- a/Marlin/src/HAL/SAMD51/HAL.cpp
+++ b/Marlin/src/HAL/SAMD51/HAL.cpp
@@ -24,6 +24,11 @@
#include
#include
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+ DefaultSerial MSerial(false, Serial);
+ DefaultSerial1 MSerial1(false, Serial1);
+#endif
+
// ------------------------
// Local defines
// ------------------------
@@ -300,7 +305,7 @@ uint16_t HAL_adc_result;
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
- if (descriptor != nullptr)
+ if (descriptor)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc0DMAProgram.startJob();
}
@@ -337,7 +342,7 @@ uint16_t HAL_adc_result;
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
- if (descriptor != nullptr)
+ if (descriptor)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc1DMAProgram.startJob();
}
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index 7fd826a1b6..f28583c771 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -32,14 +32,19 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
+ typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
+ extern DefaultSerial MSerial;
+ typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
+ extern DefaultSerial1 MSerial1;
// MYSERIAL0 required before MarlinSerial includes!
- #define _MSERIAL(X) Serial##X
+ #define __MSERIAL(X) MSerial##X
+ #define _MSERIAL(X) __MSERIAL(X)
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1
- #define MYSERIAL0 Serial
+ #define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -48,7 +53,7 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
- #define MYSERIAL1 Serial
+ #define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -56,9 +61,19 @@
#endif
#endif
+ #ifdef MMU2_SERIAL_PORT
+ #if MMU2_SERIAL_PORT == -1
+ #define MMU2_SERIAL MSerial
+ #elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #endif
+ #endif
+
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
- #define LCD_SERIAL Serial
+ #define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -88,6 +103,8 @@ typedef int8_t pin_t;
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
//
// ADC
//
@@ -132,10 +149,16 @@ void HAL_idletask();
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
index abc5f3acbf..ce32eafee5 100644
--- a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
+++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
@@ -21,30 +21,30 @@
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
/**
- * Framework doesn't define some serial to save sercom resources
+ * Framework doesn't define some serials to save sercom resources
* hence if these are used I need to define them
*/
#include "../../inc/MarlinConfig.h"
-#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
- Uart Serial2(&sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
+#if USING_SERIAL_1
+ UartT Serial2(false, &sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
void SERCOM4_0_Handler() { Serial2.IrqHandler(); }
void SERCOM4_1_Handler() { Serial2.IrqHandler(); }
void SERCOM4_2_Handler() { Serial2.IrqHandler(); }
void SERCOM4_3_Handler() { Serial2.IrqHandler(); }
#endif
-#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2
- Uart Serial3(&sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
+#if USING_SERIAL_2
+ UartT Serial3(false, &sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
void SERCOM1_0_Handler() { Serial3.IrqHandler(); }
void SERCOM1_1_Handler() { Serial3.IrqHandler(); }
void SERCOM1_2_Handler() { Serial3.IrqHandler(); }
void SERCOM1_3_Handler() { Serial3.IrqHandler(); }
#endif
-#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3
- Uart Serial4(&sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
+#if USING_SERIAL_3
+ UartT Serial4(false, &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
void SERCOM5_0_Handler() { Serial4.IrqHandler(); }
void SERCOM5_1_Handler() { Serial4.IrqHandler(); }
void SERCOM5_2_Handler() { Serial4.IrqHandler(); }
diff --git a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
index f3821d8d5a..b7293415d1 100644
--- a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
+++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
@@ -20,6 +20,10 @@
*/
#pragma once
-extern Uart Serial2;
-extern Uart Serial3;
-extern Uart Serial4;
+#include "../../core/serial_hook.h"
+
+typedef Serial0Type UartT;
+
+extern UartT Serial2;
+extern UartT Serial3;
+extern UartT Serial4;
diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.cpp b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
index 161c04084f..fc21a1ad8c 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
@@ -26,7 +26,7 @@
#include "QSPIFlash.h"
-#define INVALID_ADDR 0xffffffff
+#define INVALID_ADDR 0xFFFFFFFF
#define SECTOR_OF(a) (a & ~(SFLASH_SECTOR_SIZE - 1))
#define OFFSET_OF(a) (a & (SFLASH_SECTOR_SIZE - 1))
@@ -35,10 +35,10 @@ uint8_t QSPIFlash::_buf[SFLASH_SECTOR_SIZE];
uint32_t QSPIFlash::_addr = INVALID_ADDR;
void QSPIFlash::begin() {
- if (_flashBase != nullptr) return;
+ if (_flashBase) return;
_flashBase = new Adafruit_SPIFlashBase(new Adafruit_FlashTransport_QSPI());
- _flashBase->begin(NULL);
+ _flashBase->begin(nullptr);
}
size_t QSPIFlash::size() {
diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.h b/Marlin/src/HAL/SAMD51/QSPIFlash.h
index b6f22769ff..db4abec91c 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.h
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.h
@@ -24,7 +24,6 @@
* THE SOFTWARE.
*
* Derived from Adafruit_SPIFlash class with no SdFat references
- *
*/
#pragma once
diff --git a/Marlin/src/HAL/SAMD51/eeprom_flash.cpp b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
index 429ef1c2d4..871bf22b7f 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
@@ -79,7 +79,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
diff --git a/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
index b403f7939f..faa7637197 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
@@ -56,7 +56,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = qspi.readByte(pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
index 3283195897..d9a0225a7a 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
@@ -59,7 +59,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/SAMD51/fastio.h b/Marlin/src/HAL/SAMD51/fastio.h
index c456dfce30..a95b7cac0c 100644
--- a/Marlin/src/HAL/SAMD51/fastio.h
+++ b/Marlin/src/HAL/SAMD51/fastio.h
@@ -31,7 +31,7 @@
*/
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
/**
diff --git a/Marlin/src/HAL/SAMD51/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h
index c28937d6c6..81376db79a 100644
--- a/Marlin/src/HAL/SAMD51/pinsDebug.h
+++ b/Marlin/src/HAL/SAMD51/pinsDebug.h
@@ -150,5 +150,4 @@ void pwm_details(int32_t pin) {
* 93 | PA10 | QSPI: IO2
* 94 | PA11 | QSPI: IO3
* 95 | PB31 | SD: DETECT
- *
*/
diff --git a/Marlin/src/HAL/SAMD51/spi_pins.h b/Marlin/src/HAL/SAMD51/spi_pins.h
index 5a9b1275ef..2a667bcaa1 100644
--- a/Marlin/src/HAL/SAMD51/spi_pins.h
+++ b/Marlin/src/HAL/SAMD51/spi_pins.h
@@ -30,16 +30,16 @@
* SPI | 53 52 50 51 |
* SPI1 | 83 81 80 82 |
* +-------------------------+
- * Any pin can be used for Chip Select (SS_PIN)
+ * Any pin can be used for Chip Select (SD_SS_PIN)
*/
- #ifndef SCK_PIN
- #define SCK_PIN 52
+ #ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 52
#endif
- #ifndef MISO_PIN
- #define MISO_PIN 50
+ #ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 50
#endif
- #ifndef MOSI_PIN
- #define MOSI_PIN 51
+ #ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 51
#endif
#ifndef SDSS
#define SDSS 53
@@ -51,4 +51,4 @@
#endif
-#define SS_PIN SDSS
+#define SD_SS_PIN SDSS
diff --git a/Marlin/src/HAL/SAMD51/timers.cpp b/Marlin/src/HAL/SAMD51/timers.cpp
index a68af2e074..5c55d32407 100644
--- a/Marlin/src/HAL/SAMD51/timers.cpp
+++ b/Marlin/src/HAL/SAMD51/timers.cpp
@@ -157,7 +157,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/SAMD51/watchdog.cpp b/Marlin/src/HAL/SAMD51/watchdog.cpp
index ebc8dffe13..9de451836a 100644
--- a/Marlin/src/HAL/SAMD51/watchdog.cpp
+++ b/Marlin/src/HAL/SAMD51/watchdog.cpp
@@ -24,28 +24,30 @@
#if ENABLED(USE_WATCHDOG)
- #include "watchdog.h"
+#include "watchdog.h"
- void watchdog_init() {
- // The low-power oscillator used by the WDT runs at 32,768 Hz with
- // a 1:32 prescale, thus 1024 Hz, though probably not super precise.
+#define WDT_TIMEOUT_REG TERN(WATCHDOG_DURATION_8S, WDT_CONFIG_PER_CYC8192, WDT_CONFIG_PER_CYC4096) // 4 or 8 second timeout
- // Setup WDT clocks
- MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
- MCLK->APBAMASK.bit.WDT_ = true;
- OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
+void watchdog_init() {
+ // The low-power oscillator used by the WDT runs at 32,768 Hz with
+ // a 1:32 prescale, thus 1024 Hz, though probably not super precise.
- WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
- SYNC(WDT->SYNCBUSY.bit.ENABLE);
+ // Setup WDT clocks
+ MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
+ MCLK->APBAMASK.bit.WDT_ = true;
+ OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
- WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
- WDT->CONFIG.reg = WDT_CONFIG_PER_CYC4096; // Set at least 4s period for chip reset
+ WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
+ SYNC(WDT->SYNCBUSY.bit.ENABLE);
- HAL_watchdog_refresh();
+ WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
+ WDT->CONFIG.reg = WDT_TIMEOUT_REG; // Set a 4s or 8s period for chip reset
- WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
- SYNC(WDT->SYNCBUSY.bit.ENABLE);
- }
+ HAL_watchdog_refresh();
+
+ WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
+ SYNC(WDT->SYNCBUSY.bit.ENABLE);
+}
#endif // USE_WATCHDOG
diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp
index b1b727ce19..b8db5b5e0b 100644
--- a/Marlin/src/HAL/STM32/HAL.cpp
+++ b/Marlin/src/HAL/STM32/HAL.cpp
@@ -28,6 +28,10 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
+#ifdef USBCON
+ DefaultSerial MSerial(false, SerialUSB);
+#endif
+
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
#include
@@ -63,7 +67,7 @@ uint16_t HAL_adc_result;
void HAL_init() {
FastIO_init();
- #if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT)
+ #if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
@@ -81,7 +85,9 @@ void HAL_init() {
SetTimerInterruptPriorities();
- TERN_(EMERGENCY_PARSER, USB_Hook_init());
+ #if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
+ USB_Hook_init();
+ #endif
}
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
@@ -122,9 +128,18 @@ extern "C" {
// TODO: Make sure this doesn't cause any delay
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
-
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
+// Reset the system (to initiate a firmware flash)
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
+// Maple Compatibility
+volatile uint32_t systick_uptime_millis = 0;
+systickCallback_t systick_user_callback;
+void systick_attach_callback(systickCallback_t cb) { systick_user_callback = cb; }
+void HAL_SYSTICK_Callback() {
+ systick_uptime_millis++;
+ if (systick_user_callback) systick_user_callback();
+}
+
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h
index 60ab45374a..29df0a5c6d 100644
--- a/Marlin/src/HAL/STM32/HAL.h
+++ b/Marlin/src/HAL/STM32/HAL.h
@@ -29,6 +29,7 @@
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
+#include "Servo.h"
#include "watchdog.h"
#include "MarlinSerial.h"
@@ -38,6 +39,9 @@
#ifdef USBCON
#include
+ #include "../../core/serial_hook.h"
+ typedef ForwardSerial0Type< decltype(SerialUSB) > DefaultSerial;
+ extern DefaultSerial MSerial;
#endif
// ------------------------
@@ -47,7 +51,7 @@
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
- #define MYSERIAL0 SerialUSB
+ #define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 1, 6)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -56,7 +60,7 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
- #define MYSERIAL1 SerialUSB
+ #define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 1, 6)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -64,9 +68,19 @@
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if MMU2_SERIAL_PORT == -1
+ #define MMU2_SERIAL MSerial
+ #elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
+ #endif
+#endif
+
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
- #define LCD_SERIAL SerialUSB
+ #define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -95,14 +109,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
// ------------------------
// Types
// ------------------------
@@ -110,6 +116,8 @@
typedef int16_t pin_t;
#define HAL_SERVO_LIB libServo
+#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
+#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
// ------------------------
// Public Variables
@@ -134,6 +142,8 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
void _delay_ms(const int delay);
extern "C" char* _sbrk(int incr);
@@ -154,14 +164,14 @@ static inline int freeMemory() {
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
-inline void HAL_adc_init() {}
-
#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION 10
+#define HAL_ADC_RESOLUTION ADC_RESOLUTION // 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+inline void HAL_adc_init() { analogReadResolution(HAL_ADC_RESOLUTION); }
+
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
@@ -177,3 +187,26 @@ uint16_t HAL_adc_get_result();
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);
+
+// Maple Compatibility
+typedef void (*systickCallback_t)(void);
+void systick_attach_callback(systickCallback_t cb);
+void HAL_SYSTICK_Callback();
+extern volatile uint32_t systick_uptime_millis;
+
+#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
+
+/**
+ * set_pwm_frequency
+ * Set the frequency of the timer corresponding to the provided pin
+ * All Timer PWM pins run at the same frequency
+ */
+void set_pwm_frequency(const pin_t pin, int f_desired);
+
+/**
+ * set_pwm_duty
+ * Set the PWM duty cycle of the provided pin to the provided value
+ * Optionally allows inverting the duty cycle [default = false]
+ * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
+ */
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
diff --git a/Marlin/src/HAL/STM32/HAL_SPI.cpp b/Marlin/src/HAL/STM32/HAL_SPI.cpp
index 202442a71b..eef480777b 100644
--- a/Marlin/src/HAL/STM32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/STM32/HAL_SPI.cpp
@@ -45,10 +45,10 @@ static SPISettings spiConfig;
#include "../shared/Delay.h"
void spiBegin(void) {
- OUT_WRITE(SS_PIN, HIGH);
- OUT_WRITE(SCK_PIN, HIGH);
- SET_INPUT(MISO_PIN);
- OUT_WRITE(MOSI_PIN, HIGH);
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ OUT_WRITE(SD_SCK_PIN, HIGH);
+ SET_INPUT(SD_MISO_PIN);
+ OUT_WRITE(SD_MOSI_PIN, HIGH);
}
static uint16_t delay_STM32_soft_spi;
@@ -72,15 +72,15 @@ static SPISettings spiConfig;
uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
for (uint8_t bits = 8; bits--;) {
- WRITE(SCK_PIN, LOW);
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, b & 0x80);
DELAY_NS(delay_STM32_soft_spi);
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(delay_STM32_soft_spi);
b <<= 1; // little setup time
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
}
DELAY_NS(125);
return b;
@@ -132,11 +132,9 @@ static SPISettings spiConfig;
* @details Only configures SS pin since stm32duino creates and initialize the SPI object
*/
void spiBegin() {
- #if !PIN_EXISTS(SS)
- #error "SS_PIN not defined!"
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
-
- OUT_WRITE(SS_PIN, HIGH);
}
// Configure SPI for specified SPI speed
@@ -156,10 +154,9 @@ static SPISettings spiConfig;
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);
+ SPI.setMISO(SD_MISO_PIN);
+ SPI.setMOSI(SD_MOSI_PIN);
+ SPI.setSCLK(SD_SCK_PIN);
#endif
SPI.begin();
@@ -173,9 +170,7 @@ static SPISettings spiConfig;
* @details
*/
uint8_t spiRec() {
- SPI.beginTransaction(spiConfig);
uint8_t returnByte = SPI.transfer(0xFF);
- SPI.endTransaction();
return returnByte;
}
@@ -191,9 +186,7 @@ static SPISettings spiConfig;
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte == 0) return;
memset(buf, 0xFF, nbyte);
- SPI.beginTransaction(spiConfig);
SPI.transfer(buf, nbyte);
- SPI.endTransaction();
}
/**
@@ -204,9 +197,7 @@ static SPISettings spiConfig;
* @details
*/
void spiSend(uint8_t b) {
- SPI.beginTransaction(spiConfig);
SPI.transfer(b);
- SPI.endTransaction();
}
/**
@@ -219,10 +210,8 @@ static SPISettings spiConfig;
*/
void spiSendBlock(uint8_t token, const uint8_t* buf) {
uint8_t rxBuf[512];
- SPI.beginTransaction(spiConfig);
SPI.transfer(token);
SPI.transfer((uint8_t*)buf, &rxBuf, 512);
- SPI.endTransaction();
}
#endif // SOFTWARE_SPI
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.cpp b/Marlin/src/HAL/STM32/MarlinSPI.cpp
new file mode 100644
index 0000000000..5086b41784
--- /dev/null
+++ b/Marlin/src/HAL/STM32/MarlinSPI.cpp
@@ -0,0 +1,168 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "MarlinSPI.h"
+
+static void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb, uint32_t dataSize) {
+ spi_init(obj, speed, mode, msb);
+ // spi_init set 8bit always
+ // TODO: copy the code from spi_init and handle data size, to avoid double init always!!
+ if (dataSize != SPI_DATASIZE_8BIT) {
+ obj->handle.Init.DataSize = dataSize;
+ HAL_SPI_Init(&obj->handle);
+ __HAL_SPI_ENABLE(&obj->handle);
+ }
+}
+
+void MarlinSPI::setClockDivider(uint8_t _div) {
+ _speed = spi_getClkFreq(&_spi);// / _div;
+ _clockDivider = _div;
+}
+
+void MarlinSPI::begin(void) {
+ //TODO: only call spi_init if any parameter changed!!
+ spi_init(&_spi, _speed, _dataMode, _bitOrder, _dataSize);
+}
+
+void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc) {
+ _dmaHandle.Init.Direction = direction;
+ _dmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
+ _dmaHandle.Init.Mode = DMA_NORMAL;
+ _dmaHandle.Init.Priority = DMA_PRIORITY_LOW;
+ _dmaHandle.Init.MemInc = minc ? DMA_MINC_ENABLE : DMA_MINC_DISABLE;
+
+ if (_dataSize == DATA_SIZE_8BIT) {
+ _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ }
+ else {
+ _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ }
+ #ifdef STM32F4xx
+ _dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ #endif
+
+ // start DMA hardware
+ // TODO: check if hardware is already enabled
+ #ifdef SPI1_BASE
+ if (_spiHandle.Instance == SPI1) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_3;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
+ #endif
+ }
+ #endif
+ #ifdef SPI2_BASE
+ if (_spiHandle.Instance == SPI2) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
+ #endif
+ }
+ #endif
+ #ifdef SPI3_BASE
+ if (_spiHandle.Instance == SPI3) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
+ #endif
+ }
+ #endif
+
+ HAL_DMA_Init(&_dmaHandle);
+}
+
+byte MarlinSPI::transfer(uint8_t _data) {
+ uint8_t rxData = 0xFF;
+ HAL_SPI_TransmitReceive(&_spi.handle, &_data, &rxData, 1, HAL_MAX_DELAY);
+ return rxData;
+}
+
+uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
+ const uint8_t ff = 0xFF;
+
+ //if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) //only enable if disabled
+ __HAL_SPI_ENABLE(&_spi.handle);
+
+ if (receiveBuf) {
+ setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true);
+ HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_RXDMAEN); /* Enable Rx DMA Request */
+ }
+
+ // check for 2 lines transfer
+ bool mincTransmit = true;
+ if (transmitBuf == nullptr && _spi.handle.Init.Direction == SPI_DIRECTION_2LINES && _spi.handle.Init.Mode == SPI_MODE_MASTER) {
+ transmitBuf = &ff;
+ mincTransmit = false;
+ }
+
+ if (transmitBuf) {
+ setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit);
+ HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
+ }
+
+ if (transmitBuf) {
+ HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaTx);
+ HAL_DMA_DeInit(&_dmaTx);
+ }
+
+ // while ((_spi.handle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
+
+ if (receiveBuf) {
+ HAL_DMA_PollForTransfer(&_dmaRx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaRx);
+ HAL_DMA_DeInit(&_dmaRx);
+ }
+
+ return 1;
+}
+
+uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc) {
+ setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc);
+ HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
+ __HAL_SPI_ENABLE(&_spi.handle);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
+ HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaTx);
+ // DeInit objects
+ HAL_DMA_DeInit(&_dmaTx);
+ return 1;
+}
+
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.h b/Marlin/src/HAL/STM32/MarlinSPI.h
new file mode 100644
index 0000000000..fbd3585ff4
--- /dev/null
+++ b/Marlin/src/HAL/STM32/MarlinSPI.h
@@ -0,0 +1,107 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "HAL.h"
+#include
+
+extern "C" {
+ #include
+}
+
+/**
+ * Marlin currently requires 3 SPI classes:
+ *
+ * SPIClass:
+ * This class is normally provided by frameworks and has a semi-default interface.
+ * This is needed because some libraries reference it globally.
+ *
+ * SPISettings:
+ * Container for SPI configs for SPIClass. As above, libraries may reference it globally.
+ *
+ * These two classes are often provided by frameworks so we cannot extend them to add
+ * useful methods for Marlin.
+ *
+ * MarlinSPI:
+ * Provides the default SPIClass interface plus some Marlin goodies such as a simplified
+ * interface for SPI DMA transfer.
+ *
+ */
+
+#define DATA_SIZE_8BIT SPI_DATASIZE_8BIT
+#define DATA_SIZE_16BIT SPI_DATASIZE_16BIT
+
+class MarlinSPI {
+public:
+ MarlinSPI() : MarlinSPI(NC, NC, NC, NC) {}
+
+ MarlinSPI(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)NC) : _mosiPin(mosi), _misoPin(miso), _sckPin(sclk), _ssPin(ssel) {
+ _spi.pin_miso = digitalPinToPinName(_misoPin);
+ _spi.pin_mosi = digitalPinToPinName(_mosiPin);
+ _spi.pin_sclk = digitalPinToPinName(_sckPin);
+ _spi.pin_ssel = digitalPinToPinName(_ssPin);
+ _dataSize = DATA_SIZE_8BIT;
+ _bitOrder = MSBFIRST;
+ _dataMode = SPI_MODE_0;
+ _spi.handle.State = HAL_SPI_STATE_RESET;
+ setClockDivider(SPI_SPEED_CLOCK_DIV2_MHZ);
+ }
+
+ void begin(void);
+ void end(void) {}
+
+ byte transfer(uint8_t _data);
+ uint8_t dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length);
+ uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = true);
+
+ /* These methods are deprecated and kept for compatibility.
+ * Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
+ */
+ void setBitOrder(BitOrder _order) { _bitOrder = _order; }
+
+ void setDataMode(uint8_t _mode) {
+ switch (_mode) {
+ case SPI_MODE0: _dataMode = SPI_MODE_0; break;
+ case SPI_MODE1: _dataMode = SPI_MODE_1; break;
+ case SPI_MODE2: _dataMode = SPI_MODE_2; break;
+ case SPI_MODE3: _dataMode = SPI_MODE_3; break;
+ }
+ }
+
+ void setClockDivider(uint8_t _div);
+
+private:
+ void setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc = false);
+
+ spi_t _spi;
+ DMA_HandleTypeDef _dmaTx;
+ DMA_HandleTypeDef _dmaRx;
+ BitOrder _bitOrder;
+ spi_mode_e _dataMode;
+ uint8_t _clockDivider;
+ uint32_t _speed;
+ uint32_t _dataSize;
+ pin_t _mosiPin;
+ pin_t _misoPin;
+ pin_t _sckPin;
+ pin_t _ssPin;
+};
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp
index a146664366..c420ce40cf 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp
@@ -16,7 +16,6 @@
* along with this program. If not, see .
*
*/
-
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
@@ -36,7 +35,7 @@
#define DECLARE_SERIAL_PORT(ser_num) \
void _rx_complete_irq_ ## ser_num (serial_t * obj); \
- MarlinSerial MSerial ## ser_num (USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
+ MSerialT MSerial ## ser_num (true, USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); }
#define DECLARE_SERIAL_PORT_EXP(ser_num) DECLARE_SERIAL_PORT(ser_num)
@@ -49,6 +48,10 @@
DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2)
#endif
+#if defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT >= 0
+ DECLARE_SERIAL_PORT_EXP(MMU2_SERIAL_PORT)
+#endif
+
#if defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT >= 0
DECLARE_SERIAL_PORT_EXP(LCD_SERIAL_PORT)
#endif
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h
index 3611cc78d7..8cc4f0dd4c 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.h
+++ b/Marlin/src/HAL/STM32/MarlinSerial.h
@@ -24,21 +24,15 @@
#include "../../feature/e_parser.h"
#endif
+#include "../../core/serial_hook.h"
+
typedef void (*usart_rx_callback_t)(serial_t * obj);
-class MarlinSerial : public HardwareSerial {
-public:
+struct MarlinSerial : public HardwareSerial {
MarlinSerial(void* peripheral, usart_rx_callback_t rx_callback) :
HardwareSerial(peripheral), _rx_callback(rx_callback)
- #if ENABLED(EMERGENCY_PARSER)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
{ }
- #if ENABLED(EMERGENCY_PARSER)
- static inline bool emergency_parser_enabled() { return true; }
- #endif
-
void begin(unsigned long baud, uint8_t config);
inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
@@ -46,19 +40,17 @@ public:
protected:
usart_rx_callback_t _rx_callback;
- #if ENABLED(EMERGENCY_PARSER)
- EmergencyParser::State emergency_state;
- #endif
};
-extern MarlinSerial MSerial1;
-extern MarlinSerial MSerial2;
-extern MarlinSerial MSerial3;
-extern MarlinSerial MSerial4;
-extern MarlinSerial MSerial5;
-extern MarlinSerial MSerial6;
-extern MarlinSerial MSerial7;
-extern MarlinSerial MSerial8;
-extern MarlinSerial MSerial9;
-extern MarlinSerial MSerial10;
-extern MarlinSerial MSerialLP1;
+typedef Serial0Type MSerialT;
+extern MSerialT MSerial1;
+extern MSerialT MSerial2;
+extern MSerialT MSerial3;
+extern MSerialT MSerial4;
+extern MSerialT MSerial5;
+extern MSerialT MSerial6;
+extern MSerialT MSerial7;
+extern MSerialT MSerial8;
+extern MSerialT MSerial9;
+extern MSerialT MSerial10;
+extern MSerialT MSerialLP1;
diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
index 6e73e87c21..e00fb9b16f 100644
--- a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
+++ b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
@@ -19,10 +19,11 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
-#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC)
+#if ENABLED(SDIO_SUPPORT)
#include
#include
@@ -31,7 +32,7 @@
#error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
#endif
-#ifdef USBD_USE_CDC_COMPOSITE
+#if HAS_SD_HOST_DRIVE
// use USB drivers
@@ -87,18 +88,37 @@
MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency
Additional testing is required as there are clearly some 4bit initialization problems
-
- Add -DTRANSFER_CLOCK_DIV=8 to build parameters to improve SDIO stability
*/
- #ifndef TRANSFER_CLOCK_DIV
- #define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40)
- #endif
-
#ifndef USBD_OK
#define USBD_OK 0
#endif
+ // Target Clock, configurable. Default is 18MHz, from STM32F1
+ #ifndef SDIO_CLOCK
+ #define SDIO_CLOCK 18000000 /* 18 MHz */
+ #endif
+
+ // SDIO retries, configurable. Default is 3, from STM32F1
+ #ifndef SDIO_READ_RETRIES
+ #define SDIO_READ_RETRIES 3
+ #endif
+
+ // SDIO Max Clock (naming from STM Manual, don't change)
+ #define SDIOCLK 48000000
+
+ static uint32_t clock_to_divider(uint32_t clk) {
+ // limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
+ // Also limited to no more than 48Mhz (SDIOCLK).
+ const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
+ clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
+ clk = min(clk, (uint32_t)SDIOCLK);
+ // Round up divider, so we don't run the card over the speed supported,
+ // and subtract by 2, because STM32 will add 2, as written in the manual:
+ // SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
+ return pclk2 / clk + (pclk2 % clk != 0) - 2;
+ }
+
void go_to_transfer_speed() {
SD_InitTypeDef Init;
@@ -108,7 +128,7 @@
Init.ClockPowerSave = hsd.Init.ClockPowerSave;
Init.BusWide = hsd.Init.BusWide;
Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
- Init.ClockDiv = TRANSFER_CLOCK_DIV;
+ Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
/* Initialize SDIO peripheral interface with default configuration */
SDIO_Init(hsd.Instance, Init);
@@ -154,38 +174,25 @@
//Initialize the SDIO (with initial <400Khz Clock)
tempreg = 0; //Reset value
tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled
- tempreg |= (uint32_t)0x76; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
+ tempreg |= SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
// Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
SDIO->CLKCR = tempreg;
// Power up the SDIO
- SDIO->POWER = 0x03;
+ SDIO_PowerState_ON(SDIO);
}
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
- UNUSED(hsd); /* Prevent unused argument(s) compilation warning */
+ UNUSED(hsd); // Prevent unused argument(s) compilation warning
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock
}
- constexpr uint8_t SD_RETRY_COUNT = TERN(SD_CHECK_AND_RETRY, 3, 1);
-
bool SDIO_Init() {
- //init SDIO and get SD card info
-
- uint8_t retryCnt = SD_RETRY_COUNT;
+ uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
hsd.Instance = SDIO;
- hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
-
- /*
- hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
- hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
- hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
- hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
- hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
- hsd.Init.ClockDiv = 8;
- */
+ hsd.State = HAL_SD_STATE_RESET;
SD_LowLevel_Init();
@@ -257,7 +264,7 @@
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
hsd.Instance = SDIO;
- uint8_t retryCnt = SD_RETRY_COUNT;
+ uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
for (;;) {
@@ -306,7 +313,7 @@
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
hsd.Instance = SDIO;
- uint8_t retryCnt = SD_RETRY_COUNT;
+ uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
for (;;) {
status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout
@@ -319,3 +326,4 @@
#endif // !USBD_USE_CDC_COMPOSITE
#endif // SDIO_SUPPORT
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/eeprom_flash.cpp b/Marlin/src/HAL/STM32/eeprom_flash.cpp
index 0933b9f4e8..633a286dc8 100644
--- a/Marlin/src/HAL/STM32/eeprom_flash.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_flash.cpp
@@ -28,15 +28,6 @@
#include "../shared/eeprom_api.h"
-#if HAS_SERVOS
- #include "Servo.h"
- #define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
- #define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
-#else
- #define PAUSE_SERVO_OUTPUT()
- #define RESUME_SERVO_OUTPUT()
-#endif
-
/**
* The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that
* even have multiple "banks" of flash.
@@ -70,7 +61,9 @@
#define FLASH_UNIT_SIZE 0x20000 // 128kB
#endif
- #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1)
+ #ifndef FLASH_ADDRESS_START
+ #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1)
+ #endif
#define FLASH_ADDRESS_END (FLASH_ADDRESS_START + FLASH_UNIT_SIZE - 1)
#define EEPROM_SLOTS ((FLASH_UNIT_SIZE) / (MARLIN_EEPROM_SIZE))
@@ -113,7 +106,7 @@ bool PersistentStore::access_start() {
// 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");
+ if (eeprom_data_written) DEBUG_ECHOLNPGM("Dangling EEPROM write_data");
uint32_t address = FLASH_ADDRESS_START;
while (address <= FLASH_ADDRESS_END) {
uint32_t address_value = (*(__IO uint32_t*)address);
@@ -172,11 +165,11 @@ bool PersistentStore::access_finish() {
current_slot = EEPROM_SLOTS - 1;
UNLOCK_FLASH();
- PAUSE_SERVO_OUTPUT();
+ TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
DISABLE_ISRS();
status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
ENABLE_ISRS();
- RESUME_SERVO_OUTPUT();
+ TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
if (status != HAL_OK) {
DEBUG_ECHOLNPAIR("HAL_FLASHEx_Erase=", status);
DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
@@ -227,11 +220,11 @@ bool PersistentStore::access_finish() {
// Interrupts during this time can have unpredictable results, such as killing Servo
// output. Servo output still glitches with interrupts disabled, but recovers after the
// erase.
- PAUSE_SERVO_OUTPUT();
+ TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
DISABLE_ISRS();
eeprom_buffer_flush();
ENABLE_ISRS();
- RESUME_SERVO_OUTPUT();
+ TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
eeprom_data_written = false;
#endif
@@ -261,7 +254,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
const uint8_t c = TERN(FLASH_EEPROM_LEVELING, ram_eeprom[pos], eeprom_buffered_read_byte(pos));
if (writing) *value = c;
diff --git a/Marlin/src/HAL/STM32/eeprom_sdcard.cpp b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
index 711a83ed5b..f811468fb4 100644
--- a/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
@@ -19,13 +19,12 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
/**
* Implementation of EEPROM settings in SD Card
*/
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
-
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDCARD_EEPROM_EMULATION)
@@ -78,7 +77,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
+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 c = HAL_eeprom_data[pos + i];
if (writing) value[i] = c;
@@ -89,4 +88,4 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uin
}
#endif // SDCARD_EEPROM_EMULATION
-#endif // STM32 && !STM32GENERIC
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/eeprom_sram.cpp b/Marlin/src/HAL/STM32/eeprom_sram.cpp
index 5f6f26f9c6..135bcabde9 100644
--- a/Marlin/src/HAL/STM32/eeprom_sram.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_sram.cpp
@@ -52,7 +52,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from either external EEPROM, program flash or Backup SRAM
const uint8_t c = ( *(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos)) );
diff --git a/Marlin/src/HAL/STM32/eeprom_wired.cpp b/Marlin/src/HAL/STM32/eeprom_wired.cpp
index 8c46e45f03..ad54c12c47 100644
--- a/Marlin/src/HAL/STM32/eeprom_wired.cpp
+++ b/Marlin/src/HAL/STM32/eeprom_wired.cpp
@@ -65,7 +65,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from either external EEPROM, program flash or Backup SRAM
const uint8_t c = eeprom_read_byte((uint8_t*)pos);
diff --git a/Marlin/src/HAL/STM32/fast_pwm.cpp b/Marlin/src/HAL/STM32/fast_pwm.cpp
new file mode 100644
index 0000000000..42eecb5e1a
--- /dev/null
+++ b/Marlin/src/HAL/STM32/fast_pwm.cpp
@@ -0,0 +1,59 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if NEEDS_HARDWARE_PWM
+
+#include "HAL.h"
+#include "timers.h"
+
+void set_pwm_frequency(const pin_t pin, int f_desired) {
+ if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
+
+ PinName pin_name = digitalPinToPinName(pin);
+ TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance
+
+ LOOP_S_L_N(i, 0, NUM_HARDWARE_TIMERS) // Protect used timers
+ if (timer_instance[i] && timer_instance[i]->getHandle()->Instance == Instance)
+ return;
+
+ pwm_start(pin_name, f_desired, 0, RESOLUTION_8B_COMPARE_FORMAT);
+}
+
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
+ PinName pin_name = digitalPinToPinName(pin);
+ TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM);
+ uint16_t adj_val = Instance->ARR * v / v_size;
+ if (invert) adj_val = Instance->ARR - adj_val;
+
+ switch (get_pwm_channel(pin_name)) {
+ case TIM_CHANNEL_1: LL_TIM_OC_SetCompareCH1(Instance, adj_val); break;
+ case TIM_CHANNEL_2: LL_TIM_OC_SetCompareCH2(Instance, adj_val); break;
+ case TIM_CHANNEL_3: LL_TIM_OC_SetCompareCH3(Instance, adj_val); break;
+ case TIM_CHANNEL_4: LL_TIM_OC_SetCompareCH4(Instance, adj_val); break;
+ }
+}
+
+#endif // NEEDS_HARDWARE_PWM
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/fastio.h b/Marlin/src/HAL/STM32/fastio.h
index d90b2fbeb0..17751c44dd 100644
--- a/Marlin/src/HAL/STM32/fastio.h
+++ b/Marlin/src/HAL/STM32/fastio.h
@@ -51,19 +51,19 @@ void FastIO_init(); // Must be called before using fast io macros
#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx)
#define _WRITE(IO, V) do { \
- if (V) FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO])) ; \
- else FastIOPortMap[STM_PORT(digitalPin[IO])]->BRR = _BV32(STM_PIN(digitalPin[IO])) ; \
+ if (V) FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
+ else FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \
}while(0)
#else
- #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPin[IO])]->BSRR = _BV32(STM_PIN(digitalPin[IO]) + ((V) ? 0 : 16)))
+ #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO)) + ((V) ? 0 : 16)))
#endif
-#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPin[IO])]->IDR, _BV32(STM_PIN(digitalPin[IO]))))
-#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPin[IO])]->ODR ^= _BV32(STM_PIN(digitalPin[IO])))
+#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO)))))
+#define _TOGGLE(IO) TBI32(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR, STM_PIN(digitalPinToPinName(IO)))
#define _GET_MODE(IO)
#define _SET_MODE(IO,M) pinMode(IO, M)
-#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) /*!< Output Push Pull Mode & GPIO_NOPULL */
+#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) //!< Output Push Pull Mode & GPIO_NOPULL
#define _SET_OUTPUT_OD(IO) pinMode(IO, OUTPUT_OPEN_DRAIN)
#define WRITE(IO,V) _WRITE(IO,V)
@@ -73,9 +73,9 @@ void FastIO_init(); // Must be called before using fast io macros
#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, INPUT) /*!< Input Floating Mode */
-#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */
-#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */
+#define SET_INPUT(IO) _SET_MODE(IO, INPUT) //!< Input Floating Mode
+#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) //!< Input with Pull-up activation
+#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) //!< Input with Pull-down activation
#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
#define SET_PWM(IO) _SET_MODE(IO, PWM)
diff --git a/Marlin/src/HAL/STM32/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h
index 5f1c4b1601..e07c0d9cda 100644
--- a/Marlin/src/HAL/STM32/inc/Conditionals_adv.h
+++ b/Marlin/src/HAL/STM32/inc/Conditionals_adv.h
@@ -20,3 +20,7 @@
*
*/
#pragma once
+
+#if defined(USBD_USE_CDC_COMPOSITE) && DISABLED(NO_SD_HOST_DRIVE)
+ #define HAS_SD_HOST_DRIVE 1
+#endif
diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h
index 30d0750d90..4df75a0505 100644
--- a/Marlin/src/HAL/STM32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h
@@ -28,9 +28,6 @@
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
//#endif
-#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
- #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32."
-#endif
#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT)
#undef SDCARD_EEPROM_EMULATION // Avoid additional error noise
@@ -54,3 +51,7 @@
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#endif
+
+#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32F4xx, STM32F1xx)
+ #error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32F4 and STM32F1 hardware."
+#endif
diff --git a/Marlin/src/HAL/STM32/pinsDebug.h b/Marlin/src/HAL/STM32/pinsDebug.h
index ec08e3fd75..048f788e3d 100644
--- a/Marlin/src/HAL/STM32/pinsDebug.h
+++ b/Marlin/src/HAL/STM32/pinsDebug.h
@@ -18,17 +18,247 @@
*/
#pragma once
-#if !(defined(NUM_DIGITAL_PINS) || defined(BOARD_NR_GPIO_PINS))
- #error "M43 not supported for this board"
+#include
+
+#ifndef NUM_DIGITAL_PINS
+ // Only in ST's Arduino core (STM32duino, STM32Core)
+ #error "Expected NUM_DIGITAL_PINS not found"
#endif
-// Strange - STM32F4 comes to HAL_STM32 rather than HAL_STM32F4 for these files
-#ifdef STM32F4
- #ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core)
- #include "pinsDebug_STM32duino.h"
- #elif defined(BOARD_NR_GPIO_PINS) // Only in STM32GENERIC (Maple)
- #include "pinsDebug_STM32GENERIC.h"
+/**
+ * Life gets complicated if you want an easy to use 'M43 I' output (in port/pin order)
+ * because the variants in this platform do not always define all the I/O port/pins
+ * that a CPU has.
+ *
+ * VARIABLES:
+ * Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and
+ * digitalWrite commands and by M42.
+ * - does not contain port/pin info
+ * - is not in port/pin order
+ * - typically a variant will only assign Ard_num to port/pins that are actually used
+ * Index - M43 counter - only used to get Ard_num
+ * x - a parameter/argument used to search the pin_array to try to find a signal name
+ * associated with a Ard_num
+ * Port_pin - port number and pin number for use with CPU registers and printing reports
+ *
+ * Since M43 uses digitalRead and digitalWrite commands, only the Port_pins with an Ard_num
+ * are accessed and/or displayed.
+ *
+ * Three arrays are used.
+ *
+ * digitalPin[] is provided by the platform. It consists of the Port_pin numbers in
+ * Arduino pin number order.
+ *
+ * pin_array is a structure generated by the pins/pinsDebug.h header file. It is generated by
+ * the preprocessor. Only the signals associated with enabled options are in this table.
+ * It contains:
+ * - name of the signal
+ * - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines.
+ * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the
+ * argument to digitalPinToPinName(IO) to get the Port_pin number
+ * - if it is a digital or analog signal. PWMs are considered digital here.
+ *
+ * pin_xref is a structure generated by this header file. It is generated by the
+ * preprocessor. It is in port/pin order. It contains just the port/pin numbers defined by the
+ * platform for this variant.
+ * - Ard_num
+ * - printable version of Port_pin
+ *
+ * Routines with an "x" as a parameter/argument are used to search the pin_array to try to
+ * find a signal name associated with a port/pin.
+ *
+ * NOTE - the Arduino pin number is what is used by the M42 command, NOT the port/pin for that
+ * signal. The Arduino pin number is listed by the M43 I command.
+ */
+
+////////////////////////////////////////////////////////
+//
+// make a list of the Arduino pin numbers in the Port/Pin order
+//
+
+#define _PIN_ADD_2(NAME_ALPHA, ARDUINO_NUM) { {NAME_ALPHA}, ARDUINO_NUM },
+#define _PIN_ADD(NAME_ALPHA, ARDUINO_NUM) { NAME_ALPHA, ARDUINO_NUM },
+#define PIN_ADD(NAME) _PIN_ADD(#NAME, NAME)
+
+typedef struct {
+ char Port_pin_alpha[5];
+ pin_t Ard_num;
+} XrefInfo;
+
+const XrefInfo pin_xref[] PROGMEM = {
+ #include "pins_Xref.h"
+};
+
+////////////////////////////////////////////////////////////
+
+#define MODE_PIN_INPUT 0 // Input mode (reset state)
+#define MODE_PIN_OUTPUT 1 // General purpose output mode
+#define MODE_PIN_ALT 2 // Alternate function mode
+#define MODE_PIN_ANALOG 3 // Analog mode
+
+#define PIN_NUM(P) (P & 0x000F)
+#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
+#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
+#define PORT_NUM(P) ((P >> 4) & 0x0007)
+#define PORT_ALPHA(P) ('A' + (P >> 4))
+
+/**
+ * Translation of routines & variables used by pinsDebug.h
+ */
+#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
+#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
+#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
+#define PRINT_PIN(Q)
+#define PRINT_PORT(ANUM) port_print(ANUM)
+#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine
+#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
+
+// x is a variable used to search pin_array
+#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
+#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].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 MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
+
+#ifndef M43_NEVER_TOUCH
+ #define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
+ #ifdef KILL_PIN
+ #define M43_NEVER_TOUCH(Index) m43_never_touch(Index)
+
+ bool m43_never_touch(const pin_t Index) {
+ static pin_t M43_kill_index = -1;
+ if (M43_kill_index < 0)
+ for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++)
+ if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break;
+ return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB
+ }
#else
- #error "M43 not supported for this board"
+ #define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index)
#endif
#endif
+
+uint8_t get_pin_mode(const pin_t Ard_num) {
+ const PinName dp = digitalPinToPinName(Ard_num);
+ uint32_t ll_pin = STM_LL_GPIO_PIN(dp);
+ GPIO_TypeDef *port = get_GPIO_Port(STM_PORT(dp));
+ uint32_t mode = LL_GPIO_GetPinMode(port, ll_pin);
+ switch (mode) {
+ case LL_GPIO_MODE_ANALOG: return MODE_PIN_ANALOG;
+ case LL_GPIO_MODE_INPUT: return MODE_PIN_INPUT;
+ case LL_GPIO_MODE_OUTPUT: return MODE_PIN_OUTPUT;
+ case LL_GPIO_MODE_ALTERNATE: return MODE_PIN_ALT;
+ TERN_(STM32F1xx, case LL_GPIO_MODE_FLOATING:)
+ default: return 0;
+ }
+}
+
+bool GET_PINMODE(const pin_t Ard_num) {
+ const uint8_t pin_mode = get_pin_mode(Ard_num);
+ return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM
+}
+
+int8_t digital_pin_to_analog_pin(pin_t Ard_num) {
+ Ard_num -= NUM_ANALOG_FIRST;
+ return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1;
+}
+
+bool IS_ANALOG(const pin_t Ard_num) {
+ return get_pin_mode(Ard_num) == MODE_PIN_ANALOG;
+}
+
+bool is_digital(const pin_t x) {
+ const uint8_t pin_mode = get_pin_mode(pin_array[x].pin);
+ return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
+}
+
+void port_print(const pin_t Ard_num) {
+ char buffer[16];
+ pin_t Index;
+ for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++)
+ if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break;
+
+ const char * ppa = pin_xref[Index].Port_pin_alpha;
+ sprintf_P(buffer, PSTR("%s"), ppa);
+ SERIAL_ECHO(buffer);
+ if (ppa[3] == '\0') SERIAL_CHAR(' ');
+
+ // print analog pin number
+ const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num);
+ if (Port_pin >= 0) {
+ sprintf_P(buffer, PSTR(" (A%d) "), Port_pin);
+ SERIAL_ECHO(buffer);
+ if (Port_pin < 10) SERIAL_CHAR(' ');
+ }
+ else
+ SERIAL_ECHO_SP(7);
+
+ // Print number to be used with M42
+ sprintf_P(buffer, PSTR(" M42 P%d "), Ard_num);
+ SERIAL_ECHO(buffer);
+ if (Ard_num < 10) SERIAL_CHAR(' ');
+ if (Ard_num < 100) SERIAL_CHAR(' ');
+}
+
+bool pwm_status(const pin_t Ard_num) {
+ return get_pin_mode(Ard_num) == MODE_PIN_ALT;
+}
+
+void pwm_details(const pin_t Ard_num) {
+ #ifndef STM32F1xx
+ if (pwm_status(Ard_num)) {
+ uint32_t alt_all = 0;
+ const PinName dp = digitalPinToPinName(Ard_num);
+ pin_t pin_number = uint8_t(PIN_NUM(dp));
+ const bool over_7 = pin_number >= 8;
+ const uint8_t ind = over_7 ? 1 : 0;
+ switch (PORT_ALPHA(dp)) { // get alt function
+ case 'A' : alt_all = GPIOA->AFR[ind]; break;
+ case 'B' : alt_all = GPIOB->AFR[ind]; break;
+ case 'C' : alt_all = GPIOC->AFR[ind]; break;
+ case 'D' : alt_all = GPIOD->AFR[ind]; break;
+ #ifdef PE_0
+ case 'E' : alt_all = GPIOE->AFR[ind]; break;
+ #elif defined (PF_0)
+ case 'F' : alt_all = GPIOF->AFR[ind]; break;
+ #elif defined (PG_0)
+ case 'G' : alt_all = GPIOG->AFR[ind]; break;
+ #elif defined (PH_0)
+ case 'H' : alt_all = GPIOH->AFR[ind]; break;
+ #elif defined (PI_0)
+ case 'I' : alt_all = GPIOI->AFR[ind]; break;
+ #elif defined (PJ_0)
+ case 'J' : alt_all = GPIOJ->AFR[ind]; break;
+ #elif defined (PK_0)
+ case 'K' : alt_all = GPIOK->AFR[ind]; break;
+ #elif defined (PL_0)
+ case 'L' : alt_all = GPIOL->AFR[ind]; break;
+ #endif
+ }
+ if (over_7) pin_number -= 8;
+
+ uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F;
+ SERIAL_ECHOPAIR("Alt Function: ", alt_func);
+ if (alt_func < 10) SERIAL_CHAR(' ');
+ SERIAL_ECHOPGM(" - ");
+ switch (alt_func) {
+ case 0 : SERIAL_ECHOPGM("system (misc. I/O)"); break;
+ case 1 : SERIAL_ECHOPGM("TIM1/TIM2 (probably PWM)"); break;
+ case 2 : SERIAL_ECHOPGM("TIM3..5 (probably PWM)"); break;
+ case 3 : SERIAL_ECHOPGM("TIM8..11 (probably PWM)"); break;
+ case 4 : SERIAL_ECHOPGM("I2C1..3"); break;
+ case 5 : SERIAL_ECHOPGM("SPI1/SPI2"); break;
+ case 6 : SERIAL_ECHOPGM("SPI3"); break;
+ case 7 : SERIAL_ECHOPGM("USART1..3"); break;
+ case 8 : SERIAL_ECHOPGM("USART4..6"); break;
+ case 9 : SERIAL_ECHOPGM("CAN1/CAN2, TIM12..14 (probably PWM)"); break;
+ case 10 : SERIAL_ECHOPGM("OTG"); break;
+ case 11 : SERIAL_ECHOPGM("ETH"); break;
+ case 12 : SERIAL_ECHOPGM("FSMC, SDIO, OTG"); break;
+ case 13 : SERIAL_ECHOPGM("DCMI"); break;
+ case 14 : SERIAL_ECHOPGM("unused (shouldn't see this)"); break;
+ case 15 : SERIAL_ECHOPGM("EVENTOUT"); break;
+ }
+ }
+ #else
+ // TODO: F1 doesn't support changing pins function, so we need to check the function of the PIN and if it's enabled
+ #endif
+} // pwm_details
diff --git a/Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h b/Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h
deleted file mode 100644
index 9069d9f7bd..0000000000
--- a/Marlin/src/HAL/STM32/pinsDebug_STM32GENERIC.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * 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
-
-/**
- * Support routines for STM32GENERIC (Maple)
- */
-
-/**
- * Translation of routines & variables used by pinsDebug.h
- */
-
-#ifdef BOARD_NR_GPIO_PINS // Only in STM32GENERIC (Maple)
-
-#ifdef __STM32F1__
- #include "../STM32F1/fastio.h"
-#elif defined(STM32F4) || defined(STM32F7)
- #include "../STM32_F4_F7/fastio.h"
-#else
- #include "fastio.h"
-#endif
-
-extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS];
-
-#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS
-#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS
-#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS)
-#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin)
-#define pwm_status(pin) PWM_PIN(pin)
-#define digitalRead_mod(p) extDigitalRead(p)
-#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); SERIAL_ECHO(buffer); }while(0)
-#define PRINT_PORT(p) print_port(p)
-#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 MULTI_NAME_PAD 21 // space needed to be pretty if not first name assigned to a pin
-
-// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
-#ifndef M43_NEVER_TOUCH
- #define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX)
-#endif
-
-static inline int8_t get_pin_mode(pin_t pin) {
- return VALID_PIN(pin) ? _GET_MODE(pin) : -1;
-}
-
-static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
- if (!VALID_PIN(pin)) return -1;
- int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel);
- #ifdef NUM_ANALOG_INPUTS
- if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = ADCx;
- #endif
- return pin_t(adc_channel);
-}
-
-static inline bool IS_ANALOG(pin_t pin) {
- if (!VALID_PIN(pin)) return false;
- if (PIN_MAP[pin].adc_channel != ADCx) {
- #ifdef NUM_ANALOG_INPUTS
- if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false;
- #endif
- return _GET_MODE(pin) == GPIO_INPUT_ANALOG && !M43_NEVER_TOUCH(pin);
- }
- return false;
-}
-
-static inline bool GET_PINMODE(const pin_t pin) {
- return VALID_PIN(pin) && !IS_INPUT(pin);
-}
-
-static inline bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
- const pin_t pin = GET_ARRAY_PIN(array_pin);
- return (!IS_ANALOG(pin)
- #ifdef NUM_ANALOG_INPUTS
- || PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS
- #endif
- );
-}
-
-#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density
-
-static inline void pwm_details(const pin_t pin) {
- if (PWM_PIN(pin)) {
- timer_dev * const tdev = PIN_MAP[pin].timer_device;
- const uint8_t channel = PIN_MAP[pin].timer_channel;
- const char num = (
- #if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
- tdev == &timer8 ? '8' :
- tdev == &timer5 ? '5' :
- #endif
- tdev == &timer4 ? '4' :
- tdev == &timer3 ? '3' :
- tdev == &timer2 ? '2' :
- tdev == &timer1 ? '1' : '?'
- );
- char buffer[10];
- sprintf_P(buffer, PSTR(" TIM%c CH%c"), num, ('0' + channel));
- SERIAL_ECHO(buffer);
- }
-}
-
-static inline void print_port(pin_t pin) {
- const char port = 'A' + char(pin >> 4); // pin div 16
- const int16_t gbit = PIN_MAP[pin].gpio_bit;
- char buffer[8];
- sprintf_P(buffer, PSTR("P%c%hd "), port, gbit);
- if (gbit < 10) SERIAL_CHAR(' ');
- SERIAL_ECHO(buffer);
-}
-
-#endif // BOARD_NR_GPIO_PINS
diff --git a/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h b/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h
deleted file mode 100644
index 09f2bb54e6..0000000000
--- a/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * 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
-
-#ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core)
-
-/**
- * Life gets complicated if you want an easy to use 'M43 I' output (in port/pin order)
- * because the variants in this platform do not always define all the I/O port/pins
- * that a CPU has.
- *
- * VARIABLES:
- * Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and
- * digitalWrite commands and by M42.
- * - does not contain port/pin info
- * - is not in port/pin order
- * - typically a variant will only assign Ard_num to port/pins that are actually used
- * Index - M43 counter - only used to get Ard_num
- * x - a parameter/argument used to search the pin_array to try to find a signal name
- * associated with a Ard_num
- * Port_pin - port number and pin number for use with CPU registers and printing reports
- *
- * Since M43 uses digitalRead and digitalWrite commands, only the Port_pins with an Ard_num
- * are accessed and/or displayed.
- *
- * Three arrays are used.
- *
- * digitalPin[] is provided by the platform. It consists of the Port_pin numbers in
- * Arduino pin number order.
- *
- * pin_array is a structure generated by the pins/pinsDebug.h header file. It is generated by
- * the preprocessor. Only the signals associated with enabled options are in this table.
- * It contains:
- * - name of the signal
- * - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines.
- * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as an
- * index into digitalPin[] to get the Port_pin number
- * - if it is a digital or analog signal. PWMs are considered digital here.
- *
- * pin_xref is a structure generated by this header file. It is generated by the
- * preprocessor. It is in port/pin order. It contains just the port/pin numbers defined by the
- * platform for this variant.
- * - Ard_num
- * - printable version of Port_pin
- *
- * Routines with an "x" as a parameter/argument are used to search the pin_array to try to
- * find a signal name associated with a port/pin.
- *
- * NOTE - the Arduino pin number is what is used by the M42 command, NOT the port/pin for that
- * signal. The Arduino pin number is listed by the M43 I command.
- */
-
-extern const PinName digitalPin[]; // provided by the platform
-
-////////////////////////////////////////////////////////
-//
-// make a list of the Arduino pin numbers in the Port/Pin order
-//
-
-#define _PIN_ADD_2(NAME_ALPHA, ARDUINO_NUM) { {NAME_ALPHA}, ARDUINO_NUM },
-#define _PIN_ADD(NAME_ALPHA, ARDUINO_NUM) { NAME_ALPHA, ARDUINO_NUM },
-#define PIN_ADD(NAME) _PIN_ADD(#NAME, NAME)
-
-typedef struct {
- char Port_pin_alpha[5];
- pin_t Ard_num;
-} XrefInfo;
-
-const XrefInfo pin_xref[] PROGMEM = {
- #include "pins_Xref.h"
-};
-
-////////////////////////////////////////////////////////////
-
-#define MODE_PIN_INPUT 0 // Input mode (reset state)
-#define MODE_PIN_OUTPUT 1 // General purpose output mode
-#define MODE_PIN_ALT 2 // Alternate function mode
-#define MODE_PIN_ANALOG 3 // Analog mode
-
-#define PIN_NUM(P) (P & 0x000F)
-#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
-#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
-#define PORT_NUM(P) ((P >> 4) & 0x0007)
-#define PORT_ALPHA(P) ('A' + (P >> 4))
-
-/**
- * Translation of routines & variables used by pinsDebug.h
- */
-#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
-#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
-#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
-#define PRINT_PIN(Q)
-#define PRINT_PORT(ANUM) port_print(ANUM)
-#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine
-#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
-
-// x is a variable used to search pin_array
-#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
-#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].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 MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
-
-#ifndef M43_NEVER_TOUCH
- #define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
- #ifdef KILL_PIN
- #define M43_NEVER_TOUCH(Index) m43_never_touch(Index)
-
- bool m43_never_touch(const pin_t Index) {
- static pin_t M43_kill_index = -1;
- if (M43_kill_index < 0)
- for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++)
- if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break;
- return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB
- }
- #else
- #define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index)
- #endif
-#endif
-
-uint8_t get_pin_mode(const pin_t Ard_num) {
- uint32_t mode_all = 0;
- const PinName dp = digitalPin[Ard_num];
- switch (PORT_ALPHA(dp)) {
- case 'A' : mode_all = GPIOA->MODER; break;
- case 'B' : mode_all = GPIOB->MODER; break;
- case 'C' : mode_all = GPIOC->MODER; break;
- case 'D' : mode_all = GPIOD->MODER; break;
- #ifdef PE_0
- case 'E' : mode_all = GPIOE->MODER; break;
- #elif defined(PF_0)
- case 'F' : mode_all = GPIOF->MODER; break;
- #elif defined(PG_0)
- case 'G' : mode_all = GPIOG->MODER; break;
- #elif defined(PH_0)
- case 'H' : mode_all = GPIOH->MODER; break;
- #elif defined(PI_0)
- case 'I' : mode_all = GPIOI->MODER; break;
- #elif defined(PJ_0)
- case 'J' : mode_all = GPIOJ->MODER; break;
- #elif defined(PK_0)
- case 'K' : mode_all = GPIOK->MODER; break;
- #elif defined(PL_0)
- case 'L' : mode_all = GPIOL->MODER; break;
- #endif
- }
- return (mode_all >> (2 * uint8_t(PIN_NUM(dp)))) & 0x03;
-}
-
-bool GET_PINMODE(const pin_t Ard_num) {
- const uint8_t pin_mode = get_pin_mode(Ard_num);
- return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM
-}
-
-int8_t digital_pin_to_analog_pin(pin_t Ard_num) {
- Ard_num -= NUM_ANALOG_FIRST;
- return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1;
-}
-
-bool IS_ANALOG(const pin_t Ard_num) {
- return get_pin_mode(Ard_num) == MODE_PIN_ANALOG;
-}
-
-bool is_digital(const pin_t x) {
- const uint8_t pin_mode = get_pin_mode(pin_array[x].pin);
- return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
-}
-
-void port_print(const pin_t Ard_num) {
- char buffer[16];
- pin_t Index;
- for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++)
- if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break;
-
- const char * ppa = pin_xref[Index].Port_pin_alpha;
- sprintf_P(buffer, PSTR("%s"), ppa);
- SERIAL_ECHO(buffer);
- if (ppa[3] == '\0') SERIAL_CHAR(' ');
-
- // print analog pin number
- const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num);
- if (Port_pin >= 0) {
- sprintf_P(buffer, PSTR(" (A%d) "), Port_pin);
- SERIAL_ECHO(buffer);
- if (Port_pin < 10) SERIAL_CHAR(' ');
- }
- else
- SERIAL_ECHO_SP(7);
-
- // Print number to be used with M42
- sprintf_P(buffer, PSTR(" M42 P%d "), Ard_num);
- SERIAL_ECHO(buffer);
- if (Ard_num < 10) SERIAL_CHAR(' ');
- if (Ard_num < 100) SERIAL_CHAR(' ');
-}
-
-bool pwm_status(const pin_t Ard_num) {
- return get_pin_mode(Ard_num) == MODE_PIN_ALT;
-}
-
-void pwm_details(const pin_t Ard_num) {
- if (pwm_status(Ard_num)) {
- uint32_t alt_all = 0;
- const PinName dp = digitalPin[Ard_num];
- pin_t pin_number = uint8_t(PIN_NUM(dp));
- const bool over_7 = pin_number >= 8;
- const uint8_t ind = over_7 ? 1 : 0;
- switch (PORT_ALPHA(dp)) { // get alt function
- case 'A' : alt_all = GPIOA->AFR[ind]; break;
- case 'B' : alt_all = GPIOB->AFR[ind]; break;
- case 'C' : alt_all = GPIOC->AFR[ind]; break;
- case 'D' : alt_all = GPIOD->AFR[ind]; break;
- #ifdef PE_0
- case 'E' : alt_all = GPIOE->AFR[ind]; break;
- #elif defined (PF_0)
- case 'F' : alt_all = GPIOF->AFR[ind]; break;
- #elif defined (PG_0)
- case 'G' : alt_all = GPIOG->AFR[ind]; break;
- #elif defined (PH_0)
- case 'H' : alt_all = GPIOH->AFR[ind]; break;
- #elif defined (PI_0)
- case 'I' : alt_all = GPIOI->AFR[ind]; break;
- #elif defined (PJ_0)
- case 'J' : alt_all = GPIOJ->AFR[ind]; break;
- #elif defined (PK_0)
- case 'K' : alt_all = GPIOK->AFR[ind]; break;
- #elif defined (PL_0)
- case 'L' : alt_all = GPIOL->AFR[ind]; break;
- #endif
- }
- if (over_7) pin_number -= 8;
-
- uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F;
- SERIAL_ECHOPAIR("Alt Function: ", alt_func);
- if (alt_func < 10) SERIAL_CHAR(' ');
- SERIAL_ECHOPGM(" - ");
- switch (alt_func) {
- case 0 : SERIAL_ECHOPGM("system (misc. I/O)"); break;
- case 1 : SERIAL_ECHOPGM("TIM1/TIM2 (probably PWM)"); break;
- case 2 : SERIAL_ECHOPGM("TIM3..5 (probably PWM)"); break;
- case 3 : SERIAL_ECHOPGM("TIM8..11 (probably PWM)"); break;
- case 4 : SERIAL_ECHOPGM("I2C1..3"); break;
- case 5 : SERIAL_ECHOPGM("SPI1/SPI2"); break;
- case 6 : SERIAL_ECHOPGM("SPI3"); break;
- case 7 : SERIAL_ECHOPGM("USART1..3"); break;
- case 8 : SERIAL_ECHOPGM("USART4..6"); break;
- case 9 : SERIAL_ECHOPGM("CAN1/CAN2, TIM12..14 (probably PWM)"); break;
- case 10 : SERIAL_ECHOPGM("OTG"); break;
- case 11 : SERIAL_ECHOPGM("ETH"); break;
- case 12 : SERIAL_ECHOPGM("FSMC, SDIO, OTG"); break;
- case 13 : SERIAL_ECHOPGM("DCMI"); break;
- case 14 : SERIAL_ECHOPGM("unused (shouldn't see this)"); break;
- case 15 : SERIAL_ECHOPGM("EVENTOUT"); break;
- }
- }
-} // pwm_details
-
-#endif // NUM_DIGITAL_PINS
diff --git a/Marlin/src/HAL/STM32/spi_pins.h b/Marlin/src/HAL/STM32/spi_pins.h
index 176e2a7b20..e2052c5c77 100644
--- a/Marlin/src/HAL/STM32/spi_pins.h
+++ b/Marlin/src/HAL/STM32/spi_pins.h
@@ -21,15 +21,15 @@
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*/
-#ifndef SCK_PIN
- #define SCK_PIN PIN_SPI_SCK
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN PIN_SPI_SCK
#endif
-#ifndef MISO_PIN
- #define MISO_PIN PIN_SPI_MISO
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN PIN_SPI_MISO
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN PIN_SPI_MOSI
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN PIN_SPI_MOSI
#endif
-#ifndef SS_PIN
- #define SS_PIN PIN_SPI_SS
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN PIN_SPI_SS
#endif
diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
index 3a080d5e27..87ca2dbbe1 100644
--- a/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
+++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
@@ -47,13 +48,14 @@ void TFT_FSMC::Init() {
uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
+ // Perform the SRAM1 memory initialization sequence
SRAMx.Instance = FSMC_NORSRAM_DEVICE;
SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
- /* SRAMx.Init */
+ // SRAMx.Init
SRAMx.Init.NSBank = NSBank;
SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
- SRAMx.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
+ SRAMx.Init.MemoryDataWidth = TERN(TFT_INTERFACE_FSMC_8BIT, FSMC_NORSRAM_MEM_BUS_WIDTH_8, FSMC_NORSRAM_MEM_BUS_WIDTH_16);
SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
@@ -66,8 +68,8 @@ void TFT_FSMC::Init() {
#ifdef STM32F4xx
SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE;
#endif
- /* Read Timing - relatively slow to ensure ID information is correctly read from TFT controller */
- /* Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss */
+ // Read Timing - relatively slow to ensure ID information is correctly read from TFT controller
+ // Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss
Timing.AddressSetupTime = 15;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 24;
@@ -75,8 +77,8 @@ void TFT_FSMC::Init() {
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FSMC_ACCESS_MODE_A;
- /* Write Timing */
- /* Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss */
+ // Write Timing
+ // Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss
ExtTiming.AddressSetupTime = 8;
ExtTiming.AddressHoldTime = 15;
ExtTiming.DataSetupTime = 8;
@@ -130,7 +132,7 @@ void TFT_FSMC::Init() {
uint32_t TFT_FSMC::GetID() {
uint32_t id;
- WriteReg(0x0000);
+ WriteReg(0);
id = LCD->RAM;
if (id == 0)
@@ -140,41 +142,40 @@ uint32_t TFT_FSMC::GetID() {
return id;
}
- uint32_t TFT_FSMC::ReadID(uint16_t Reg) {
- uint32_t id;
- WriteReg(Reg);
- id = LCD->RAM; // dummy read
- id = Reg << 24;
- id |= (LCD->RAM & 0x00FF) << 16;
- id |= (LCD->RAM & 0x00FF) << 8;
- id |= LCD->RAM & 0x00FF;
- return id;
- }
+uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
+ uint32_t id;
+ WriteReg(Reg);
+ id = LCD->RAM; // dummy read
+ id = Reg << 24;
+ id |= (LCD->RAM & 0x00FF) << 16;
+ id |= (LCD->RAM & 0x00FF) << 8;
+ id |= LCD->RAM & 0x00FF;
+ return id;
+}
bool TFT_FSMC::isBusy() {
- if (__IS_DMA_ENABLED(&DMAtx))
+ #if defined(STM32F1xx)
+ volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
+ #elif defined(STM32F4xx)
+ volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
+ #endif
+ if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
- return __IS_DMA_ENABLED(&DMAtx);
+ }
+ else
+ Abort();
+ return dmaEnabled;
}
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.PeriphInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
-
- __HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx));
- __HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx));
-
- #ifdef STM32F1xx
- DMAtx.Instance->CNDTR = Count;
- DMAtx.Instance->CPAR = (uint32_t)Data;
- DMAtx.Instance->CMAR = (uint32_t)&(LCD->RAM);
- #elif defined(STM32F4xx)
- DMAtx.Instance->NDTR = Count;
- DMAtx.Instance->PAR = (uint32_t)Data;
- DMAtx.Instance->M0AR = (uint32_t)&(LCD->RAM);
- #endif
- __HAL_DMA_ENABLE(&DMAtx);
+ DataTransferBegin();
+ HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(LCD->RAM), Count);
+ HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ Abort();
}
#endif // HAS_FSMC_TFT
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/tft/tft_fsmc.h b/Marlin/src/HAL/STM32/tft/tft_fsmc.h
index 8500fee113..2200abaa10 100644
--- a/Marlin/src/HAL/STM32/tft/tft_fsmc.h
+++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.h
@@ -21,34 +21,33 @@
*/
#pragma once
+#include "../../../inc/MarlinConfig.h"
+
#ifdef STM32F1xx
#include "stm32f1xx_hal.h"
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#else
- #error FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware.
+ #error "FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware."
#endif
#ifndef LCD_READ_ID
- #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
+ #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
-#define DATASIZE_8BIT SPI_DATASIZE_8BIT
-#define DATASIZE_16BIT SPI_DATASIZE_16BIT
-#define TFT_IO TFT_FSMC
+#define DATASIZE_8BIT SPI_DATASIZE_8BIT
+#define DATASIZE_16BIT SPI_DATASIZE_16BIT
+#define TFT_IO_DRIVER TFT_FSMC
-#ifdef STM32F1xx
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
-#elif defined(STM32F4xx)
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
-#endif
+#define TFT_DATASIZE TERN(TFT_INTERFACE_FSMC_8BIT, DATASIZE_8BIT, DATASIZE_16BIT)
+typedef TERN(TFT_INTERFACE_FSMC_8BIT, uint8_t, uint16_t) tft_data_t;
typedef struct {
- __IO uint16_t REG;
- __IO uint16_t RAM;
+ __IO tft_data_t REG;
+ __IO tft_data_t RAM;
} LCD_CONTROLLER_TypeDef;
class TFT_FSMC {
@@ -58,8 +57,8 @@ class TFT_FSMC {
static LCD_CONTROLLER_TypeDef *LCD;
- static uint32_t ReadID(uint16_t Reg);
- static void Transmit(uint16_t Data) { LCD->RAM = Data; __DSB(); }
+ static uint32_t ReadID(tft_data_t Reg);
+ static void Transmit(tft_data_t Data) { LCD->RAM = Data; __DSB(); }
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
@@ -68,17 +67,23 @@ class TFT_FSMC {
static bool isBusy();
static void Abort() { __HAL_DMA_DISABLE(&DMAtx); }
- static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {}
+ static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {}
static void DataTransferEnd() {};
- static void WriteData(uint16_t Data) { Transmit(Data); }
- static void WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); }
+ static void WriteData(uint16_t Data) { Transmit(tft_data_t(Data)); }
+ static void WriteReg(uint16_t Reg) { LCD->REG = tft_data_t(Reg); __DSB(); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); }
+ static void WriteMultiple(uint16_t Color, uint32_t Count) {
+ static uint16_t Data; Data = Color;
+ while (Count > 0) {
+ TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
+ Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
+ }
+ }
};
-
#ifdef STM32F1xx
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)
#elif defined(STM32F4xx)
@@ -100,14 +105,16 @@ const PinMap PinMap_FSMC[] = {
{PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05
{PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06
{PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07
- {PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
- {PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
- {PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
- {PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
- {PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
- {PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
- {PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
- {PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
+ #if DISABLED(TFT_INTERFACE_FSMC_8BIT)
+ {PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
+ {PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
+ {PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
+ {PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
+ {PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
+ {PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
+ {PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
+ {PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
+ #endif
{PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE
{PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE
{NC, NP, 0}
@@ -123,7 +130,11 @@ const PinMap PinMap_FSMC_CS[] = {
{NC, NP, 0}
};
-#define FSMC_RS(A) (void *)((2 << A) - 2)
+#if ENABLED(TFT_INTERFACE_FSMC_8BIT)
+ #define FSMC_RS(A) (void *)((2 << (A-1)) - 1)
+#else
+ #define FSMC_RS(A) (void *)((2 << A) - 2)
+#endif
const PinMap PinMap_FSMC_RS[] = {
#ifdef PF0
diff --git a/Marlin/src/HAL/STM32/tft/tft_spi.cpp b/Marlin/src/HAL/STM32/tft/tft_spi.cpp
index d3eb4ba8db..3cb797d5f2 100644
--- a/Marlin/src/HAL/STM32/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/STM32/tft/tft_spi.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
@@ -33,22 +34,13 @@ DMA_HandleTypeDef TFT_SPI::DMAtx;
void TFT_SPI::Init() {
SPI_TypeDef *spiInstance;
- #if PIN_EXISTS(TFT_RESET)
- OUT_WRITE(TFT_RESET_PIN, HIGH);
- HAL_Delay(100);
- #endif
-
- #if PIN_EXISTS(TFT_BACKLIGHT)
- OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
- #endif
-
OUT_WRITE(TFT_A0_PIN, HIGH);
OUT_WRITE(TFT_CS_PIN, HIGH);
if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return;
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return;
- #if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
+ #if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return;
#endif
@@ -56,12 +48,7 @@ void TFT_SPI::Init() {
SPIx.State = HAL_SPI_STATE_RESET;
SPIx.Init.NSS = SPI_NSS_SOFT;
SPIx.Init.Mode = SPI_MODE_MASTER;
- SPIx.Init.Direction =
- #if TFT_MISO_PIN == TFT_MOSI_PIN
- SPI_DIRECTION_1LINE;
- #else
- SPI_DIRECTION_2LINES;
- #endif
+ SPIx.Init.Direction = (TFT_MISO_PIN == TFT_MOSI_PIN) ? SPI_DIRECTION_1LINE : SPI_DIRECTION_2LINES;
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
SPIx.Init.CLKPhase = SPI_PHASE_1EDGE;
SPIx.Init.CLKPolarity = SPI_POLARITY_LOW;
@@ -73,7 +60,7 @@ void TFT_SPI::Init() {
pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK);
pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI);
- #if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
+ #if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN
pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO);
#endif
pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN);
@@ -81,23 +68,41 @@ void TFT_SPI::Init() {
#ifdef SPI1_BASE
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
- __HAL_RCC_DMA1_CLK_ENABLE();
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ DMAtx.Instance = DMA1_Channel3;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ DMAtx.Instance = DMA2_Stream3;
+ DMAtx.Init.Channel = DMA_CHANNEL_3;
+ #endif
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
- DMAtx.Instance = DMA1_Channel3;
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
- __HAL_RCC_DMA1_CLK_ENABLE();
- DMAtx.Instance = DMA1_Channel5;
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ DMAtx.Instance = DMA1_Channel5;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ DMAtx.Instance = DMA1_Stream4;
+ DMAtx.Init.Channel = DMA_CHANNEL_0;
+ #endif
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
- __HAL_RCC_DMA2_CLK_ENABLE();
- DMAtx.Instance = DMA2_Channel2;
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ DMAtx.Instance = DMA2_Channel2;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ DMAtx.Instance = DMA1_Stream5;
+ DMAtx.Init.Channel = DMA_CHANNEL_0;
+ #endif
}
#endif
@@ -109,6 +114,9 @@ void TFT_SPI::Init() {
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DMAtx.Init.Mode = DMA_NORMAL;
DMAtx.Init.Priority = DMA_PRIORITY_LOW;
+ #ifdef STM32F4xx
+ DMAtx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ #endif
}
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
@@ -127,11 +135,10 @@ uint32_t TFT_SPI::GetID() {
}
uint32_t TFT_SPI::ReadID(uint16_t Reg) {
- #if !PIN_EXISTS(TFT_MISO)
- return 0;
- #else
+ uint32_t Data = 0;
+ #if PIN_EXISTS(TFT_MISO)
uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler;
- uint32_t i, Data = 0;
+ uint32_t i;
SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4;
DataTransferBegin(DATASIZE_8BIT);
@@ -155,27 +162,42 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
DataTransferEnd();
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
-
- return Data >> 7;
#endif
+
+ return Data >> 7;
}
bool TFT_SPI::isBusy() {
- if (DMAtx.Instance->CCR & DMA_CCR_EN)
+ #if defined(STM32F1xx)
+ volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
+ #elif defined(STM32F4xx)
+ volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
+ #endif
+ if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
- return DMAtx.Instance->CCR & DMA_CCR_EN;
+ }
+ else
+ Abort();
+ return dmaEnabled;
}
void TFT_SPI::Abort() {
- __HAL_DMA_DISABLE(&DMAtx);
+ // Wait for any running spi
+ while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
+ while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
+ // First, abort any running dma
+ HAL_DMA_Abort(&DMAtx);
+ // DeInit objects
+ HAL_DMA_DeInit(&DMAtx);
+ HAL_SPI_DeInit(&SPIx);
+ // Deselect CS
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) {
- #if TFT_MISO_PIN == TFT_MOSI_PIN
+ if (TFT_MISO_PIN == TFT_MOSI_PIN)
SPI_1LINE_TX(&SPIx);
- #endif
__HAL_SPI_ENABLE(&SPIx);
@@ -184,29 +206,30 @@ void TFT_SPI::Transmit(uint16_t Data) {
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
- #if TFT_MISO_PIN != TFT_MOSI_PIN
+ if (TFT_MISO_PIN != TFT_MOSI_PIN)
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
- #endif
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
+ // Wait last dma finish, to start another
+ while(isBusy()) { }
+
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
+ if (TFT_MISO_PIN == TFT_MOSI_PIN)
+ SPI_1LINE_TX(&SPIx);
+
DataTransferBegin();
- #if TFT_MISO_PIN == TFT_MOSI_PIN
- SPI_1LINE_TX(&SPIx);
- #endif
-
- DMAtx.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << DMAtx.ChannelIndex);
- DMAtx.Instance->CNDTR = Count;
- DMAtx.Instance->CPAR = (uint32_t)&(SPIx.Instance->DR);
- DMAtx.Instance->CMAR = (uint32_t)Data;
- __HAL_DMA_ENABLE(&DMAtx);
+ HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
+
+ HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ Abort();
}
#endif // HAS_SPI_TFT
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/tft/tft_spi.h b/Marlin/src/HAL/STM32/tft/tft_spi.h
index 1eed45a709..667b5f366b 100644
--- a/Marlin/src/HAL/STM32/tft/tft_spi.h
+++ b/Marlin/src/HAL/STM32/tft/tft_spi.h
@@ -38,7 +38,7 @@
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
-#define TFT_IO TFT_SPI
+#define TFT_IO_DRIVER TFT_SPI
class TFT_SPI {
private:
@@ -64,4 +64,11 @@ public:
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
+ static void WriteMultiple(uint16_t Color, uint32_t Count) {
+ static uint16_t Data; Data = Color;
+ while (Count > 0) {
+ TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
+ Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
+ }
+ }
};
diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.cpp b/Marlin/src/HAL/STM32/tft/xpt2046.cpp
index 921e377a9f..04294e669c 100644
--- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,10 +19,11 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
-#if HAS_TFT_XPT2046
+#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
#include "xpt2046.h"
#include "pinconfig.h"
@@ -27,7 +31,6 @@
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
SPI_HandleTypeDef XPT2046::SPIx;
-DMA_HandleTypeDef XPT2046::DMAtx;
void XPT2046::Init() {
SPI_TypeDef *spiInstance;
@@ -67,43 +70,24 @@ void XPT2046::Init() {
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
- #ifdef STM32F1xx
- DMAtx.Instance = DMA1_Channel3;
- #elif defined(STM32F4xx)
- DMAtx.Instance = DMA2_Stream3; // DMA2_Stream5
- #endif
- //SERIAL_ECHO_MSG(" Touch Screen on SPI1");
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
- #ifdef STM32F1xx
- DMAtx.Instance = DMA1_Channel5;
- #elif defined(STM32F4xx)
- DMAtx.Instance = DMA1_Stream4;
- #endif
- //SERIAL_ECHO_MSG(" Touch Screen on SPI2");
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
- #ifdef STM32F1xx
- DMAtx.Instance = DMA2_Channel2;
- #elif defined(STM32F4xx)
- DMAtx.Instance = DMA1_Stream5; // DMA1_Stream7
- #endif
- //SERIAL_ECHO_MSG(" Touch Screen on SPI3");
}
#endif
}
else {
- SPIx.Instance = NULL;
+ SPIx.Instance = nullptr;
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
- //SERIAL_ECHO_MSG(" Touch Screen on Software SPI");
}
getRawData(XPT2046_Z1);
@@ -183,3 +167,4 @@ uint16_t XPT2046::SoftwareIO(uint16_t data) {
}
#endif // HAS_TFT_XPT2046
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/tft/xpt2046.h b/Marlin/src/HAL/STM32/tft/xpt2046.h
index 7a6d8439c5..5b8acf4b87 100644
--- a/Marlin/src/HAL/STM32/tft/xpt2046.h
+++ b/Marlin/src/HAL/STM32/tft/xpt2046.h
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,19 +60,11 @@ enum XPTCoordinate : uint8_t {
#define XPT2046_Z1_THRESHOLD 10
#endif
-#ifdef STM32F1xx
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
-#elif defined(STM32F4xx)
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
-#endif
-
-
class XPT2046 {
private:
static SPI_HandleTypeDef SPIx;
- static DMA_HandleTypeDef DMAtx;
- static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; }
+ static bool isBusy() { return false; }
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
diff --git a/Marlin/src/HAL/STM32/timers.cpp b/Marlin/src/HAL/STM32/timers.cpp
index c0ba19abe5..e8e18a47d4 100644
--- a/Marlin/src/HAL/STM32/timers.cpp
+++ b/Marlin/src/HAL/STM32/timers.cpp
@@ -27,8 +27,6 @@
// Local defines
// ------------------------
-#define NUM_HARDWARE_TIMERS 2
-
// Default timer priorities. Override by specifying alternate priorities in the board pins file.
// The TONE timer is not present here, as it currently cannot be set programmatically. It is set
// by defining TIM_IRQ_PRIO in the variant.h or platformio.ini file, which adjusts the default
@@ -68,26 +66,23 @@
#endif
#ifdef STM32F0xx
- #define MCU_TIMER_RATE (F_CPU) // Frequency of timer peripherals
#define MCU_STEP_TIMER 16
#define MCU_TEMP_TIMER 17
#elif defined(STM32F1xx)
- #define MCU_TIMER_RATE (F_CPU)
#define MCU_STEP_TIMER 4
#define MCU_TEMP_TIMER 2
#elif defined(STM32F401xC) || defined(STM32F401xE)
- #define MCU_TIMER_RATE (F_CPU / 2)
#define MCU_STEP_TIMER 9
#define MCU_TEMP_TIMER 10
#elif defined(STM32F4xx) || defined(STM32F7xx)
- #define MCU_TIMER_RATE (F_CPU / 2)
#define MCU_STEP_TIMER 6 // STM32F401 has no TIM6, TIM7, or TIM8
#define MCU_TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used.
#endif
#ifndef HAL_TIMER_RATE
- #define HAL_TIMER_RATE MCU_TIMER_RATE
+ #define HAL_TIMER_RATE GetStepperTimerClkFreq()
#endif
+
#ifndef STEP_TIMER
#define STEP_TIMER MCU_STEP_TIMER
#endif
@@ -100,21 +95,23 @@
#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
-#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn
-#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X)
-#define STEP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(STEP_TIMER)
-#define TEMP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(TEMP_TIMER)
-
// ------------------------
// Private Variables
// ------------------------
-HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL };
+HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { nullptr };
// ------------------------
// Public functions
// ------------------------
+uint32_t GetStepperTimerClkFreq() {
+ // Timer input clocks vary between devices, and in some cases between timers on the same device.
+ // Retrieve at runtime to ensure device compatibility. Cache result to avoid repeated overhead.
+ static uint32_t clkfreq = timer_instance[STEP_TIMER_NUM]->getTimerClkFreq();
+ return clkfreq;
+}
+
// frequency is in Hertz
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
if (!HAL_timer_initialized(timer_num)) {
@@ -194,87 +191,132 @@ void SetTimerInterruptPriorities() {
TERN_(HAS_SERVOS, libServo::setInterruptPriority(SERVO_TIMER_IRQ_PRIO, 0));
}
-// This is a terrible hack to replicate the behavior used in the framework's SoftwareSerial.cpp
-// to choose a serial timer. It will select TIM7 on most boards used by Marlin, but this is more
-// resiliant to new MCUs which may not have a TIM7. Best practice is to explicitly specify
-// TIMER_SERIAL to avoid relying on framework selections which may not be predictable.
-#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
+// ------------------------
+// Detect timer conflicts
+// ------------------------
+
+// This list serves two purposes. Firstly, it facilitates build-time mapping between
+// variant-defined timer names (such as TIM1) and timer numbers. It also replicates
+// the order of timers used in the framework's SoftwareSerial.cpp. The first timer in
+// this list will be automatically used by SoftwareSerial if it is not already defined
+// in the board's variant or compiler options.
+static constexpr struct {uintptr_t base_address; int timer_number;} stm32_timer_map[] = {
+ #ifdef TIM18_BASE
+ { uintptr_t(TIM18), 18 },
#endif
+ #ifdef TIM7_BASE
+ { uintptr_t(TIM7), 7 },
+ #endif
+ #ifdef TIM6_BASE
+ { uintptr_t(TIM6), 6 },
+ #endif
+ #ifdef TIM22_BASE
+ { uintptr_t(TIM22), 22 },
+ #endif
+ #ifdef TIM21_BASE
+ { uintptr_t(TIM21), 21 },
+ #endif
+ #ifdef TIM17_BASE
+ { uintptr_t(TIM17), 17 },
+ #endif
+ #ifdef TIM16_BASE
+ { uintptr_t(TIM16), 16 },
+ #endif
+ #ifdef TIM15_BASE
+ { uintptr_t(TIM15), 15 },
+ #endif
+ #ifdef TIM14_BASE
+ { uintptr_t(TIM14), 14 },
+ #endif
+ #ifdef TIM13_BASE
+ { uintptr_t(TIM13), 13 },
+ #endif
+ #ifdef TIM11_BASE
+ { uintptr_t(TIM11), 11 },
+ #endif
+ #ifdef TIM10_BASE
+ { uintptr_t(TIM10), 10 },
+ #endif
+ #ifdef TIM12_BASE
+ { uintptr_t(TIM12), 12 },
+ #endif
+ #ifdef TIM19_BASE
+ { uintptr_t(TIM19), 19 },
+ #endif
+ #ifdef TIM9_BASE
+ { uintptr_t(TIM9), 9 },
+ #endif
+ #ifdef TIM5_BASE
+ { uintptr_t(TIM5), 5 },
+ #endif
+ #ifdef TIM4_BASE
+ { uintptr_t(TIM4), 4 },
+ #endif
+ #ifdef TIM3_BASE
+ { uintptr_t(TIM3), 3 },
+ #endif
+ #ifdef TIM2_BASE
+ { uintptr_t(TIM2), 2 },
+ #endif
+ #ifdef TIM20_BASE
+ { uintptr_t(TIM20), 20 },
+ #endif
+ #ifdef TIM8_BASE
+ { uintptr_t(TIM8), 8 },
+ #endif
+ #ifdef TIM1_BASE
+ { uintptr_t(TIM1), 1 }
+ #endif
+};
+
+// Convert from a timer base address to its integer timer number.
+static constexpr int get_timer_num_from_base_address(uintptr_t base_address) {
+ for (const auto &timer : stm32_timer_map)
+ if (timer.base_address == base_address) return timer.timer_number;
+ return 0;
+}
+
+// The platform's SoftwareSerial.cpp will use the first timer from stm32_timer_map.
+#if HAS_TMC_SW_SERIAL && !defined(TIMER_SERIAL)
+ #define TIMER_SERIAL (stm32_timer_map[0].base_address)
#endif
-// Place all timers used into an array, then recursively check for duplicates during compilation.
-// This does not currently account for timers used for PWM, such as for fans.
-// Timers are actually pointers. Convert to integers to simplify constexpr logic.
-static constexpr uintptr_t timers_in_use[] = {
- uintptr_t(TEMP_TIMER_DEV), // Override in pins file
- uintptr_t(STEP_TIMER_DEV), // Override in pins file
+// constexpr doesn't like using the base address pointers that timers evaluate to.
+// We can get away with casting them to uintptr_t, if we do so inside an array.
+// GCC will not currently do it directly to a uintptr_t.
+IF_ENABLED(HAS_TMC_SW_SERIAL, static constexpr uintptr_t timer_serial[] = {uintptr_t(TIMER_SERIAL)});
+IF_ENABLED(SPEAKER, static constexpr uintptr_t timer_tone[] = {uintptr_t(TIMER_TONE)});
+IF_ENABLED(HAS_SERVOS, static constexpr uintptr_t timer_servo[] = {uintptr_t(TIMER_SERVO)});
+
+enum TimerPurpose { TP_SERIAL, TP_TONE, TP_SERVO, TP_STEP, TP_TEMP };
+
+// List of timers, to enable checking for conflicts.
+// Includes the purpose of each timer to ease debugging when evaluating at build-time.
+// This cannot yet account for timers used for PWM output, such as for fans.
+static constexpr struct { TimerPurpose p; int t; } timers_in_use[] = {
#if HAS_TMC_SW_SERIAL
- uintptr_t(TIMER_SERIAL), // Set in variant.h, or as a define in platformio.h if not present in variant.h
+ {TP_SERIAL, get_timer_num_from_base_address(timer_serial[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
#if ENABLED(SPEAKER)
- uintptr_t(TIMER_TONE), // Set in variant.h, or as a define in platformio.h if not present in variant.h
+ {TP_TONE, get_timer_num_from_base_address(timer_tone[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
#if HAS_SERVOS
- uintptr_t(TIMER_SERVO), // Set in variant.h, or as a define in platformio.h if not present in variant.h
+ {TP_SERVO, get_timer_num_from_base_address(timer_servo[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
- };
+ {TP_STEP, STEP_TIMER},
+ {TP_TEMP, TEMP_TIMER},
+};
-static constexpr bool verify_no_duplicate_timers() {
+static constexpr bool verify_no_timer_conflicts() {
LOOP_L_N(i, COUNT(timers_in_use))
LOOP_S_L_N(j, i + 1, COUNT(timers_in_use))
- if (timers_in_use[i] == timers_in_use[j]) return false;
+ if (timers_in_use[i].t == timers_in_use[j].t) return false;
return true;
}
-// If this assertion fails at compile time, review the timers_in_use array. If default_envs is
-// defined properly in platformio.ini, VS Code can evaluate the array when hovering over it,
-// making it easy to identify the conflicting timers.
-static_assert(verify_no_duplicate_timers(), "One or more timer conflict detected");
+// If this assertion fails at compile time, review the timers_in_use array.
+// If default_envs is defined properly in platformio.ini, VS Code can evaluate the array
+// when hovering over it, making it easy to identify the conflicting timers.
+static_assert(verify_no_timer_conflicts(), "One or more timer conflict detected. Examine \"timers_in_use\" to help identify conflict.");
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/timers.h b/Marlin/src/HAL/STM32/timers.h
index 5515219ead..4649824303 100644
--- a/Marlin/src/HAL/STM32/timers.h
+++ b/Marlin/src/HAL/STM32/timers.h
@@ -43,6 +43,8 @@
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX UINT16_MAX
+#define NUM_HARDWARE_TIMERS 2
+
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#endif
@@ -57,7 +59,8 @@
// 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))
+extern uint32_t GetStepperTimerClkFreq();
+#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / (STEPPER_TIMER_RATE))
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
@@ -102,7 +105,7 @@ void SetTimerInterruptPriorities();
// 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;
+ return timer_instance[timer_num] != nullptr;
}
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;
diff --git a/Marlin/src/HAL/STM32/usb_host.cpp b/Marlin/src/HAL/STM32/usb_host.cpp
new file mode 100644
index 0000000000..ed743361e6
--- /dev/null
+++ b/Marlin/src/HAL/STM32/usb_host.cpp
@@ -0,0 +1,117 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "../../inc/MarlinConfig.h"
+
+#if BOTH(USE_OTG_USB_HOST, USBHOST)
+
+#include "usb_host.h"
+#include "../shared/Marduino.h"
+#include "usbh_core.h"
+#include "usbh_msc.h"
+
+USBH_HandleTypeDef hUsbHost;
+USBHost usb;
+BulkStorage bulk(&usb);
+
+static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id) {
+ switch(id) {
+ case HOST_USER_SELECT_CONFIGURATION:
+ //SERIAL_ECHOLNPGM("APPLICATION_SELECT_CONFIGURATION");
+ break;
+ case HOST_USER_DISCONNECTION:
+ //SERIAL_ECHOLNPGM("APPLICATION_DISCONNECT");
+ //usb.setUsbTaskState(USB_STATE_RUNNING);
+ break;
+ case HOST_USER_CLASS_ACTIVE:
+ //SERIAL_ECHOLNPGM("APPLICATION_READY");
+ usb.setUsbTaskState(USB_STATE_RUNNING);
+ break;
+ case HOST_USER_CONNECTION:
+ break;
+ default:
+ break;
+ }
+}
+
+bool USBHost::start() {
+ if (USBH_Init(&hUsbHost, USBH_UserProcess, TERN(USE_USB_HS_IN_FS, HOST_HS, HOST_FS)) != USBH_OK) {
+ SERIAL_ECHOLNPGM("Error: USBH_Init");
+ return false;
+ }
+ if (USBH_RegisterClass(&hUsbHost, USBH_MSC_CLASS) != USBH_OK) {
+ SERIAL_ECHOLNPGM("Error: USBH_RegisterClass");
+ return false;
+ }
+ if (USBH_Start(&hUsbHost) != USBH_OK) {
+ SERIAL_ECHOLNPGM("Error: USBH_Start");
+ return false;
+ }
+ return true;
+}
+
+void USBHost::Task() {
+ USBH_Process(&hUsbHost);
+}
+
+uint8_t USBHost::getUsbTaskState() {
+ return usb_task_state;
+}
+
+void USBHost::setUsbTaskState(uint8_t state) {
+ usb_task_state = state;
+ if (usb_task_state == USB_STATE_RUNNING) {
+ MSC_LUNTypeDef info;
+ USBH_MSC_GetLUNInfo(&hUsbHost, usb.lun, &info);
+ capacity = info.capacity.block_nbr / 2000;
+ block_size = info.capacity.block_size;
+ block_count = info.capacity.block_nbr;
+ // SERIAL_ECHOLNPAIR("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
+ // SERIAL_ECHOLNPAIR("info.capacity.block_size: %d\n", info.capacity.block_size);
+ // SERIAL_ECHOLNPAIR("capacity : %d MB\n", capacity);
+ }
+};
+
+bool BulkStorage::LUNIsGood(uint8_t t) {
+ return USBH_MSC_IsReady(&hUsbHost) && USBH_MSC_UnitIsReady(&hUsbHost, t);
+}
+
+uint32_t BulkStorage::GetCapacity(uint8_t lun) {
+ return usb->block_count;
+}
+
+uint16_t BulkStorage::GetSectorSize(uint8_t lun) {
+ return usb->block_size;
+}
+
+uint8_t BulkStorage::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
+ return USBH_MSC_Read(&hUsbHost, lun, addr, buf, blocks) != USBH_OK;
+}
+
+uint8_t BulkStorage::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) {
+ return USBH_MSC_Write(&hUsbHost, lun, addr, const_cast (buf), blocks) != USBH_OK;
+}
+
+#endif // USE_OTG_USB_HOST && USBHOST
+#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/usb_host.h b/Marlin/src/HAL/STM32/usb_host.h
new file mode 100644
index 0000000000..c0001c0d75
--- /dev/null
+++ b/Marlin/src/HAL/STM32/usb_host.h
@@ -0,0 +1,60 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+typedef enum {
+ USB_STATE_INIT,
+ USB_STATE_ERROR,
+ USB_STATE_RUNNING,
+} usb_state_t;
+
+class USBHost {
+public:
+ bool start();
+ void Task();
+ uint8_t getUsbTaskState();
+ void setUsbTaskState(uint8_t state);
+ uint8_t regRd(uint8_t reg) { return 0x0; };
+ uint8_t usb_task_state = USB_STATE_INIT;
+ uint8_t lun = 0;
+ uint32_t capacity = 0;
+ uint16_t block_size = 0;
+ uint32_t block_count = 0;
+};
+
+class BulkStorage {
+public:
+ BulkStorage(USBHost *usb) : usb(usb) {};
+
+ bool LUNIsGood(uint8_t t);
+ uint32_t GetCapacity(uint8_t lun);
+ uint16_t GetSectorSize(uint8_t lun);
+ uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
+ uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf);
+
+ USBHost *usb;
+};
+
+extern USBHost usb;
+extern BulkStorage bulk;
diff --git a/Marlin/src/HAL/STM32/usb_serial.cpp b/Marlin/src/HAL/STM32/usb_serial.cpp
index 2dd1bef12c..705d649ff5 100644
--- a/Marlin/src/HAL/STM32/usb_serial.cpp
+++ b/Marlin/src/HAL/STM32/usb_serial.cpp
@@ -16,12 +16,11 @@
* along with this program. If not, see .
*
*/
-
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfigPre.h"
-#if ENABLED(EMERGENCY_PARSER)
+#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
#include "usb_serial.h"
#include "../../feature/e_parser.h"
@@ -51,5 +50,5 @@ void USB_Hook_init() {
USBD_CDC_fops.Receive = USBD_CDC_Receive_hook;
}
-#endif // EMERGENCY_PARSER
+#endif // EMERGENCY_PARSER && USBD_USE_CDC
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/watchdog.cpp b/Marlin/src/HAL/STM32/watchdog.cpp
index 37e5638b05..aad0a79a0c 100644
--- a/Marlin/src/HAL/STM32/watchdog.cpp
+++ b/Marlin/src/HAL/STM32/watchdog.cpp
@@ -25,19 +25,25 @@
#if ENABLED(USE_WATCHDOG)
- #include "../../inc/MarlinConfig.h"
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
- #include "watchdog.h"
- #include
+#include "../../inc/MarlinConfig.h"
- void watchdog_init() { IWatchdog.begin(4000000); } // 4 sec timeout
+#include "watchdog.h"
+#include
- void HAL_watchdog_refresh() {
- IWatchdog.reload();
- #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
- TOGGLE(LED_PIN); // heartbeat indicator
- #endif
- }
+void watchdog_init() {
+ #if DISABLED(DISABLE_WATCHDOG_INIT)
+ IWatchdog.begin(WDT_TIMEOUT_US);
+ #endif
+}
+
+void HAL_watchdog_refresh() {
+ IWatchdog.reload();
+ #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
+ TOGGLE(LED_PIN); // heartbeat indicator
+ #endif
+}
#endif // USE_WATCHDOG
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp
index d7f9264be6..c1e29a843c 100644
--- a/Marlin/src/HAL/STM32F1/HAL.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL.cpp
@@ -82,8 +82,9 @@
// Public Variables
// ------------------------
-#if (defined(SERIAL_USB) && !defined(USE_USB_COMPOSITE))
+#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
USBSerial SerialUSB;
+ DefaultSerial MSerial(false, SerialUSB);
#endif
uint16_t HAL_adc_result;
@@ -97,6 +98,9 @@ const uint8_t adc_pins[] = {
#if HAS_TEMP_ADC_0
TEMP_0_PIN,
#endif
+ #if HAS_TEMP_ADC_PROBE
+ TEMP_PROBE_PIN,
+ #endif
#if HAS_HEATED_BED
TEMP_BED_PIN,
#endif
@@ -127,7 +131,7 @@ const uint8_t adc_pins[] = {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH_PIN,
#endif
- #if ENABLED(ADC_KEYPAD)
+ #if HAS_ADC_BUTTONS
ADC_KEYPAD_PIN,
#endif
#if HAS_JOY_ADC_X
@@ -151,6 +155,9 @@ enum TempPinIndex : char {
#if HAS_TEMP_ADC_0
TEMP_0,
#endif
+ #if HAS_TEMP_ADC_PROBE
+ TEMP_PROBE,
+ #endif
#if HAS_HEATED_BED
TEMP_BED,
#endif
@@ -181,7 +188,7 @@ enum TempPinIndex : char {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH,
#endif
- #if ENABLED(ADC_KEYPAD)
+ #if HAS_ADC_BUTTONS
ADC_KEY,
#endif
#if HAS_JOY_ADC_X
@@ -245,7 +252,7 @@ void HAL_init() {
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
- #ifdef USE_USB_COMPOSITE
+ #if HAS_SD_HOST_DRIVE
MSC_SD_init();
#endif
#if PIN_EXISTS(USB_CONNECT)
@@ -257,17 +264,15 @@ void HAL_init() {
// HAL idle task
void HAL_idletask() {
- #ifdef USE_USB_COMPOSITE
- #if HAS_SHARED_MEDIA
- // If Marlin is using the SD card we need to lock it to prevent access from
- // a PC via USB.
- // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
- // this will not reliably detect delete operations. To be safe we will lock
- // the disk if Marlin has it mounted. Unfortunately there is currently no way
- // to unmount the disk from the LCD menu.
- // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
- /* copy from lpc1768 framework, should be fixed later for process HAS_SHARED_MEDIA*/
- #endif
+ #if HAS_SHARED_MEDIA
+ // If Marlin is using the SD card we need to lock it to prevent access from
+ // a PC via USB.
+ // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
+ // this will not reliably detect delete operations. To be safe we will lock
+ // the disk if Marlin has it mounted. Unfortunately there is currently no way
+ // to unmount the disk from the LCD menu.
+ // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
+ /* copy from lpc1768 framework, should be fixed later for process HAS_SD_HOST_DRIVE*/
// process USB mass storage device class loop
MarlinMSC.loop();
#endif
@@ -341,6 +346,9 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if HAS_TEMP_ADC_0
case TEMP_0_PIN: pin_index = TEMP_0; break;
#endif
+ #if HAS_TEMP_ADC_PROBE
+ case TEMP_PROBE_PIN: pin_index = TEMP_PROBE; break;
+ #endif
#if HAS_HEATED_BED
case TEMP_BED_PIN: pin_index = TEMP_BED; break;
#endif
@@ -380,7 +388,7 @@ 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)
+ #if HAS_ADC_BUTTONS
case ADC_KEYPAD_PIN: pin_index = ADC_KEY; break;
#endif
#if ENABLED(POWER_MONITOR_CURRENT)
diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h
index 5c03593eb0..30bf60b6e8 100644
--- a/Marlin/src/HAL/STM32F1/HAL.h
+++ b/Marlin/src/HAL/STM32F1/HAL.h
@@ -42,7 +42,7 @@
#include "../../inc/MarlinConfigPre.h"
-#ifdef USE_USB_COMPOSITE
+#if HAS_SD_HOST_DRIVE
#include "msc_sd.h"
#endif
@@ -61,8 +61,11 @@
#endif
#ifdef SERIAL_USB
- #ifndef USE_USB_COMPOSITE
- #define UsbSerial Serial
+ typedef ForwardSerial0Type< USBSerial > DefaultSerial;
+ extern DefaultSerial MSerial;
+
+ #if !HAS_SD_HOST_DRIVE
+ #define UsbSerial MSerial
#else
#define UsbSerial MarlinCompositeSerial
#endif
@@ -99,6 +102,18 @@
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if MMU2_SERIAL_PORT == -1
+ #define MMU2_SERIAL UsbSerial
+ #elif WITHIN(MMU2_SERIAL_PORT, 1, NUM_UARTS)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #elif NUM_UARTS == 5
+ #error "MMU2_SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
+ #else
+ #error "MMU2_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
+ #endif
+#endif
+
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL UsbSerial
@@ -109,6 +124,9 @@
#else
#error "LCD_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
#endif
+ #if HAS_DGUS_LCD
+ #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
+ #endif
#endif
// Set interrupt grouping for this MCU
@@ -124,7 +142,7 @@ void HAL_idletask();
#endif
#ifndef digitalPinHasPWM
- #define digitalPinHasPWM(P) (PIN_MAP[P].timer_device != nullptr)
+ #define digitalPinHasPWM(P) !!PIN_MAP[P].timer_device
#define NO_COMPILE_TIME_PWM
#endif
@@ -137,14 +155,6 @@ void HAL_idletask();
// On AVR this is in math.h?
#define square(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
#define RST_POWER_ON 1
#define RST_EXTERNAL 2
#define RST_BROWN_OUT 4
@@ -185,6 +195,8 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
+inline void HAL_reboot() {} // reboot the board or restart the bootloader
+
void _delay_ms(const int delay);
#pragma GCC diagnostic push
@@ -198,17 +210,9 @@ extern "C" {
extern "C" char* _sbrk(int incr);
-/*
-static int freeMemory() {
- volatile int top;
- top = (int)((char*)&top - reinterpret_cast(_sbrk(0)));
- return top;
-}
-*/
-
-static int freeMemory() {
+static inline int freeMemory() {
volatile char top;
- return &top - reinterpret_cast(_sbrk(0));
+ return &top - _sbrk(0);
}
#pragma GCC diagnostic pop
@@ -242,3 +246,20 @@ void analogWrite(pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!?
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);
+
+#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
+
+/**
+ * set_pwm_frequency
+ * Set the frequency of the timer corresponding to the provided pin
+ * All Timer PWM pins run at the same frequency
+ */
+void set_pwm_frequency(const pin_t pin, int f_desired);
+
+/**
+ * set_pwm_duty
+ * Set the PWM duty cycle of the provided pin to the provided value
+ * Optionally allows inverting the duty cycle [default = false]
+ * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
+ */
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
diff --git a/Marlin/src/HAL/STM32F1/HAL_SPI.cpp b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
index 4d72473e7f..7e876f765f 100644
--- a/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
@@ -24,9 +24,6 @@
/**
* Software SPI functions originally from Arduino Sd2Card Library
* Copyright (c) 2009 by William Greiman
- */
-
-/**
* Adapted to the STM32F1 HAL
*/
@@ -64,8 +61,8 @@
* @details Only configures SS pin since libmaple creates and initialize the SPI object
*/
void spiBegin() {
- #if PIN_EXISTS(SS)
- OUT_WRITE(SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
}
@@ -113,7 +110,7 @@ void spiInit(uint8_t spiRate) {
* @details
*/
uint8_t spiRec() {
- uint8_t returnByte = SPI.transfer(ff);
+ uint8_t returnByte = SPI.transfer(0xFF);
return returnByte;
}
@@ -157,7 +154,7 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
#if ENABLED(SPI_EEPROM)
// Read single byte from specified SPI channel
-uint8_t spiRec(uint32_t chan) { return SPI.transfer(ff); }
+uint8_t spiRec(uint32_t chan) { return SPI.transfer(0xFF); }
// Write single byte to specified SPI channel
void spiSend(uint32_t chan, byte b) { SPI.send(b); }
diff --git a/Marlin/src/HAL/STM32F1/MarlinSPI.h b/Marlin/src/HAL/STM32F1/MarlinSPI.h
new file mode 100644
index 0000000000..fab245f904
--- /dev/null
+++ b/Marlin/src/HAL/STM32F1/MarlinSPI.h
@@ -0,0 +1,45 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+/**
+ * Marlin currently requires 3 SPI classes:
+ *
+ * SPIClass:
+ * This class is normally provided by frameworks and has a semi-default interface.
+ * This is needed because some libraries reference it globally.
+ *
+ * SPISettings:
+ * Container for SPI configs for SPIClass. As above, libraries may reference it globally.
+ *
+ * These two classes are often provided by frameworks so we cannot extend them to add
+ * useful methods for Marlin.
+ *
+ * MarlinSPI:
+ * Provides the default SPIClass interface plus some Marlin goodies such as a simplified
+ * interface for SPI DMA transfer.
+ *
+ */
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
index ebf11cb429..c404e81b35 100644
--- a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
@@ -28,7 +28,7 @@
// Copied from ~/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/usart_private.h
// Changed to handle Emergency Parser
-static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MarlinSerial &serial) {
+static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MSerialT &serial) {
/* Handle RXNEIE and TXEIE interrupts.
* RXNE signifies availability of a byte in DR.
*
@@ -90,20 +90,20 @@ constexpr bool serial_handles_emergency(int port) {
;
}
-#define DEFINE_HWSERIAL_MARLIN(name, n) \
- MarlinSerial name(USART##n, \
- BOARD_USART##n##_TX_PIN, \
- BOARD_USART##n##_RX_PIN, \
- serial_handles_emergency(n)); \
- extern "C" void __irq_usart##n(void) { \
+#define DEFINE_HWSERIAL_MARLIN(name, n) \
+ MSerialT name(serial_handles_emergency(n),\
+ USART##n, \
+ BOARD_USART##n##_TX_PIN, \
+ BOARD_USART##n##_RX_PIN); \
+ extern "C" void __irq_usart##n(void) { \
my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \
}
#define DEFINE_HWSERIAL_UART_MARLIN(name, n) \
- MarlinSerial name(UART##n, \
+ MSerialT name(serial_handles_emergency(n), \
+ UART##n, \
BOARD_USART##n##_TX_PIN, \
- BOARD_USART##n##_RX_PIN, \
- serial_handles_emergency(n)); \
+ BOARD_USART##n##_RX_PIN); \
extern "C" void __irq_usart##n(void) { \
my_usart_irq(UART##n->rb, UART##n->wb, UART##n##_BASE, MSerial##n); \
}
@@ -111,7 +111,9 @@ constexpr bool serial_handles_emergency(int port) {
// Instantiate all UARTs even if they are not needed
// This avoids a bunch of logic to figure out every serial
// port which may be in use on the system.
-DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
+#if DISABLED(MKS_WIFI_MODULE)
+ DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
+#endif
DEFINE_HWSERIAL_MARLIN(MSerial2, 2);
DEFINE_HWSERIAL_MARLIN(MSerial3, 3);
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.h b/Marlin/src/HAL/STM32F1/MarlinSerial.h
index 6aa94b64ff..692e97e618 100644
--- a/Marlin/src/HAL/STM32F1/MarlinSerial.h
+++ b/Marlin/src/HAL/STM32F1/MarlinSerial.h
@@ -26,28 +26,13 @@
#include
#include "../../inc/MarlinConfigPre.h"
-#if ENABLED(EMERGENCY_PARSER)
- #include "../../feature/e_parser.h"
-#endif
+#include "../../core/serial_hook.h"
// Increase priority of serial interrupts, to reduce overflow errors
#define UART_IRQ_PRIO 1
-class MarlinSerial : public HardwareSerial {
-public:
- #if ENABLED(EMERGENCY_PARSER)
- const bool ep_enabled;
- EmergencyParser::State emergency_state;
- inline bool emergency_parser_enabled() { return ep_enabled; }
- #endif
-
- MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin, bool TERN_(EMERGENCY_PARSER, ep_capable)) :
- HardwareSerial(usart_device, tx_pin, rx_pin)
- #if ENABLED(EMERGENCY_PARSER)
- , ep_enabled(ep_capable)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
- { }
+struct MarlinSerial : public HardwareSerial {
+ MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) : HardwareSerial(usart_device, tx_pin, rx_pin) { }
#ifdef UART_IRQ_PRIO
// Shadow the parent methods to set IRQ priority after begin()
@@ -62,10 +47,12 @@ public:
#endif
};
-extern MarlinSerial MSerial1;
-extern MarlinSerial MSerial2;
-extern MarlinSerial MSerial3;
+typedef Serial0Type MSerialT;
+
+extern MSerialT MSerial1;
+extern MSerialT MSerial2;
+extern MSerialT MSerial3;
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
- extern MarlinSerial MSerial4;
- extern MarlinSerial MSerial5;
+ extern MSerialT MSerial4;
+ extern MSerialT MSerial5;
#endif
diff --git a/Marlin/src/HAL/STM32F1/SPI.cpp b/Marlin/src/HAL/STM32F1/SPI.cpp
index 0452cf6293..c0a35b88d1 100644
--- a/Marlin/src/HAL/STM32F1/SPI.cpp
+++ b/Marlin/src/HAL/STM32F1/SPI.cpp
@@ -147,6 +147,18 @@ SPIClass::SPIClass(uint32_t spi_num) {
_currentSetting->state = SPI_STATE_IDLE;
}
+SPIClass::SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel) : SPIClass(1) {
+ #if BOARD_NR_SPI >= 1
+ if (mosi == BOARD_SPI1_MOSI_PIN) setModule(1);
+ #endif
+ #if BOARD_NR_SPI >= 2
+ if (mosi == BOARD_SPI2_MOSI_PIN) setModule(2);
+ #endif
+ #if BOARD_NR_SPI >= 3
+ if (mosi == BOARD_SPI3_MOSI_PIN) setModule(3);
+ #endif
+}
+
/**
* Set up/tear down
*/
@@ -656,7 +668,7 @@ static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
#if BOARD_NR_SPI >= 3
case RCC_SPI3: return board_spi_pins + 2;
#endif
- default: return NULL;
+ default: return nullptr;
}
}
diff --git a/Marlin/src/HAL/STM32F1/SPI.h b/Marlin/src/HAL/STM32F1/SPI.h
index 0d20a46577..828644f1dd 100644
--- a/Marlin/src/HAL/STM32F1/SPI.h
+++ b/Marlin/src/HAL/STM32F1/SPI.h
@@ -163,6 +163,11 @@ public:
*/
SPIClass(uint32_t spiPortNumber);
+ /**
+ * Init using pins
+ */
+ SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel=-1);
+
/**
* @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).
*/
diff --git a/Marlin/src/HAL/STM32F1/Servo.cpp b/Marlin/src/HAL/STM32F1/Servo.cpp
index e1ee831493..36f7c6d512 100644
--- a/Marlin/src/HAL/STM32F1/Servo.cpp
+++ b/Marlin/src/HAL/STM32F1/Servo.cpp
@@ -45,7 +45,7 @@ uint8_t ServoCount = 0;
*
* This uses the smallest prescaler that allows an overflow < 2^16.
*/
-#define MAX_OVERFLOW UINT16_MAX //((1 << 16) - 1)
+#define MAX_OVERFLOW UINT16_MAX // _BV(16) - 1
#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND)
#define TAU_MSEC 20
#define TAU_USEC (TAU_MSEC * 1000)
diff --git a/Marlin/src/HAL/STM32F1/SoftwareSerial.cpp b/Marlin/src/HAL/STM32F1/SoftwareSerial.cpp
deleted file mode 100644
index 993403cf72..0000000000
--- a/Marlin/src/HAL/STM32F1/SoftwareSerial.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * 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(__STM32F1__) && !defined(HAVE_SW_SERIAL)
-
-/**
- * Empty class for Software Serial implementation (Custom RX/TX pins)
- *
- * TODO: Optionally use https://github.com/FYSETC/SoftwareSerialM if TMC UART is wanted
- */
-
-#include "SoftwareSerial.h"
-
-// Constructor
-
-SoftwareSerial::SoftwareSerial(int8_t RX_pin, int8_t TX_pin) {}
-
-// Public
-
-void SoftwareSerial::begin(const uint32_t baudrate) {
-}
-
-bool SoftwareSerial::available() {
- return false;
-}
-
-uint8_t SoftwareSerial::read() {
- return 0;
-}
-
-uint16_t SoftwareSerial::write(uint8_t byte) {
- return 0;
-}
-
-void SoftwareSerial::flush() {}
-
-void SoftwareSerial::listen() {
- listening = true;
-}
-
-void SoftwareSerial::stopListening() {
- listening = false;
-}
-
-#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/SoftwareSerial.h b/Marlin/src/HAL/STM32F1/SoftwareSerial.h
deleted file mode 100644
index 1c8058665a..0000000000
--- a/Marlin/src/HAL/STM32F1/SoftwareSerial.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * 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
-
-#ifndef HAVE_SW_SERIAL
- #define SW_SERIAL_PLACEHOLDER 1
-#endif
-
-class SoftwareSerial {
-public:
- SoftwareSerial(int8_t RX_pin, int8_t TX_pin);
-
- void begin(const uint32_t baudrate);
-
- bool available();
-
- uint8_t read();
- uint16_t write(uint8_t byte);
- void flush();
-
- void listen();
- void stopListening();
-
-protected:
- bool listening;
-};
diff --git a/Marlin/src/HAL/STM32F1/build_flags.py b/Marlin/src/HAL/STM32F1/build_flags.py
index 98c871a1d8..c51fd4fa58 100755
--- a/Marlin/src/HAL/STM32F1/build_flags.py
+++ b/Marlin/src/HAL/STM32F1/build_flags.py
@@ -3,7 +3,7 @@ import sys
#dynamic build flags for generic compile options
if __name__ == "__main__":
- args = " ".join([ "-std=gnu11",
+ args = " ".join([ "-std=gnu++14",
"-Os",
"-mcpu=cortex-m3",
"-mthumb",
diff --git a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
index 894abb882a..784a80c29f 100644
--- a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
+++ b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
@@ -20,16 +20,17 @@
#include "../../../inc/MarlinConfig.h"
-#if BOTH(HAS_GRAPHICAL_LCD, FORCE_SOFT_SPI)
+#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI)
-#include "../HAL.h"
#include
+#include "../../shared/HAL_SPI.h"
-#undef SPI_SPEED
-#define SPI_SPEED 0 // Fastest
-//#define SPI_SPEED 2 // Slower
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_FULL_SPEED // Fastest
+ //#define LCD_SPI_SPEED SPI_QUARTER_SPEED // Slower
+#endif
-static uint8_t SPI_speed = SPI_SPEED;
+static uint8_t SPI_speed = LCD_SPI_SPEED;
static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) {
LOOP_L_N(i, 8) {
@@ -105,7 +106,7 @@ static uint8_t swSpiInit(const uint8_t spi_speed) {
uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch (msg) {
case U8G_COM_MSG_INIT:
- SPI_speed = swSpiInit(SPI_SPEED);
+ SPI_speed = swSpiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_STOP:
@@ -161,5 +162,5 @@ uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB && FORCE_SOFT_SPI
#endif // STM32F1
diff --git a/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
index f77306a88a..a6395698aa 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
@@ -25,6 +25,8 @@
* with simple implementations supplied by Marlin.
*/
+#ifdef __STM32F1__
+
#include "../../inc/MarlinConfig.h"
#if ENABLED(IIC_BL24CXX_EEPROM)
@@ -46,6 +48,7 @@ bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ size_t written = 0;
while (size--) {
uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
@@ -53,7 +56,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
- delay(2);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
@@ -66,7 +69,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t * const p = (uint8_t * const)pos;
uint8_t c = eeprom_read_byte(p);
@@ -79,3 +82,4 @@ bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t
}
#endif // IIC_BL24CXX_EEPROM
+#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/eeprom_flash.cpp b/Marlin/src/HAL/STM32F1/eeprom_flash.cpp
index 8db8c8638b..dfcaaaf29f 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_flash.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_flash.cpp
@@ -101,7 +101,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
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*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
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);
diff --git a/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp b/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp
index 33dd277add..ccc3fc537f 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_if_iic.cpp
@@ -25,6 +25,8 @@
* Enable USE_SHARED_EEPROM if not supplied by the framework.
*/
+#ifdef __STM32F1__
+
#include "../../inc/MarlinConfig.h"
#if ENABLED(IIC_BL24CXX_EEPROM)
@@ -49,3 +51,4 @@ uint8_t eeprom_read_byte(uint8_t *pos) {
}
#endif // IIC_BL24CXX_EEPROM
+#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp b/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp
index 11959191f6..d608ccee14 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_sdcard.cpp
@@ -79,7 +79,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
+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 c = HAL_eeprom_data[pos + i];
if (writing) value[i] = c;
diff --git a/Marlin/src/HAL/STM32F1/eeprom_wired.cpp b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
index b4699d00dc..16cfc24af6 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
@@ -1,6 +1,5 @@
/**
* Marlin 3D Printer Firmware
- *
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
@@ -17,17 +16,17 @@
* along with this program. If not, see .
*
*/
+
+/**
+ * HAL PersistentStore for STM32F1
+ */
+
#ifdef __STM32F1__
#include "../../inc/MarlinConfig.h"
#if USE_WIRED_EEPROM
-/**
- * PersistentStore for Arduino-style EEPROM interface
- * with simple implementations supplied by Marlin.
- */
-
#include "../shared/eeprom_if.h"
#include "../shared/eeprom_api.h"
@@ -72,7 +71,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing && value) *value = c;
diff --git a/Marlin/src/HAL/STM32F1/fast_pwm.cpp b/Marlin/src/HAL/STM32F1/fast_pwm.cpp
new file mode 100644
index 0000000000..884d482af5
--- /dev/null
+++ b/Marlin/src/HAL/STM32F1/fast_pwm.cpp
@@ -0,0 +1,68 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#ifdef __STM32F1__
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if NEEDS_HARDWARE_PWM
+
+#include
+#include "HAL.h"
+#include "timers.h"
+
+void set_pwm_frequency(const pin_t pin, int f_desired) {
+ if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer
+
+ timer_dev *timer = PIN_MAP[pin].timer_device;
+ uint8_t channel = PIN_MAP[pin].timer_channel;
+
+ // Protect used timers
+ if (timer == get_timer_dev(TEMP_TIMER_NUM)) return;
+ if (timer == get_timer_dev(STEP_TIMER_NUM)) return;
+ #if PULSE_TIMER_NUM != STEP_TIMER_NUM
+ if (timer == get_timer_dev(PULSE_TIMER_NUM)) return;
+ #endif
+
+ if (!(timer->regs.bas->SR & TIMER_CR1_CEN)) // Ensure the timer is enabled
+ timer_init(timer);
+
+ timer_set_mode(timer, channel, TIMER_PWM);
+ uint16_t preload = 255; // Lock 255 PWM resolution for high frequencies
+ int32_t prescaler = (HAL_TIMER_RATE) / (preload + 1) / f_desired - 1;
+ if (prescaler > 65535) { // For low frequencies increase prescaler
+ prescaler = 65535;
+ preload = (HAL_TIMER_RATE) / (prescaler + 1) / f_desired - 1;
+ }
+ if (prescaler < 0) return; // Too high frequency
+ timer_set_reload(timer, preload);
+ timer_set_prescaler(timer, prescaler);
+}
+
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
+ timer_dev *timer = PIN_MAP[pin].timer_device;
+ uint16_t max_val = timer->regs.bas->ARR * v / v_size;
+ if (invert) max_val = v_size - max_val;
+ pwmWrite(pin, max_val);
+}
+
+#endif // NEEDS_HARDWARE_PWM
+#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/fastio.h b/Marlin/src/HAL/STM32F1/fastio.h
index e0e2e03a1c..e75254d692 100644
--- a/Marlin/src/HAL/STM32F1/fastio.h
+++ b/Marlin/src/HAL/STM32F1/fastio.h
@@ -29,9 +29,9 @@
#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 & _BV32(PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
+#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = _BV32(PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16))
+#define TOGGLE(IO) TBI32(PIN_MAP[IO].gpio_device->regs->ODR, 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)
@@ -51,7 +51,7 @@
#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
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
diff --git a/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h b/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h
index 25110d7c80..5f1c4b1601 100644
--- a/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h
+++ b/Marlin/src/HAL/STM32F1/inc/Conditionals_LCD.h
@@ -20,15 +20,3 @@
*
*/
#pragma once
-
-#if ENABLED(USE_USB_COMPOSITE)
- //#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE."
- #undef SD_CHECK_AND_RETRY
-#endif
-
-// This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
-#if ENABLED(TOUCH_SCREEN) && !HAS_GRAPHICAL_TFT
- #undef TOUCH_SCREEN
- #undef TOUCH_SCREEN_CALIBRATION
- #define HAS_TOUCH_XPT2046 1
-#endif
diff --git a/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h
index 5f1c4b1601..0fe7924765 100644
--- a/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h
+++ b/Marlin/src/HAL/STM32F1/inc/Conditionals_adv.h
@@ -20,3 +20,11 @@
*
*/
#pragma once
+
+#ifdef USE_USB_COMPOSITE
+ //#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE."
+ #undef SD_CHECK_AND_RETRY
+ #if DISABLED(NO_SD_HOST_DRIVE)
+ #define HAS_SD_HOST_DRIVE 1
+ #endif
+#endif
diff --git a/Marlin/src/HAL/STM32F1/inc/SanityCheck.h b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
index 9d5026fbab..8d4c54ec0f 100644
--- a/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
@@ -25,15 +25,6 @@
* Test STM32F1-specific configuration values for errors at compile-time.
*/
-#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
- #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32F1."
-#endif
-
-#if !defined(HAVE_SW_SERIAL) && HAS_TMC_SW_SERIAL
- #warning "With TMC2208/9 consider using SoftwareSerialM with HAVE_SW_SERIAL and appropriate SS_TIMER."
- #error "Missing SoftwareSerial implementation."
-#endif
-
#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT)
#undef SDCARD_EEPROM_EMULATION // Avoid additional error noise
#if USE_FALLBACK_EEPROM
@@ -51,3 +42,10 @@
#if ENABLED(NEOPIXEL_LED)
#error "NEOPIXEL_LED (Adafruit NeoPixel) is not supported for HAL/STM32F1. Comment out this line to proceed at your own risk!"
#endif
+
+// Emergency Parser needs at least one serial with HardwareSerial or USBComposite.
+// The USBSerial maple don't allow any hook to implement EMERGENCY_PARSER.
+// And copy all USBSerial code to marlin space to support EMERGENCY_PARSER, when we have another options, don't worth it.
+#if ENABLED(EMERGENCY_PARSER) && !defined(USE_USB_COMPOSITE) && ((SERIAL_PORT == -1 && !defined(SERIAL_PORT_2)) || (SERIAL_PORT_2 == -1 && !defined(SERIAL_PORT)))
+ #error "EMERGENCY_PARSER is only supported by HardwareSerial or USBComposite in HAL/STM32F1."
+#endif
diff --git a/Marlin/src/HAL/STM32F1/msc_sd.cpp b/Marlin/src/HAL/STM32F1/msc_sd.cpp
index 6a4652e467..548a6dbc57 100644
--- a/Marlin/src/HAL/STM32F1/msc_sd.cpp
+++ b/Marlin/src/HAL/STM32F1/msc_sd.cpp
@@ -13,7 +13,9 @@
* along with this program. If not, see .
*
*/
-#ifdef USE_USB_COMPOSITE
+#include "../../inc/MarlinConfigPre.h"
+
+#if defined(__STM32F1__) && HAS_SD_HOST_DRIVE
#include "msc_sd.h"
#include "SPI.h"
@@ -21,7 +23,7 @@
#define PRODUCT_ID 0x29
USBMassStorage MarlinMSC;
-MarlinUSBCompositeSerial MarlinCompositeSerial;
+Serial0Type MarlinCompositeSerial(true);
#include "../../inc/MarlinConfig.h"
@@ -77,4 +79,4 @@ void MSC_SD_init() {
#endif
}
-#endif // USE_USB_COMPOSITE
+#endif // __STM32F1__ && HAS_SD_HOST_DRIVE
diff --git a/Marlin/src/HAL/STM32F1/msc_sd.h b/Marlin/src/HAL/STM32F1/msc_sd.h
index 1e4e4c44b1..151287f7a7 100644
--- a/Marlin/src/HAL/STM32F1/msc_sd.h
+++ b/Marlin/src/HAL/STM32F1/msc_sd.h
@@ -18,25 +18,9 @@
#include
#include "../../inc/MarlinConfigPre.h"
-#if ENABLED(EMERGENCY_PARSER)
- #include "../../feature/e_parser.h"
-#endif
-
-class MarlinUSBCompositeSerial : public USBCompositeSerial {
-public:
- MarlinUSBCompositeSerial() : USBCompositeSerial()
- #if ENABLED(EMERGENCY_PARSER)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
- { }
-
- #if ENABLED(EMERGENCY_PARSER)
- EmergencyParser::State emergency_state;
- inline bool emergency_parser_enabled() { return true; }
- #endif
-};
+#include "../../core/serial_hook.h"
extern USBMassStorage MarlinMSC;
-extern MarlinUSBCompositeSerial MarlinCompositeSerial;
+extern Serial0Type MarlinCompositeSerial;
void MSC_SD_init();
diff --git a/Marlin/src/HAL/STM32F1/onboard_sd.cpp b/Marlin/src/HAL/STM32F1/onboard_sd.cpp
index 0440db9438..6092aea320 100644
--- a/Marlin/src/HAL/STM32F1/onboard_sd.cpp
+++ b/Marlin/src/HAL/STM32F1/onboard_sd.cpp
@@ -9,9 +9,10 @@
* No restriction on use. You can use, modify and redistribute it for
* personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
* Redistributions of source code must retain the above copyright notice.
- *
*/
+#ifdef __STM32F1__
+
#include "../../inc/MarlinConfig.h"
#if SD_CONNECTION_IS(ONBOARD)
@@ -20,10 +21,11 @@
#include "SPI.h"
#include "fastio.h"
-#if HAS_SHARED_MEDIA
- #ifndef ONBOARD_SPI_DEVICE
- #define ONBOARD_SPI_DEVICE SPI_DEVICE
- #endif
+#ifndef ONBOARD_SPI_DEVICE
+ #define ONBOARD_SPI_DEVICE SPI_DEVICE
+#endif
+
+#if HAS_SD_HOST_DRIVE
#define ONBOARD_SD_SPI SPI
#else
SPIClass OnboardSPI(ONBOARD_SPI_DEVICE);
@@ -554,3 +556,4 @@ DRESULT disk_read (
#endif // _DISKIO_IOCTL
#endif // SD_CONNECTION_IS(ONBOARD)
+#endif // __STM32F1__
diff --git a/Marlin/src/HAL/STM32F1/pinsDebug.h b/Marlin/src/HAL/STM32F1/pinsDebug.h
index 2d63ebd770..8e7a3d8135 100644
--- a/Marlin/src/HAL/STM32F1/pinsDebug.h
+++ b/Marlin/src/HAL/STM32F1/pinsDebug.h
@@ -18,10 +18,102 @@
*/
#pragma once
-#ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core)
- #include "../STM32/pinsDebug_STM32duino.h"
-#elif defined(BOARD_NR_GPIO_PINS) // Only in STM32GENERIC (Maple)
- #include "../STM32/pinsDebug_STM32GENERIC.h"
-#else
- #error "M43 not supported for this board"
+/**
+ * Support routines for STM32GENERIC (Maple)
+ */
+
+/**
+ * Translation of routines & variables used by pinsDebug.h
+ */
+
+#ifndef BOARD_NR_GPIO_PINS // Only in STM32GENERIC (Maple)
+ #error "Expected BOARD_NR_GPIO_PINS not found"
#endif
+
+#include "fastio.h"
+
+extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS];
+
+#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS
+#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS
+#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS)
+#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin)
+#define pwm_status(pin) PWM_PIN(pin)
+#define digitalRead_mod(p) extDigitalRead(p)
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PORT(p) print_port(p)
+#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 MULTI_NAME_PAD 21 // space needed to be pretty if not first name assigned to a pin
+
+// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
+#ifndef M43_NEVER_TOUCH
+ #define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX)
+#endif
+
+static inline int8_t get_pin_mode(pin_t pin) {
+ return VALID_PIN(pin) ? _GET_MODE(pin) : -1;
+}
+
+static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
+ if (!VALID_PIN(pin)) return -1;
+ int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel);
+ #ifdef NUM_ANALOG_INPUTS
+ if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = ADCx;
+ #endif
+ return pin_t(adc_channel);
+}
+
+static inline bool IS_ANALOG(pin_t pin) {
+ if (!VALID_PIN(pin)) return false;
+ if (PIN_MAP[pin].adc_channel != ADCx) {
+ #ifdef NUM_ANALOG_INPUTS
+ if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false;
+ #endif
+ return _GET_MODE(pin) == GPIO_INPUT_ANALOG && !M43_NEVER_TOUCH(pin);
+ }
+ return false;
+}
+
+static inline bool GET_PINMODE(const pin_t pin) {
+ return VALID_PIN(pin) && !IS_INPUT(pin);
+}
+
+static inline bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
+ const pin_t pin = GET_ARRAY_PIN(array_pin);
+ return (!IS_ANALOG(pin)
+ #ifdef NUM_ANALOG_INPUTS
+ || PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS
+ #endif
+ );
+}
+
+#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density
+
+static inline void pwm_details(const pin_t pin) {
+ if (PWM_PIN(pin)) {
+ timer_dev * const tdev = PIN_MAP[pin].timer_device;
+ const uint8_t channel = PIN_MAP[pin].timer_channel;
+ const char num = (
+ #if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
+ tdev == &timer8 ? '8' :
+ tdev == &timer5 ? '5' :
+ #endif
+ tdev == &timer4 ? '4' :
+ tdev == &timer3 ? '3' :
+ tdev == &timer2 ? '2' :
+ tdev == &timer1 ? '1' : '?'
+ );
+ char buffer[10];
+ sprintf_P(buffer, PSTR(" TIM%c CH%c"), num, ('0' + channel));
+ SERIAL_ECHO(buffer);
+ }
+}
+
+static inline void print_port(pin_t pin) {
+ const char port = 'A' + char(pin >> 4); // pin div 16
+ const int16_t gbit = PIN_MAP[pin].gpio_bit;
+ char buffer[8];
+ sprintf_P(buffer, PSTR("P%c%hd "), port, gbit);
+ if (gbit < 10) SERIAL_CHAR(' ');
+ SERIAL_ECHO(buffer);
+}
diff --git a/Marlin/src/HAL/STM32F1/spi_pins.h b/Marlin/src/HAL/STM32F1/spi_pins.h
index 8f2b324f64..7d650ffe37 100644
--- a/Marlin/src/HAL/STM32F1/spi_pins.h
+++ b/Marlin/src/HAL/STM32F1/spi_pins.h
@@ -31,28 +31,24 @@
* SPI2 | PB12 PB13 PB14 PB15 |
* SPI3 | PA15 PB3 PB4 PB5 |
* +-----------------------------+
- * Any pin can be used for Chip Select (SS_PIN)
+ * Any pin can be used for Chip Select (SD_SS_PIN)
* SPI1 is enabled by default
*/
-#ifndef SCK_PIN
- #define SCK_PIN PA5
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN PA5
#endif
-#ifndef MISO_PIN
- #define MISO_PIN PA6
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN PA6
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN PA7
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN PA7
#endif
-#ifndef SS_PIN
- #define SS_PIN PA4
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN PA4
#endif
#undef SDSS
-#define SDSS SS_PIN
+#define SDSS SD_SS_PIN
-#if ENABLED(ENABLE_SPI3)
- #define SPI_DEVICE 3
-#elif ENABLED(ENABLE_SPI2)
- #define SPI_DEVICE 2
-#else
+#ifndef SPI_DEVICE
#define SPI_DEVICE 1
#endif
diff --git a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp
index 069be7ad54..5b52fb416f 100644
--- a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp
+++ b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.cpp
@@ -89,13 +89,10 @@ void TFT_FSMC::Init() {
uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN;
uint32_t controllerAddress;
- #if PIN_EXISTS(TFT_RESET)
- OUT_WRITE(TFT_RESET_PIN, HIGH);
- delay(100);
- #endif
-
- #if PIN_EXISTS(TFT_BACKLIGHT)
- OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
+ #if ENABLED(LCD_USE_DMA_FSMC)
+ dma_init(FSMC_DMA_DEV);
+ dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL);
+ dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM);
#endif
struct fsmc_nor_psram_reg_map* fsmcPsramRegion;
diff --git a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h
index 6fcfea8a11..d9ee1f4c77 100644
--- a/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h
+++ b/Marlin/src/HAL/STM32F1/tft/tft_fsmc.h
@@ -22,7 +22,7 @@
#pragma once
#ifndef LCD_READ_ID
- #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
+ #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
@@ -30,9 +30,9 @@
#include
-#define DATASIZE_8BIT DMA_SIZE_8BITS
-#define DATASIZE_16BIT DMA_SIZE_16BITS
-#define TFT_IO TFT_FSMC
+#define DATASIZE_8BIT DMA_SIZE_8BITS
+#define DATASIZE_16BIT DMA_SIZE_16BITS
+#define TFT_IO_DRIVER TFT_FSMC
typedef struct {
__IO uint16_t REG;
diff --git a/Marlin/src/HAL/STM32F1/tft/tft_spi.h b/Marlin/src/HAL/STM32F1/tft/tft_spi.h
index bb26fc21b6..da9a8e0c22 100644
--- a/Marlin/src/HAL/STM32F1/tft/tft_spi.h
+++ b/Marlin/src/HAL/STM32F1/tft/tft_spi.h
@@ -34,7 +34,7 @@
#define DATASIZE_8BIT DATA_SIZE_8BIT
#define DATASIZE_16BIT DATA_SIZE_16BIT
-#define TFT_IO TFT_SPI
+#define TFT_IO_DRIVER TFT_SPI
#define DMA_MINC_ENABLE 1
#define DMA_MINC_DISABLE 0
diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp
index 616d05fead..98371c5ffb 100644
--- a/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.cpp
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
-#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
+#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
#include "xpt2046.h"
#include
diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.h b/Marlin/src/HAL/STM32F1/tft/xpt2046.h
index 019f75efce..65602bda0f 100644
--- a/Marlin/src/HAL/STM32F1/tft/xpt2046.h
+++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.h
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +28,16 @@
#endif
#ifndef TOUCH_MISO_PIN
- #define TOUCH_MISO_PIN MISO_PIN
+ #define TOUCH_MISO_PIN SD_MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
- #define TOUCH_MOSI_PIN MOSI_PIN
+ #define TOUCH_MOSI_PIN SD_MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
- #define TOUCH_SCK_PIN SCK_PIN
+ #define TOUCH_SCK_PIN SD_SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
- #define TOUCH_CS_PIN CS_PIN
+ #define TOUCH_CS_PIN SD_SS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
diff --git a/Marlin/src/HAL/STM32F1/timers.h b/Marlin/src/HAL/STM32F1/timers.h
index 6f360f6bfc..3e2e7775f1 100644
--- a/Marlin/src/HAL/STM32F1/timers.h
+++ b/Marlin/src/HAL/STM32F1/timers.h
@@ -129,8 +129,10 @@ timer_dev* get_timer_dev(int number);
#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler()
#endif
-extern "C" void tempTC_Handler();
-extern "C" void stepTC_Handler();
+extern "C" {
+ void tempTC_Handler();
+ void stepTC_Handler();
+}
// ------------------------
// Public Variables
diff --git a/Marlin/src/HAL/STM32F1/watchdog.cpp b/Marlin/src/HAL/STM32F1/watchdog.cpp
index 4123bc3ef0..b812a4fa64 100644
--- a/Marlin/src/HAL/STM32F1/watchdog.cpp
+++ b/Marlin/src/HAL/STM32F1/watchdog.cpp
@@ -33,6 +33,11 @@
#include
#include "watchdog.h"
+/**
+ * The watchdog clock is 40Khz. So for a 4s or 8s interval use a /256 preescaler and 625 or 1250 reload value (counts down to 0).
+ */
+#define STM32F1_WD_RELOAD TERN(WATCHDOG_DURATION_8S, 1250, 625) // 4 or 8 second timeout
+
void HAL_watchdog_refresh() {
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
TOGGLE(LED_PIN); // heartbeat indicator
@@ -49,10 +54,12 @@ void watchdogSetup() {
*
* @return No return
*
- * @details The watchdog clock is 40Khz. We need a 4 seconds interval, so use a /256 preescaler and 625 reload value (counts down to 0)
+ * @details The watchdog clock is 40Khz. So for a 4s or 8s interval use a /256 preescaler and 625 or 1250 reload value (counts down to 0).
*/
void watchdog_init() {
- //iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD);
+ #if DISABLED(DISABLE_WATCHDOG_INIT)
+ iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD);
+ #endif
}
#endif // USE_WATCHDOG
diff --git a/Marlin/src/HAL/STM32F1/watchdog.h b/Marlin/src/HAL/STM32F1/watchdog.h
index 7185d69775..68920f8cb6 100644
--- a/Marlin/src/HAL/STM32F1/watchdog.h
+++ b/Marlin/src/HAL/STM32F1/watchdog.h
@@ -27,18 +27,9 @@
#include
-/**
- * The watchdog clock is 40Khz. We need a 4 seconds interval, so use a /256 preescaler and
- * 625 reload value (counts down to 0)
- * use 1250 for 8 seconds
- */
-#define STM32F1_WD_RELOAD 625
-
-// Arduino STM32F1 core now has watchdog support
-
-// Initialize watchdog with a 4 second countdown time
+// Initialize watchdog with a 4 or 8 second countdown time
void watchdog_init();
-// Reset watchdog. MUST be called at least every 4 seconds after the
-// first watchdog_init or STM32F1 will reset.
+// Reset watchdog. MUST be called every 4 or 8 seconds after the
+// first watchdog_init or the STM32F1 will reset.
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/STM32_F4_F7/HAL.cpp b/Marlin/src/HAL/STM32_F4_F7/HAL.cpp
deleted file mode 100644
index b4629d2afd..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/HAL.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- * Copyright (c) 2017 Victor Perez
- *
- * 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(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-#include "HAL.h"
-
-//#include
-
-// ------------------------
-// Public Variables
-// ------------------------
-
-uint16_t HAL_adc_result;
-
-// ------------------------
-// Public functions
-// ------------------------
-
-/* VGPV Done with defines
-// disable interrupts
-void cli() { noInterrupts(); }
-
-// enable interrupts
-void sei() { interrupts(); }
-*/
-
-void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
-
-uint8_t HAL_get_reset_source() {
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) return RST_WATCHDOG;
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) != RESET) return RST_SOFTWARE;
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET) return RST_EXTERNAL;
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) return RST_POWER_ON;
- return 0;
-}
-
-void _delay_ms(const int delay_ms) { delay(delay_ms); }
-
-extern "C" {
- extern unsigned int _ebss; // end of bss section
-}
-
-// return free memory between end of heap (or end bss) and whatever is current
-
-/*
-#include
-//extern caddr_t _sbrk(int incr);
-#ifndef CONFIG_HEAP_END
-extern char _lm_heap_end;
-#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end)
-#endif
-
-extern "C" {
- static int freeMemory() {
- char top = 't';
- return &top - reinterpret_cast(sbrk(0));
- }
- int freeMemory() {
- int free_memory;
- int heap_end = (int)_sbrk(0);
- free_memory = ((int)&free_memory) - ((int)heap_end);
- return free_memory;
- }
-}
-*/
-
-// ------------------------
-// ADC
-// ------------------------
-
-void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
-
-uint16_t HAL_adc_get_result() { return HAL_adc_result; }
-
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
diff --git a/Marlin/src/HAL/STM32_F4_F7/HAL.h b/Marlin/src/HAL/STM32_F4_F7/HAL.h
deleted file mode 100644
index 88e48f0fa0..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/HAL.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- * Copyright (c) 2017 Victor Perez
- *
- * 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
-
-#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
-
-#if defined(STM32F4) && USBCON
- #include
-#endif
-
-// ------------------------
-// Defines
-// ------------------------
-
-// Serial override
-//extern HalSerial usb_serial;
-
-#define _MSERIAL(X) SerialUART##X
-#define MSERIAL(X) _MSERIAL(X)
-#define SerialUART0 Serial1
-
-#if defined(STM32F4) && SERIAL_PORT == 0
- #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
-#elif SERIAL_PORT == -1
- #define MYSERIAL0 SerialUSB
-#elif WITHIN(SERIAL_PORT, 0, 6)
- #define MYSERIAL0 MSERIAL(SERIAL_PORT)
-#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_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
- #elif SERIAL_PORT_2 == -1
- #define MYSERIAL1 SerialUSB
- #elif WITHIN(SERIAL_PORT_2, 0, 6)
- #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
- #else
- #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration."
- #endif
-#endif
-
-#ifdef LCD_SERIAL_PORT
- #if defined(STM32F4) && LCD_SERIAL_PORT == 0
- #error "LCD_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
- #elif LCD_SERIAL_PORT == -1
- #define LCD_SERIAL SerialUSB
- #elif WITHIN(LCD_SERIAL_PORT, 0, 6)
- #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
- #else
- #error "LCD_SERIAL_PORT must be from -1 to 6. Please update your configuration."
- #endif
-#endif
-
-/**
- * TODO: review this to return 1 for pins that are not analog input
- */
-#ifndef analogInputToDigitalPin
- #define analogInputToDigitalPin(p) (p)
-#endif
-
-#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
-#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
-#define ISRS_ENABLED() (!__get_PRIMASK())
-#define ENABLE_ISRS() __enable_irq()
-#define DISABLE_ISRS() __disable_irq()
-#define cli() __disable_irq()
-#define sei() __enable_irq()
-
-// On AVR this is in math.h?
-#define square(x) ((x)*(x))
-
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
-// ------------------------
-// Types
-// ------------------------
-
-typedef int8_t pin_t;
-
-#ifdef STM32F4
- #define HAL_SERVO_LIB libServo
-#endif
-
-// ------------------------
-// Public Variables
-// ------------------------
-
-// Result of last ADC conversion
-extern uint16_t HAL_adc_result;
-
-// ------------------------
-// Public functions
-// ------------------------
-
-// Memory related
-#define __bss_end __bss_end__
-
-inline void HAL_init() {}
-
-// Clear reset reason
-void HAL_clear_reset_source();
-
-// Reset reason
-uint8_t HAL_get_reset_source();
-
-void _delay_ms(const int delay);
-
-/*
-extern "C" {
- int freeMemory();
-}
-*/
-
-extern "C" char* _sbrk(int incr);
-
-/*
-int freeMemory() {
- volatile int top;
- top = (int)((char*)&top - reinterpret_cast(_sbrk(0)));
- return top;
-}
-*/
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-
-static inline int freeMemory() {
- volatile char top;
- return &top - reinterpret_cast(_sbrk(0));
-}
-
-#pragma GCC diagnostic pop
-
-//
-// ADC
-//
-
-#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
-
-inline void HAL_adc_init() {}
-
-#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION 10
-#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
-#define HAL_READ_ADC() HAL_adc_result
-#define HAL_ADC_READY() true
-
-void HAL_adc_start_conversion(const uint8_t adc_pin);
-uint16_t HAL_adc_get_result();
-
-#define GET_PIN_MAP_PIN(index) index
-#define GET_PIN_MAP_INDEX(pin) pin
-#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
-
-#ifdef STM32F4
- #define JTAG_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY)
- #define JTAGSWD_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_NONE)
-#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp b/Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp
deleted file mode 100644
index ebd0b4cee7..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/HAL_SPI.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
- * Copyright (c) 2017 Victor Perez
- *
- * 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(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-/**
- * Software SPI functions originally from Arduino Sd2Card Library
- * Copyright (c) 2009 by William Greiman
- */
-
-/**
- * Adapted to the Marlin STM32F4/7 HAL
- */
-
-#include "../../inc/MarlinConfig.h"
-
-#include
-#include
-#include "../shared/HAL_SPI.h"
-#include "spi_pins.h"
-
-// ------------------------
-// Public Variables
-// ------------------------
-
-static SPISettings spiConfig;
-
-// ------------------------
-// Public functions
-// ------------------------
-
-#if ENABLED(SOFTWARE_SPI)
- // ------------------------
- // Software SPI
- // ------------------------
- #error "Software SPI not supported for STM32F4/7. Use Hardware SPI."
-#else
-
-// ------------------------
-// Hardware SPI
-// ------------------------
-
-/**
- * VGPV SPI speed start and F_CPU/2, by default 72/2 = 36Mhz
- */
-
-/**
- * @brief Begin SPI port setup
- *
- * @return Nothing
- *
- * @details Only configures SS pin since libmaple creates and initialize the SPI object
- */
-void spiBegin() {
- #if !defined(SS_PIN) || SS_PIN < 0
- #error "SS_PIN not defined!"
- #endif
-
- OUT_WRITE(SS_PIN, HIGH);
-}
-
-/** Configure SPI for specified SPI speed */
-void spiInit(uint8_t spiRate) {
- // Use datarates Marlin uses
- uint32_t clock;
- switch (spiRate) {
- case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000
- case SPI_HALF_SPEED: clock = 5000000; break;
- case SPI_QUARTER_SPEED: clock = 2500000; break;
- case SPI_EIGHTH_SPEED: clock = 1250000; break;
- case SPI_SPEED_5: clock = 625000; break;
- case SPI_SPEED_6: clock = 300000; break;
- default: clock = 4000000; // Default from the SPI libarary
- }
- spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
- SPI.begin();
-}
-
-/**
- * @brief Receives a single byte from the SPI port.
- *
- * @return Byte received
- *
- * @details
- */
-uint8_t spiRec() {
- SPI.beginTransaction(spiConfig);
- uint8_t returnByte = SPI.transfer(0xFF);
- SPI.endTransaction();
- return returnByte;
-}
-
-/**
- * @brief Receives a number of bytes from the SPI port to a buffer
- *
- * @param buf Pointer to starting address of buffer to write to.
- * @param nbyte Number of bytes to receive.
- * @return Nothing
- *
- * @details Uses DMA
- */
-void spiRead(uint8_t* buf, uint16_t nbyte) {
- SPI.beginTransaction(spiConfig);
- #ifndef STM32GENERIC
- SPI.dmaTransfer(0, const_cast(buf), nbyte);
- #else
- SPI.transfer((uint8_t*)buf, nbyte);
- #endif
- SPI.endTransaction();
-}
-
-/**
- * @brief Sends a single byte on SPI port
- *
- * @param b Byte to send
- *
- * @details
- */
-void spiSend(uint8_t b) {
- SPI.beginTransaction(spiConfig);
- SPI.transfer(b);
- SPI.endTransaction();
-}
-
-/**
- * @brief Write token and then write from 512 byte buffer to SPI (for SD card)
- *
- * @param buf Pointer with buffer start address
- * @return Nothing
- *
- * @details Use DMA
- */
-void spiSendBlock(uint8_t token, const uint8_t* buf) {
- SPI.beginTransaction(spiConfig);
- SPI.transfer(token);
- #ifndef STM32GENERIC
- SPI.dmaSend(const_cast(buf), 512);
- #else
- SPI.transfer((uint8_t*)buf, nullptr, 512);
- #endif
- SPI.endTransaction();
-}
-
-#endif // SOFTWARE_SPI
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
diff --git a/Marlin/src/HAL/STM32_F4_F7/README.md b/Marlin/src/HAL/STM32_F4_F7/README.md
deleted file mode 100644
index 3b5a9ab02e..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# This HAL is for...
-
- - STM32F407 MCU with STM32Generic Arduino core by danieleff.
- - STM32F765 board "The Borg" with STM32Generic.
-
-See the `README.md` files in HAL_STM32F4 and HAL_STM32F7 for the specifics of those hals.
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F4/README.md b/Marlin/src/HAL/STM32_F4_F7/STM32F4/README.md
deleted file mode 100644
index 10396e875b..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F4/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# This HAL is for the STM32F407 MCU used with STM32Generic Arduino core by danieleff.
-
-# Arduino core is located at:
-
-https://github.com/danieleff/STM32GENERIC
-
-Unzip it into [Arduino]/hardware folder
-
-# This HAL is in development.
-
-This HAL is a modified version of Chris Barr's Picoprint STM32F4 HAL.
-
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp
deleted file mode 100644
index dc41f89131..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- *
- * 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(STM32GENERIC) && defined(STM32F4)
-
-#include "../../../inc/MarlinConfig.h"
-
-// ------------------------
-// Local defines
-// ------------------------
-
-#define NUM_HARDWARE_TIMERS 2
-#define STEP_TIMER_IRQ_ID TIM5_IRQn
-#define TEMP_TIMER_IRQ_ID TIM7_IRQn
-
-// ------------------------
-// Private Variables
-// ------------------------
-
-stm32_timer_t TimerHandle[NUM_HARDWARE_TIMERS];
-
-// ------------------------
-// Public functions
-// ------------------------
-
-bool timers_initialized[NUM_HARDWARE_TIMERS] = {false};
-
-void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
-
- if (!timers_initialized[timer_num]) {
- constexpr uint32_t step_prescaler = STEPPER_TIMER_PRESCALE - 1,
- temp_prescaler = TEMP_TIMER_PRESCALE - 1;
- switch (timer_num) {
- case STEP_TIMER_NUM:
- // STEPPER TIMER TIM5 - use a 32bit timer
- __HAL_RCC_TIM5_CLK_ENABLE();
- TimerHandle[timer_num].handle.Instance = TIM5;
- TimerHandle[timer_num].handle.Init.Prescaler = step_prescaler;
- TimerHandle[timer_num].handle.Init.CounterMode = TIM_COUNTERMODE_UP;
- TimerHandle[timer_num].handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- TimerHandle[timer_num].callback = (uint32_t)TC5_Handler;
- HAL_NVIC_SetPriority(STEP_TIMER_IRQ_ID, 1, 0);
- break;
-
- case TEMP_TIMER_NUM:
- // TEMP TIMER TIM7 - any available 16bit Timer (1 already used for PWM)
- __HAL_RCC_TIM7_CLK_ENABLE();
- TimerHandle[timer_num].handle.Instance = TIM7;
- TimerHandle[timer_num].handle.Init.Prescaler = temp_prescaler;
- TimerHandle[timer_num].handle.Init.CounterMode = TIM_COUNTERMODE_UP;
- TimerHandle[timer_num].handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- TimerHandle[timer_num].callback = (uint32_t)TC7_Handler;
- HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_ID, 2, 0);
- break;
- }
- timers_initialized[timer_num] = true;
- }
-
- TimerHandle[timer_num].handle.Init.Period = (((HAL_TIMER_RATE) / TimerHandle[timer_num].handle.Init.Prescaler) / frequency) - 1;
- if (HAL_TIM_Base_Init(&TimerHandle[timer_num].handle) == HAL_OK)
- HAL_TIM_Base_Start_IT(&TimerHandle[timer_num].handle);
-}
-
-extern "C" void TIM5_IRQHandler() {
- ((void(*)())TimerHandle[0].callback)();
-}
-extern "C" void TIM7_IRQHandler() {
- ((void(*)())TimerHandle[1].callback)();
-}
-
-void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- switch (timer_num) {
- case STEP_TIMER_NUM: HAL_NVIC_EnableIRQ(STEP_TIMER_IRQ_ID); break;
- case TEMP_TIMER_NUM: HAL_NVIC_EnableIRQ(TEMP_TIMER_IRQ_ID); break;
- }
-}
-
-void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- switch (timer_num) {
- case STEP_TIMER_NUM: HAL_NVIC_DisableIRQ(STEP_TIMER_IRQ_ID); break;
- case TEMP_TIMER_NUM: HAL_NVIC_DisableIRQ(TEMP_TIMER_IRQ_ID); break;
- }
- // 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();
-}
-
-bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
- switch (timer_num) {
- case STEP_TIMER_NUM: return NVIC->ISER[(uint32_t)((int32_t)STEP_TIMER_IRQ_ID) >> 5] & (uint32_t)(1 << ((uint32_t)((int32_t)STEP_TIMER_IRQ_ID) & (uint32_t)0x1F));
- case TEMP_TIMER_NUM: return NVIC->ISER[(uint32_t)((int32_t)TEMP_TIMER_IRQ_ID) >> 5] & (uint32_t)(1 << ((uint32_t)((int32_t)TEMP_TIMER_IRQ_ID) & (uint32_t)0x1F));
- }
- return false;
-}
-
-#endif // STM32GENERIC && STM32F4
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h b/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h
deleted file mode 100644
index a4a7ad82cc..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F4/timers.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2017 Victor Perez
- *
- * 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
-
-// ------------------------
-// Defines
-// ------------------------
-
-#define FORCE_INLINE __attribute__((always_inline)) inline
-
-#define hal_timer_t uint32_t // TODO: One is 16-bit, one 32-bit - does this need to be checked?
-#define HAL_TIMER_TYPE_MAX 0xFFFF
-
-#define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals
-
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
-#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
-#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
-#endif
-
-#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
-#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
-
-#define STEPPER_TIMER_PRESCALE 54 // was 40,prescaler for setting stepper timer, 2Mhz
-#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer
-#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
-
-#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
-#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
-#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
-
-#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
-#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
-#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
-
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
-
-// TODO change this
-
-#ifdef STM32GENERIC
- #define TC_TIMER_ARGS
-#else
- #define TC_TIMER_ARGS stimer_t *htim
-#endif
-
-extern void TC5_Handler(TC_TIMER_ARGS);
-extern void TC7_Handler(TC_TIMER_ARGS);
-#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() void TC5_Handler(TC_TIMER_ARGS)
-#endif
-#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() void TC7_Handler(TC_TIMER_ARGS)
-#endif
-
-// ------------------------
-// Types
-// ------------------------
-
-#ifdef STM32GENERIC
- typedef struct {
- TIM_HandleTypeDef handle;
- uint32_t callback;
- } tTimerConfig;
- typedef tTimerConfig stm32_timer_t;
-#else
- typedef stimer_t stm32_timer_t;
-#endif
-
-// ------------------------
-// Public Variables
-// ------------------------
-
-extern stm32_timer_t TimerHandle[];
-
-// ------------------------
-// Public functions
-// ------------------------
-
-void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
-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);
-}
-
-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);
-}
-
-#ifdef STM32GENERIC
- FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
- if (__HAL_TIM_GET_FLAG(&TimerHandle[timer_num].handle, TIM_FLAG_UPDATE) == SET)
- __HAL_TIM_CLEAR_FLAG(&TimerHandle[timer_num].handle, TIM_FLAG_UPDATE);
- }
-#else
- #define HAL_timer_isr_prologue(TIMER_NUM)
-#endif
-
-#define HAL_timer_isr_epilogue(TIMER_NUM)
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F7/README.md b/Marlin/src/HAL/STM32_F4_F7/STM32F7/README.md
deleted file mode 100644
index 23155b425e..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# This HAL is for the STM32F765 board "The Borg" used with STM32Generic Arduino core by danieleff.
-
-# Original core is located at:
-
-https://github.com/danieleff/STM32GENERIC
-
-but I haven't committed the changes needed for the Borg there yet, so please use:
-
-https://github.com/Spawn32/STM32GENERIC
-
-Unzip it into [Arduino]/hardware folder
-
-
-Download the latest GNU ARM Embedded Toolchain:
-
-https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
-
-(The one in Arduino doesn't support STM32F7).
-
-Change compiler.path in platform.txt to point to the one you downloaded.
-
-# This HAL is in development.
-# Currently only tested on "The Borg".
-
-You will also need the latest Arduino 1.9.0-beta or newer.
-
-This HAL is a modified version of Chris Barr's Picoprint STM32F4 HAL, so shouldn't be to hard to get it to work on a F4.
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp
deleted file mode 100644
index 4d116f440b..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp
+++ /dev/null
@@ -1,900 +0,0 @@
-/**
- * TMC26XStepper.cpp - - TMC26X Stepper library for Wiring/Arduino
- *
- * based on the stepper library by Tom Igoe, et. al.
- *
- * Copyright (c) 2011, Interactive Matter, Marcus Nowotny
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-#if defined(STM32GENERIC) && defined(STM32F7)
-
-#include "../../../inc/MarlinConfigPre.h"
-
-#if HAS_DRIVER(TMC2660)
-
-#include
-#include
-#include "TMC2660.h"
-
-#include "../../../inc/MarlinConfig.h"
-#include "../../../MarlinCore.h"
-#include "../../../module/stepper/indirection.h"
-#include "../../../module/printcounter.h"
-#include "../../../libs/duration_t.h"
-#include "../../../libs/hex_print.h"
-
-//some default values used in initialization
-#define DEFAULT_MICROSTEPPING_VALUE 32
-
-//TMC26X register definitions
-#define DRIVER_CONTROL_REGISTER 0x0ul
-#define CHOPPER_CONFIG_REGISTER 0x80000ul
-#define COOL_STEP_REGISTER 0xA0000ul
-#define STALL_GUARD2_LOAD_MEASURE_REGISTER 0xC0000ul
-#define DRIVER_CONFIG_REGISTER 0xE0000ul
-
-#define REGISTER_BIT_PATTERN 0xFFFFFul
-
-//definitions for the driver control register
-#define MICROSTEPPING_PATTERN 0xFul
-#define STEP_INTERPOLATION 0x200ul
-#define DOUBLE_EDGE_STEP 0x100ul
-#define VSENSE 0x40ul
-#define READ_MICROSTEP_POSTION 0x0ul
-#define READ_STALL_GUARD_READING 0x10ul
-#define READ_STALL_GUARD_AND_COOL_STEP 0x20ul
-#define READ_SELECTION_PATTERN 0x30ul
-
-//definitions for the chopper config register
-#define CHOPPER_MODE_STANDARD 0x0ul
-#define CHOPPER_MODE_T_OFF_FAST_DECAY 0x4000ul
-#define T_OFF_PATTERN 0xFul
-#define RANDOM_TOFF_TIME 0x2000ul
-#define BLANK_TIMING_PATTERN 0x18000ul
-#define BLANK_TIMING_SHIFT 15
-#define HYSTERESIS_DECREMENT_PATTERN 0x1800ul
-#define HYSTERESIS_DECREMENT_SHIFT 11
-#define HYSTERESIS_LOW_VALUE_PATTERN 0x780ul
-#define HYSTERESIS_LOW_SHIFT 7
-#define HYSTERESIS_START_VALUE_PATTERN 0x78ul
-#define HYSTERESIS_START_VALUE_SHIFT 4
-#define T_OFF_TIMING_PATERN 0xFul
-
-//definitions for cool step register
-#define MINIMUM_CURRENT_FOURTH 0x8000ul
-#define CURRENT_DOWN_STEP_SPEED_PATTERN 0x6000ul
-#define SE_MAX_PATTERN 0xF00ul
-#define SE_CURRENT_STEP_WIDTH_PATTERN 0x60ul
-#define SE_MIN_PATTERN 0xFul
-
-//definitions for StallGuard2 current register
-#define STALL_GUARD_FILTER_ENABLED 0x10000ul
-#define STALL_GUARD_TRESHHOLD_VALUE_PATTERN 0x17F00ul
-#define CURRENT_SCALING_PATTERN 0x1Ful
-#define STALL_GUARD_CONFIG_PATTERN 0x17F00ul
-#define STALL_GUARD_VALUE_PATTERN 0x7F00ul
-
-//definitions for the input from the TMC2660
-#define STATUS_STALL_GUARD_STATUS 0x1ul
-#define STATUS_OVER_TEMPERATURE_SHUTDOWN 0x2ul
-#define STATUS_OVER_TEMPERATURE_WARNING 0x4ul
-#define STATUS_SHORT_TO_GROUND_A 0x8ul
-#define STATUS_SHORT_TO_GROUND_B 0x10ul
-#define STATUS_OPEN_LOAD_A 0x20ul
-#define STATUS_OPEN_LOAD_B 0x40ul
-#define STATUS_STAND_STILL 0x80ul
-#define READOUT_VALUE_PATTERN 0xFFC00ul
-
-#define CPU_32_BIT
-
-//default values
-#define INITIAL_MICROSTEPPING 0x3ul //32th microstepping
-
-SPIClass SPI_6(SPI6, SPI6_MOSI_PIN, SPI6_MISO_PIN, SPI6_SCK_PIN);
-
-#define STEPPER_SPI SPI_6
-
-//debuging output
-
-//#define TMC_DEBUG1
-
-uint8_t current_scaling = 0;
-
-/**
- * Constructor
- * number_of_steps - the steps per rotation
- * cs_pin - the SPI client select pin
- * dir_pin - the pin where the direction pin is connected
- * step_pin - the pin where the step pin is connected
- */
-TMC26XStepper::TMC26XStepper(const int16_t in_steps, int16_t cs_pin, int16_t dir_pin, int16_t step_pin, uint16_t current, uint16_t resistor) {
- // We are not started yet
- started = false;
-
- // By default cool step is not enabled
- cool_step_enabled = false;
-
- // Save the pins for later use
- this->cs_pin = cs_pin;
- this->dir_pin = dir_pin;
- this->step_pin = step_pin;
-
- // Store the current sense resistor value for later use
- this->resistor = resistor;
-
- // Initizalize our status values
- this->steps_left = 0;
- this->direction = 0;
-
- // Initialize register values
- driver_control_register_value = DRIVER_CONTROL_REGISTER | INITIAL_MICROSTEPPING;
- chopper_config_register = CHOPPER_CONFIG_REGISTER;
-
- // Setting the default register values
- driver_control_register_value = DRIVER_CONTROL_REGISTER|INITIAL_MICROSTEPPING;
- microsteps = _BV(INITIAL_MICROSTEPPING);
- chopper_config_register = CHOPPER_CONFIG_REGISTER;
- cool_step_register_value = COOL_STEP_REGISTER;
- stallguard2_current_register_value = STALL_GUARD2_LOAD_MEASURE_REGISTER;
- driver_configuration_register_value = DRIVER_CONFIG_REGISTER | READ_STALL_GUARD_READING;
-
- // Set the current
- setCurrent(current);
- // Set to a conservative start value
- setConstantOffTimeChopper(7, 54, 13,12,1);
- // Set a nice microstepping value
- setMicrosteps(DEFAULT_MICROSTEPPING_VALUE);
- // Save the number of steps
- number_of_steps = in_steps;
-}
-
-
-/**
- * start & configure the stepper driver
- * just must be called.
- */
-void TMC26XStepper::start() {
-
- #ifdef TMC_DEBUG1
- SERIAL_ECHOLNPGM("\n TMC26X stepper library");
- SERIAL_ECHOPAIR("\n CS pin: ", cs_pin);
- SERIAL_ECHOPAIR("\n DIR pin: ", dir_pin);
- SERIAL_ECHOPAIR("\n STEP pin: ", step_pin);
- SERIAL_PRINTF("\n current scaling: %d", current_scaling);
- SERIAL_PRINTF("\n Resistor: %d", resistor);
- //SERIAL_PRINTF("\n current: %d", current);
- SERIAL_ECHOPAIR("\n Microstepping: ", microsteps);
- #endif
-
- //set the pins as output & its initial value
- pinMode(step_pin, OUTPUT);
- pinMode(dir_pin, OUTPUT);
- pinMode(cs_pin, OUTPUT);
- extDigitalWrite(step_pin, LOW);
- extDigitalWrite(dir_pin, LOW);
- extDigitalWrite(cs_pin, HIGH);
-
- STEPPER_SPI.begin();
- STEPPER_SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE3));
-
- //set the initial values
- send262(driver_control_register_value);
- send262(chopper_config_register);
- send262(cool_step_register_value);
- send262(stallguard2_current_register_value);
- send262(driver_configuration_register_value);
-
- //save that we are in running mode
- started = true;
-}
-
-/**
- * Mark the driver as unstarted to be able to start it again
- */
-void TMC26XStepper::un_start() { started = false; }
-
-
-/**
- * Sets the speed in revs per minute
- */
-void TMC26XStepper::setSpeed(uint16_t whatSpeed) {
- this->speed = whatSpeed;
- this->step_delay = 60UL * sq(1000UL) / ((uint32_t)this->number_of_steps * (uint32_t)whatSpeed * (uint32_t)this->microsteps);
- #ifdef TMC_DEBUG0 // crashes
- SERIAL_ECHOPAIR("\nStep delay in micros: ", this->step_delay);
- #endif
- // Update the next step time
- this->next_step_time = this->last_step_time + this->step_delay;
-}
-
-uint16_t TMC26XStepper::getSpeed() { return this->speed; }
-
-/**
- * Moves the motor steps_to_move steps.
- * Negative indicates the reverse direction.
- */
-char TMC26XStepper::step(int16_t steps_to_move) {
- if (this->steps_left == 0) {
- this->steps_left = ABS(steps_to_move); // how many steps to take
-
- // determine direction based on whether steps_to_move is + or -:
- if (steps_to_move > 0)
- this->direction = 1;
- else if (steps_to_move < 0)
- this->direction = 0;
- return 0;
- }
- return -1;
-}
-
-char TMC26XStepper::move() {
- // decrement the number of steps, moving one step each time:
- if (this->steps_left > 0) {
- uint32_t time = micros();
- // move only if the appropriate delay has passed:
-
- // rem if (time >= this->next_step_time) {
-
- if (ABS(time - this->last_step_time) > this->step_delay) {
- // increment or decrement the step number,
- // depending on direction:
- if (this->direction == 1)
- extDigitalWrite(step_pin, HIGH);
- else {
- extDigitalWrite(dir_pin, HIGH);
- extDigitalWrite(step_pin, HIGH);
- }
- // get the timeStamp of when you stepped:
- this->last_step_time = time;
- this->next_step_time = time + this->step_delay;
- // decrement the steps left:
- steps_left--;
- //disable the step & dir pins
- extDigitalWrite(step_pin, LOW);
- extDigitalWrite(dir_pin, LOW);
- }
- return -1;
- }
- return 0;
-}
-
-char TMC26XStepper::isMoving() { return this->steps_left > 0; }
-
-uint16_t TMC26XStepper::getStepsLeft() { return this->steps_left; }
-
-char TMC26XStepper::stop() {
- //note to self if the motor is currently moving
- char state = isMoving();
- //stop the motor
- this->steps_left = 0;
- this->direction = 0;
- //return if it was moving
- return state;
-}
-
-void TMC26XStepper::setCurrent(uint16_t current) {
- uint8_t current_scaling = 0;
- //calculate the current scaling from the max current setting (in mA)
- float mASetting = (float)current,
- resistor_value = (float)this->resistor;
- // remove vsense flag
- this->driver_configuration_register_value &= ~(VSENSE);
- // Derived from I = (cs + 1) / 32 * (Vsense / Rsense)
- // leading to cs = 32 * R * I / V (with V = 0,31V oder 0,165V and I = 1000 * current)
- // with Rsense = 0,15
- // for vsense = 0,310V (VSENSE not set)
- // or vsense = 0,165V (VSENSE set)
- current_scaling = (byte)((resistor_value * mASetting * 32.0 / (0.31 * sq(1000.0))) - 0.5); //theoretically - 1.0 for better rounding it is 0.5
-
- // Check if the current scalingis too low
- if (current_scaling < 16) {
- // Set the csense bit to get a use half the sense voltage (to support lower motor currents)
- this->driver_configuration_register_value |= VSENSE;
- // and recalculate the current setting
- current_scaling = (byte)((resistor_value * mASetting * 32.0 / (0.165 * sq(1000.0))) - 0.5); //theoretically - 1.0 for better rounding it is 0.5
- #ifdef TMC_DEBUG0 // crashes
- SERIAL_ECHOPAIR("\nCS (Vsense=1): ",current_scaling);
- #endif
- }
- #ifdef TMC_DEBUG0 // crashes
- else
- SERIAL_ECHOPAIR("\nCS: ", current_scaling);
- #endif
-
- // do some sanity checks
- NOMORE(current_scaling, 31);
-
- // delete the old value
- stallguard2_current_register_value &= ~(CURRENT_SCALING_PATTERN);
- // set the new current scaling
- stallguard2_current_register_value |= current_scaling;
- // if started we directly send it to the motor
- if (started) {
- send262(driver_configuration_register_value);
- send262(stallguard2_current_register_value);
- }
-}
-
-uint16_t TMC26XStepper::getCurrent() {
- // Calculate the current according to the datasheet to be on the safe side.
- // This is not the fastest but the most accurate and illustrative way.
- float result = (float)(stallguard2_current_register_value & CURRENT_SCALING_PATTERN),
- resistor_value = (float)this->resistor,
- voltage = (driver_configuration_register_value & VSENSE) ? 0.165 : 0.31;
- result = (result + 1.0) / 32.0 * voltage / resistor_value * sq(1000.0);
- return (uint16_t)result;
-}
-
-void TMC26XStepper::setStallGuardThreshold(char stallguard_threshold, char stallguard_filter_enabled) {
- // We just have 5 bits
- LIMIT(stallguard_threshold, -64, 63);
-
- // Add trim down to 7 bits
- stallguard_threshold &= 0x7F;
- // Delete old StallGuard settings
- stallguard2_current_register_value &= ~(STALL_GUARD_CONFIG_PATTERN);
- if (stallguard_filter_enabled)
- stallguard2_current_register_value |= STALL_GUARD_FILTER_ENABLED;
-
- // Set the new StallGuard threshold
- stallguard2_current_register_value |= (((uint32_t)stallguard_threshold << 8) & STALL_GUARD_CONFIG_PATTERN);
- // If started we directly send it to the motor
- if (started) send262(stallguard2_current_register_value);
-}
-
-char TMC26XStepper::getStallGuardThreshold() {
- uint32_t stallguard_threshold = stallguard2_current_register_value & STALL_GUARD_VALUE_PATTERN;
- //shift it down to bit 0
- stallguard_threshold >>= 8;
- //convert the value to an int16_t to correctly handle the negative numbers
- char result = stallguard_threshold;
- //check if it is negative and fill it up with leading 1 for proper negative number representation
- //rem if (result & _BV(6)) {
-
- if (TEST(result, 6)) result |= 0xC0;
- return result;
-}
-
-char TMC26XStepper::getStallGuardFilter() {
- if (stallguard2_current_register_value & STALL_GUARD_FILTER_ENABLED)
- return -1;
- return 0;
-}
-
-/**
- * Set the number of microsteps per step.
- * 0,2,4,8,16,32,64,128,256 is supported
- * any value in between will be mapped to the next smaller value
- * 0 and 1 set the motor in full step mode
- */
-void TMC26XStepper::setMicrosteps(const int16_t in_steps) {
- uint16_t setting_pattern;
-
- if (in_steps >= 256) setting_pattern = 0;
- else if (in_steps >= 128) setting_pattern = 1;
- else if (in_steps >= 64) setting_pattern = 2;
- else if (in_steps >= 32) setting_pattern = 3;
- else if (in_steps >= 16) setting_pattern = 4;
- else if (in_steps >= 8) setting_pattern = 5;
- else if (in_steps >= 4) setting_pattern = 6;
- else if (in_steps >= 2) setting_pattern = 7;
- else if (in_steps <= 1) setting_pattern = 8; // 1 and 0 lead to full step
-
- microsteps = _BV(8 - setting_pattern);
-
- #ifdef TMC_DEBUG0 // crashes
- SERIAL_ECHOPAIR("\n Microstepping: ", microsteps);
- #endif
-
- // Delete the old value
- this->driver_control_register_value &= 0x000FFFF0UL;
-
- // Set the new value
- this->driver_control_register_value |= setting_pattern;
-
- // If started we directly send it to the motor
- if (started) send262(driver_control_register_value);
-
- // Recalculate the stepping delay by simply setting the speed again
- this->setSpeed(this->speed);
-}
-
-/**
- * returns the effective number of microsteps at the moment
- */
-int16_t TMC26XStepper::getMicrosteps() { return microsteps; }
-
-/**
- * constant_off_time: The off time setting controls the minimum chopper frequency.
- * For most applications an off time within the range of 5μs to 20μs will fit.
- * 2...15: off time setting
- *
- * blank_time: Selects the comparator blank time. This time needs to safely cover the switching event and the
- * duration of the ringing on the sense resistor. For
- * 0: min. setting 3: max. setting
- *
- * fast_decay_time_setting: Fast decay time setting. With CHM=1, these bits control the portion of fast decay for each chopper cycle.
- * 0: slow decay only
- * 1...15: duration of fast decay phase
- *
- * sine_wave_offset: Sine wave offset. With CHM=1, these bits control the sine wave offset.
- * A positive offset corrects for zero crossing error.
- * -3..-1: negative offset 0: no offset 1...12: positive offset
- *
- * use_current_comparator: Selects usage of the current comparator for termination of the fast decay cycle.
- * If current comparator is enabled, it terminates the fast decay cycle in case the current
- * reaches a higher negative value than the actual positive value.
- * 1: enable comparator termination of fast decay cycle
- * 0: end by time only
- */
-void TMC26XStepper::setConstantOffTimeChopper(char constant_off_time, char blank_time, char fast_decay_time_setting, char sine_wave_offset, uint8_t use_current_comparator) {
- // Perform some sanity checks
- LIMIT(constant_off_time, 2, 15);
-
- // Save the constant off time
- this->constant_off_time = constant_off_time;
-
- // Calculate the value acc to the clock cycles
- const char blank_value = blank_time >= 54 ? 3 :
- blank_time >= 36 ? 2 :
- blank_time >= 24 ? 1 : 0;
-
- LIMIT(fast_decay_time_setting, 0, 15);
- LIMIT(sine_wave_offset, -3, 12);
-
- // Shift the sine_wave_offset
- sine_wave_offset += 3;
-
- // Calculate the register setting
- // First of all delete all the values for this
- chopper_config_register &= ~(_BV(12) | BLANK_TIMING_PATTERN | HYSTERESIS_DECREMENT_PATTERN | HYSTERESIS_LOW_VALUE_PATTERN | HYSTERESIS_START_VALUE_PATTERN | T_OFF_TIMING_PATERN);
- // Set the constant off pattern
- chopper_config_register |= CHOPPER_MODE_T_OFF_FAST_DECAY;
- // Set the blank timing value
- chopper_config_register |= ((uint32_t)blank_value) << BLANK_TIMING_SHIFT;
- // Setting the constant off time
- chopper_config_register |= constant_off_time;
- // Set the fast decay time
- // Set msb
- chopper_config_register |= (((uint32_t)(fast_decay_time_setting & 0x8)) << HYSTERESIS_DECREMENT_SHIFT);
- // Other bits
- chopper_config_register |= (((uint32_t)(fast_decay_time_setting & 0x7)) << HYSTERESIS_START_VALUE_SHIFT);
- // Set the sine wave offset
- chopper_config_register |= (uint32_t)sine_wave_offset << HYSTERESIS_LOW_SHIFT;
- // Using the current comparator?
- if (!use_current_comparator)
- chopper_config_register |= _BV(12);
-
- // If started we directly send it to the motor
- if (started) {
- // rem send262(driver_control_register_value);
- send262(chopper_config_register);
- }
-}
-
-/**
- * constant_off_time: The off time setting controls the minimum chopper frequency.
- * For most applications an off time within the range of 5μs to 20μs will fit.
- * 2...15: off time setting
- *
- * blank_time: Selects the comparator blank time. This time needs to safely cover the switching event and the
- * duration of the ringing on the sense resistor. For
- * 0: min. setting 3: max. setting
- *
- * hysteresis_start: Hysteresis start setting. Please remark, that this value is an offset to the hysteresis end value HEND.
- * 1...8
- *
- * hysteresis_end: Hysteresis end setting. Sets the hysteresis end value after a number of decrements. Decrement interval time is controlled by HDEC.
- * The sum HSTRT+HEND must be <16. At a current setting CS of max. 30 (amplitude reduced to 240), the sum is not limited.
- * -3..-1: negative HEND 0: zero HEND 1...12: positive HEND
- *
- * hysteresis_decrement: Hysteresis decrement setting. This setting determines the slope of the hysteresis during on time and during fast decay time.
- * 0: fast decrement 3: very slow decrement
- */
-
-void TMC26XStepper::setSpreadCycleChopper(char constant_off_time, char blank_time, char hysteresis_start, char hysteresis_end, char hysteresis_decrement) {
- // Perform some sanity checks
- LIMIT(constant_off_time, 2, 15);
-
- // Save the constant off time
- this->constant_off_time = constant_off_time;
-
- // Calculate the value acc to the clock cycles
- const char blank_value = blank_time >= 54 ? 3 :
- blank_time >= 36 ? 2 :
- blank_time >= 24 ? 1 : 0;
-
- LIMIT(hysteresis_start, 1, 8);
- hysteresis_start--;
-
- LIMIT(hysteresis_start, -3, 12);
-
- // Shift the hysteresis_end
- hysteresis_end += 3;
-
- LIMIT(hysteresis_decrement, 0, 3);
-
- //first of all delete all the values for this
- chopper_config_register &= ~(CHOPPER_MODE_T_OFF_FAST_DECAY | BLANK_TIMING_PATTERN | HYSTERESIS_DECREMENT_PATTERN | HYSTERESIS_LOW_VALUE_PATTERN | HYSTERESIS_START_VALUE_PATTERN | T_OFF_TIMING_PATERN);
-
- //set the blank timing value
- chopper_config_register |= ((uint32_t)blank_value) << BLANK_TIMING_SHIFT;
- //setting the constant off time
- chopper_config_register |= constant_off_time;
- //set the hysteresis_start
- chopper_config_register |= ((uint32_t)hysteresis_start) << HYSTERESIS_START_VALUE_SHIFT;
- //set the hysteresis end
- chopper_config_register |= ((uint32_t)hysteresis_end) << HYSTERESIS_LOW_SHIFT;
- //set the hystereis decrement
- chopper_config_register |= ((uint32_t)blank_value) << BLANK_TIMING_SHIFT;
- //if started we directly send it to the motor
- if (started) {
- //rem send262(driver_control_register_value);
- send262(chopper_config_register);
- }
-}
-
-/**
- * In a constant off time chopper scheme both coil choppers run freely, i.e. are not synchronized.
- * The frequency of each chopper mainly depends on the coil current and the position dependant motor coil inductivity, thus it depends on the microstep position.
- * With some motors a slightly audible beat can occur between the chopper frequencies, especially when they are near to each other. This typically occurs at a
- * few microstep positions within each quarter wave. This effect normally is not audible when compared to mechanical noise generated by ball bearings, etc.
- * Further factors which can cause a similar effect are a poor layout of sense resistor GND connection.
- * Hint: A common factor, which can cause motor noise, is a bad PCB layout causing coupling of both sense resistor voltages
- * (please refer to sense resistor layout hint in chapter 8.1).
- * In order to minimize the effect of a beat between both chopper frequencies, an internal random generator is provided.
- * It modulates the slow decay time setting when switched on by the RNDTF bit. The RNDTF feature further spreads the chopper spectrum,
- * reducing electromagnetic emission on single frequencies.
- */
-void TMC26XStepper::setRandomOffTime(char value) {
- if (value)
- chopper_config_register |= RANDOM_TOFF_TIME;
- else
- chopper_config_register &= ~(RANDOM_TOFF_TIME);
- //if started we directly send it to the motor
- if (started) {
- //rem send262(driver_control_register_value);
- send262(chopper_config_register);
- }
-}
-
-void TMC26XStepper::setCoolStepConfiguration(
- uint16_t lower_SG_threshold,
- uint16_t SG_hysteresis,
- uint8_t current_decrement_step_size,
- uint8_t current_increment_step_size,
- uint8_t lower_current_limit
-) {
- // Sanitize the input values
- NOMORE(lower_SG_threshold, 480);
- // Divide by 32
- lower_SG_threshold >>= 5;
- NOMORE(SG_hysteresis, 480);
- // Divide by 32
- SG_hysteresis >>= 5;
- NOMORE(current_decrement_step_size, 3);
- NOMORE(current_increment_step_size, 3);
- NOMORE(lower_current_limit, 1);
-
- // Store the lower level in order to enable/disable the cool step
- this->cool_step_lower_threshold=lower_SG_threshold;
- // If cool step is not enabled we delete the lower value to keep it disabled
- if (!this->cool_step_enabled) lower_SG_threshold = 0;
- // The good news is that we can start with a complete new cool step register value
- // And simply set the values in the register
- cool_step_register_value = ((uint32_t)lower_SG_threshold)
- | (((uint32_t)SG_hysteresis) << 8)
- | (((uint32_t)current_decrement_step_size) << 5)
- | (((uint32_t)current_increment_step_size) << 13)
- | (((uint32_t)lower_current_limit) << 15)
- | COOL_STEP_REGISTER; // Register signature
-
- if (started) send262(cool_step_register_value);
-}
-
-void TMC26XStepper::setCoolStepEnabled(boolean enabled) {
- // Simply delete the lower limit to disable the cool step
- cool_step_register_value &= ~SE_MIN_PATTERN;
- // And set it to the proper value if cool step is to be enabled
- if (enabled)
- cool_step_register_value |= this->cool_step_lower_threshold;
- // And save the enabled status
- this->cool_step_enabled = enabled;
- // Save the register value
- if (started) send262(cool_step_register_value);
-}
-
-boolean TMC26XStepper::isCoolStepEnabled() { return this->cool_step_enabled; }
-
-uint16_t TMC26XStepper::getCoolStepLowerSgThreshold() {
- // We return our internally stored value - in order to provide the correct setting even if cool step is not enabled
- return this->cool_step_lower_threshold<<5;
-}
-
-uint16_t TMC26XStepper::getCoolStepUpperSgThreshold() {
- return uint8_t((cool_step_register_value & SE_MAX_PATTERN) >> 8) << 5;
-}
-
-uint8_t TMC26XStepper::getCoolStepCurrentIncrementSize() {
- return uint8_t((cool_step_register_value & CURRENT_DOWN_STEP_SPEED_PATTERN) >> 13);
-}
-
-uint8_t TMC26XStepper::getCoolStepNumberOfSGReadings() {
- return uint8_t((cool_step_register_value & SE_CURRENT_STEP_WIDTH_PATTERN) >> 5);
-}
-
-uint8_t TMC26XStepper::getCoolStepLowerCurrentLimit() {
- return uint8_t((cool_step_register_value & MINIMUM_CURRENT_FOURTH) >> 15);
-}
-
-void TMC26XStepper::setEnabled(boolean enabled) {
- //delete the t_off in the chopper config to get sure
- chopper_config_register &= ~(T_OFF_PATTERN);
- if (enabled) {
- //and set the t_off time
- chopper_config_register |= this->constant_off_time;
- }
- //if not enabled we don't have to do anything since we already delete t_off from the register
- if (started) send262(chopper_config_register);
-}
-
-boolean TMC26XStepper::isEnabled() { return !!(chopper_config_register & T_OFF_PATTERN); }
-
-/**
- * reads a value from the TMC26X status register. The value is not obtained directly but can then
- * be read by the various status routines.
- *
- */
-void TMC26XStepper::readStatus(char read_value) {
- uint32_t old_driver_configuration_register_value = driver_configuration_register_value;
- //reset the readout configuration
- driver_configuration_register_value &= ~(READ_SELECTION_PATTERN);
- //this now equals TMC26X_READOUT_POSITION - so we just have to check the other two options
- if (read_value == TMC26X_READOUT_STALLGUARD)
- driver_configuration_register_value |= READ_STALL_GUARD_READING;
- else if (read_value == TMC26X_READOUT_CURRENT)
- driver_configuration_register_value |= READ_STALL_GUARD_AND_COOL_STEP;
-
- //all other cases are ignored to prevent funny values
- //check if the readout is configured for the value we are interested in
- if (driver_configuration_register_value != old_driver_configuration_register_value) {
- //because then we need to write the value twice - one time for configuring, second time to get the value, see below
- send262(driver_configuration_register_value);
- }
- //write the configuration to get the last status
- send262(driver_configuration_register_value);
-}
-
-int16_t TMC26XStepper::getMotorPosition() {
- //we read it out even if we are not started yet - perhaps it is useful information for somebody
- readStatus(TMC26X_READOUT_POSITION);
- return getReadoutValue();
-}
-
-//reads the StallGuard setting from last status
-//returns -1 if StallGuard information is not present
-int16_t TMC26XStepper::getCurrentStallGuardReading() {
- //if we don't yet started there cannot be a StallGuard value
- if (!started) return -1;
- //not time optimal, but solution optiomal:
- //first read out the StallGuard value
- readStatus(TMC26X_READOUT_STALLGUARD);
- return getReadoutValue();
-}
-
-uint8_t TMC26XStepper::getCurrentCSReading() {
- //if we don't yet started there cannot be a StallGuard value
- if (!started) return 0;
- //not time optimal, but solution optiomal:
- //first read out the StallGuard value
- readStatus(TMC26X_READOUT_CURRENT);
- return (getReadoutValue() & 0x1F);
-}
-
-uint16_t TMC26XStepper::getCurrentCurrent() {
- float result = (float)getCurrentCSReading(),
- resistor_value = (float)this->resistor,
- voltage = (driver_configuration_register_value & VSENSE)? 0.165 : 0.31;
- result = (result + 1.0) / 32.0 * voltage / resistor_value * sq(1000.0);
- return (uint16_t)result;
-}
-
-/**
- * Return true if the StallGuard threshold has been reached
- */
-boolean TMC26XStepper::isStallGuardOverThreshold() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_STALL_GUARD_STATUS);
-}
-
-/**
- * returns if there is any over temperature condition:
- * OVER_TEMPERATURE_PREWARING if pre warning level has been reached
- * OVER_TEMPERATURE_SHUTDOWN if the temperature is so hot that the driver is shut down
- * Any of those levels are not too good.
- */
-char TMC26XStepper::getOverTemperature() {
- if (!this->started) return 0;
-
- if (driver_status_result & STATUS_OVER_TEMPERATURE_SHUTDOWN)
- return TMC26X_OVERTEMPERATURE_SHUTDOWN;
-
- if (driver_status_result & STATUS_OVER_TEMPERATURE_WARNING)
- return TMC26X_OVERTEMPERATURE_PREWARING;
-
- return 0;
-}
-
-// Is motor channel A shorted to ground
-boolean TMC26XStepper::isShortToGroundA() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_SHORT_TO_GROUND_A);
-}
-
-// Is motor channel B shorted to ground
-boolean TMC26XStepper::isShortToGroundB() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_SHORT_TO_GROUND_B);
-}
-
-// Is motor channel A connected
-boolean TMC26XStepper::isOpenLoadA() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_OPEN_LOAD_A);
-}
-
-// Is motor channel B connected
-boolean TMC26XStepper::isOpenLoadB() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_OPEN_LOAD_B);
-}
-
-// Is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
-boolean TMC26XStepper::isStandStill() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_STAND_STILL);
-}
-
-//is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
-boolean TMC26XStepper::isStallGuardReached() {
- if (!this->started) return false;
- return (driver_status_result & STATUS_STALL_GUARD_STATUS);
-}
-
-//reads the StallGuard setting from last status
-//returns -1 if StallGuard information is not present
-int16_t TMC26XStepper::getReadoutValue() {
- return (int)(driver_status_result >> 10);
-}
-
-int16_t TMC26XStepper::getResistor() { return this->resistor; }
-
-boolean TMC26XStepper::isCurrentScalingHalfed() {
- return !!(this->driver_configuration_register_value & VSENSE);
-}
-/**
- * version() returns the version of the library:
- */
-int16_t TMC26XStepper::version() { return 1; }
-
-void TMC26XStepper::debugLastStatus() {
- #ifdef TMC_DEBUG1
- if (this->started) {
- if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_PREWARING)
- SERIAL_ECHOLNPGM("\n WARNING: Overtemperature Prewarning!");
- else if (this->getOverTemperature()&TMC26X_OVERTEMPERATURE_SHUTDOWN)
- SERIAL_ECHOLNPGM("\n ERROR: Overtemperature Shutdown!");
-
- if (this->isShortToGroundA())
- SERIAL_ECHOLNPGM("\n ERROR: SHORT to ground on channel A!");
-
- if (this->isShortToGroundB())
- SERIAL_ECHOLNPGM("\n ERROR: SHORT to ground on channel B!");
-
- if (this->isOpenLoadA())
- SERIAL_ECHOLNPGM("\n ERROR: Channel A seems to be unconnected!");
-
- if (this->isOpenLoadB())
- SERIAL_ECHOLNPGM("\n ERROR: Channel B seems to be unconnected!");
-
- if (this->isStallGuardReached())
- SERIAL_ECHOLNPGM("\n INFO: Stall Guard level reached!");
-
- if (this->isStandStill())
- SERIAL_ECHOLNPGM("\n INFO: Motor is standing still.");
-
- uint32_t readout_config = driver_configuration_register_value & READ_SELECTION_PATTERN;
- const int16_t value = getReadoutValue();
- if (readout_config == READ_MICROSTEP_POSTION) {
- SERIAL_ECHOPAIR("\n Microstep position phase A: ", value);
- }
- else if (readout_config == READ_STALL_GUARD_READING) {
- SERIAL_ECHOPAIR("\n Stall Guard value:", value);
- }
- else if (readout_config == READ_STALL_GUARD_AND_COOL_STEP) {
- SERIAL_ECHOPAIR("\n Approx Stall Guard: ", value & 0xF);
- SERIAL_ECHOPAIR("\n Current level", value & 0x1F0);
- }
- }
- #endif
-}
-
-/**
- * send register settings to the stepper driver via SPI
- * returns the current status
- */
-inline void TMC26XStepper::send262(uint32_t datagram) {
- uint32_t i_datagram;
-
- //preserver the previous spi mode
- //uint8_t oldMode = SPCR & SPI_MODE_MASK;
-
- //if the mode is not correct set it to mode 3
- //if (oldMode != SPI_MODE3) {
- // SPI.setDataMode(SPI_MODE3);
- //}
-
- //select the TMC driver
- extDigitalWrite(cs_pin, LOW);
-
- //ensure that only valid bist are set (0-19)
- //datagram &=REGISTER_BIT_PATTERN;
-
- #ifdef TMC_DEBUG1
- //SERIAL_PRINTF("Sending ");
- //SERIAL_PRINTF("Sending ", datagram,HEX);
- //SERIAL_ECHOPAIR("\n\nSending \n", print_hex_long(datagram));
- SERIAL_PRINTF("\n\nSending %x", datagram);
- #endif
-
- //write/read the values
- i_datagram = STEPPER_SPI.transfer((datagram >> 16) & 0xFF);
- i_datagram <<= 8;
- i_datagram |= STEPPER_SPI.transfer((datagram >> 8) & 0xFF);
- i_datagram <<= 8;
- i_datagram |= STEPPER_SPI.transfer((datagram) & 0xFF);
- i_datagram >>= 4;
-
- #ifdef TMC_DEBUG1
- //SERIAL_PRINTF("Received ");
- //SERIAL_PRINTF("Received ", i_datagram,HEX);
- //SERIAL_ECHOPAIR("\n\nReceived \n", i_datagram);
- SERIAL_PRINTF("\n\nReceived %x", i_datagram);
- debugLastStatus();
- #endif
-
- //deselect the TMC chip
- extDigitalWrite(cs_pin, HIGH);
-
- //restore the previous SPI mode if neccessary
- //if the mode is not correct set it to mode 3
- //if (oldMode != SPI_MODE3) {
- // SPI.setDataMode(oldMode);
- //}
-
- //store the datagram as status result
- driver_status_result = i_datagram;
-}
-
-#endif // HAS_DRIVER(TMC2660)
-
-#endif // STM32GENERIC && STM32F7
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h b/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h
deleted file mode 100644
index f1d0133a3b..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h
+++ /dev/null
@@ -1,594 +0,0 @@
-/**
- * TMC26XStepper.h - - TMC26X Stepper library for Wiring/Arduino
- *
- * based on the stepper library by Tom Igoe, et. al.
- *
- * Copyright (c) 2011, Interactive Matter, Marcus Nowotny
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-#pragma once
-
-#include
-
-//! return value for TMC26XStepper.getOverTemperature() if there is a overtemperature situation in the TMC chip
-/*!
- * This warning indicates that the TMC chip is too warm.
- * It is still working but some parameters may be inferior.
- * You should do something against it.
- */
-#define TMC26X_OVERTEMPERATURE_PREWARING 1
-//! return value for TMC26XStepper.getOverTemperature() if there is a overtemperature shutdown in the TMC chip
-/*!
- * This warning indicates that the TMC chip is too warm to operate and has shut down to prevent damage.
- * It will stop working until it cools down again.
- * If you encouter this situation you must do something against it. Like reducing the current or improving the PCB layout
- * and/or heat management.
- */
-#define TMC26X_OVERTEMPERATURE_SHUTDOWN 2
-
-//which values can be read out
-/*!
- * Selects to readout the microstep position from the motor.
- *\sa readStatus()
- */
-#define TMC26X_READOUT_POSITION 0
-/*!
- * Selects to read out the StallGuard value of the motor.
- *\sa readStatus()
- */
-#define TMC26X_READOUT_STALLGUARD 1
-/*!
- * Selects to read out the current current setting (acc. to CoolStep) and the upper bits of the StallGuard value from the motor.
- *\sa readStatus(), setCurrent()
- */
-#define TMC26X_READOUT_CURRENT 3
-
-/*!
- * Define to set the minimum current for CoolStep operation to 1/2 of the selected CS minium.
- *\sa setCoolStepConfiguration()
- */
-#define COOL_STEP_HALF_CS_LIMIT 0
-/*!
- * Define to set the minimum current for CoolStep operation to 1/4 of the selected CS minium.
- *\sa setCoolStepConfiguration()
- */
-#define COOL_STEP_QUARTDER_CS_LIMIT 1
-
-/*!
- * \class TMC26XStepper
- * \brief Class representing a TMC26X stepper driver
- *
- * To use one of these drivers in your code create an object of its class:
- * \code
- * TMC26XStepper tmc_stepper = TMC26XStepper(200,1,2,3,500);
- * \endcode
- * see TMC26XStepper(int16_t number_of_steps, int16_t cs_pin, int16_t dir_pin, int16_t step_pin, uint16_t rms_current)
- *
- * Keep in mind that you need to start the driver with start() in order to configure the TMC26X.
- *
- * The most important function is move(). It checks if the motor requires a step. It's important to call move() as
- * often as possible in loop(). I suggest using a very fast loop routine and always call move() at the beginning or end.
- *
- * To move you must set a movement speed with setSpeed(). The speed is a positive value, setting the RPM.
- *
- * To really move the motor you have to call step() to tell the driver to move the motor the given number
- * of steps in the given direction. Positive values move the motor in one direction, negative values in the other.
- *
- * You can check with isMoving() if the motor is still moving or stop it abruptly with stop().
- */
-class TMC26XStepper {
- public:
- /*!
- * \brief Create a new representation of a stepper motor connected to a TMC26X stepper driver
- *
- * Main constructor. If in doubt use this. All parameters must be provided as described below.
- *
- * \param number_of_steps Number of steps the motor has per rotation.
- * \param cs_pin Arduino pin connected to the Client Select Pin (!CS) of the TMC26X for SPI.
- * \param dir_pin Arduino pin connected to the DIR input of the TMC26X.
- * \param step_pin Arduino pin connected to the STEP pin of the TMC26X.
- * \param rms_current Maximum current to provide to the motor in mA (!). A value of 200 will send up to 200mA to the motor.
- * \param resistor Current sense resistor in milli-Ohm, defaults to 0.15 Ohm (or 150 milli-Ohm) as in the TMC260 Arduino Shield.
- *
- * You must also call TMC26XStepper.start() to configure the stepper driver for use.
- *
- * By default the Constant Off Time chopper is used. See TMC26XStepper.setConstantOffTimeChopper() for details.
- * This should work on most motors (YMMV). You may want to configure and use the Spread Cycle Chopper. See setSpreadCycleChopper().
- *
- * By default a microstepping of 1/32 is used to provide a smooth motor run while still giving a good progression per step.
- * Change stepping by sending setMicrosteps() a different value.
- * \sa start(), setMicrosteps()
- */
- TMC26XStepper(const int16_t in_steps, int16_t cs_pin, int16_t dir_pin, int16_t step_pin, uint16_t current, uint16_t resistor=100); //resistor=150
-
- /*!
- * \brief Configure and start the TMC26X stepper driver. Before this is called the stepper driver is nonfunctional.
- *
- * Configure the TMC26X stepper driver for the given values via SPI.
- * Most member functions are non-functional if the driver has not been started,
- * therefore it is best to call this in setup().
- */
- void start();
-
- /*!
- * \brief Reset the stepper in unconfigured mode.
- *
- * Allows start to be called again. It doesn't change the internal stepper
- * configuration or the desired configuration. It just marks the stepper as
- * not-yet-started. The stepper doesn't need to be reconfigured before
- * starting again, and is not reset to any factory settings.
- * It must be reset intentionally.
- * (Hint: Normally you do not need this function)
- */
- void un_start();
-
- /*!
- * \brief Set the rotation speed in RPM.
- * \param whatSpeed the desired speed in RPM.
- */
- void setSpeed(uint16_t whatSpeed);
-
- /*!
- * \brief Report the currently selected speed in RPM.
- * \sa setSpeed()
- */
- uint16_t getSpeed();
-
- /*!
- * \brief Set the number of microsteps in 2^i values (rounded) up to 256
- *
- * This method sets the number of microsteps per step in 2^i interval.
- * It accepts 1, 2, 4, 16, 32, 64, 128 or 256 as valid microsteps.
- * Other values will be rounded down to the next smaller value (e.g., 3 gives a microstepping of 2).
- * You can always check the current microstepping with getMicrosteps().
- */
- void setMicrosteps(const int16_t in_steps);
-
- /*!
- * \brief Return the effective current number of microsteps selected.
- *
- * Always returns the effective number of microsteps.
- * This may be different from the micro-steps set in setMicrosteps() since it is rounded to 2^i.
- *
- * \sa setMicrosteps()
- */
- int16_t getMicrosteps();
-
- /*!
- * \brief Initiate a movement with the given number of steps. Positive values move in one direction, negative in the other.
- *
- * \param number_of_steps The number of steps to move the motor.
- * \return 0 if the motor was not moving and moves now. -1 if the motor is moving and the new steps could not be set.
- *
- * If the previous movement is incomplete the function returns -1 and doesn't change the steps to move the motor.
- * If the motor does not move it returns 0.
- *
- * The movement direction is determined by the sign of the steps parameter. The motor direction in machine space
- * cannot be determined, as it depends on the construction of the motor and how it functions in the drive system.
- *
- * For safety, verify with isMoving() or even use stop() to stop the motor before giving it new step directions.
- * \sa isMoving(), getStepsLeft(), stop()
- */
- char step(int16_t number_of_steps);
-
- /*!
- * \brief Central movement method. Must be called as often as possible in the loop function and is very fast.
- *
- * Check if the motor still has to move and whether the wait-to-step interval has expired, and manages the
- * number of steps remaining to fulfill the current move command.
- *
- * This function is implemented to be as fast as possible, so call it as often as possible in your loop.
- * It should be invoked with as frequently and with as much regularity as possible.
- *
- * This can be called even when the motor is known not to be moving. It will simply return.
- *
- * The frequency with which this function is called determines the top stepping speed of the motor.
- * It is recommended to call this using a hardware timer to ensure regular invocation.
- * \sa step()
- */
- char move();
-
- /*!
- * \brief Check whether the last movement command is done.
- * \return 0 if the motor stops, -1 if the motor is moving.
- *
- * Used to determine if the motor is ready for new movements.
- *\sa step(), move()
- */
- char isMoving();
-
- /*!
- * \brief Get the number of steps left in the current movement.
- * \return The number of steps left in the movement. Always positive.
- */
- uint16_t getStepsLeft();
-
- /*!
- * \brief Stop the motor immediately.
- * \return -1 if the motor was moving and is really stoped or 0 if it was not moving at all.
- *
- * This method directly and abruptly stops the motor and may be used as an emergency stop.
- */
- char stop();
-
- /*!
- * \brief Set and configure the classical Constant Off Timer Chopper
- * \param constant_off_time The off time setting controls the minimum chopper frequency. For most applications an off time within the range of 5μs to 20μs will fit. Setting this parameter to zero completely disables all driver transistors and the motor can free-wheel. 0: chopper off, 1:15: off time setting (1 will work with minimum blank time of 24 clocks)
- * \param blank_time Comparator blank time. This duration needs to safely cover the duration of the switching event and the ringing on the sense resistor. For most low current drivers, a setting of 1 or 2 is good. For high current applications with large MOSFETs, a setting of 2 or 3 will be required. 0 (min setting) … (3) amx setting
- * \param fast_decay_time_setting Fast decay time setting. Controls the portion of fast decay for each chopper cycle. 0: slow decay only, 1…15: duration of fast decay phase
- * \param sine_wave_offset Sine wave offset. Controls the sine wave offset. A positive offset corrects for zero crossing error. -3…-1: negative offset, 0: no offset,1…12: positive offset
- * \param use_curreent_comparator Selects usage of the current comparator for termination of the fast decay cycle. If current comparator is enabled, it terminates the fast decay cycle in case the current reaches a higher negative value than the actual positive value. (0 disable, -1 enable).
- *
- * The classic constant off time chopper uses a fixed portion of fast decay following each on phase.
- * While the duration of the on time is determined by the chopper comparator, the fast decay time needs
- * to be set by the user in a way, that the current decay is enough for the driver to be able to follow
- * the falling slope of the sine wave, and on the other hand it should not be too long, in order to minimize
- * motor current ripple and power dissipation. This best can be tuned using an oscilloscope or
- * trying out motor smoothness at different velocities. A good starting value is a fast decay time setting
- * similar to the slow decay time setting.
- * After tuning of the fast decay time, the offset should be determined, in order to have a smooth zero transition.
- * This is necessary, because the fast decay phase leads to the absolute value of the motor current being lower
- * than the target current (see figure 17). If the zero offset is too low, the motor stands still for a short
- * moment during current zero crossing, if it is set too high, it makes a larger microstep.
- * Typically, a positive offset setting is required for optimum operation.
- *
- * \sa setSpreadCycleChoper() for other alternatives.
- * \sa setRandomOffTime() for spreading the noise over a wider spectrum
- */
- void setConstantOffTimeChopper(char constant_off_time, char blank_time, char fast_decay_time_setting, char sine_wave_offset, uint8_t use_current_comparator);
-
- /*!
- * \brief Sets and configures with spread cycle chopper.
- * \param constant_off_time The off time setting controls the minimum chopper frequency. For most applications an off time within the range of 5μs to 20μs will fit. Setting this parameter to zero completely disables all driver transistors and the motor can free-wheel. 0: chopper off, 1:15: off time setting (1 will work with minimum blank time of 24 clocks)
- * \param blank_time Selects the comparator blank time. This time needs to safely cover the switching event and the duration of the ringing on the sense resistor. For most low current drivers, a setting of 1 or 2 is good. For high current applications with large MOSFETs, a setting of 2 or 3 will be required. 0 (min setting) … (3) amx setting
- * \param hysteresis_start Hysteresis start setting. Please remark, that this value is an offset to the hysteresis end value. 1 … 8
- * \param hysteresis_end Hysteresis end setting. Sets the hysteresis end value after a number of decrements. Decrement interval time is controlled by hysteresis_decrement. The sum hysteresis_start + hysteresis_end must be <16. At a current setting CS of max. 30 (amplitude reduced to 240), the sum is not limited.
- * \param hysteresis_decrement Hysteresis decrement setting. This setting determines the slope of the hysteresis during on time and during fast decay time. 0 (fast decrement) … 3 (slow decrement).
- *
- * The spreadCycle chopper scheme (pat.fil.) is a precise and simple to use chopper principle, which automatically determines
- * the optimum fast decay portion for the motor. Anyhow, a number of settings can be made in order to optimally fit the driver
- * to the motor.
- * Each chopper cycle is comprised of an on-phase, a slow decay phase, a fast decay phase and a second slow decay phase.
- * The slow decay phases limit the maximum chopper frequency and are important for low motor and driver power dissipation.
- * The hysteresis start setting limits the chopper frequency by forcing the driver to introduce a minimum amount of
- * current ripple into the motor coils. The motor inductivity determines the ability to follow a changing motor current.
- * The duration of the on- and fast decay phase needs to cover at least the blank time, because the current comparator is
- * disabled during this time.
- *
- * \sa setRandomOffTime() for spreading the noise over a wider spectrum
- */
- void setSpreadCycleChopper(char constant_off_time, char blank_time, char hysteresis_start, char hysteresis_end, char hysteresis_decrement);
-
- /*!
- * \brief Use random off time for noise reduction (0 for off, -1 for on).
- * \param value 0 for off, -1 for on
- *
- * In a constant off time chopper scheme both coil choppers run freely, i.e. are not synchronized.
- * The frequency of each chopper mainly depends on the coil current and the position dependant motor coil inductivity,
- * thus it depends on the microstep position. With some motors a slightly audible beat can occur between the chopper
- * frequencies, especially when they are near to each other. This typically occurs at a few microstep positions within
- * each quarter wave.
- * This effect normally is not audible when compared to mechanical noise generated by ball bearings,
- * etc. Further factors which can cause a similar effect are a poor layout of sense resistor GND connection.
- * In order to minimize the effect of a beat between both chopper frequencies, an internal random generator is provided.
- * It modulates the slow decay time setting when switched on. The random off time feature further spreads the chopper spectrum,
- * reducing electromagnetic emission on single frequencies.
- */
- void setRandomOffTime(char value);
-
- /*!
- * \brief set the maximum motor current in mA (1000 is 1 Amp)
- * Keep in mind this is the maximum peak Current. The RMS current will be 1/sqrt(2) smaller. The actual current can also be smaller
- * by employing CoolStep.
- * \param current the maximum motor current in mA
- * \sa getCurrent(), getCurrentCurrent()
- */
- void setCurrent(uint16_t current);
-
- /*!
- * \brief readout the motor maximum current in mA (1000 is an Amp)
- * This is the maximum current. to get the current current - which may be affected by CoolStep us getCurrentCurrent()
- * \return the maximum motor current in milli amps
- * \sa getCurrentCurrent()
- */
- uint16_t getCurrent();
-
- /*!
- * \brief set the StallGuard threshold in order to get sensible StallGuard readings.
- * \param stallguard_threshold -64 … 63 the StallGuard threshold
- * \param stallguard_filter_enabled 0 if the filter is disabled, -1 if it is enabled
- *
- * The StallGuard threshold is used to optimize the StallGuard reading to sensible values. It should be at 0 at
- * the maximum allowable load on the otor (but not before). = is a good starting point (and the default)
- * If you get Stall Gaurd readings of 0 without any load or with too little laod increase the value.
- * If you get readings of 1023 even with load decrease the setting.
- *
- * If you switch on the filter the StallGuard reading is only updated each 4th full step to reduce the noise in the
- * reading.
- *
- * \sa getCurrentStallGuardReading() to read out the current value.
- */
- void setStallGuardThreshold(char stallguard_threshold, char stallguard_filter_enabled);
-
- /*!
- * \brief reads out the StallGuard threshold
- * \return a number between -64 and 63.
- */
- char getStallGuardThreshold();
-
- /*!
- * \brief returns the current setting of the StallGuard filter
- * \return 0 if not set, -1 if set
- */
- char getStallGuardFilter();
-
- /*!
- * \brief This method configures the CoolStep smart energy operation. You must have a proper StallGuard configuration for the motor situation (current, voltage, speed) in rder to use this feature.
- * \param lower_SG_threshold Sets the lower threshold for stallGuard2TM reading. Below this value, the motor current becomes increased. Allowed values are 0...480
- * \param SG_hysteresis Sets the distance between the lower and the upper threshold for stallGuard2TM reading. Above the upper threshold (which is lower_SG_threshold+SG_hysteresis+1) the motor current becomes decreased. Allowed values are 0...480
- * \param current_decrement_step_size Sets the current decrement steps. If the StallGuard value is above the threshold the current gets decremented by this step size. 0...32
- * \param current_increment_step_size Sets the current increment step. The current becomes incremented for each measured stallGuard2TM value below the lower threshold. 0...8
- * \param lower_current_limit Sets the lower motor current limit for coolStepTM operation by scaling the CS value. Values can be COOL_STEP_HALF_CS_LIMIT, COOL_STEP_QUARTER_CS_LIMIT
- * The CoolStep smart energy operation automatically adjust the current sent into the motor according to the current load,
- * read out by the StallGuard in order to provide the optimum torque with the minimal current consumption.
- * You configure the CoolStep current regulator by defining upper and lower bounds of StallGuard readouts. If the readout is above the
- * limit the current gets increased, below the limit the current gets decreased.
- * You can specify the upper an lower threshold of the StallGuard readout in order to adjust the current. You can also set the number of
- * StallGuard readings neccessary above or below the limit to get a more stable current adjustement.
- * The current adjustement itself is configured by the number of steps the current gests in- or decreased and the absolut minimum current
- * (1/2 or 1/4th otf the configured current).
- * \sa COOL_STEP_HALF_CS_LIMIT, COOL_STEP_QUARTER_CS_LIMIT
- */
- void setCoolStepConfiguration(uint16_t lower_SG_threshold, uint16_t SG_hysteresis, uint8_t current_decrement_step_size,
- uint8_t current_increment_step_size, uint8_t lower_current_limit);
-
- /*!
- * \brief enables or disables the CoolStep smart energy operation feature. It must be configured before enabling it.
- * \param enabled true if CoolStep should be enabled, false if not.
- * \sa setCoolStepConfiguration()
- */
- void setCoolStepEnabled(boolean enabled);
-
-
- /*!
- * \brief check if the CoolStep feature is enabled
- * \sa setCoolStepEnabled()
- */
- boolean isCoolStepEnabled();
-
- /*!
- * \brief returns the lower StallGuard threshold for the CoolStep operation
- * \sa setCoolStepConfiguration()
- */
- uint16_t getCoolStepLowerSgThreshold();
-
- /*!
- * \brief returns the upper StallGuard threshold for the CoolStep operation
- * \sa setCoolStepConfiguration()
- */
- uint16_t getCoolStepUpperSgThreshold();
-
- /*!
- * \brief returns the number of StallGuard readings befor CoolStep adjusts the motor current.
- * \sa setCoolStepConfiguration()
- */
- uint8_t getCoolStepNumberOfSGReadings();
-
- /*!
- * \brief returns the increment steps for the current for the CoolStep operation
- * \sa setCoolStepConfiguration()
- */
- uint8_t getCoolStepCurrentIncrementSize();
-
- /*!
- * \brief returns the absolut minium current for the CoolStep operation
- * \sa setCoolStepConfiguration()
- * \sa COOL_STEP_HALF_CS_LIMIT, COOL_STEP_QUARTER_CS_LIMIT
- */
- uint8_t getCoolStepLowerCurrentLimit();
-
- /*!
- * \brief Get the current microstep position for phase A
- * \return The current microstep position for phase A 0…255
- *
- * Keep in mind that this routine reads and writes a value via SPI - so this may take a bit time.
- */
- int16_t getMotorPosition();
-
- /*!
- * \brief Reads the current StallGuard value.
- * \return The current StallGuard value, lesser values indicate higher load, 0 means stall detected.
- * Keep in mind that this routine reads and writes a value via SPI - so this may take a bit time.
- * \sa setStallGuardThreshold() for tuning the readout to sensible ranges.
- */
- int16_t getCurrentStallGuardReading();
-
- /*!
- * \brief Reads the current current setting value as fraction of the maximum current
- * Returns values between 0 and 31, representing 1/32 to 32/32 (=1)
- * \sa setCoolStepConfiguration()
- */
- uint8_t getCurrentCSReading();
-
-
- /*!
- *\brief a convenience method to determine if the current scaling uses 0.31V or 0.165V as reference.
- *\return false if 0.13V is the reference voltage, true if 0.165V is used.
- */
- boolean isCurrentScalingHalfed();
-
- /*!
- * \brief Reads the current current setting value and recalculates the absolute current in mA (1A would be 1000).
- * This method calculates the currently used current setting (either by setting or by CoolStep) and reconstructs
- * the current in mA by usinge the VSENSE and resistor value. This method uses floating point math - so it
- * may not be the fastest.
- * \sa getCurrentCSReading(), getResistor(), isCurrentScalingHalfed(), getCurrent()
- */
- uint16_t getCurrentCurrent();
-
- /*!
- * \brief checks if there is a StallGuard warning in the last status
- * \return 0 if there was no warning, -1 if there was some warning.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- *
- * \sa setStallGuardThreshold() for tuning the readout to sensible ranges.
- */
- boolean isStallGuardOverThreshold();
-
- /*!
- * \brief Return over temperature status of the last status readout
- * return 0 is everything is OK, TMC26X_OVERTEMPERATURE_PREWARING if status is reached, TMC26X_OVERTEMPERATURE_SHUTDOWN is the chip is shutdown, -1 if the status is unknown.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
- char getOverTemperature();
-
- /*!
- * \brief Is motor channel A shorted to ground detected in the last status readout.
- * \return true is yes, false if not.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
-
- boolean isShortToGroundA();
-
- /*!
- * \brief Is motor channel B shorted to ground detected in the last status readout.
- * \return true is yes, false if not.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
- boolean isShortToGroundB();
- /*!
- * \brief iIs motor channel A connected according to the last statu readout.
- * \return true is yes, false if not.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
- boolean isOpenLoadA();
-
- /*!
- * \brief iIs motor channel A connected according to the last statu readout.
- * \return true is yes, false if not.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
- boolean isOpenLoadB();
-
- /*!
- * \brief Is chopper inactive since 2^20 clock cycles - defaults to ~0,08s
- * \return true is yes, false if not.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- */
- boolean isStandStill();
-
- /*!
- * \brief checks if there is a StallGuard warning in the last status
- * \return 0 if there was no warning, -1 if there was some warning.
- * Keep in mind that this method does not enforce a readout but uses the value of the last status readout.
- * You may want to use getMotorPosition() or getCurrentStallGuardReading() to enforce an updated status readout.
- *
- * \sa isStallGuardOverThreshold()
- * TODO why?
- *
- * \sa setStallGuardThreshold() for tuning the readout to sensible ranges.
- */
- boolean isStallGuardReached();
-
- /*!
- *\brief enables or disables the motor driver bridges. If disabled the motor can run freely. If enabled not.
- *\param enabled a boolean value true if the motor should be enabled, false otherwise.
- */
- void setEnabled(boolean enabled);
-
- /*!
- *\brief checks if the output bridges are enabled. If the bridges are not enabled the motor can run freely
- *\return true if the bridges and by that the motor driver are enabled, false if not.
- *\sa setEnabled()
- */
- boolean isEnabled();
-
- /*!
- * \brief Manually read out the status register
- * This function sends a byte to the motor driver in order to get the current readout. The parameter read_value
- * seletcs which value will get returned. If the read_vlaue changes in respect to the previous readout this method
- * automatically send two bytes to the motor: one to set the redout and one to get the actual readout. So this method
- * may take time to send and read one or two bits - depending on the previous readout.
- * \param read_value selects which value to read out (0..3). You can use the defines TMC26X_READOUT_POSITION, TMC_262_READOUT_STALLGUARD, or TMC_262_READOUT_CURRENT
- * \sa TMC26X_READOUT_POSITION, TMC_262_READOUT_STALLGUARD, TMC_262_READOUT_CURRENT
- */
- void readStatus(char read_value);
-
- /*!
- * \brief Returns the current sense resistor value in milliohm.
- * The default value of ,15 Ohm will return 150.
- */
- int16_t getResistor();
-
- /*!
- * \brief Prints out all the information that can be found in the last status read out - it does not force a status readout.
- * The result is printed via Serial
- */
- void debugLastStatus();
-
- /*!
- * \brief library version
- * \return the version number as int.
- */
- int16_t version();
-
- private:
- uint16_t steps_left; // The steps the motor has to do to complete the movement
- int16_t direction; // Direction of rotation
- uint32_t step_delay; // Delay between steps, in ms, based on speed
- int16_t number_of_steps; // Total number of steps this motor can take
- uint16_t speed; // Store the current speed in order to change the speed after changing microstepping
- uint16_t resistor; // Current sense resitor value in milliohm
-
- uint32_t last_step_time, // Timestamp (ms) of the last step
- next_step_time; // Timestamp (ms) of the next step
-
- // Driver control register copies to easily set & modify the registers
- uint32_t driver_control_register_value,
- chopper_config_register,
- cool_step_register_value,
- stallguard2_current_register_value,
- driver_configuration_register_value,
- driver_status_result; // The driver status result
-
- // Helper routione to get the top 10 bit of the readout
- inline int16_t getReadoutValue();
-
- // The pins for the stepper driver
- uint8_t cs_pin, step_pin, dir_pin;
-
- // Status values
- boolean started; // If the stepper has been started yet
- int16_t microsteps; // The current number of micro steps
- char constant_off_time; // We need to remember this value in order to enable and disable the motor
- uint8_t cool_step_lower_threshold; // we need to remember the threshold to enable and disable the CoolStep feature
- boolean cool_step_enabled; // We need to remember this to configure the coolstep if it si enabled
-
- // SPI sender
- inline void send262(uint32_t datagram);
-};
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp
deleted file mode 100644
index f7ded7454d..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- *
- * 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(STM32GENERIC) && defined(STM32F7)
-
-#include "../../../inc/MarlinConfig.h"
-
-// ------------------------
-// Local defines
-// ------------------------
-
-#define NUM_HARDWARE_TIMERS 2
-
-//#define PRESCALER 1
-
-// ------------------------
-// Private Variables
-// ------------------------
-
-tTimerConfig timerConfig[NUM_HARDWARE_TIMERS];
-
-// ------------------------
-// Public functions
-// ------------------------
-
-bool timers_initialized[NUM_HARDWARE_TIMERS] = { false };
-
-void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
-
- if (!timers_initialized[timer_num]) {
- switch (timer_num) {
- case STEP_TIMER_NUM:
- //STEPPER TIMER TIM5 //use a 32bit timer
- __HAL_RCC_TIM5_CLK_ENABLE();
- timerConfig[0].timerdef.Instance = TIM5;
- timerConfig[0].timerdef.Init.Prescaler = (STEPPER_TIMER_PRESCALE);
- timerConfig[0].timerdef.Init.CounterMode = TIM_COUNTERMODE_UP;
- timerConfig[0].timerdef.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- timerConfig[0].IRQ_Id = TIM5_IRQn;
- timerConfig[0].callback = (uint32_t)TC5_Handler;
- HAL_NVIC_SetPriority(timerConfig[0].IRQ_Id, 1, 0);
- #if PIN_EXISTS(STEPPER_ENABLE)
- OUT_WRITE(STEPPER_ENABLE_PIN, HIGH);
- #endif
- break;
- case TEMP_TIMER_NUM:
- //TEMP TIMER TIM7 // any available 16bit Timer (1 already used for PWM)
- __HAL_RCC_TIM7_CLK_ENABLE();
- timerConfig[1].timerdef.Instance = TIM7;
- timerConfig[1].timerdef.Init.Prescaler = (TEMP_TIMER_PRESCALE);
- timerConfig[1].timerdef.Init.CounterMode = TIM_COUNTERMODE_UP;
- timerConfig[1].timerdef.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- timerConfig[1].IRQ_Id = TIM7_IRQn;
- timerConfig[1].callback = (uint32_t)TC7_Handler;
- HAL_NVIC_SetPriority(timerConfig[1].IRQ_Id, 2, 0);
- break;
- }
- timers_initialized[timer_num] = true;
- }
-
- timerConfig[timer_num].timerdef.Init.Period = (((HAL_TIMER_RATE) / timerConfig[timer_num].timerdef.Init.Prescaler) / frequency) - 1;
-
- if (HAL_TIM_Base_Init(&timerConfig[timer_num].timerdef) == HAL_OK)
- HAL_TIM_Base_Start_IT(&timerConfig[timer_num].timerdef);
-}
-
-//forward the interrupt
-extern "C" void TIM5_IRQHandler() {
- ((void(*)())timerConfig[0].callback)();
-}
-extern "C" void TIM7_IRQHandler() {
- ((void(*)())timerConfig[1].callback)();
-}
-
-void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare) {
- __HAL_TIM_SetAutoreload(&timerConfig[timer_num].timerdef, compare);
-}
-
-void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- HAL_NVIC_EnableIRQ(timerConfig[timer_num].IRQ_Id);
-}
-
-void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- HAL_NVIC_DisableIRQ(timerConfig[timer_num].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();
-}
-
-hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
- return __HAL_TIM_GetAutoreload(&timerConfig[timer_num].timerdef);
-}
-
-uint32_t HAL_timer_get_count(const uint8_t timer_num) {
- return __HAL_TIM_GetCounter(&timerConfig[timer_num].timerdef);
-}
-
-void HAL_timer_isr_prologue(const uint8_t timer_num) {
- if (__HAL_TIM_GET_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE) == SET) {
- __HAL_TIM_CLEAR_FLAG(&timerConfig[timer_num].timerdef, TIM_FLAG_UPDATE);
- }
-}
-
-bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
- const uint32_t IRQ_Id = uint32_t(timerConfig[timer_num].IRQ_Id);
- return NVIC->ISER[IRQ_Id >> 5] & _BV32(IRQ_Id & 0x1F);
-}
-
-#endif // STM32GENERIC && STM32F7
diff --git a/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h b/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h
deleted file mode 100644
index d2f78259d6..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/timers.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- *
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2017 Victor Perez
- *
- * 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
-
-// ------------------------
-// Defines
-// ------------------------
-
-#define FORCE_INLINE __attribute__((always_inline)) inline
-
-#define hal_timer_t uint32_t // TODO: One is 16-bit, one 32-bit - does this need to be checked?
-#define HAL_TIMER_TYPE_MAX 0xFFFF
-
-#define HAL_TIMER_RATE (HAL_RCC_GetSysClockFreq() / 2) // frequency of timer peripherals
-
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
-#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
-#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
-#endif
-
-#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
-#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
-
-#define STEPPER_TIMER_PRESCALE 54 // was 40,prescaler for setting stepper timer, 2Mhz
-#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer
-#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
-
-#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
-#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
-#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
-
-#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
-#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
-
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
-
-#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
-#define TEMP_ISR_ENABLED() HAL_timer_interrupt_enabled(TEMP_TIMER_NUM)
-
-// TODO change this
-
-extern void TC5_Handler();
-extern void TC7_Handler();
-#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() void TC5_Handler()
-#endif
-#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() void TC7_Handler()
-#endif
-
-// ------------------------
-// Types
-// ------------------------
-
-typedef struct {
- TIM_HandleTypeDef timerdef;
- IRQn_Type IRQ_Id;
- uint32_t callback;
-} tTimerConfig;
-
-// ------------------------
-// Public Variables
-// ------------------------
-
-//extern const tTimerConfig timerConfig[];
-
-// ------------------------
-// Public functions
-// ------------------------
-
-void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
-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);
-
-void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare);
-hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
-uint32_t HAL_timer_get_count(const uint8_t timer_num);
-void HAL_timer_isr_prologue(const uint8_t timer_num);
-#define HAL_timer_isr_epilogue(TIMER_NUM)
diff --git a/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp
deleted file mode 100644
index e0726c7cd5..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/**
- ******************************************************************************
- * @file eeprom_emul.cpp
- * @author MCD Application Team
- * @version V1.2.6
- * @date 04-November-2016
- * @brief This file provides all the EEPROM emulation firmware functions.
- ******************************************************************************
- * @attention
- *
- * Copyright © 2016 STMicroelectronics International N.V.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted, provided that the following conditions are met:
- *
- * 1. Redistribution of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of other
- * contributors to this software may be used to endorse or promote products
- * derived from this software without specific written permission.
- * 4. This software, including modifications and/or derivative works of this
- * software, must execute solely and exclusively on microcontroller or
- * microprocessor devices manufactured by or for STMicroelectronics.
- * 5. Redistribution and use of this software other than as permitted under
- * this license is void and will automatically terminate your rights under
- * this license.
- *
- * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
- * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
- * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-/** @addtogroup EEPROM_Emulation
- * @{
- */
-#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(FLASH_EEPROM_EMULATION)
-
-/* Includes ------------------------------------------------------------------*/
-#include "eeprom_emul.h"
-
-/* Private variables ---------------------------------------------------------*/
-
-/* Global variable used to store variable value in read sequence */
-uint16_t DataVar = 0;
-
-/* Virtual address defined by the user: 0xFFFF value is prohibited */
-uint16_t VirtAddVarTab[NB_OF_VAR];
-
-/* Private function prototypes -----------------------------------------------*/
-
-static HAL_StatusTypeDef EE_Format();
-static uint16_t EE_FindValidPage(uint8_t Operation);
-static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
-static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
-static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
-
- /**
- * @brief Restore the pages to a known good state in case of page's status
- * corruption after a power loss.
- * @param None.
- * @retval - Flash error code: on write Flash error
- * - FLASH_COMPLETE: on success
- */
-
-/* Private functions ---------------------------------------------------------*/
-
-uint16_t EE_Initialize() {
- /* Get Page0 and Page1 status */
- uint16_t PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS),
- PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
-
- FLASH_EraseInitTypeDef pEraseInit;
- pEraseInit.TypeErase = TYPEERASE_SECTORS;
- pEraseInit.Sector = PAGE0_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
-
- HAL_StatusTypeDef FlashStatus; // = HAL_OK
-
- /* Check for invalid header states and repair if necessary */
- uint32_t SectorError;
- switch (PageStatus0) {
- case ERASED:
- if (PageStatus1 == VALID_PAGE) { /* Page0 erased, Page1 valid */
- /* Erase Page0 */
- if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
- /* As the last operation, simply return the result */
- return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- }
- }
- else if (PageStatus1 == RECEIVE_DATA) { /* Page0 erased, Page1 receive */
- /* Erase Page0 */
- if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
- HAL_StatusTypeDef fStat = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- /* If erase operation was failed, a Flash error code is returned */
- if (fStat != HAL_OK) return fStat;
- }
- /* Mark Page1 as valid */
- /* As the last operation, simply return the result */
- return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
- }
- else { /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
- /* Erase both Page0 and Page1 and set Page0 as valid page */
- /* As the last operation, simply return the result */
- return EE_Format();
- }
- break;
-
- case RECEIVE_DATA:
- if (PageStatus1 == VALID_PAGE) { /* Page0 receive, Page1 valid */
- /* Transfer data from Page1 to Page0 */
- int16_t x = -1;
- for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
- if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
- x = VarIdx;
- if (VarIdx != x) {
- /* Read the last variables' updates */
- uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
- /* In case variable corresponding to the virtual address was found */
- if (ReadStatus != 0x1) {
- /* Transfer the variable to the Page0 */
- uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
- /* If program operation was failed, a Flash error code is returned */
- if (EepromStatus != HAL_OK) return EepromStatus;
- }
- }
- }
- /* Mark Page0 as valid */
- FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
- /* If program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- pEraseInit.Sector = PAGE1_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
- /* Erase Page1 */
- if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
- /* As the last operation, simply return the result */
- return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- }
- }
- else if (PageStatus1 == ERASED) { /* Page0 receive, Page1 erased */
- pEraseInit.Sector = PAGE1_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
- /* Erase Page1 */
- if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
- HAL_StatusTypeDef fStat = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- /* If erase operation was failed, a Flash error code is returned */
- if (fStat != HAL_OK) return fStat;
- }
- /* Mark Page0 as valid */
- /* As the last operation, simply return the result */
- return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
- }
- else { /* Invalid state -> format eeprom */
- /* Erase both Page0 and Page1 and set Page0 as valid page */
- /* As the last operation, simply return the result */
- return EE_Format();
- }
- break;
-
- case VALID_PAGE:
- if (PageStatus1 == VALID_PAGE) { /* Invalid state -> format eeprom */
- /* Erase both Page0 and Page1 and set Page0 as valid page */
- FlashStatus = EE_Format();
- /* If erase/program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- }
- else if (PageStatus1 == ERASED) { /* Page0 valid, Page1 erased */
- pEraseInit.Sector = PAGE1_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
- /* Erase Page1 */
- if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
- FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- /* If erase operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- }
- }
- else { /* Page0 valid, Page1 receive */
- /* Transfer data from Page0 to Page1 */
- int16_t x = -1;
- for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
- if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
- x = VarIdx;
-
- if (VarIdx != x) {
- /* Read the last variables' updates */
- uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
- /* In case variable corresponding to the virtual address was found */
- if (ReadStatus != 0x1) {
- /* Transfer the variable to the Page1 */
- uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
- /* If program operation was failed, a Flash error code is returned */
- if (EepromStatus != HAL_OK) return EepromStatus;
- }
- }
- }
- /* Mark Page1 as valid */
- FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
- /* If program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- pEraseInit.Sector = PAGE0_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
- /* Erase Page0 */
- if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
- /* As the last operation, simply return the result */
- return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- }
- }
- break;
-
- default: /* Any other state -> format eeprom */
- /* Erase both Page0 and Page1 and set Page0 as valid page */
- /* As the last operation, simply return the result */
- return EE_Format();
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Verify if specified page is fully erased.
- * @param Address: page address
- * This parameter can be one of the following values:
- * @arg PAGE0_BASE_ADDRESS: Page0 base address
- * @arg PAGE1_BASE_ADDRESS: Page1 base address
- * @retval page fully erased status:
- * - 0: if Page not erased
- * - 1: if Page erased
- */
-uint16_t EE_VerifyPageFullyErased(uint32_t Address) {
- uint32_t ReadStatus = 1;
- /* Check each active page address starting from end */
- while (Address <= PAGE0_END_ADDRESS) {
- /* Get the current location content to be compared with virtual address */
- uint16_t AddressValue = (*(__IO uint16_t*)Address);
- /* Compare the read address with the virtual address */
- if (AddressValue != ERASED) {
- /* In case variable value is read, reset ReadStatus flag */
- ReadStatus = 0;
- break;
- }
- /* Next address location */
- Address += 4;
- }
- /* Return ReadStatus value: (0: Page not erased, 1: Sector erased) */
- return ReadStatus;
-}
-
-/**
- * @brief Returns the last stored variable data, if found, which correspond to
- * the passed virtual address
- * @param VirtAddress: Variable virtual address
- * @param Data: Global variable contains the read variable value
- * @retval Success or error status:
- * - 0: if variable was found
- * - 1: if the variable was not found
- * - NO_VALID_PAGE: if no valid page was found.
- */
-uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) {
- uint16_t ReadStatus = 1;
-
- /* Get active Page for read operation */
- uint16_t ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
-
- /* Check if there is no valid page */
- if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
-
- /* Get the valid Page start and end Addresses */
- uint32_t PageStartAddress = uint32_t(EEPROM_START_ADDRESS) + uint32_t(ValidPage * (PAGE_SIZE)),
- Address = PageStartAddress + PAGE_SIZE - 2;
-
- /* Check each active page address starting from end */
- while (Address > PageStartAddress + 2) {
- /* Get the current location content to be compared with virtual address */
- uint16_t AddressValue = (*(__IO uint16_t*)Address);
-
- /* Compare the read address with the virtual address */
- if (AddressValue == VirtAddress) {
- /* Get content of Address-2 which is variable value */
- *Data = (*(__IO uint16_t*)(Address - 2));
- /* In case variable value is read, reset ReadStatus flag */
- ReadStatus = 0;
- break;
- }
- else /* Next address location */
- Address -= 4;
- }
- /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
- return ReadStatus;
-}
-
-/**
- * @brief Writes/upadtes variable data in EEPROM.
- * @param VirtAddress: Variable virtual address
- * @param Data: 16 bit data to be written
- * @retval Success or error status:
- * - FLASH_COMPLETE: on success
- * - PAGE_FULL: if valid page is full
- * - NO_VALID_PAGE: if no valid page was found
- * - Flash error code: on write Flash error
- */
-uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) {
- /* Write the variable virtual address and value in the EEPROM */
- uint16_t Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
-
- /* In case the EEPROM active page is full */
- if (Status == PAGE_FULL) /* Perform Page transfer */
- Status = EE_PageTransfer(VirtAddress, Data);
-
- /* Return last operation status */
- return Status;
-}
-
-/**
- * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE
- * @param None
- * @retval Status of the last operation (Flash write or erase) done during
- * EEPROM formatting
- */
-static HAL_StatusTypeDef EE_Format() {
- FLASH_EraseInitTypeDef pEraseInit;
- pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
- pEraseInit.Sector = PAGE0_ID;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
-
- HAL_StatusTypeDef FlashStatus; // = HAL_OK
-
- /* Erase Page0 */
- if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
- uint32_t SectorError;
- FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- /* If erase operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- }
- /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
- FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
- /* If program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
-
- pEraseInit.Sector = PAGE1_ID;
- /* Erase Page1 */
- if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
- /* As the last operation, just return the result code */
- uint32_t SectorError;
- return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- }
-
- return HAL_OK;
-}
-
-/**
- * @brief Find valid Page for write or read operation
- * @param Operation: operation to achieve on the valid page.
- * This parameter can be one of the following values:
- * @arg READ_FROM_VALID_PAGE: read operation from valid page
- * @arg WRITE_IN_VALID_PAGE: write operation from valid page
- * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case
- * of no valid page was found
- */
-static uint16_t EE_FindValidPage(uint8_t Operation) {
- /* Get Page0 and Page1 actual status */
- uint16_t PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS),
- PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
-
- /* Write or read operation */
- switch (Operation) {
- case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
- if (PageStatus1 == VALID_PAGE) {
- /* Page0 receiving data */
- return (PageStatus0 == RECEIVE_DATA) ? PAGE0 : PAGE1;
- }
- else if (PageStatus0 == VALID_PAGE) {
- /* Page1 receiving data */
- return (PageStatus1 == RECEIVE_DATA) ? PAGE1 : PAGE0;
- }
- else
- return NO_VALID_PAGE; /* No valid Page */
-
- case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
- if (PageStatus0 == VALID_PAGE)
- return PAGE0; /* Page0 valid */
- else if (PageStatus1 == VALID_PAGE)
- return PAGE1; /* Page1 valid */
- else
- return NO_VALID_PAGE; /* No valid Page */
-
- default:
- return PAGE0; /* Page0 valid */
- }
-}
-
-/**
- * @brief Verify if active page is full and Writes variable in EEPROM.
- * @param VirtAddress: 16 bit virtual address of the variable
- * @param Data: 16 bit data to be written as variable value
- * @retval Success or error status:
- * - FLASH_COMPLETE: on success
- * - PAGE_FULL: if valid page is full
- * - NO_VALID_PAGE: if no valid page was found
- * - Flash error code: on write Flash error
- */
-static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) {
- /* Get valid Page for write operation */
- uint16_t ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
-
- /* Check if there is no valid page */
- if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
-
- /* Get the valid Page start and end Addresses */
- uint32_t Address = uint32_t(EEPROM_START_ADDRESS) + uint32_t(ValidPage * (PAGE_SIZE)),
- PageEndAddress = Address + PAGE_SIZE - 1;
-
- /* Check each active page address starting from begining */
- while (Address < PageEndAddress) {
- /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
- if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) {
- /* Set variable data */
- HAL_StatusTypeDef FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
- /* If program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
- /* Set variable virtual address, return status */
- return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
- }
- else /* Next address location */
- Address += 4;
- }
-
- /* Return PAGE_FULL in case the valid page is full */
- return PAGE_FULL;
-}
-
-/**
- * @brief Transfers last updated variables data from the full Page to
- * an empty one.
- * @param VirtAddress: 16 bit virtual address of the variable
- * @param Data: 16 bit data to be written as variable value
- * @retval Success or error status:
- * - FLASH_COMPLETE: on success
- * - PAGE_FULL: if valid page is full
- * - NO_VALID_PAGE: if no valid page was found
- * - Flash error code: on write Flash error
- */
-static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) {
- /* Get active Page for read operation */
- uint16_t ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
- uint32_t NewPageAddress = EEPROM_START_ADDRESS;
- uint16_t OldPageId = 0;
-
- if (ValidPage == PAGE1) { /* Page1 valid */
- /* New page address where variable will be moved to */
- NewPageAddress = PAGE0_BASE_ADDRESS;
- /* Old page ID where variable will be taken from */
- OldPageId = PAGE1_ID;
- }
- else if (ValidPage == PAGE0) { /* Page0 valid */
- /* New page address where variable will be moved to */
- NewPageAddress = PAGE1_BASE_ADDRESS;
- /* Old page ID where variable will be taken from */
- OldPageId = PAGE0_ID;
- }
- else
- return NO_VALID_PAGE; /* No valid Page */
-
- /* Set the new Page status to RECEIVE_DATA status */
- HAL_StatusTypeDef FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
- /* If program operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
-
- /* Write the variable passed as parameter in the new active page */
- uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
- /* If program operation was failed, a Flash error code is returned */
- if (EepromStatus != HAL_OK) return EepromStatus;
-
- /* Transfer process: transfer variables from old to the new active page */
- for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
- if (VirtAddVarTab[VarIdx] != VirtAddress) { /* Check each variable except the one passed as parameter */
- /* Read the other last variable updates */
- uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
- /* In case variable corresponding to the virtual address was found */
- if (ReadStatus != 0x1) {
- /* Transfer the variable to the new active page */
- EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
- /* If program operation was failed, a Flash error code is returned */
- if (EepromStatus != HAL_OK) return EepromStatus;
- }
- }
- }
-
- FLASH_EraseInitTypeDef pEraseInit;
- pEraseInit.TypeErase = TYPEERASE_SECTORS;
- pEraseInit.Sector = OldPageId;
- pEraseInit.NbSectors = 1;
- pEraseInit.VoltageRange = VOLTAGE_RANGE;
-
- /* Erase the old Page: Set old Page status to ERASED status */
- uint32_t SectorError;
- FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
- /* If erase operation was failed, a Flash error code is returned */
- if (FlashStatus != HAL_OK) return FlashStatus;
-
- /* Set new Page status to VALID_PAGE status */
- /* As the last operation, just return the result code */
- return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
-}
-
-#endif // FLASH_EEPROM_EMULATION
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
-
-/**
- * @}
- */
-
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h b/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h
deleted file mode 100644
index 84c4c6e3d2..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/eeprom_emul.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/******************************************************************************
- * @file eeprom_emul.h
- * @author MCD Application Team
- * @version V1.2.6
- * @date 04-November-2016
- * @brief This file contains all the functions prototypes for the EEPROM
- * emulation firmware library.
- ******************************************************************************
- * @attention
- *
- * Copyright © 2016 STMicroelectronics International N.V.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted, provided that the following conditions are met:
- *
- * 1. Redistribution of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of other
- * contributors to this software may be used to endorse or promote products
- * derived from this software without specific written permission.
- * 4. This software, including modifications and/or derivative works of this
- * software, must execute solely and exclusively on microcontroller or
- * microprocessor devices manufactured by or for STMicroelectronics.
- * 5. Redistribution and use of this software other than as permitted under
- * this license is void and will automatically terminate your rights under
- * this license.
- *
- * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
- * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
- * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************/
-#pragma once
-
-// ------------------------
-// Includes
-// ------------------------
-
-#include "../../inc/MarlinConfig.h"
-
-/* Exported constants --------------------------------------------------------*/
-/* EEPROM emulation firmware error codes */
-#define EE_OK uint32_t(HAL_OK)
-#define EE_ERROR uint32_t(HAL_ERROR)
-#define EE_BUSY uint32_t(HAL_BUSY)
-#define EE_TIMEOUT uint32_t(HAL_TIMEOUT)
-
-/* Define the size of the sectors to be used */
-#define PAGE_SIZE uint32_t(0x4000) /* Page size = 16KByte */
-
-/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
- be done by word */
-#define VOLTAGE_RANGE uint8_t(VOLTAGE_RANGE_3)
-
-/* EEPROM start address in Flash */
-#ifdef STM32F7
- #define EEPROM_START_ADDRESS uint32_t(0x08100000) /* EEPROM emulation start address:
- from sector2 : after 16KByte of used
- Flash memory */
-#else
- #define EEPROM_START_ADDRESS uint32_t(0x08078000) /* EEPROM emulation start address:
- after 480KByte of used Flash memory */
-#endif
-
-/* Pages 0 and 1 base and end addresses */
-#define PAGE0_BASE_ADDRESS uint32_t(EEPROM_START_ADDRESS + 0x0000)
-#define PAGE0_END_ADDRESS uint32_t(EEPROM_START_ADDRESS + PAGE_SIZE - 1)
-#define PAGE0_ID FLASH_SECTOR_1
-
-#define PAGE1_BASE_ADDRESS uint32_t(EEPROM_START_ADDRESS + 0x4000)
-#define PAGE1_END_ADDRESS uint32_t(EEPROM_START_ADDRESS + 2 * (PAGE_SIZE) - 1)
-#define PAGE1_ID FLASH_SECTOR_2
-
-/* Used Flash pages for EEPROM emulation */
-#define PAGE0 uint16_t(0x0000)
-#define PAGE1 uint16_t(0x0001) /* Page nb between PAGE0_BASE_ADDRESS & PAGE1_BASE_ADDRESS*/
-
-/* No valid page define */
-#define NO_VALID_PAGE uint16_t(0x00AB)
-
-/* Page status definitions */
-#define ERASED uint16_t(0xFFFF) /* Page is empty */
-#define RECEIVE_DATA uint16_t(0xEEEE) /* Page is marked to receive data */
-#define VALID_PAGE uint16_t(0x0000) /* Page containing valid data */
-
-/* Valid pages in read and write defines */
-#define READ_FROM_VALID_PAGE uint8_t(0x00)
-#define WRITE_IN_VALID_PAGE uint8_t(0x01)
-
-/* Page full define */
-#define PAGE_FULL uint8_t(0x80)
-
-/* Variables' number */
-#define NB_OF_VAR uint16_t(4096)
-
-/* Exported functions ------------------------------------------------------- */
-uint16_t EE_Initialize();
-uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
-uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp
deleted file mode 100644
index 00b808fd48..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/eeprom_flash.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * 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