diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index d87d10569d..7549e3defc 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -48,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
@@ -64,38 +64,37 @@ 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
#- STM32F103CB_malyan
diff --git a/.gitignore b/.gitignore
index 62f73a7c0d..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
diff --git a/Makefile b/Makefile
index 8e1c77aa99..ebcdf25e2d 100644
--- a/Makefile
+++ b/Makefile
@@ -27,8 +27,6 @@ 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
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
@@ -40,8 +38,6 @@ tests-single-local-docker:
.PHONY: tests-single-local-docker
tests-all-local:
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
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
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index fe19ab5e89..77ce26e435 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -160,15 +160,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
@@ -558,7 +558,7 @@
#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
@@ -1153,11 +1153,6 @@
*/
#define BLTOUCH
-/**
- * Pressure sensor with a BLTouch-like interface
- */
-//#define CREALITY_TOUCH
-
/**
* Touch-MI Probe by hotends.fr
*
@@ -1211,10 +1206,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
@@ -1254,12 +1259,39 @@
// X and Y axis travel speed (mm/m) between probes
#define XY_PROBE_SPEED 10000
-// Feedrate (mm/m) for the first approach when double-probing (MULTIPLE_PROBING == 2)
-#define Z_PROBE_SPEED_FAST (HOMING_FEEDRATE_Z * 2)
+// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
+#define Z_PROBE_SPEED_FAST (4*60)
// Feedrate (mm/m) for the "accurate" probe of each point
#define Z_PROBE_SPEED_SLOW Z_PROBE_SPEED_FAST
+/**
+ * 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
*
@@ -1321,6 +1353,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
@@ -1381,8 +1420,8 @@
// @section homing
-//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed
-
+//#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, ...
@@ -1476,26 +1515,41 @@
#else
#define FIL_RUNOUT_STATE LOW // set to true to invert the logic of the sensor.
#endif
- #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
- #define FIL_RUNOUT_PULL // Use internal pullup / pulldown for filament runout pins.
+ #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
+ //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
// Override individually if the runout sensors vary
//#define FIL_RUNOUT1_STATE LOW
- //#define FIL_RUNOUT1_PULL
+ //#define FIL_RUNOUT1_PULLUP
+ //#define FIL_RUNOUT1_PULLDOWN
+
//#define FIL_RUNOUT2_STATE LOW
- //#define FIL_RUNOUT2_PULL
+ //#define FIL_RUNOUT2_PULLUP
+ //#define FIL_RUNOUT2_PULLDOWN
+
//#define FIL_RUNOUT3_STATE LOW
- //#define FIL_RUNOUT3_PULL
+ //#define FIL_RUNOUT3_PULLUP
+ //#define FIL_RUNOUT3_PULLDOWN
+
//#define FIL_RUNOUT4_STATE LOW
- //#define FIL_RUNOUT4_PULL
+ //#define FIL_RUNOUT4_PULLUP
+ //#define FIL_RUNOUT4_PULLDOWN
+
//#define FIL_RUNOUT5_STATE LOW
- //#define FIL_RUNOUT5_PULL
+ //#define FIL_RUNOUT5_PULLUP
+ //#define FIL_RUNOUT5_PULLDOWN
+
//#define FIL_RUNOUT6_STATE LOW
- //#define FIL_RUNOUT6_PULL
+ //#define FIL_RUNOUT6_PULLUP
+ //#define FIL_RUNOUT6_PULLDOWN
+
//#define FIL_RUNOUT7_STATE LOW
- //#define FIL_RUNOUT7_PULL
+ //#define FIL_RUNOUT7_PULLUP
+ //#define FIL_RUNOUT7_PULLDOWN
+
//#define FIL_RUNOUT8_STATE LOW
- //#define FIL_RUNOUT8_PULL
+ //#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.)
@@ -1569,10 +1623,21 @@
//#define MESH_BED_LEVELING
/**
- * 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.
@@ -1586,6 +1651,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
@@ -1599,10 +1667,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
@@ -1687,6 +1756,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
/**
@@ -1723,8 +1817,7 @@
#endif
// Homing speeds (mm/min)
-#define HOMING_FEEDRATE_XY (50*60)
-#define HOMING_FEEDRATE_Z (4*60)
+#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -1932,6 +2025,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"
@@ -1967,6 +2064,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
@@ -2011,9 +2111,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
@@ -2056,16 +2156,6 @@
*/
#define SDSUPPORT
-/**
- * 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
*
@@ -2596,6 +2686,16 @@
//
//#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
//
@@ -2628,6 +2728,10 @@
//#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:
*
@@ -2661,6 +2765,7 @@
//#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
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 98f762086d..a9de1c418b 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -163,7 +163,7 @@
#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 LOW_EXCESS_HEAT_LIMIT 3
#define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
#define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
#endif
@@ -284,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
@@ -558,7 +558,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_
@@ -568,7 +568,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_
@@ -586,6 +586,11 @@
#endif
#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_
@@ -813,10 +818,10 @@
//#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 for probe points.
+ #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } }
- // Define positions names for probing points.
+ // 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"
@@ -825,8 +830,8 @@
#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
- //#define ASSISTED_TRAMMING_MENU_ITEM // Add a menu item to run G35 Assisted Tramming (MarlinUI)
- //#define ASSISTED_TRAMMING_WIZARD // Make the menu item open a Tramming Wizard sub-menu
+ //#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
/**
@@ -866,8 +871,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.
@@ -1039,7 +1042,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
@@ -1072,7 +1075,7 @@
#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)
+ #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
@@ -1099,8 +1102,15 @@
#if HAS_BED_PROBE
//#define PROBE_OFFSET_WIZARD
#if ENABLED(PROBE_OFFSET_WIZARD)
- #define PROBE_OFFSET_START -4.0 // Estimated nozzle-to-probe Z offset, plus a little extra
- //#define PROBE_OFFSET_WIZARD_XY_POS XY_CENTER // Set a convenient position to do the measurement
+ //
+ // 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
@@ -1144,33 +1154,38 @@
#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
-#define LCD_SET_PROGRESS_MANUALLY
+ // On the Info Screen, display XY with one decimal place when possible
+ //#define LCD_DECIMAL_SMALL_XY
-// Show the E position (filament used) during printing
-//#define LCD_SHOW_E_TOTAL
+ // Add an 'M73' G-code to set the current percentage
+ #define LCD_SET_PROGRESS_MANUALLY
-#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) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
+#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_MARLINUI_U8GLIB
+ #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
#endif
@@ -1187,6 +1202,16 @@
#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.
@@ -1195,6 +1220,8 @@
//#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
@@ -1206,6 +1233,7 @@
#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
@@ -1234,7 +1262,8 @@
#define POWER_LOSS_PIN -1 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
#define POWER_LOSS_STATE LOW // State of pin indicating power loss
#endif
- //#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.
@@ -1329,9 +1358,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
*
@@ -1342,7 +1368,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
/**
@@ -1368,13 +1405,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
/**
@@ -1509,6 +1549,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)
//
@@ -1576,18 +1629,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
@@ -1749,6 +1798,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.
@@ -2040,21 +2093,21 @@
#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
@@ -3072,6 +3125,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)
@@ -3306,6 +3363,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
@@ -3625,10 +3684,7 @@
//#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
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 ce15ed29fb..2b565bbe13 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -82,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."
@@ -97,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."
@@ -122,12 +137,16 @@ inline uint8_t HAL_get_reset_source() { return MCUSR; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- int freeMemory();
-}
-#pragma GCC diagnostic pop
+#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/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/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/DUE/HAL.cpp b/Marlin/src/HAL/DUE/HAL.cpp
index 6ce85a4643..2ae70843f0 100644
--- a/Marlin/src/HAL/DUE/HAL.cpp
+++ b/Marlin/src/HAL/DUE/HAL.cpp
@@ -102,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 88ace59575..78c8a800b9 100644
--- a/Marlin/src/HAL/DUE/HAL.h
+++ b/Marlin/src/HAL/DUE/HAL.h
@@ -36,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)
@@ -59,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
@@ -75,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
@@ -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 0451d8bcc4..342c373735 100644
--- a/Marlin/src/HAL/DUE/HAL_SPI.cpp
+++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp
@@ -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);
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 be4b49c0f9..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
@@ -64,12 +64,11 @@
#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) {
@@ -100,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) */
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 ea7204fa36..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
@@ -59,9 +59,6 @@
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
-
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
#include "../../shared/Marduino.h"
diff --git a/Marlin/src/HAL/DUE/fastio.h b/Marlin/src/HAL/DUE/fastio.h
index 5fb8b4d015..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
/**
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/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 9b937d1a7c..65073c510d 100644
--- a/Marlin/src/HAL/DUE/timers.cpp
+++ b/Marlin/src/HAL/DUE/timers.cpp
@@ -121,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/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
index db5e82ec55..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
@@ -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
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 ead448d78d..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
// ------------------------
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index ebc16c9525..3dc27c6493 100644
--- a/Marlin/src/HAL/ESP32/HAL.h
+++ b/Marlin/src/HAL/ESP32/HAL.h
@@ -55,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
@@ -67,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
// ------------------------
@@ -90,6 +88,13 @@ 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();
@@ -100,10 +105,16 @@ 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);
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/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 7d35186b1c..a47697113d 100644
--- a/Marlin/src/HAL/ESP32/timers.h
+++ b/Marlin/src/HAL/ESP32/timers.h
@@ -44,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
@@ -59,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
@@ -90,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/HAL.h b/Marlin/src/HAL/HAL.h
index 5eca2f7eac..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
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 1c8dbfd4dc..e4f4dd3fc3 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -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
@@ -107,8 +113,3 @@ inline void HAL_reboot() {} // reboot the board or restart the bootloader
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/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 e916249389..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
@@ -73,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;
@@ -100,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();
@@ -117,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 eadc409324..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
diff --git a/Marlin/src/HAL/LINUX/spi_pins.h b/Marlin/src/HAL/LINUX/spi_pins.h
index 01ba28e5b6..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_MARLINUI_U8GLIB, 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/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 cb637e715d..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
@@ -201,8 +217,3 @@ void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
inline void HAL_reboot() {} // reboot the board or restart the bootloader
-
-// Add strcmp_P if missing
-#ifndef strcmp_P
- #define strcmp_P(a, b) strcmp((a), (b))
-#endif
diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
index 16ac789fc0..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);
@@ -150,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
@@ -392,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/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/eeprom_flash.cpp b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
index 3c0c3c8ec3..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.
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_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 21d149fcaf..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
@@ -116,8 +116,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#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
@@ -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/main.cpp b/Marlin/src/HAL/LPC1768/main.cpp
index 085b8ce04b..f41a576376 100644
--- a/Marlin/src/HAL/LPC1768/main.cpp
+++ b/Marlin/src/HAL/LPC1768/main.cpp
@@ -31,18 +31,18 @@
#include
#include
-extern "C" {
- #include
-}
-
#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(); }
@@ -90,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
diff --git a/Marlin/src/HAL/LPC1768/spi_pins.h b/Marlin/src/HAL/LPC1768/spi_pins.h
index b4da5d4df2..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_MARLINUI_U8GLIB) && (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/xpt2046.h b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
index 29db0b3fc4..65602bda0f 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.h
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
@@ -28,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 e6744fb005..4b63854685 100644
--- a/Marlin/src/HAL/LPC1768/timers.h
+++ b/Marlin/src/HAL/LPC1768/timers.h
@@ -152,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 057e10e0f5..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
@@ -62,10 +62,13 @@
#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) */
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 ca9d6ecfbe..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
@@ -60,9 +60,11 @@
#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;
diff --git a/Marlin/src/HAL/SAMD51/HAL.cpp b/Marlin/src/HAL/SAMD51/HAL.cpp
index d985ef3787..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
// ------------------------
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index 7cb3635bd7..f28583c771 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -32,15 +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
@@ -49,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
@@ -57,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
@@ -135,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/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/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/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp
index c886f9c0b9..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
diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h
index c92c8890ea..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
@@ -156,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();
diff --git a/Marlin/src/HAL/STM32/HAL_SPI.cpp b/Marlin/src/HAL/STM32/HAL_SPI.cpp
index f947e6ef32..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,8 +132,8 @@ static SPISettings spiConfig;
* @details Only configures SS pin since stm32duino 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
}
@@ -154,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();
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.cpp b/Marlin/src/HAL/STM32/MarlinSPI.cpp
index da11b88a60..5086b41784 100644
--- a/Marlin/src/HAL/STM32/MarlinSPI.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSPI.cpp
@@ -19,7 +19,6 @@
* along with this program. If not, see .
*
*/
-
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "MarlinSPI.h"
@@ -61,7 +60,6 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
}
#ifdef STM32F4xx
- _dmaHandle.Init.Channel = DMA_CHANNEL_3;
_dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
#endif
@@ -74,7 +72,8 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
- _dmaHandle.Instance = DMA2_Stream3;
+ _dmaHandle.Init.Channel = DMA_CHANNEL_3;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
#endif
}
#endif
@@ -84,7 +83,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
#elif defined(STM32F4xx)
- //TODO: f4 dma config
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
#endif
}
#endif
@@ -94,7 +95,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
#elif defined(STM32F4xx)
- //TODO: f4 dma config
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
#endif
}
#endif
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 9c2666ed26..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
@@ -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 702e42e561..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))
@@ -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
diff --git a/Marlin/src/HAL/STM32/eeprom_sdcard.cpp b/Marlin/src/HAL/STM32/eeprom_sdcard.cpp
index c9180bf09b..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)
@@ -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/fast_pwm.cpp b/Marlin/src/HAL/STM32/fast_pwm.cpp
index 99101c6e81..42eecb5e1a 100644
--- a/Marlin/src/HAL/STM32/fast_pwm.cpp
+++ b/Marlin/src/HAL/STM32/fast_pwm.cpp
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfigPre.h"
@@ -55,3 +56,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
}
#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 ea28b8f3bf..17751c44dd 100644
--- a/Marlin/src/HAL/STM32/fastio.h
+++ b/Marlin/src/HAL/STM32/fastio.h
@@ -59,7 +59,7 @@ void FastIO_init(); // Must be called before using fast io macros
#endif
#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO)))))
-#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR ^= _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)
diff --git a/Marlin/src/HAL/STM32/inc/SanityCheck.h b/Marlin/src/HAL/STM32/inc/SanityCheck.h
index c51fecc7bd..4df75a0505 100644
--- a/Marlin/src/HAL/STM32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32/inc/SanityCheck.h
@@ -51,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 71480153a7..0000000000
--- a/Marlin/src/HAL/STM32/pinsDebug_STM32duino.h
+++ /dev/null
@@ -1,273 +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 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
- #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 = digitalPinToPinName(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 = 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;
- }
- }
-} // 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 e2e0128c5e..2200abaa10 100644
--- a/Marlin/src/HAL/STM32/tft/tft_fsmc.h
+++ b/Marlin/src/HAL/STM32/tft/tft_fsmc.h
@@ -25,10 +25,8 @@
#ifdef STM32F1xx
#include "stm32f1xx_hal.h"
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
- #define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#else
#error "FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware."
#endif
@@ -44,9 +42,12 @@
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_FSMC
+#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 {
@@ -56,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:
@@ -66,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)
@@ -98,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}
@@ -121,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 d477b58c00..667b5f366b 100644
--- a/Marlin/src/HAL/STM32/tft/tft_spi.h
+++ b/Marlin/src/HAL/STM32/tft/tft_spi.h
@@ -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 f95bb8ca4d..04294e669c 100644
--- a/Marlin/src/HAL/STM32/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/STM32/tft/xpt2046.cpp
@@ -19,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"
@@ -30,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;
@@ -70,34 +70,16 @@ 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
}
@@ -106,7 +88,6 @@ void XPT2046::Init() {
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);
@@ -186,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 3acf3898a3..5b8acf4b87 100644
--- a/Marlin/src/HAL/STM32/tft/xpt2046.h
+++ b/Marlin/src/HAL/STM32/tft/xpt2046.h
@@ -60,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 90f8c3dc94..e8e18a47d4 100644
--- a/Marlin/src/HAL/STM32/timers.cpp
+++ b/Marlin/src/HAL/STM32/timers.cpp
@@ -27,7 +27,6 @@
// Local defines
// ------------------------
-
// 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
@@ -96,11 +95,6 @@
#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
// ------------------------
@@ -197,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/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_F4_F7/inc/SanityCheck.h b/Marlin/src/HAL/STM32/usb_host.h
similarity index 50%
rename from Marlin/src/HAL/STM32_F4_F7/inc/SanityCheck.h
rename to Marlin/src/HAL/STM32/usb_host.h
index 9bb36f3bbb..c0001c0d75 100644
--- a/Marlin/src/HAL/STM32_F4_F7/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32/usb_host.h
@@ -21,21 +21,40 @@
*/
#pragma once
-/**
- * Test STM32F4/7-specific configuration values for errors at compile-time.
- */
-//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
-// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
-//#endif
+#include
-#if ENABLED(EMERGENCY_PARSER)
- #error "EMERGENCY_PARSER is not yet implemented for STM32F4/7. Disable EMERGENCY_PARSER to continue."
-#endif
+typedef enum {
+ USB_STATE_INIT,
+ USB_STATE_ERROR,
+ USB_STATE_RUNNING,
+} usb_state_t;
-#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
- #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32F4/F7."
-#endif
+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;
+};
-#if HAS_TMC_SW_SERIAL
- #error "TMC220x Software Serial is not supported on this platform."
-#endif
+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 25c47d694f..705d649ff5 100644
--- a/Marlin/src/HAL/STM32/usb_serial.cpp
+++ b/Marlin/src/HAL/STM32/usb_serial.cpp
@@ -16,7 +16,6 @@
* along with this program. If not, see .
*
*/
-
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfigPre.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 3d83408311..aad0a79a0c 100644
--- a/Marlin/src/HAL/STM32/watchdog.cpp
+++ b/Marlin/src/HAL/STM32/watchdog.cpp
@@ -46,5 +46,4 @@ void HAL_watchdog_refresh() {
}
#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 dfa99d83f4..c1e29a843c 100644
--- a/Marlin/src/HAL/STM32F1/HAL.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL.cpp
@@ -84,6 +84,7 @@
#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
USBSerial SerialUSB;
+ DefaultSerial MSerial(false, SerialUSB);
#endif
uint16_t HAL_adc_result;
diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h
index 2880865dbb..30bf60b6e8 100644
--- a/Marlin/src/HAL/STM32F1/HAL.h
+++ b/Marlin/src/HAL/STM32F1/HAL.h
@@ -61,8 +61,11 @@
#endif
#ifdef SERIAL_USB
+ typedef ForwardSerial0Type< USBSerial > DefaultSerial;
+ extern DefaultSerial MSerial;
+
#if !HAS_SD_HOST_DRIVE
- #define UsbSerial Serial
+ #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
@@ -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
@@ -200,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
diff --git a/Marlin/src/HAL/STM32F1/HAL_SPI.cpp b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
index 76b1c3e246..7e876f765f 100644
--- a/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL_SPI.cpp
@@ -61,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
}
diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
index 7c9625d64c..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); \
}
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/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/dogm/u8g_com_stm32duino_swspi.cpp b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
index 60596054e8..784a80c29f 100644
--- a/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
+++ b/Marlin/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp
@@ -23,12 +23,14 @@
#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI)
#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) {
@@ -104,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:
diff --git a/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
index 94b5e099bd..a6395698aa 100644
--- a/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
+++ b/Marlin/src/HAL/STM32F1/eeprom_bl24cxx.cpp
@@ -48,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;
@@ -55,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;
diff --git a/Marlin/src/HAL/STM32F1/eeprom_wired.cpp b/Marlin/src/HAL/STM32F1/eeprom_wired.cpp
index 6e992a22a3..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
diff --git a/Marlin/src/HAL/STM32F1/fastio.h b/Marlin/src/HAL/STM32F1/fastio.h
index a618fccc57..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)
diff --git a/Marlin/src/HAL/STM32F1/msc_sd.cpp b/Marlin/src/HAL/STM32F1/msc_sd.cpp
index 44242358ee..548a6dbc57 100644
--- a/Marlin/src/HAL/STM32F1/msc_sd.cpp
+++ b/Marlin/src/HAL/STM32F1/msc_sd.cpp
@@ -13,6 +13,8 @@
* along with this program. If not, see .
*
*/
+#include "../../inc/MarlinConfigPre.h"
+
#if defined(__STM32F1__) && HAS_SD_HOST_DRIVE
#include "msc_sd.h"
@@ -21,7 +23,7 @@
#define PRODUCT_ID 0x29
USBMassStorage MarlinMSC;
-MarlinUSBCompositeSerial MarlinCompositeSerial;
+Serial0Type MarlinCompositeSerial(true);
#include "../../inc/MarlinConfig.h"
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/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 59ac446410..7d650ffe37 100644
--- a/Marlin/src/HAL/STM32F1/spi_pins.h
+++ b/Marlin/src/HAL/STM32F1/spi_pins.h
@@ -31,23 +31,23 @@
* 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
#ifndef SPI_DEVICE
#define SPI_DEVICE 1
diff --git a/Marlin/src/HAL/STM32F1/tft/xpt2046.h b/Marlin/src/HAL/STM32F1/tft/xpt2046.h
index 29db0b3fc4..65602bda0f 100644
--- a/Marlin/src/HAL/STM32F1/tft/xpt2046.h
+++ b/Marlin/src/HAL/STM32F1/tft/xpt2046.h
@@ -28,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/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 00a65de792..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/HAL.h
+++ /dev/null
@@ -1,199 +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();
-
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
-
-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 e67808c3c4..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.cpp
+++ /dev/null
@@ -1,898 +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 208c3bc7e0..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/STM32F7/TMC2660.h
+++ /dev/null
@@ -1,593 +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 8c5795b685..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 .
- *
- */
-#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(FLASH_EEPROM_EMULATION)
-
-#include "../shared/eeprom_api.h"
-#include "eeprom_emul.h"
-
-// FLASH_FLAG_PGSERR (Programming Sequence Error) was renamed to
-// FLASH_FLAG_ERSERR (Erasing Sequence Error) in STM32F4/7
-
-#ifdef STM32F7
- #define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR
-#else
- //#define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR
-#endif
-
-void ee_write_byte(uint8_t *pos, unsigned char value) {
- HAL_FLASH_Unlock();
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
-
- const unsigned eeprom_address = (unsigned)pos;
- if (EE_WriteVariable(eeprom_address, uint16_t(value)) != EE_OK)
- for (;;) HAL_Delay(1); // Spin forever until watchdog reset
-
- HAL_FLASH_Lock();
-}
-
-uint8_t ee_read_byte(uint8_t *pos) {
- uint16_t data = 0xFF;
- const unsigned eeprom_address = (unsigned)pos;
- (void)EE_ReadVariable(eeprom_address, &data); // Data unchanged on error
- return uint8_t(data);
-}
-
-#ifndef MARLIN_EEPROM_SIZE
- #error "MARLIN_EEPROM_SIZE is required for Flash-based EEPROM."
-#endif
-size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
-
-bool PersistentStore::access_finish() { return true; }
-
-bool PersistentStore::access_start() {
- static bool ee_initialized = false;
- if (!ee_initialized) {
- HAL_FLASH_Unlock();
-
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
-
- /* EEPROM Init */
- if (EE_Initialize() != EE_OK)
- for (;;) HAL_Delay(1); // Spin forever until watchdog reset
-
- HAL_FLASH_Lock();
- ee_initialized = true;
- }
- return true;
-}
-
-bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
- while (size--) {
- uint8_t * const p = (uint8_t * const)pos;
- uint8_t v = *value;
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
- if (v != ee_read_byte(p)) {
- ee_write_byte(p, v);
- if (ee_read_byte(p) != v) {
- SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
- return true;
- }
- }
- crc16(crc, &v, 1);
- pos++;
- value++;
- }
- return false;
-}
-
-bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
- do {
- uint8_t c = ee_read_byte((uint8_t*)pos);
- if (writing) *value = c;
- crc16(crc, &c, 1);
- pos++;
- value++;
- } while (--size);
- return false;
-}
-
-#endif // FLASH_EEPROM_EMULATION
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
diff --git a/Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp b/Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp
deleted file mode 100644
index 2bf386bec5..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/eeprom_wired.cpp
+++ /dev/null
@@ -1,77 +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) 2016 Victor Perez victor_pv@hotmail.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-#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"
-
-#ifndef MARLIN_EEPROM_SIZE
- #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM."
-#endif
-size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
-
-bool PersistentStore::access_start() { eeprom_init(); return true; }
-bool PersistentStore::access_finish() { return true; }
-
-bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
- while (size--) {
- uint8_t * const p = (uint8_t * const)pos;
- uint8_t v = *value;
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
- if (v != eeprom_read_byte(p)) {
- eeprom_write_byte(p, v);
- if (eeprom_read_byte(p) != v) {
- SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
- return true;
- }
- }
- crc16(crc, &v, 1);
- pos++;
- value++;
- }
- return false;
-}
-
-bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
- do {
- uint8_t c = eeprom_read_byte((uint8_t*)pos);
- if (writing) *value = c;
- crc16(crc, &c, 1);
- pos++;
- value++;
- } while (--size);
- return false;
-}
-
-#endif // USE_WIRED_EEPROM
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
diff --git a/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h b/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h
deleted file mode 100644
index fdff8cc644..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/endstop_interrupts.h
+++ /dev/null
@@ -1,49 +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 .
- *
- */
-#pragma once
-
-#include "../../module/endstops.h"
-
-// One ISR for all EXT-Interrupts
-void endstop_ISR() { endstops.update(); }
-
-void setup_endstop_interrupts() {
- #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE)
- TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN));
- TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN));
- TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN));
- TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN));
- TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN));
- TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN));
- TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN));
- TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN));
- TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN));
- TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN));
- TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN));
- TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN));
- TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN));
- TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN));
- TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
- TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
- TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
-}
diff --git a/Marlin/src/HAL/STM32_F4_F7/fastio.h b/Marlin/src/HAL/STM32_F4_F7/fastio.h
deleted file mode 100644
index f42be58354..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/fastio.h
+++ /dev/null
@@ -1,310 +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 .
- *
- */
-#pragma once
-
-/**
- * Fast I/O interfaces for STM32F4/7
- * These use GPIO functions instead of Direct Port Manipulation, as on AVR.
- */
-
-#ifndef PWM
- #define PWM OUTPUT
-#endif
-
-#define READ(IO) digitalRead(IO)
-#define WRITE(IO,V) digitalWrite(IO,V)
-
-#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 OUT_WRITE(IO,V) do{ _SET_OUTPUT(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_OUTPUT(IO) OUT_WRITE(IO, LOW)
-#define SET_PWM(IO) _SET_MODE(IO, PWM)
-
-#define TOGGLE(IO) OUT_WRITE(IO, !READ(IO))
-
-#define IS_INPUT(IO)
-#define IS_OUTPUT(IO)
-
-#define PWM_PIN(P) true
-
-// digitalRead/Write wrappers
-#define extDigitalRead(IO) digitalRead(IO)
-#define extDigitalWrite(IO,V) digitalWrite(IO,V)
-
-//
-// Pins Definitions
-//
-#define PORTA 0
-#define PORTB 1
-#define PORTC 2
-#define PORTD 3
-#define PORTE 4
-#define PORTF 5
-#define PORTG 6
-
-#define _STM32_PIN(P,PN) ((PORT##P * 16) + PN)
-
-#undef PA0
-#define PA0 _STM32_PIN(A, 0)
-#undef PA1
-#define PA1 _STM32_PIN(A, 1)
-#undef PA2
-#define PA2 _STM32_PIN(A, 2)
-#undef PA3
-#define PA3 _STM32_PIN(A, 3)
-#undef PA4
-#define PA4 _STM32_PIN(A, 4)
-#undef PA5
-#define PA5 _STM32_PIN(A, 5)
-#undef PA6
-#define PA6 _STM32_PIN(A, 6)
-#undef PA7
-#define PA7 _STM32_PIN(A, 7)
-#undef PA8
-#define PA8 _STM32_PIN(A, 8)
-#undef PA9
-#define PA9 _STM32_PIN(A, 9)
-#undef PA10
-#define PA10 _STM32_PIN(A, 10)
-#undef PA11
-#define PA11 _STM32_PIN(A, 11)
-#undef PA12
-#define PA12 _STM32_PIN(A, 12)
-#undef PA13
-#define PA13 _STM32_PIN(A, 13)
-#undef PA14
-#define PA14 _STM32_PIN(A, 14)
-#undef PA15
-#define PA15 _STM32_PIN(A, 15)
-
-#undef PB0
-#define PB0 _STM32_PIN(B, 0)
-#undef PB1
-#define PB1 _STM32_PIN(B, 1)
-#undef PB2
-#define PB2 _STM32_PIN(B, 2)
-#undef PB3
-#define PB3 _STM32_PIN(B, 3)
-#undef PB4
-#define PB4 _STM32_PIN(B, 4)
-#undef PB5
-#define PB5 _STM32_PIN(B, 5)
-#undef PB6
-#define PB6 _STM32_PIN(B, 6)
-#undef PB7
-#define PB7 _STM32_PIN(B, 7)
-#undef PB8
-#define PB8 _STM32_PIN(B, 8)
-#undef PB9
-#define PB9 _STM32_PIN(B, 9)
-#undef PB10
-#define PB10 _STM32_PIN(B, 10)
-#undef PB11
-#define PB11 _STM32_PIN(B, 11)
-#undef PB12
-#define PB12 _STM32_PIN(B, 12)
-#undef PB13
-#define PB13 _STM32_PIN(B, 13)
-#undef PB14
-#define PB14 _STM32_PIN(B, 14)
-#undef PB15
-#define PB15 _STM32_PIN(B, 15)
-
-#undef PC0
-#define PC0 _STM32_PIN(C, 0)
-#undef PC1
-#define PC1 _STM32_PIN(C, 1)
-#undef PC2
-#define PC2 _STM32_PIN(C, 2)
-#undef PC3
-#define PC3 _STM32_PIN(C, 3)
-#undef PC4
-#define PC4 _STM32_PIN(C, 4)
-#undef PC5
-#define PC5 _STM32_PIN(C, 5)
-#undef PC6
-#define PC6 _STM32_PIN(C, 6)
-#undef PC7
-#define PC7 _STM32_PIN(C, 7)
-#undef PC8
-#define PC8 _STM32_PIN(C, 8)
-#undef PC9
-#define PC9 _STM32_PIN(C, 9)
-#undef PC10
-#define PC10 _STM32_PIN(C, 10)
-#undef PC11
-#define PC11 _STM32_PIN(C, 11)
-#undef PC12
-#define PC12 _STM32_PIN(C, 12)
-#undef PC13
-#define PC13 _STM32_PIN(C, 13)
-#undef PC14
-#define PC14 _STM32_PIN(C, 14)
-#undef PC15
-#define PC15 _STM32_PIN(C, 15)
-
-#undef PD0
-#define PD0 _STM32_PIN(D, 0)
-#undef PD1
-#define PD1 _STM32_PIN(D, 1)
-#undef PD2
-#define PD2 _STM32_PIN(D, 2)
-#undef PD3
-#define PD3 _STM32_PIN(D, 3)
-#undef PD4
-#define PD4 _STM32_PIN(D, 4)
-#undef PD5
-#define PD5 _STM32_PIN(D, 5)
-#undef PD6
-#define PD6 _STM32_PIN(D, 6)
-#undef PD7
-#define PD7 _STM32_PIN(D, 7)
-#undef PD8
-#define PD8 _STM32_PIN(D, 8)
-#undef PD9
-#define PD9 _STM32_PIN(D, 9)
-#undef PD10
-#define PD10 _STM32_PIN(D, 10)
-#undef PD11
-#define PD11 _STM32_PIN(D, 11)
-#undef PD12
-#define PD12 _STM32_PIN(D, 12)
-#undef PD13
-#define PD13 _STM32_PIN(D, 13)
-#undef PD14
-#define PD14 _STM32_PIN(D, 14)
-#undef PD15
-#define PD15 _STM32_PIN(D, 15)
-
-#undef PE0
-#define PE0 _STM32_PIN(E, 0)
-#undef PE1
-#define PE1 _STM32_PIN(E, 1)
-#undef PE2
-#define PE2 _STM32_PIN(E, 2)
-#undef PE3
-#define PE3 _STM32_PIN(E, 3)
-#undef PE4
-#define PE4 _STM32_PIN(E, 4)
-#undef PE5
-#define PE5 _STM32_PIN(E, 5)
-#undef PE6
-#define PE6 _STM32_PIN(E, 6)
-#undef PE7
-#define PE7 _STM32_PIN(E, 7)
-#undef PE8
-#define PE8 _STM32_PIN(E, 8)
-#undef PE9
-#define PE9 _STM32_PIN(E, 9)
-#undef PE10
-#define PE10 _STM32_PIN(E, 10)
-#undef PE11
-#define PE11 _STM32_PIN(E, 11)
-#undef PE12
-#define PE12 _STM32_PIN(E, 12)
-#undef PE13
-#define PE13 _STM32_PIN(E, 13)
-#undef PE14
-#define PE14 _STM32_PIN(E, 14)
-#undef PE15
-#define PE15 _STM32_PIN(E, 15)
-
-#ifdef STM32F7
-
- #undef PORTF
- #define PORTF 5
- #undef PF0
- #define PF0 _STM32_PIN(F, 0)
- #undef PF1
- #define PF1 _STM32_PIN(F, 1)
- #undef PF2
- #define PF2 _STM32_PIN(F, 2)
- #undef PF3
- #define PF3 _STM32_PIN(F, 3)
- #undef PF4
- #define PF4 _STM32_PIN(F, 4)
- #undef PF5
- #define PF5 _STM32_PIN(F, 5)
- #undef PF6
- #define PF6 _STM32_PIN(F, 6)
- #undef PF7
- #define PF7 _STM32_PIN(F, 7)
- #undef PF8
- #define PF8 _STM32_PIN(F, 8)
- #undef PF9
- #define PF9 _STM32_PIN(F, 9)
- #undef PF10
- #define PF10 _STM32_PIN(F, 10)
- #undef PF11
- #define PF11 _STM32_PIN(F, 11)
- #undef PF12
- #define PF12 _STM32_PIN(F, 12)
- #undef PF13
- #define PF13 _STM32_PIN(F, 13)
- #undef PF14
- #define PF14 _STM32_PIN(F, 14)
- #undef PF15
- #define PF15 _STM32_PIN(F, 15)
-
- #undef PORTG
- #define PORTG 6
- #undef PG0
- #define PG0 _STM32_PIN(G, 0)
- #undef PG1
- #define PG1 _STM32_PIN(G, 1)
- #undef PG2
- #define PG2 _STM32_PIN(G, 2)
- #undef PG3
- #define PG3 _STM32_PIN(G, 3)
- #undef PG4
- #define PG4 _STM32_PIN(G, 4)
- #undef PG5
- #define PG5 _STM32_PIN(G, 5)
- #undef PG6
- #define PG6 _STM32_PIN(G, 6)
- #undef PG7
- #define PG7 _STM32_PIN(G, 7)
- #undef PG8
- #define PG8 _STM32_PIN(G, 8)
- #undef PG9
- #define PG9 _STM32_PIN(G, 9)
- #undef PG10
- #define PG10 _STM32_PIN(G, 10)
- #undef PG11
- #define PG11 _STM32_PIN(G, 11)
- #undef PG12
- #define PG12 _STM32_PIN(G, 12)
- #undef PG13
- #define PG13 _STM32_PIN(G, 13)
- #undef PG14
- #define PG14 _STM32_PIN(G, 14)
- #undef PG15
- #define PG15 _STM32_PIN(G, 15)
-
-#endif // STM32GENERIC && STM32F7
diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h b/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h
deleted file mode 100644
index 5f1c4b1601..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-#pragma once
diff --git a/Marlin/src/HAL/STM32_F4_F7/pinsDebug.h b/Marlin/src/HAL/STM32_F4_F7/pinsDebug.h
deleted file mode 100644
index 973abb1b01..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/pinsDebug.h
+++ /dev/null
@@ -1,27 +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
-
-#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 Pins Debugging not supported for this board."
-#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/spi_pins.h b/Marlin/src/HAL/STM32_F4_F7/spi_pins.h
deleted file mode 100644
index 75a6a2b250..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/spi_pins.h
+++ /dev/null
@@ -1,35 +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
-
-/**
- * Define SPI Pins: SCK, MISO, MOSI, SS
- */
-#ifndef SCK_PIN
- #define SCK_PIN PA5
-#endif
-#ifndef MISO_PIN
- #define MISO_PIN PA6
-#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN PA7
-#endif
-#ifndef SS_PIN
- #define SS_PIN PA8
-#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/timers.h b/Marlin/src/HAL/STM32_F4_F7/timers.h
deleted file mode 100644
index 4e8c81783e..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/timers.h
+++ /dev/null
@@ -1,28 +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
-
-#ifdef STM32F4
- #include "STM32F4/timers.h"
-#else
- #include "STM32F7/timers.h"
-#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/watchdog.cpp b/Marlin/src/HAL/STM32_F4_F7/watchdog.cpp
deleted file mode 100644
index c0afd0cd58..0000000000
--- a/Marlin/src/HAL/STM32_F4_F7/watchdog.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(USE_WATCHDOG)
-
-#include "watchdog.h"
-
-#define WDT_TIMEOUT_COUNT TERN(WATCHDOG_DURATION_8S, 8192, 4096) // 4 or 8 second timeout
-
-IWDG_HandleTypeDef hiwdg;
-
-void watchdog_init() {
- hiwdg.Instance = IWDG;
- hiwdg.Init.Prescaler = IWDG_PRESCALER_32; // 32kHz LSI clock and 32x prescalar = 1024Hz IWDG clock
- hiwdg.Init.Reload = WDT_TIMEOUT_COUNT - 1;
- if (HAL_IWDG_Init(&hiwdg) != HAL_OK) {
- //Error_Handler();
- }
- else {
- #if PIN_EXISTS(LED) && DISABLED(PINS_DEBUGGING)
- TOGGLE(LED_PIN); // heartbeat indicator
- #endif
- }
-}
-
-void HAL_watchdog_refresh() {
- /* Refresh IWDG: reload counter */
- if (HAL_IWDG_Refresh(&hiwdg) != HAL_OK) {
- /* Refresh Error */
- //Error_Handler();
- }
-}
-
-#endif // USE_WATCHDOG
-#endif // STM32GENERIC && (STM32F4 || STM32F7)
diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.cpp b/Marlin/src/HAL/TEENSY31_32/HAL.cpp
index 8c3dd83377..51636d29bf 100644
--- a/Marlin/src/HAL/TEENSY31_32/HAL.cpp
+++ b/Marlin/src/HAL/TEENSY31_32/HAL.cpp
@@ -31,6 +31,9 @@
#include
+DefaultSerial MSerial(false);
+USBSerialType USBSerial(false, SerialUSB);
+
uint16_t HAL_adc_result;
static const uint8_t pin2sc1a[] = {
diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h
index 8ab358e9e1..5273b38637 100644
--- a/Marlin/src/HAL/TEENSY31_32/HAL.h
+++ b/Marlin/src/HAL/TEENSY31_32/HAL.h
@@ -50,12 +50,18 @@
#define IS_TEENSY32 1
#endif
-#define _MSERIAL(X) Serial##X
+#include "../../core/serial_hook.h"
+typedef Serial0Type DefaultSerial;
+extern DefaultSerial MSerial;
+typedef ForwardSerial0Type USBSerialType;
+extern USBSerialType USBSerial;
+
+#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define Serial0 Serial
+#define MSerial0 MSerial
#if SERIAL_PORT == -1
- #define MYSERIAL0 SerialUSB
+ #define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#endif
@@ -74,17 +80,6 @@ typedef int8_t pin_t;
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
-#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)))
-// Add type-checking to pgm_read_word
-#undef pgm_read_word
-#define pgm_read_word(addr) (*((uint16_t*)(addr)))
-
inline void HAL_init() {}
// Clear the reset reason
@@ -97,12 +92,16 @@ inline void HAL_reboot() {} // reboot the board or restart the bootloader
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- int freeMemory();
-}
-#pragma GCC diagnostic pop
+#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
diff --git a/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
index cdb3f4701c..dce236ef6b 100644
--- a/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY31_32/HAL_SPI.cpp
@@ -35,18 +35,18 @@ static SPISettings spiConfig;
// Initialize SPI bus
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);
- 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 0 && DISABLED(SOFTWARE_SPI)
// 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(SPI_HALF_SPEED); // 1
diff --git a/Marlin/src/HAL/TEENSY31_32/fastio.h b/Marlin/src/HAL/TEENSY31_32/fastio.h
index 9a299de9c7..622799ec8c 100644
--- a/Marlin/src/HAL/TEENSY31_32/fastio.h
+++ b/Marlin/src/HAL/TEENSY31_32/fastio.h
@@ -28,7 +28,7 @@
*/
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
diff --git a/Marlin/src/HAL/TEENSY31_32/spi_pins.h b/Marlin/src/HAL/TEENSY31_32/spi_pins.h
index 5754fbfeed..6d0d05f85a 100644
--- a/Marlin/src/HAL/TEENSY31_32/spi_pins.h
+++ b/Marlin/src/HAL/TEENSY31_32/spi_pins.h
@@ -21,7 +21,7 @@
*/
#pragma once
-#define SCK_PIN 13
-#define MISO_PIN 12
-#define MOSI_PIN 11
-#define SS_PIN 20 //SDSS // A.28, A.29, B.21, C.26, C.29
+#define SD_SCK_PIN 13
+#define SD_MISO_PIN 12
+#define SD_MOSI_PIN 11
+#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29
diff --git a/Marlin/src/HAL/TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h
index 135b328830..61b8673596 100644
--- a/Marlin/src/HAL/TEENSY31_32/timers.h
+++ b/Marlin/src/HAL/TEENSY31_32/timers.h
@@ -74,10 +74,10 @@ typedef uint32_t hal_timer_t;
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
+ #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
#endif
#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
+ #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
#endif
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
diff --git a/Marlin/src/HAL/TEENSY35_36/HAL.cpp b/Marlin/src/HAL/TEENSY35_36/HAL.cpp
index 92907353b8..547681de5f 100644
--- a/Marlin/src/HAL/TEENSY35_36/HAL.cpp
+++ b/Marlin/src/HAL/TEENSY35_36/HAL.cpp
@@ -31,6 +31,9 @@
#include
+DefaultSerial MSerial(false);
+USBSerialType USBSerial(false, SerialUSB);
+
uint16_t HAL_adc_result, HAL_adc_select;
static const uint8_t pin2sc1a[] = {
diff --git a/Marlin/src/HAL/TEENSY35_36/HAL.h b/Marlin/src/HAL/TEENSY35_36/HAL.h
index 2b735d6224..94c514bf62 100644
--- a/Marlin/src/HAL/TEENSY35_36/HAL.h
+++ b/Marlin/src/HAL/TEENSY35_36/HAL.h
@@ -53,12 +53,18 @@
#define IS_TEENSY35 1
#endif
-#define _MSERIAL(X) Serial##X
+#include "../../core/serial_hook.h"
+typedef Serial0Type DefaultSerial;
+extern DefaultSerial MSerial;
+typedef ForwardSerial0Type USBSerialType;
+extern USBSerialType USBSerial;
+
+#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define Serial0 Serial
+#define MSerial0 MSerial
#if SERIAL_PORT == -1
- #define MYSERIAL0 SerialUSB
+ #define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#endif
@@ -80,17 +86,6 @@ typedef int8_t pin_t;
#undef sq
#define sq(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)))
-// Add type-checking to pgm_read_word
-#undef pgm_read_word
-#define pgm_read_word(addr) (*((uint16_t*)(addr)))
-
inline void HAL_init() {}
// Clear reset reason
@@ -103,12 +98,16 @@ inline void HAL_reboot() {} // reboot the board or restart the bootloader
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- int freeMemory();
-}
-#pragma GCC diagnostic pop
+#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
diff --git a/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
index b36900a321..84852cd358 100644
--- a/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY35_36/HAL_SPI.cpp
@@ -35,18 +35,18 @@
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);
- 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 0 && DISABLED(SOFTWARE_SPI)
// 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(SPI_HALF_SPEED); // 1
diff --git a/Marlin/src/HAL/TEENSY35_36/fastio.h b/Marlin/src/HAL/TEENSY35_36/fastio.h
index 9a299de9c7..622799ec8c 100644
--- a/Marlin/src/HAL/TEENSY35_36/fastio.h
+++ b/Marlin/src/HAL/TEENSY35_36/fastio.h
@@ -28,7 +28,7 @@
*/
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
diff --git a/Marlin/src/HAL/TEENSY35_36/spi_pins.h b/Marlin/src/HAL/TEENSY35_36/spi_pins.h
index c76344d075..cfffdc9325 100644
--- a/Marlin/src/HAL/TEENSY35_36/spi_pins.h
+++ b/Marlin/src/HAL/TEENSY35_36/spi_pins.h
@@ -25,7 +25,7 @@
* HAL SPI Pins for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0)
*/
-#define SCK_PIN 13
-#define MISO_PIN 12
-#define MOSI_PIN 11
-#define SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29
+#define SD_SCK_PIN 13
+#define SD_MISO_PIN 12
+#define SD_MOSI_PIN 11
+#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29
diff --git a/Marlin/src/HAL/TEENSY35_36/timers.h b/Marlin/src/HAL/TEENSY35_36/timers.h
index 5c623cd801..99269ac657 100644
--- a/Marlin/src/HAL/TEENSY35_36/timers.h
+++ b/Marlin/src/HAL/TEENSY35_36/timers.h
@@ -73,10 +73,10 @@ typedef uint32_t hal_timer_t;
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
+ #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler()
#endif
#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
+ #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler()
#endif
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.cpp b/Marlin/src/HAL/TEENSY40_41/HAL.cpp
index 5b1b4272f5..26449d7eb2 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL.cpp
+++ b/Marlin/src/HAL/TEENSY40_41/HAL.cpp
@@ -32,6 +32,9 @@
#include
+DefaultSerial MSerial(false);
+USBSerialType USBSerial(false, SerialUSB);
+
uint16_t HAL_adc_result, HAL_adc_select;
static const uint8_t pin2sc1a[] = {
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h
index 1e0043342d..6aa1e521a4 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL.h
+++ b/Marlin/src/HAL/TEENSY40_41/HAL.h
@@ -37,6 +37,10 @@
#include
#include
+#if HAS_ETHERNET
+ #include "../../feature/ethernet.h"
+#endif
+
//#define ST7920_DELAY_1 DELAY_NS(600)
//#define ST7920_DELAY_2 DELAY_NS(750)
//#define ST7920_DELAY_3 DELAY_NS(750)
@@ -51,9 +55,15 @@
#define IS_TEENSY41 1
#endif
-#define _MSERIAL(X) Serial##X
+#include "../../core/serial_hook.h"
+typedef Serial0Type DefaultSerial;
+extern DefaultSerial MSerial;
+typedef ForwardSerial0Type USBSerialType;
+extern USBSerialType USBSerial;
+
+#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define Serial0 Serial
+#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
@@ -92,21 +102,10 @@ typedef int8_t pin_t;
#undef sq
#define sq(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
// Don't place string constants in PROGMEM
#undef PSTR
#define PSTR(str) ({static const char *data = (str); &data[0];})
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*((void**)(addr)))
-// Add type-checking to pgm_read_word
-#undef pgm_read_word
-#define pgm_read_word(addr) (*((uint16_t*)(addr)))
-
// Enable hooks into idle and setup for HAL
#define HAL_IDLETASK 1
FORCE_INLINE void HAL_idletask() {}
@@ -120,12 +119,16 @@ uint8_t HAL_get_reset_source();
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- uint32_t freeMemory();
-}
-#pragma GCC diagnostic pop
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+extern "C" uint32_t freeMemory();
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
// ADC
diff --git a/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
index 20b472aa35..8c93049027 100644
--- a/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
+++ b/Marlin/src/HAL/TEENSY40_41/HAL_SPI.cpp
@@ -50,20 +50,20 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #ifndef SS_PIN
- #error "SS_PIN is not defined!"
+ #ifndef SD_SS_PIN
+ #error "SD_SS_PIN is not defined!"
#endif
- OUT_WRITE(SS_PIN, HIGH);
+ OUT_WRITE(SD_SS_PIN, 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);
#if 0 && DISABLED(SOFTWARE_SPI)
// 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(SPI_HALF_SPEED); // 1
diff --git a/Marlin/src/HAL/TEENSY40_41/spi_pins.h b/Marlin/src/HAL/TEENSY40_41/spi_pins.h
index d6f8d41bf6..ba4a2c700a 100644
--- a/Marlin/src/HAL/TEENSY40_41/spi_pins.h
+++ b/Marlin/src/HAL/TEENSY40_41/spi_pins.h
@@ -25,7 +25,7 @@
* HAL SPI Pins for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A)
*/
-#define SCK_PIN 13
-#define MISO_PIN 12
-#define MOSI_PIN 11
-#define SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29
+#define SD_SCK_PIN 13
+#define SD_MISO_PIN 12
+#define SD_MOSI_PIN 11
+#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29
diff --git a/Marlin/src/HAL/TEENSY40_41/timers.h b/Marlin/src/HAL/TEENSY40_41/timers.h
index 7e4cd080cb..556333d7f4 100644
--- a/Marlin/src/HAL/TEENSY40_41/timers.h
+++ b/Marlin/src/HAL/TEENSY40_41/timers.h
@@ -72,14 +72,16 @@ typedef uint32_t hal_timer_t;
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() // GPT1_Handler()
+ #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() // GPT1_Handler()
#endif
#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() // GPT2_Handler()
+ #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() // GPT2_Handler()
#endif
-extern "C" void stepTC_Handler();
-extern "C" void tempTC_Handler();
+extern "C" {
+ void stepTC_Handler();
+ void tempTC_Handler();
+}
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
diff --git a/Marlin/src/HAL/platforms.h b/Marlin/src/HAL/platforms.h
index ef17d19170..e0617bdf7f 100644
--- a/Marlin/src/HAL/platforms.h
+++ b/Marlin/src/HAL/platforms.h
@@ -37,8 +37,6 @@
#define HAL_PATH(PATH, NAME) XSTR(PATH/LPC1768/NAME)
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
#define HAL_PATH(PATH, NAME) XSTR(PATH/STM32F1/NAME)
-#elif defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
- #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32_F4_F7/NAME)
#elif defined(ARDUINO_ARCH_STM32)
#define HAL_PATH(PATH, NAME) XSTR(PATH/STM32/NAME)
#elif defined(ARDUINO_ARCH_ESP32)
diff --git a/Marlin/src/HAL/shared/Marduino.h b/Marlin/src/HAL/shared/Marduino.h
index 3003f3cc28..d0ee6ecc9d 100644
--- a/Marlin/src/HAL/shared/Marduino.h
+++ b/Marlin/src/HAL/shared/Marduino.h
@@ -28,9 +28,9 @@
#undef DISABLED // Redefined by ESP32
#undef M_PI // Redefined by all
#undef _BV // Redefined by some
-#undef sq // Redefined by teensy3/wiring.h
#undef SBI // Redefined by arduino/const_functions.h
#undef CBI // Redefined by arduino/const_functions.h
+#undef sq // Redefined by teensy3/wiring.h
#undef UNUSED // Redefined by stm32f4xx_hal_def.h
#include // NOTE: If included earlier then this line is a NOOP
@@ -40,18 +40,16 @@
#undef _BV
#define _BV(b) (1UL << (b))
+#ifndef SBI
+ #define SBI(A,B) (A |= _BV(B))
+#endif
+#ifndef CBI
+ #define CBI(A,B) (A &= ~_BV(B))
+#endif
#undef sq
#define sq(x) ((x)*(x))
-#ifndef SBI
- #define SBI(A,B) (A |= (1 << (B)))
-#endif
-
-#ifndef CBI
- #define CBI(A,B) (A &= ~(1 << (B)))
-#endif
-
#ifndef __AVR__
#ifndef strchr_P // Some platforms define a macro (DUE, teensy35)
inline const char* strchr_P(const char *s, int c) { return strchr(s,c); }
@@ -83,3 +81,5 @@
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
+
+#include "progmem.h"
diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp
index 59734bfbfe..decf74e6e9 100644
--- a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp
+++ b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp
@@ -43,10 +43,9 @@ static bool isDataProc(uint32_t instr) {
}
UnwResult UnwStartArm(UnwState * const state) {
- bool found = false;
uint16_t t = UNW_MAX_INSTR_COUNT;
- do {
+ for (;;) {
uint32_t instr;
/* Attempt to read the instruction */
@@ -527,7 +526,7 @@ UnwResult UnwStartArm(UnwState * const state) {
if (--t == 0) return UNWIND_EXHAUSTED;
- } while (!found);
+ }
return UNWIND_UNSUPPORTED;
}
diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp
index be4abd090f..0c6a70649d 100644
--- a/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp
+++ b/Marlin/src/HAL/shared/backtrace/unwarm_thumb.cpp
@@ -30,12 +30,11 @@ static int32_t signExtend11(const uint16_t value) {
}
UnwResult UnwStartThumb(UnwState * const state) {
- bool found = false;
uint16_t t = UNW_MAX_INSTR_COUNT;
uint32_t lastJumpAddr = 0; // Last JUMP address, to try to detect infinite loops
bool loopDetected = false; // If a loop was detected
- do {
+ for (;;) {
uint16_t instr;
/* Attempt to read the instruction */
@@ -1059,7 +1058,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
if (--t == 0) return UNWIND_EXHAUSTED;
- } while (!found);
+ }
return UNWIND_SUCCESS;
}
diff --git a/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp b/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp
index bfc062af20..f1ee81ed4a 100644
--- a/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp
+++ b/Marlin/src/HAL/shared/backtrace/unwarmbytab.cpp
@@ -128,11 +128,8 @@ static UnwResult UnwTabStateInit(const UnwindCallbacks *cb, UnwTabState *ucb, ui
* Execute unwinding instructions
*/
static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabState *ucb) {
-
int instruction;
- uint32_t mask;
- uint32_t reg;
- uint32_t vsp;
+ uint32_t mask, reg, vsp;
/* Consume all instruction byte */
while ((instruction = UnwTabGetNextInstruction(cb, ucb)) != -1) {
@@ -140,12 +137,12 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
if ((instruction & 0xC0) == 0x00) { // ARM_EXIDX_CMD_DATA_POP
/* vsp = vsp + (xxxxxx << 2) + 4 */
ucb->vrs[13] += ((instruction & 0x3F) << 2) + 4;
- } else
- if ((instruction & 0xC0) == 0x40) { // ARM_EXIDX_CMD_DATA_PUSH
+ }
+ else if ((instruction & 0xC0) == 0x40) { // ARM_EXIDX_CMD_DATA_PUSH
/* vsp = vsp - (xxxxxx << 2) - 4 */
ucb->vrs[13] -= ((instruction & 0x3F) << 2) - 4;
- } else
- if ((instruction & 0xF0) == 0x80) {
+ }
+ else if ((instruction & 0xF0) == 0x80) {
/* pop under mask {r15-r12},{r11-r4} or refuse to unwind */
instruction = instruction << 8 | UnwTabGetNextInstruction(cb, ucb);
@@ -171,17 +168,17 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
}
/* Patch up the vrs sp if it was in the mask */
- if ((instruction & (1 << (13 - 4))) != 0)
+ if (instruction & (1 << (13 - 4)))
ucb->vrs[13] = vsp;
-
- } else
- if ((instruction & 0xF0) == 0x90 && // ARM_EXIDX_CMD_REG_TO_SP
- instruction != 0x9D &&
- instruction != 0x9F) {
+ }
+ else if ((instruction & 0xF0) == 0x90 // ARM_EXIDX_CMD_REG_TO_SP
+ && instruction != 0x9D
+ && instruction != 0x9F
+ ) {
/* vsp = r[nnnn] */
ucb->vrs[13] = ucb->vrs[instruction & 0x0F];
- } else
- if ((instruction & 0xF0) == 0xA0) { // ARM_EXIDX_CMD_REG_POP
+ }
+ else if ((instruction & 0xF0) == 0xA0) { // ARM_EXIDX_CMD_REG_POP
/* pop r4-r[4+nnn] or pop r4-r[4+nnn], r14*/
vsp = ucb->vrs[13];
@@ -204,8 +201,8 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
ucb->vrs[13] = vsp;
- } else
- if (instruction == 0xB0) { // ARM_EXIDX_CMD_FINISH
+ }
+ else if (instruction == 0xB0) { // ARM_EXIDX_CMD_FINISH
/* finished */
if (ucb->vrs[15] == 0)
ucb->vrs[15] = ucb->vrs[14];
@@ -213,8 +210,8 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
/* All done unwinding */
return UNWIND_SUCCESS;
- } else
- if (instruction == 0xB1) { // ARM_EXIDX_CMD_REG_POP
+ }
+ else if (instruction == 0xB1) { // ARM_EXIDX_CMD_REG_POP
/* pop register under mask {r3,r2,r1,r0} */
vsp = ucb->vrs[13];
mask = UnwTabGetNextInstruction(cb, ucb);
@@ -234,16 +231,15 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
}
ucb->vrs[13] = (uint32_t)vsp;
- } else
- if (instruction == 0xB2) { // ARM_EXIDX_CMD_DATA_POP
+ }
+ else if (instruction == 0xB2) { // ARM_EXIDX_CMD_DATA_POP
/* vps = vsp + 0x204 + (uleb128 << 2) */
ucb->vrs[13] += 0x204 + (UnwTabGetNextInstruction(cb, ucb) << 2);
-
- } else
- if (instruction == 0xB3 || // ARM_EXIDX_CMD_VFP_POP
- instruction == 0xC8 ||
- instruction == 0xC9) {
-
+ }
+ else if (instruction == 0xB3 // ARM_EXIDX_CMD_VFP_POP
+ || instruction == 0xC8
+ || instruction == 0xC9
+ ) {
/* pop VFP double-precision registers */
vsp = ucb->vrs[13];
@@ -266,27 +262,20 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
}
ucb->vrs[13] = vsp;
-
- } else
- if ((instruction & 0xF8) == 0xB8 ||
- (instruction & 0xF8) == 0xD0) {
-
+ }
+ else if ((instruction & 0xF8) == 0xB8 || (instruction & 0xF8) == 0xD0) {
/* Pop VFP double precision registers D[8]-D[8+nnn] */
ucb->vrs[14] = 0x80 | (instruction & 0x07);
-
- if ((instruction & 0xF8) == 0xD0) {
+ if ((instruction & 0xF8) == 0xD0)
ucb->vrs[14] = 1 << 17;
- }
-
- } else
+ }
+ else
return UNWIND_UNSUPPORTED_DWARF_INSTR;
}
-
return UNWIND_SUCCESS;
}
static inline __attribute__((always_inline)) uint32_t read_psp() {
-
/* Read the current PSP and return its value as a pointer */
uint32_t psp;
diff --git a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
index e749530645..5ca46f9886 100644
--- a/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
+++ b/Marlin/src/HAL/shared/backtrace/unwmemaccess.cpp
@@ -74,17 +74,6 @@
#define START_FLASH_ADDR 0x08000000
#define END_FLASH_ADDR 0x08080000
-#elif MB(THE_BORG)
-
- // For STM32F765 in BORG
- // SRAM (0x20000000 - 0x20080000) (512kb)
- // FLASH (0x08000000 - 0x08100000) (1024kb)
- //
- #define START_SRAM_ADDR 0x20000000
- #define END_SRAM_ADDR 0x20080000
- #define START_FLASH_ADDR 0x08000000
- #define END_FLASH_ADDR 0x08100000
-
#elif MB(REMRAM_V1, NUCLEO_F767ZI)
// For STM32F765VI in RemRam v1
diff --git a/Marlin/src/HAL/shared/progmem.h b/Marlin/src/HAL/shared/progmem.h
new file mode 100644
index 0000000000..539d02705e
--- /dev/null
+++ b/Marlin/src/HAL/shared/progmem.h
@@ -0,0 +1,189 @@
+/**
+ * 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
+
+#ifndef __AVR__
+#ifndef __PGMSPACE_H_
+// This define should prevent reading the system pgmspace.h if included elsewhere
+// This is not normally needed.
+#define __PGMSPACE_H_ 1
+#endif
+
+#ifndef PROGMEM
+#define PROGMEM
+#endif
+#ifndef PGM_P
+#define PGM_P const char *
+#endif
+#ifndef PSTR
+#define PSTR(str) (str)
+#endif
+#ifndef F
+#define F(str) (str)
+#endif
+#ifndef _SFR_BYTE
+#define _SFR_BYTE(n) (n)
+#endif
+#ifndef memchr_P
+#define memchr_P(str, c, len) memchr((str), (c), (len))
+#endif
+#ifndef memcmp_P
+#define memcmp_P(a, b, n) memcmp((a), (b), (n))
+#endif
+#ifndef memcpy_P
+#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
+#endif
+#ifndef memmem_P
+#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen))
+#endif
+#ifndef memrchr_P
+#define memrchr_P(str, val, len) memrchr((str), (val), (len))
+#endif
+#ifndef strcat_P
+#define strcat_P(dest, src) strcat((dest), (src))
+#endif
+#ifndef strchr_P
+#define strchr_P(str, c) strchr((str), (c))
+#endif
+#ifndef strchrnul_P
+#define strchrnul_P(str, c) strchrnul((str), (c))
+#endif
+#ifndef strcmp_P
+#define strcmp_P(a, b) strcmp((a), (b))
+#endif
+#ifndef strcpy_P
+#define strcpy_P(dest, src) strcpy((dest), (src))
+#endif
+#ifndef strcasecmp_P
+#define strcasecmp_P(a, b) strcasecmp((a), (b))
+#endif
+#ifndef strcasestr_P
+#define strcasestr_P(a, b) strcasestr((a), (b))
+#endif
+#ifndef strlcat_P
+#define strlcat_P(dest, src, len) strlcat((dest), (src), (len))
+#endif
+#ifndef strlcpy_P
+#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len))
+#endif
+#ifndef strlen_P
+#define strlen_P(s) strlen((const char *)(s))
+#endif
+#ifndef strnlen_P
+#define strnlen_P(str, len) strnlen((str), (len))
+#endif
+#ifndef strncmp_P
+#define strncmp_P(a, b, n) strncmp((a), (b), (n))
+#endif
+#ifndef strncasecmp_P
+#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
+#endif
+#ifndef strncat_P
+#define strncat_P(a, b, n) strncat((a), (b), (n))
+#endif
+#ifndef strncpy_P
+#define strncpy_P(a, b, n) strncpy((a), (b), (n))
+#endif
+#ifndef strpbrk_P
+#define strpbrk_P(str, chrs) strpbrk((str), (chrs))
+#endif
+#ifndef strrchr_P
+#define strrchr_P(str, c) strrchr((str), (c))
+#endif
+#ifndef strsep_P
+#define strsep_P(strp, delim) strsep((strp), (delim))
+#endif
+#ifndef strspn_P
+#define strspn_P(str, chrs) strspn((str), (chrs))
+#endif
+#ifndef strstr_P
+#define strstr_P(a, b) strstr((a), (b))
+#endif
+#ifndef sprintf_P
+#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__)
+#endif
+#ifndef vfprintf_P
+#define vfprintf_P(s, ...) vfprintf((s), __VA_ARGS__)
+#endif
+#ifndef printf_P
+#define printf_P(...) printf(__VA_ARGS__)
+#endif
+#ifndef snprintf_P
+#define snprintf_P(s, n, ...) snprintf((s), (n), __VA_ARGS__)
+#endif
+#ifndef vsprintf_P
+#define vsprintf_P(s, ...) vsprintf((s),__VA_ARGS__)
+#endif
+#ifndef vsnprintf_P
+#define vsnprintf_P(s, n, ...) vsnprintf((s), (n),__VA_ARGS__)
+#endif
+#ifndef fprintf_P
+#define fprintf_P(s, ...) fprintf((s), __VA_ARGS__)
+#endif
+
+#ifndef pgm_read_byte
+#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
+#endif
+#ifndef pgm_read_word
+#define pgm_read_word(addr) (*(const unsigned short *)(addr))
+#endif
+#ifndef pgm_read_dword
+#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
+#endif
+#ifndef pgm_read_float
+#define pgm_read_float(addr) (*(const float *)(addr))
+#endif
+
+#ifndef pgm_read_byte_near
+#define pgm_read_byte_near(addr) pgm_read_byte(addr)
+#endif
+#ifndef pgm_read_word_near
+#define pgm_read_word_near(addr) pgm_read_word(addr)
+#endif
+#ifndef pgm_read_dword_near
+#define pgm_read_dword_near(addr) pgm_read_dword(addr)
+#endif
+#ifndef pgm_read_float_near
+#define pgm_read_float_near(addr) pgm_read_float(addr)
+#endif
+#ifndef pgm_read_byte_far
+#define pgm_read_byte_far(addr) pgm_read_byte(addr)
+#endif
+#ifndef pgm_read_word_far
+#define pgm_read_word_far(addr) pgm_read_word(addr)
+#endif
+#ifndef pgm_read_dword_far
+#define pgm_read_dword_far(addr) pgm_read_dword(addr)
+#endif
+#ifndef pgm_read_float_far
+#define pgm_read_float_far(addr) pgm_read_float(addr)
+#endif
+
+#ifndef pgm_read_pointer
+#define pgm_read_pointer
+#endif
+
+// Fix bug in pgm_read_ptr
+#undef pgm_read_ptr
+#define pgm_read_ptr(addr) (*((void**)(addr)))
+
+#endif // __AVR__
diff --git a/Marlin/src/HAL/shared/servo.h b/Marlin/src/HAL/shared/servo.h
index 6d850da851..c2560a8538 100644
--- a/Marlin/src/HAL/shared/servo.h
+++ b/Marlin/src/HAL/shared/servo.h
@@ -76,8 +76,6 @@
#include "../LPC1768/Servo.h"
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
#include "../STM32F1/Servo.h"
-#elif defined(STM32GENERIC) && defined(STM32F4)
- #include "../STM32_F4_F7/Servo.h"
#elif defined(ARDUINO_ARCH_STM32)
#include "../STM32/Servo.h"
#elif defined(ARDUINO_ARCH_ESP32)
diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index 5769da05d0..51e0efafd6 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -43,6 +43,7 @@
#include
#include "core/utility.h"
+
#include "module/motion.h"
#include "module/planner.h"
#include "module/endstops.h"
@@ -57,6 +58,7 @@
#include "gcode/parser.h"
#include "gcode/queue.h"
+#include "feature/pause.h"
#include "sd/cardreader.h"
#include "lcd/marlinui.h"
@@ -77,6 +79,10 @@
#include "lcd/dwin/e3v2/rotary_encoder.h"
#endif
+#if ENABLED(EXTENSIBLE_UI)
+ #include "lcd/extui/ui_api.h"
+#endif
+
#if HAS_ETHERNET
#include "feature/ethernet.h"
#endif
@@ -135,7 +141,6 @@
#if ENABLED(EXPERIMENTAL_I2CBUS)
#include "feature/twibus.h"
- TWIBus i2c;
#endif
#if ENABLED(I2C_POSITION_ENCODERS)
@@ -169,8 +174,8 @@
#include "feature/bedlevel/bedlevel.h"
#endif
-#if BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT)
- #include "feature/pause.h"
+#if ENABLED(GCODE_REPEAT_MARKERS)
+ #include "feature/repeat.h"
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
@@ -185,7 +190,7 @@
#include "feature/runout.h"
#endif
-#if HAS_Z_SERVO_PROBE
+#if EITHER(PROBE_TARE, HAS_Z_SERVO_PROBE)
#include "module/probe.h"
#endif
@@ -225,18 +230,7 @@
#include "feature/password/password.h"
#endif
-PGMSTR(NUL_STR, "");
PGMSTR(M112_KILL_STR, "M112 Shutdown");
-PGMSTR(G28_STR, "G28");
-PGMSTR(M21_STR, "M21");
-PGMSTR(M23_STR, "M23 %s");
-PGMSTR(M24_STR, "M24");
-PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T");
-PGMSTR(X_STR, "X"); PGMSTR(Y_STR, "Y"); PGMSTR(Z_STR, "Z"); PGMSTR(E_STR, "E");
-PGMSTR(X_LBL, "X:"); PGMSTR(Y_LBL, "Y:"); PGMSTR(Z_LBL, "Z:"); PGMSTR(E_LBL, "E:");
-PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
-PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E");
-PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
MarlinState marlin_state = MF_INITIALIZING;
@@ -259,40 +253,12 @@ bool wait_for_heatup = true;
#endif
-#if PIN_EXISTS(CHDK)
- extern millis_t chdk_timeout;
-#endif
-
-#if ENABLED(I2C_POSITION_ENCODERS)
- I2CPositionEncodersMgr I2CPEM;
-#endif
-
/**
* ***************************************************************************
* ******************************** FUNCTIONS ********************************
* ***************************************************************************
*/
-void setup_killpin() {
- #if HAS_KILL
- #if KILL_PIN_STATE
- SET_INPUT_PULLDOWN(KILL_PIN);
- #else
- SET_INPUT_PULLUP(KILL_PIN);
- #endif
- #endif
-}
-
-void setup_powerhold() {
- #if HAS_SUICIDE
- OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
- #endif
- #if ENABLED(PSU_CONTROL)
- powersupply_on = ENABLED(PSU_DEFAULT_OFF);
- if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
- #endif
-}
-
/**
* Stepper Reset (RigidBoard, et.al.)
*/
@@ -301,18 +267,6 @@ void setup_powerhold() {
void enableStepperDrivers() { SET_INPUT(STEPPER_RESET_PIN); } // Set to input, allowing pullups to pull the pin high
#endif
-#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
-
- void i2c_on_receive(int bytes) { // just echo all bytes received to serial
- i2c.receive(bytes);
- }
-
- void i2c_on_request() { // just send dummy data for now
- i2c.reply("Hello World!\n");
- }
-
-#endif
-
/**
* Sensitive pin test for M42, M226
*/
@@ -334,17 +288,6 @@ bool pin_is_protected(const pin_t pin) {
#pragma GCC diagnostic pop
-void protected_pin_err() {
- SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
-}
-
-void quickstop_stepper() {
- planner.quick_stop();
- planner.synchronize();
- set_current_from_steppers_for_axis(ALL_AXES);
- sync_plan_position();
-}
-
void enable_e_steppers() {
#define _ENA_E(N) ENABLE_AXIS_E##N();
REPEAT(E_STEPPERS, _ENA_E)
@@ -356,6 +299,8 @@ void enable_all_steppers() {
ENABLE_AXIS_Y();
ENABLE_AXIS_Z();
enable_e_steppers();
+
+ TERN_(EXTENSIBLE_UI, ExtUI::onSteppersEnabled());
}
void disable_e_steppers() {
@@ -375,43 +320,10 @@ void disable_all_steppers() {
DISABLE_AXIS_Y();
DISABLE_AXIS_Z();
disable_e_steppers();
+
+ TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
}
-#if ENABLED(G29_RETRY_AND_RECOVER)
-
- void event_probe_failure() {
- #ifdef ACTION_ON_G29_FAILURE
- host_action(PSTR(ACTION_ON_G29_FAILURE));
- #endif
- #ifdef G29_FAILURE_COMMANDS
- gcode.process_subcommands_now_P(PSTR(G29_FAILURE_COMMANDS));
- #endif
- #if ENABLED(G29_HALT_ON_FAILURE)
- #ifdef ACTION_ON_CANCEL
- host_action_cancel();
- #endif
- kill(GET_TEXT(MSG_LCD_PROBING_FAILED));
- #endif
- }
-
- void event_probe_recover() {
- TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR));
- #ifdef ACTION_ON_G29_RECOVER
- host_action(PSTR(ACTION_ON_G29_RECOVER));
- #endif
- #ifdef G29_RECOVER_COMMANDS
- gcode.process_subcommands_now_P(PSTR(G29_RECOVER_COMMANDS));
- #endif
- }
-
-#endif
-
-#if ENABLED(ADVANCED_PAUSE_FEATURE)
- #include "feature/pause.h"
-#else
- constexpr bool did_pause_print = false;
-#endif
-
/**
* A Print Job exists when the timer is running or SD printing
*/
@@ -435,6 +347,7 @@ bool printingIsPaused() {
void startOrResumeJob() {
if (!printingIsPaused()) {
+ TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
TERN_(CANCEL_OBJECTS, cancelable.reset());
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0);
#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
@@ -447,20 +360,22 @@ void startOrResumeJob() {
#if ENABLED(SDSUPPORT)
inline void abortSDPrinting() {
+ IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel());
card.endFilePrint(TERN_(SD_RESORT, true));
+
queue.clear();
quickstop_stepper();
- print_job_timer.stop();
- #if DISABLED(SD_ABORT_NO_COOLDOWN)
- thermalManager.disable_all_heaters();
- #endif
- #if !HAS_CUTTER
- thermalManager.zero_fan_speeds();
- #else
- cutter.kill(); // Full cutter shutdown including ISR control
- #endif
+
+ print_job_timer.abort();
+
+ IF_DISABLED(SD_ABORT_NO_COOLDOWN, thermalManager.disable_all_heaters());
+
+ TERN(HAS_CUTTER, cutter.kill(), thermalManager.zero_fan_speeds()); // Full cutter shutdown including ISR control
+
wait_for_heatup = false;
+
TERN_(POWER_LOSS_RECOVERY, recovery.purge());
+
#ifdef EVENT_GCODE_SD_ABORT
queue.inject_P(PSTR(EVENT_GCODE_SD_ABORT));
#endif
@@ -497,8 +412,8 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
// Prevent steppers timing-out in the middle of M600
// unless PAUSE_PARK_NO_STEPPER_TIMEOUT is disabled
- const bool parked_or_ignoring = ignore_stepper_queue ||
- (BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT) && did_pause_print);
+ const bool parked_or_ignoring = ignore_stepper_queue
+ || TERN0(PAUSE_PARK_NO_STEPPER_TIMEOUT, did_pause_print);
// Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout
if (parked_or_ignoring) gcode.reset_stepper_timeout(ms);
@@ -536,6 +451,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
}
#if PIN_EXISTS(CHDK) // Check if pin should be set to LOW (after M240 set it HIGH)
+ extern millis_t chdk_timeout;
if (chdk_timeout && ELAPSED(ms, chdk_timeout)) {
chdk_timeout = 0;
WRITE(CHDK_PIN, LOW);
@@ -572,7 +488,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
if (ELAPSED(ms, next_home_key_ms)) {
next_home_key_ms = ms + HOME_DEBOUNCE_DELAY;
LCD_MESSAGEPGM(MSG_AUTO_HOME);
- queue.enqueue_now_P(G28_STR);
+ queue.inject_P(G28_STR);
}
}
#endif
@@ -641,11 +557,12 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
#if ENABLED(DUAL_X_CARRIAGE)
// handle delayed move timeout
- if (delayed_move_time && ELAPSED(ms, delayed_move_time + 1000UL) && IsRunning()) {
+ if (delayed_move_time && ELAPSED(ms, delayed_move_time) && IsRunning()) {
// travel moves have been received so enact them
delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
destination = current_position;
prepare_line_to_destination();
+ planner.synchronize();
}
#endif
@@ -696,6 +613,10 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
* - Handle Joystick jogging
*/
void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
+ #if ENABLED(MARLIN_DEV_MODE)
+ static uint8_t idle_depth = 0;
+ if (++idle_depth > 5) SERIAL_ECHOLNPAIR("idle() call depth: ", int(idle_depth));
+ #endif
// Core Marlin activities
manage_inactivity(TERN_(ADVANCED_PAUSE_FEATURE, no_stepper_sleep));
@@ -707,7 +628,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
TERN_(MAX7219_DEBUG, max7219.idle_tasks());
// Return if setup() isn't completed
- if (marlin_state == MF_INITIALIZING) return;
+ if (marlin_state == MF_INITIALIZING) goto IDLE_DONE;
// Handle filament runout sensors
TERN_(HAS_FILAMENT_SENSOR, runout.run());
@@ -751,6 +672,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
// Run i2c Position Encoders
#if ENABLED(I2C_POSITION_ENCODERS)
+ {
static millis_t i2cpem_next_update_ms;
if (planner.has_blocks_queued()) {
const millis_t ms = millis();
@@ -759,13 +681,14 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
i2cpem_next_update_ms = ms + I2CPE_MIN_UPD_TIME_MS;
}
}
+ }
#endif
// Auto-report Temperatures / SD Status
#if HAS_AUTO_REPORTING
if (!gcode.autoreport_paused) {
- TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_report_temperatures());
- TERN_(AUTO_REPORT_SD_STATUS, card.auto_report_sd_status());
+ TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_reporter.tick());
+ TERN_(AUTO_REPORT_SD_STATUS, card.auto_reporter.tick());
}
#endif
@@ -780,6 +703,10 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
// Update the LVGL interface
TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER());
+
+ IDLE_DONE:
+ TERN_(MARLIN_DEV_MODE, idle_depth--);
+ return;
}
/**
@@ -857,6 +784,7 @@ void minkill(const bool steppers_off/*=false*/) {
*/
void stop() {
thermalManager.disable_all_heaters(); // 'unpause' taken care of in here
+
print_job_timer.stop();
#if ENABLED(PROBING_FANS_OFF)
@@ -958,6 +886,27 @@ void setup() {
#endif
#define SETUP_RUN(C) do{ SETUP_LOG(STRINGIFY(C)); C; }while(0)
+ // Set up these pins early to prevent suicide
+ #if HAS_KILL
+ SETUP_LOG("KILL_PIN");
+ #if KILL_PIN_STATE
+ SET_INPUT_PULLDOWN(KILL_PIN);
+ #else
+ SET_INPUT_PULLUP(KILL_PIN);
+ #endif
+ #endif
+
+ #if HAS_SUICIDE
+ SETUP_LOG("SUICIDE_PIN");
+ OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
+ #endif
+
+ #if ENABLED(PSU_CONTROL)
+ SETUP_LOG("PSU_CONTROL");
+ powersupply_on = ENABLED(PSU_DEFAULT_OFF);
+ if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
+ #endif
+
#if EITHER(DISABLE_DEBUG, DISABLE_JTAG)
// Disable any hardware debug to free up pins for IO
#if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE)
@@ -970,14 +919,15 @@ void setup() {
#endif
MYSERIAL0.begin(BAUDRATE);
- uint32_t serial_connect_timeout = millis() + 1000UL;
- while (!MYSERIAL0 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+ millis_t serial_connect_timeout = millis() + 1000UL;
+ while (!MYSERIAL0.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+
#if HAS_MULTI_SERIAL && !HAS_ETHERNET
MYSERIAL1.begin(BAUDRATE);
serial_connect_timeout = millis() + 1000UL;
- while (!MYSERIAL1 && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+ while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
- SERIAL_ECHO_MSG("start");
+ SERIAL_ECHOLNPGM("start");
#if BOTH(HAS_TFT_LVGL_UI, MKS_WIFI_MODULE)
mks_esp_wifi_init();
@@ -1012,14 +962,10 @@ void setup() {
SETUP_RUN(recovery.setup());
#endif
- SETUP_RUN(setup_killpin());
-
#if HAS_TMC220x
SETUP_RUN(tmc_serial_begin());
#endif
- SETUP_RUN(setup_powerhold());
-
#if HAS_STEPPER_RESET
SETUP_RUN(disableStepperDrivers());
#endif
@@ -1095,6 +1041,10 @@ void setup() {
SETUP_RUN(ui.reset_status()); // Load welcome message early. (Retained if no errors exist.)
#endif
+ #if ENABLED(PROBE_TARE)
+ SETUP_RUN(probe.tare_init());
+ #endif
+
#if BOTH(SDSUPPORT, SDCARD_EEPROM_EMULATION)
SETUP_RUN(card.mount()); // Mount media with settings before first_load
#endif
@@ -1331,7 +1281,6 @@ void loop() {
idle();
#if ENABLED(SDSUPPORT)
- card.checkautostart();
if (card.flag.abort_sd_printing) abortSDPrinting();
if (marlin_state == MF_SD_COMPLETE) finishSDPrinting();
#endif
diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h
index 908636e967..d43d46bbd8 100644
--- a/Marlin/src/MarlinCore.h
+++ b/Marlin/src/MarlinCore.h
@@ -37,11 +37,6 @@ void stop();
void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep=false));
inline void idle_no_sleep() { idle(TERN_(ADVANCED_PAUSE_FEATURE, true)); }
-#if ENABLED(EXPERIMENTAL_I2CBUS)
- #include "feature/twibus.h"
- extern TWIBus i2c;
-#endif
-
#if ENABLED(G38_PROBE_TARGET)
extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type
extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed
@@ -59,8 +54,6 @@ void disable_all_steppers();
void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
void minkill(const bool steppers_off=false);
-void quickstop_stepper();
-
// Global State of the firmware
enum MarlinState : uint8_t {
MF_INITIALIZING = 0,
@@ -103,7 +96,6 @@ extern bool wait_for_heatup;
#endif
bool pin_is_protected(const pin_t pin);
-void protected_pin_err();
#if HAS_SUICIDE
inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_INVERTING); }
@@ -116,12 +108,4 @@ void protected_pin_err();
inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; }
#endif
-#if ENABLED(G29_RETRY_AND_RECOVER)
- void event_probe_recover();
- void event_probe_failure();
-#endif
-
-extern const char NUL_STR[], M112_KILL_STR[], G28_STR[], M21_STR[], M23_STR[], M24_STR[],
- SP_A_STR[], SP_B_STR[], SP_C_STR[],
- SP_P_STR[], SP_T_STR[], SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[],
- X_LBL[], Y_LBL[], Z_LBL[], E_LBL[], SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_E_LBL[];
+extern const char M112_KILL_STR[];
diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h
index e68ba196ee..afb6887766 100644
--- a/Marlin/src/core/boards.h
+++ b/Marlin/src/core/boards.h
@@ -113,7 +113,8 @@
#define BOARD_RAMPS_S_12_EEFB 1157 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_RAMPS_S_12_EEEB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
#define BOARD_RAMPS_S_12_EFFB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
-#define BOARD_RAMPS_LONGER3D_LK4PRO 1160 // Longer LKxxPRO/ Alfawise UxxPro (PRO version)
+#define BOARD_LONGER3D_LK1_PRO 1160 // Longer LK1 PRO / Alfawise U20 Pro (PRO version)
+#define BOARD_LONGER3D_LKx_PRO 1161 // Longer LKx PRO / Alfawise Uxx Pro (PRO version)
//
// RAMBo and derivatives
@@ -188,7 +189,7 @@
#define BOARD_GEN3_PLUS 1601 // Gen3+
#define BOARD_GEN6 1602 // Gen6
#define BOARD_GEN6_DELUXE 1603 // Gen6 deluxe
-#define BOARD_GEN7_CUSTOM 1604 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics"
+#define BOARD_GEN7_CUSTOM 1604 // Gen7 custom (Alfons3 Version) https://github.com/Alfons3/Generation_7_Electronics
#define BOARD_GEN7_12 1605 // Gen7 v1.1, v1.2
#define BOARD_GEN7_13 1606 // Gen7 v1.3
#define BOARD_GEN7_14 1607 // Gen7 v1.4
@@ -289,11 +290,11 @@
// STM32 ARM Cortex-M3
//
-#define BOARD_MALYAN_M200_V2 4000 // STM32F070CB STM32F0 controller
+#define BOARD_MALYAN_M200_V2 4000 // STM32F070CB controller
#define BOARD_MALYAN_M300 4001 // STM32F070-based delta
#define BOARD_STM32F103RE 4002 // STM32F103RE Libmaple-based STM32F1 controller
-#define BOARD_MALYAN_M200 4003 // STM32C8T6 Libmaple-based STM32F1 controller
-#define BOARD_STM3R_MINI 4004 // STM32F103RE Libmaple-based STM32F1 controller
+#define BOARD_MALYAN_M200 4003 // STM32C8T6 Libmaple-based STM32F1 controller
+#define BOARD_STM3R_MINI 4004 // STM32F103RE Libmaple-based STM32F1 controller
#define BOARD_GTM32_PRO_VB 4005 // STM32F103VET6 controller
#define BOARD_GTM32_MINI 4006 // STM32F103VET6 controller
#define BOARD_GTM32_MINI_A30 4007 // STM32F103VET6 controller
@@ -307,28 +308,37 @@
#define BOARD_MKS_ROBIN_LITE 4015 // MKS Robin Lite/Lite2 (STM32F103RCT6)
#define BOARD_MKS_ROBIN_LITE3 4016 // MKS Robin Lite3 (STM32F103RCT6)
#define BOARD_MKS_ROBIN_PRO 4017 // MKS Robin Pro (STM32F103ZET6)
-#define BOARD_MKS_ROBIN_E3 4018 // MKS Robin E3 (STM32F103RCT6)
-#define BOARD_MKS_ROBIN_E3D 4019 // MKS Robin E3D (STM32F103RCT6)
-#define BOARD_MKS_ROBIN_E3P 4020 // MKS Robin E3p (STM32F103VET6)
-#define BOARD_BTT_SKR_MINI_V1_1 4021 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
-#define BOARD_BTT_SKR_MINI_E3_V1_0 4022 // BigTreeTech SKR Mini E3 (STM32F103RC)
-#define BOARD_BTT_SKR_MINI_E3_V1_2 4023 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
-#define BOARD_BTT_SKR_MINI_E3_V2_0 4024 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC)
-#define BOARD_BTT_SKR_MINI_MZ_V1_0 4025 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
-#define BOARD_BTT_SKR_E3_DIP 4026 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
-#define BOARD_JGAURORA_A5S_A1 4027 // JGAurora A5S A1 (STM32F103ZET6)
-#define BOARD_FYSETC_AIO_II 4028 // FYSETC AIO_II
-#define BOARD_FYSETC_CHEETAH 4029 // FYSETC Cheetah
-#define BOARD_FYSETC_CHEETAH_V12 4030 // FYSETC Cheetah V1.2
-#define BOARD_LONGER3D_LK 4031 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
-#define BOARD_CCROBOT_MEEB_3DP 4032 // ccrobot-online.com MEEB_3DP (STM32F103RC)
-#define BOARD_CHITU3D_V5 4033 // Chitu3D TronXY X5SA V5 Board
-#define BOARD_CHITU3D_V6 4034 // Chitu3D TronXY X5SA V5 Board
-#define BOARD_CREALITY_V4 4035 // Creality v4.x (STM32F103RE)
-#define BOARD_CREALITY_V427 4036 // Creality v4.2.7 (STM32F103RE)
-#define BOARD_TRIGORILLA_PRO 4037 // Trigorilla Pro (STM32F103ZET6)
-#define BOARD_FLY_MINI 4038 // FLY MINI (STM32F103RCT6)
-#define BOARD_FLSUN_HISPEED 4039 // FLSUN HiSpeedV1 (STM32F103VET6)
+#define BOARD_MKS_ROBIN_E3 4018 // MKS Robin E3 (STM32F103RCT6)
+#define BOARD_MKS_ROBIN_E3_V1_1 4019 // MKS Robin E3 V1.1 (STM32F103RCT6)
+#define BOARD_MKS_ROBIN_E3D 4020 // MKS Robin E3D (STM32F103RCT6)
+#define BOARD_MKS_ROBIN_E3D_V1_1 4021 // MKS Robin E3D V1.1 (STM32F103RCT6)
+#define BOARD_MKS_ROBIN_E3P 4022 // MKS Robin E3p (STM32F103VET6)
+#define BOARD_BTT_SKR_MINI_V1_1 4023 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_E3_V1_0 4024 // BigTreeTech SKR Mini E3 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC)
+#define BOARD_BTT_SKR_MINI_MZ_V1_0 4027 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
+#define BOARD_BTT_SKR_E3_DIP 4028 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
+#define BOARD_BTT_SKR_CR6 4029 // BigTreeTech SKR CR6 v1.0 (STM32F103RE)
+#define BOARD_JGAURORA_A5S_A1 4030 // JGAurora A5S A1 (STM32F103ZET6)
+#define BOARD_FYSETC_AIO_II 4031 // FYSETC AIO_II
+#define BOARD_FYSETC_CHEETAH 4032 // FYSETC Cheetah
+#define BOARD_FYSETC_CHEETAH_V12 4033 // FYSETC Cheetah V1.2
+#define BOARD_LONGER3D_LK 4034 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
+#define BOARD_CCROBOT_MEEB_3DP 4035 // ccrobot-online.com MEEB_3DP (STM32F103RC)
+#define BOARD_CHITU3D_V5 4036 // Chitu3D TronXY X5SA V5 Board
+#define BOARD_CHITU3D_V6 4037 // Chitu3D TronXY X5SA V5 Board
+#define BOARD_CREALITY_V4 4038 // Creality v4.x (STM32F103RE)
+#define BOARD_CREALITY_V427 4039 // Creality v4.2.7 (STM32F103RE)
+#define BOARD_CREALITY_V4210 4040 // Creality v4.2.10 (STM32F103RE) as found in the CR-30
+#define BOARD_CREALITY_V431 4041 // Creality v4.3.1 (STM32F103RE)
+#define BOARD_CREALITY_V452 4042 // Creality v4.5.2 (STM32F103RE)
+#define BOARD_CREALITY_V453 4043 // Creality v4.5.3 (STM32F103RE)
+#define BOARD_TRIGORILLA_PRO 4044 // Trigorilla Pro (STM32F103ZET6)
+#define BOARD_FLY_MINI 4045 // FLY MINI (STM32F103RCT6)
+#define BOARD_FLSUN_HISPEED 4046 // FLSUN HiSpeedV1 (STM32F103VET6)
+#define BOARD_BEAST 4047 // STM32F103RET6 Libmaple-based controller
+#define BOARD_MINGDA_MPX_ARM_MINI 4048 // STM32F103ZET6 Mingda MD-16
//
// ARM Cortex-M4F
@@ -341,37 +351,39 @@
// STM32 ARM Cortex-M4F
//
-#define BOARD_BEAST 4200 // STM32F4xxVxT6 Libmaple-based STM32F4 controller
-#define BOARD_GENERIC_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller
-#define BOARD_ARMED 4202 // Arm'ed STM32F4-based controller
-#define BOARD_RUMBA32_V1_0 4203 // RUMBA32 STM32F446VET6 based controller from Aus3D
-#define BOARD_RUMBA32_V1_1 4204 // RUMBA32 STM32F446VET6 based controller from Aus3D
-#define BOARD_RUMBA32_MKS 4205 // RUMBA32 STM32F446VET6 based controller from Makerbase
-#define BOARD_BLACK_STM32F407VE 4206 // BLACK_STM32F407VE
-#define BOARD_BLACK_STM32F407ZE 4207 // BLACK_STM32F407ZE
-#define BOARD_STEVAL_3DP001V1 4208 // STEVAL-3DP001V1 3D PRINTER BOARD
-#define BOARD_BTT_SKR_PRO_V1_1 4209 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
-#define BOARD_BTT_SKR_PRO_V1_2 4210 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
-#define BOARD_BTT_BTT002_V1_0 4211 // BigTreeTech BTT002 v1.0 (STM32F407VG)
-#define BOARD_BTT_GTR_V1_0 4212 // BigTreeTech GTR v1.0 (STM32F407IGT)
-#define BOARD_LERDGE_K 4213 // Lerdge K (STM32F407ZG)
-#define BOARD_LERDGE_S 4214 // Lerdge S (STM32F407VE)
-#define BOARD_LERDGE_X 4215 // Lerdge X (STM32F407VE)
-#define BOARD_VAKE403D 4216 // VAkE 403D (STM32F446VET6)
-#define BOARD_FYSETC_S6 4217 // FYSETC S6 board
-#define BOARD_FYSETC_S6_V2_0 4218 // FYSETC S6 v2.0 board
-#define BOARD_FLYF407ZG 4219 // FLYF407ZG board (STM32F407ZG)
-#define BOARD_MKS_ROBIN2 4220 // MKS_ROBIN2 (STM32F407ZE)
+#define BOARD_ARMED 4200 // Arm'ed STM32F4-based controller
+#define BOARD_RUMBA32_V1_0 4201 // RUMBA32 STM32F446VET6 based controller from Aus3D
+#define BOARD_RUMBA32_V1_1 4202 // RUMBA32 STM32F446VET6 based controller from Aus3D
+#define BOARD_RUMBA32_MKS 4203 // RUMBA32 STM32F446VET6 based controller from Makerbase
+#define BOARD_BLACK_STM32F407VE 4204 // BLACK_STM32F407VE
+#define BOARD_BLACK_STM32F407ZE 4205 // BLACK_STM32F407ZE
+#define BOARD_STEVAL_3DP001V1 4206 // STEVAL-3DP001V1 3D PRINTER BOARD
+#define BOARD_BTT_SKR_PRO_V1_1 4207 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
+#define BOARD_BTT_SKR_PRO_V1_2 4208 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
+#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VG)
+#define BOARD_BTT_GTR_V1_0 4210 // BigTreeTech GTR v1.0 (STM32F407IGT)
+#define BOARD_LERDGE_K 4211 // Lerdge K (STM32F407ZG)
+#define BOARD_LERDGE_S 4212 // Lerdge S (STM32F407VE)
+#define BOARD_LERDGE_X 4213 // Lerdge X (STM32F407VE)
+#define BOARD_VAKE403D 4214 // VAkE 403D (STM32F446VET6)
+#define BOARD_FYSETC_S6 4215 // FYSETC S6 board
+#define BOARD_FYSETC_S6_V2_0 4216 // FYSETC S6 v2.0 board
+#define BOARD_FLYF407ZG 4217 // FLYF407ZG board (STM32F407ZG)
+#define BOARD_MKS_ROBIN2 4218 // MKS_ROBIN2 (STM32F407ZE)
+#define BOARD_MKS_ROBIN_PRO_V2 4219 // MKS Robin Pro V2 (STM32F407VE)
+#define BOARD_MKS_ROBIN_NANO_V3 4220 // MKS Robin Nano V3 (STM32F407VG)
+#define BOARD_ANET_ET4 4221 // ANET ET4 V1.x (STM32F407VGT6)
+#define BOARD_ANET_ET4P 4222 // ANET ET4P V1.x (STM32F407VGT6)
+#define BOARD_FYSETC_CHEETAH_V20 4223 // FYSETC Cheetah V2.0
//
// ARM Cortex M7
//
-#define BOARD_THE_BORG 5000 // THE-BORG (Power outputs: Hotend0, Hotend1, Bed, Fan)
-#define BOARD_REMRAM_V1 5001 // RemRam v1
-#define BOARD_TEENSY41 5002 // Teensy 4.1
-#define BOARD_T41U5XBB 5003 // T41U5XBB Teensy 4.1 breakout board
-#define BOARD_NUCLEO_F767ZI 5004 // ST NUCLEO-F767ZI Dev Board
+#define BOARD_REMRAM_V1 5000 // RemRam v1
+#define BOARD_TEENSY41 5001 // Teensy 4.1
+#define BOARD_T41U5XBB 5002 // T41U5XBB Teensy 4.1 breakout board
+#define BOARD_NUCLEO_F767ZI 5003 // ST NUCLEO-F767ZI Dev Board
//
// Espressif ESP32 WiFi
diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h
index f1e477933a..923ad903cb 100644
--- a/Marlin/src/core/language.h
+++ b/Marlin/src/core/language.h
@@ -68,6 +68,7 @@
// ro Romanian
// ru Russian
// sk Slovak
+// sv Swedish
// tr Turkish
// uk Ukrainian
// vi Vietnamese
@@ -91,7 +92,7 @@
#define MACHINE_UUID DEFAULT_MACHINE_UUID
#endif
-#define MARLIN_WEBSITE_URL "https://marlinfw.org"
+#define MARLIN_WEBSITE_URL "marlinfw.org"
//#if !defined(STRING_SPLASH_LINE3) && defined(WEBSITE_URL)
// #define STRING_SPLASH_LINE3 WEBSITE_URL
@@ -154,6 +155,7 @@
#define STR_Z4_MIN "z4_min"
#define STR_Z4_MAX "z4_max"
#define STR_Z_PROBE "z_probe"
+#define STR_PROBE_EN "probe_en"
#define STR_FILAMENT_RUNOUT_SENSOR "filament"
#define STR_PROBE_OFFSET "Probe Offset"
#define STR_SKEW_MIN "min_skew_factor: "
diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h
index 7985706173..dcc688ae29 100644
--- a/Marlin/src/core/macros.h
+++ b/Marlin/src/core/macros.h
@@ -53,6 +53,7 @@
#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
#define FORCE_INLINE __attribute__((always_inline)) inline
+#define NO_INLINE __attribute__((noinline))
#define _UNUSED __attribute__((unused))
#define _O0 __attribute__((optimize("O0")))
#define _Os __attribute__((optimize("Os")))
@@ -61,11 +62,7 @@
#define _O3 __attribute__((optimize("O3")))
#ifndef UNUSED
- #if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
- #define UNUSED(X) (void)X
- #else
- #define UNUSED(x) ((void)(x))
- #endif
+ #define UNUSED(x) ((void)(x))
#endif
// Clock speed factors
@@ -88,17 +85,13 @@
#define _BV(n) (1<<(n))
#define TEST(n,b) (!!((n)&_BV(b)))
#define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0)
-
#ifndef SBI
- #define SBI(A,B) (A |= (1 << (B)))
+ #define SBI(A,B) (A |= _BV(B))
#endif
-
#ifndef CBI
- #define CBI(A,B) (A &= ~(1 << (B)))
+ #define CBI(A,B) (A &= ~_BV(B))
#endif
-
#define TBI(N,B) (N ^= _BV(B))
-
#define _BV32(b) (1UL << (b))
#define TEST32(n,b) !!((n)&_BV32(b))
#define SBI32(n,b) (n |= _BV32(b))
@@ -155,7 +148,7 @@
#endif
-// Macros to chain up to 12 conditions
+// Macros to chain up to 14 conditions
#define _DO_1(W,C,A) (_##W##_1(A))
#define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B))
#define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V))
@@ -168,6 +161,9 @@
#define _DO_10(W,C,A,V...) (_##W##_1(A) C _DO_9(W,C,V))
#define _DO_11(W,C,A,V...) (_##W##_1(A) C _DO_10(W,C,V))
#define _DO_12(W,C,A,V...) (_##W##_1(A) C _DO_11(W,C,V))
+#define _DO_13(W,C,A,V...) (_##W##_1(A) C _DO_12(W,C,V))
+#define _DO_14(W,C,A,V...) (_##W##_1(A) C _DO_13(W,C,V))
+#define _DO_15(W,C,A,V...) (_##W##_1(A) C _DO_14(W,C,V))
#define __DO_N(W,C,N,V...) _DO_##N(W,C,V)
#define _DO_N(W,C,N,V...) __DO_N(W,C,N,V)
#define DO(W,C,V...) (_DO_N(W,C,NUM_ARGS(V),V))
@@ -218,6 +214,7 @@
#define ANY_BUTTON(V...) DO(BTNEX,||,V)
#define WITHIN(N,L,H) ((N) >= (L) && (N) <= (H))
+#define ISEOL(C) ((C) == '\n' || (C) == '\r')
#define NUMERIC(a) WITHIN(a, '0', '9')
#define DECIMAL(a) (NUMERIC(a) || a == '.')
#define HEXCHR(a) (NUMERIC(a) ? (a) - '0' : WITHIN(a, 'a', 'f') ? ((a) - 'a' + 10) : WITHIN(a, 'A', 'F') ? ((a) - 'A' + 10) : -1)
@@ -288,6 +285,7 @@
#define RSQRT(x) (1.0f / sqrtf(x))
#define CEIL(x) ceilf(x)
#define FLOOR(x) floorf(x)
+#define TRUNC(x) truncf(x)
#define LROUND(x) lroundf(x)
#define FMOD(x, y) fmodf(x, y)
#define HYPOT(x,y) SQRT(HYPOT2(x,y))
@@ -317,6 +315,32 @@
#endif
+ // C++11 solution that is standard compliant. is not available on all platform
+ namespace Private {
+ template struct enable_if { };
+ template struct enable_if { typedef _Tp type; };
+ }
+ // C++11 solution using SFINAE to detect the existance of a member in a class at compile time.
+ // It creates a HasMember structure containing 'value' set to true if the member exists
+ #define HAS_MEMBER_IMPL(Member) \
+ namespace Private { \
+ template struct HasMember_ ## Member { \
+ template static Yes& test( decltype(&C::Member) ) ; \
+ template static No& test(...); \
+ enum { value = sizeof(test(0)) == sizeof(Yes) }; }; \
+ }
+
+ // Call the method if it exists, but do nothing if it does not. The method is detected at compile time.
+ // If the method exists, this is inlined and does not cost anything. Else, an "empty" wrapper is created, returning a default value
+ #define CALL_IF_EXISTS_IMPL(Return, Method, ...) \
+ HAS_MEMBER_IMPL(Method) \
+ namespace Private { \
+ template FORCE_INLINE typename enable_if::value, Return>::type Call_ ## Method(T * t, Args... a) { return static_cast(t->Method(a...)); } \
+ _UNUSED static Return Call_ ## Method(...) { return __VA_ARGS__; } \
+ }
+ #define CALL_IF_EXISTS(Return, That, Method, ...) \
+ static_cast(Private::Call_ ## Method(That, ##__VA_ARGS__))
+
#else
#define MIN_2(a,b) ((a)<(b)?(a):(b))
diff --git a/Marlin/src/core/multi_language.h b/Marlin/src/core/multi_language.h
index 6af4af2f8d..5a26edf8d4 100644
--- a/Marlin/src/core/multi_language.h
+++ b/Marlin/src/core/multi_language.h
@@ -20,6 +20,8 @@
****************************************************************************/
#pragma once
+#include "../inc/MarlinConfigPre.h"
+
typedef const char Language_Str[];
#ifdef LCD_LANGUAGE_5
@@ -57,26 +59,27 @@ typedef const char Language_Str[];
#define GET_LANG(LANG) _GET_LANG(LANG)
#if NUM_LANGUAGES > 1
- extern uint8_t lang;
+ #define HAS_MULTI_LANGUAGE 1
#define GET_TEXT(MSG) ( \
- lang == 0 ? GET_LANG(LCD_LANGUAGE)::MSG : \
- lang == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
- lang == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
- lang == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \
- GET_LANG(LCD_LANGUAGE_5)::MSG \
- )
- #define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE)::CHARSIZE, \
- GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \
- GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \
- GET_LANG(LCD_LANGUAGE_4)::CHARSIZE, \
- GET_LANG(LCD_LANGUAGE_5)::CHARSIZE)
+ ui.language == 0 ? GET_LANG(LCD_LANGUAGE )::MSG : \
+ ui.language == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
+ ui.language == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
+ ui.language == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \
+ GET_LANG(LCD_LANGUAGE_5)::MSG )
+ #define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE )::CHARSIZE, \
+ GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \
+ GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \
+ GET_LANG(LCD_LANGUAGE_4)::CHARSIZE, \
+ GET_LANG(LCD_LANGUAGE_5)::CHARSIZE )
#else
#define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG
- #define MAX_LANG_CHARSIZE GET_LANG(LCD_LANGUAGE)::CHARSIZE
+ #define MAX_LANG_CHARSIZE LANG_CHARSIZE
#endif
#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
#define GET_LANGUAGE_NAME(INDEX) GET_LANG(LCD_LANGUAGE_##INDEX)::LANGUAGE
+#define LANG_CHARSIZE GET_TEXT(CHARSIZE)
+#define USE_WIDE_GLYPH (LANG_CHARSIZE > 2)
#define MSG_1_LINE(A) A "\0" "\0"
#define MSG_2_LINE(A,B) A "\0" B "\0"
diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp
index 0d22f7bfc0..365f28ba55 100644
--- a/Marlin/src/core/serial.cpp
+++ b/Marlin/src/core/serial.cpp
@@ -23,20 +23,41 @@
#include "serial.h"
#include "../inc/MarlinConfig.h"
+#if HAS_ETHERNET
+ #include "../feature/ethernet.h"
+#endif
+
uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE;
-static PGMSTR(errormagic, "Error:");
-static PGMSTR(echomagic, "echo:");
+// Commonly-used strings in serial output
+PGMSTR(NUL_STR, ""); PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T");
+PGMSTR(X_STR, "X"); PGMSTR(Y_STR, "Y"); PGMSTR(Z_STR, "Z"); PGMSTR(E_STR, "E");
+PGMSTR(X_LBL, "X:"); PGMSTR(Y_LBL, "Y:"); PGMSTR(Z_LBL, "Z:"); PGMSTR(E_LBL, "E:");
+PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
+PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E");
+PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
#if HAS_MULTI_SERIAL
- int8_t serial_port_index = 0;
+ #ifdef SERIAL_CATCHALL
+ SerialOutputT multiSerial(MYSERIAL, SERIAL_CATCHALL);
+ #else
+ #if HAS_ETHERNET
+ // Runtime checking of the condition variable
+ ConditionalSerial serialOut1(ethernet.have_telnet_client, MYSERIAL1, false); // Takes reference here
+ #else
+ // Don't pay for runtime checking a true variable, instead use the output directly
+ #define serialOut1 MYSERIAL1
+ #endif
+ SerialOutputT multiSerial(MYSERIAL0, serialOut1);
+ #endif
#endif
void serialprintPGM(PGM_P str) {
while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c);
}
-void serial_echo_start() { serialprintPGM(echomagic); }
-void serial_error_start() { serialprintPGM(errormagic); }
+
+void serial_echo_start() { static PGMSTR(echomagic, "echo:"); serialprintPGM(echomagic); }
+void serial_error_start() { static PGMSTR(errormagic, "Error:"); serialprintPGM(errormagic); }
void serial_echopair_PGM(PGM_P const s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
void serial_echopair_PGM(PGM_P const s_P, char v) { serialprintPGM(s_P); SERIAL_CHAR(v); }
@@ -65,8 +86,6 @@ void print_bin(uint16_t val) {
}
}
-extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[];
-
void print_xyz(const float &x, const float &y, const float &z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
if (prefix) serialprintPGM(prefix);
SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z);
diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h
index 4824866aeb..4c0c32f7d8 100644
--- a/Marlin/src/core/serial.h
+++ b/Marlin/src/core/serial.h
@@ -22,14 +22,19 @@
#pragma once
#include "../inc/MarlinConfig.h"
+#include "serial_hook.h"
-#if HAS_ETHERNET
- #include "../feature/ethernet.h"
-#endif
+// Commonly-used strings in serial output
+extern const char NUL_STR[], SP_P_STR[], SP_T_STR[],
+ X_STR[], Y_STR[], Z_STR[], E_STR[],
+ X_LBL[], Y_LBL[], Z_LBL[], E_LBL[],
+ SP_A_STR[], SP_B_STR[], SP_C_STR[],
+ SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[],
+ SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_E_LBL[];
-/**
- * Define debug bit-masks
- */
+//
+// Debugging flags for use by M111
+//
enum MarlinDebugFlags : uint8_t {
MARLIN_DEBUG_NONE = 0,
MARLIN_DEBUG_ECHO = _BV(0), ///< Echo commands in order as they are processed
@@ -50,39 +55,37 @@ enum MarlinDebugFlags : uint8_t {
extern uint8_t marlin_debug_flags;
#define DEBUGGING(F) (marlin_debug_flags & (MARLIN_DEBUG_## F))
-#define SERIAL_BOTH 0x7F
+//
+// Serial redirection
+//
+typedef int8_t serial_index_t;
+#define SERIAL_ALL 0x7F
#if HAS_MULTI_SERIAL
- extern int8_t serial_port_index;
- #define _PORT_REDIRECT(n,p) REMEMBER(n,serial_port_index,p)
- #define _PORT_RESTORE(n) RESTORE(n)
-
+ #define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
+ #define SERIAL_ASSERT(P) if(multiSerial.portMask!=(P)){ debugger(); }
#ifdef SERIAL_CATCHALL
- #define SERIAL_OUT(WHAT, V...) (void)CAT(MYSERIAL,SERIAL_CATCHALL).WHAT(V)
+ typedef MultiSerial SerialOutputT;
#else
- #define SERIAL_OUT(WHAT, V...) do{ \
- const bool port2_open = TERN1(HAS_ETHERNET, ethernet.have_telnet_client); \
- if ( serial_port_index == 0 || serial_port_index == SERIAL_BOTH) (void)MYSERIAL0.WHAT(V); \
- if ((serial_port_index == 1 || serial_port_index == SERIAL_BOTH) && port2_open) (void)MYSERIAL1.WHAT(V); \
- }while(0)
+ typedef MultiSerial, decltype(MYSERIAL1)), 0> SerialOutputT;
#endif
-
- #define SERIAL_ASSERT(P) if(serial_port_index!=(P)){ debugger(); }
+ extern SerialOutputT multiSerial;
+ #define SERIAL_IMPL multiSerial
#else
#define _PORT_REDIRECT(n,p) NOOP
- #define _PORT_RESTORE(n) NOOP
- #define SERIAL_OUT(WHAT, V...) (void)MYSERIAL0.WHAT(V)
#define SERIAL_ASSERT(P) NOOP
+ #define SERIAL_IMPL MYSERIAL0
#endif
+#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V)
+
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
-#define PORT_RESTORE() _PORT_RESTORE(1)
+#define SERIAL_PORTMASK(P) _BV(P)
#define SERIAL_ECHO(x) SERIAL_OUT(print, x)
#define SERIAL_ECHO_F(V...) SERIAL_OUT(print, V)
#define SERIAL_ECHOLN(x) SERIAL_OUT(println, x)
#define SERIAL_PRINT(x,b) SERIAL_OUT(print, x, b)
#define SERIAL_PRINTLN(x,b) SERIAL_OUT(println, x, b)
-#define SERIAL_PRINTF(V...) SERIAL_OUT(printf, V)
#define SERIAL_FLUSH() SERIAL_OUT(flush)
#ifdef ARDUINO_ARCH_STM32
diff --git a/Marlin/src/core/serial_base.h b/Marlin/src/core/serial_base.h
new file mode 100644
index 0000000000..220ccae831
--- /dev/null
+++ b/Marlin/src/core/serial_base.h
@@ -0,0 +1,146 @@
+/**
+ * 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 "../inc/MarlinConfigPre.h"
+
+#if ENABLED(EMERGENCY_PARSER)
+ #include "../feature/e_parser.h"
+#endif
+
+#ifndef DEC
+ #define DEC 10
+ #define HEX 16
+ #define OCT 8
+ #define BIN 2
+#endif
+
+// flushTX is not implemented in all HAL, so use SFINAE to call the method where it is.
+CALL_IF_EXISTS_IMPL(void, flushTX );
+CALL_IF_EXISTS_IMPL(bool, connected, true);
+
+// Using Curiously Recurring Template Pattern here to avoid virtual table cost when compiling.
+// Since the real serial class is known at compile time, this results in compiler writing a completely
+// efficient code
+template
+struct SerialBase {
+ #if ENABLED(EMERGENCY_PARSER)
+ const bool ep_enabled;
+ EmergencyParser::State emergency_state;
+ inline bool emergency_parser_enabled() { return ep_enabled; }
+ SerialBase(bool ep_capable) : ep_enabled(ep_capable), emergency_state(EmergencyParser::State::EP_RESET) {}
+ #else
+ SerialBase(const bool) {}
+ #endif
+
+ // Static dispatch methods below:
+ // The most important method here is where it all ends to:
+ size_t write(uint8_t c) { return static_cast(this)->write(c); }
+ // Called when the parser finished processing an instruction, usually build to nothing
+ void msgDone() { static_cast(this)->msgDone(); }
+ // Called upon initialization
+ void begin(const long baudRate) { static_cast(this)->begin(baudRate); }
+ // Called upon destruction
+ void end() { static_cast(this)->end(); }
+ /** Check for available data from the port
+ @param index The port index, usually 0 */
+ bool available(uint8_t index = 0) { return static_cast(this)->available(index); }
+ /** Read a value from the port
+ @param index The port index, usually 0 */
+ int read(uint8_t index = 0) { return static_cast(this)->read(index); }
+ // Check if the serial port is connected (usually bypassed)
+ bool connected() { return static_cast(this)->connected(); }
+ // Redirect flush
+ void flush() { static_cast(this)->flush(); }
+ // Not all implementation have a flushTX, so let's call them only if the child has the implementation
+ void flushTX() { CALL_IF_EXISTS(void, static_cast(this), flushTX); }
+
+ // Glue code here
+ FORCE_INLINE void write(const char* str) { while (*str) write(*str++); }
+ FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
+ FORCE_INLINE void print(const char* str) { write(str); }
+ NO_INLINE void print(char c, int base = 0) { print((long)c, base); }
+ NO_INLINE void print(unsigned char c, int base = 0) { print((unsigned long)c, base); }
+ NO_INLINE void print(int c, int base = DEC) { print((long)c, base); }
+ NO_INLINE void print(unsigned int c, int base = DEC) { print((unsigned long)c, base); }
+ void print(long c, int base = DEC) { if (!base) write(c); write((const uint8_t*)"-", c < 0); printNumber(c < 0 ? -c : c, base); }
+ void print(unsigned long c, int base = DEC) { printNumber(c, base); }
+ void print(double c, int digits = 2) { printFloat(c, digits); }
+
+ NO_INLINE void println(const char s[]) { print(s); println(); }
+ NO_INLINE void println(char c, int base = 0) { print(c, base); println(); }
+ NO_INLINE void println(unsigned char c, int base = 0) { print(c, base); println(); }
+ NO_INLINE void println(int c, int base = DEC) { print(c, base); println(); }
+ NO_INLINE void println(unsigned int c, int base = DEC) { print(c, base); println(); }
+ NO_INLINE void println(long c, int base = DEC) { print(c, base); println(); }
+ NO_INLINE void println(unsigned long c, int base = DEC) { print(c, base); println(); }
+ NO_INLINE void println(double c, int digits = 2) { print(c, digits); println(); }
+ NO_INLINE void println() { write('\r'); write('\n'); }
+
+ // Print a number with the given base
+ void printNumber(unsigned long n, const 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--) write((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
+ }
+ else write('0');
+ }
+
+ // Print a decimal number
+ void printFloat(double number, uint8_t digits) {
+ // Handle negative numbers
+ if (number < 0.0) {
+ write('-');
+ 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;
+ printNumber(int_part, 10);
+
+ // Print the decimal point, but only if there are digits beyond
+ if (digits) {
+ write('.');
+ // Extract digits from the remainder one at a time
+ while (digits--) {
+ remainder *= 10.0;
+ int toPrint = int(remainder);
+ printNumber(toPrint, 10);
+ remainder -= toPrint;
+ }
+ }
+ }
+};
+
+// All serial instances will be built by chaining the features required for the function in a form of a template
+// type definition
diff --git a/Marlin/src/core/serial_hook.h b/Marlin/src/core/serial_hook.h
new file mode 100644
index 0000000000..e14b821a9c
--- /dev/null
+++ b/Marlin/src/core/serial_hook.h
@@ -0,0 +1,234 @@
+/**
+ * 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 "serial_base.h"
+
+// The most basic serial class: it dispatch to the base serial class with no hook whatsoever. This will compile to nothing but the base serial class
+template
+struct BaseSerial : public SerialBase< BaseSerial