diff --git a/LICENSE b/LICENSE
index 4ad6d9b1e2..6c0e10f3b8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -3,7 +3,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (c) 2007 Free Software Foundation, Inc.
+ Copyright (c) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -673,5 +673,4 @@ into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-.
-
+.
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index ff07c4eed0..23f142ebac 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -34,9 +34,8 @@
* - Extra features
*
* Advanced settings can be found in Configuration_adv.h
- *
*/
-#define CONFIGURATION_H_VERSION 020006
+#define CONFIGURATION_H_VERSION 020007
//===========================================================================
//============================= Getting Started =============================
@@ -111,7 +110,6 @@
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
#define SERIAL_PORT_2 1
-#define NUM_SERIAL 2
/**
* This setting determines the communication speed of the printer.
@@ -391,6 +389,7 @@
* 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v excitation (STM32 \ LPC176x....)
* 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB)
* 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB)
+ * 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup)
* 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x
* 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
* 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup
@@ -487,29 +486,17 @@
#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
-
- // If you are using a pre-configured hotend then you can use one of the value sets by uncommenting it
-
- // Ultimaker
- //#define DEFAULT_Kp 22.2
- //#define DEFAULT_Ki 1.08
- //#define DEFAULT_Kd 114
-
- // MakerGear
- //#define DEFAULT_Kp 7.0
- //#define DEFAULT_Ki 0.1
- //#define DEFAULT_Kd 12
-
- // Mendel Parts V9 on 12V
- //#define DEFAULT_Kp 63.0
- //#define DEFAULT_Ki 2.25
- //#define DEFAULT_Kd 440
-
- //FB4S
- #define DEFAULT_Kp 17.04
- #define DEFAULT_Ki 1.31
- #define DEFAULT_Kd 55.34
-
+ #if ENABLED(PID_PARAMS_PER_HOTEND)
+ // Specify between 1 and HOTENDS values per array.
+ // If fewer than EXTRUDER values are provided, the last element will be repeated.
+ #define DEFAULT_Kp_LIST { 22.20, 20.0 }
+ #define DEFAULT_Ki_LIST { 1.08, 1.0 }
+ #define DEFAULT_Kd_LIST { 114.00, 112.0 }
+ #else
+ #define DEFAULT_Kp 17.04
+ #define DEFAULT_Ki 1.31
+ #define DEFAULT_Kd 55.34
+ #endif
#endif // PIDTEMP
//===========================================================================
@@ -551,11 +538,6 @@
//#define DEFAULT_bedKi .023
//#define DEFAULT_bedKd 305.4
- //120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
- //from pidautotune
- //#define DEFAULT_bedKp 97.1
- //#define DEFAULT_bedKi 1.41
- //#define DEFAULT_bedKd 1675.16
//FB4S
#define DEFAULT_bedKp 40.68
@@ -620,7 +602,7 @@
// @section machine
-// Uncomment one of these options to enable CoreXY, CoreXZ, or CoreYZ kinematics
+// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics,
// either in the usual order or reversed
//#define COREXY
//#define COREXZ
@@ -628,6 +610,7 @@
//#define COREYX
//#define COREZX
//#define COREZY
+//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042
//===========================================================================
//============================== Endstop Settings ===========================
@@ -879,7 +862,6 @@
* - For simple switches connect...
* - normally-closed switches to GND and D32.
* - normally-open switches to 5V and D32.
- *
*/
#define Z_MIN_PROBE_PIN BL_TOUCH_Z_PIN // Pin 32 is the RAMPS default
@@ -1580,14 +1562,14 @@ EEPROM_W25Q
// @section temperature
// Preheat Constants
-#define PREHEAT_1_LABEL "ABS"
-#define PREHEAT_1_TEMP_HOTEND 250
-#define PREHEAT_1_TEMP_BED 100
+#define PREHEAT_1_LABEL "PETG"
+#define PREHEAT_1_TEMP_HOTEND 235
+#define PREHEAT_1_TEMP_BED 80
#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255
-#define PREHEAT_2_LABEL "PETG"
-#define PREHEAT_2_TEMP_HOTEND 235
-#define PREHEAT_2_TEMP_BED 80
+#define PREHEAT_2_LABEL "ABS"
+#define PREHEAT_2_TEMP_HOTEND 250
+#define PREHEAT_2_TEMP_BED 100
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
/**
@@ -1649,7 +1631,6 @@ EEPROM_W25Q
*
* Caveats: The ending Z should be the same as starting Z.
* Attention: EXPERIMENTAL. G-code arguments may change.
- *
*/
//#define NOZZLE_CLEAN_FEATURE
@@ -1802,7 +1783,6 @@ EEPROM_W25Q
*
* SD Card support is disabled by default. If your controller has an SD slot,
* you must uncomment the following option or it won't work.
- *
*/
#define SDSUPPORT
@@ -2039,6 +2019,14 @@ EEPROM_W25Q
//
//#define FF_INTERFACEBOARD
+//
+// TFT GLCD Panel with Marlin UI
+// Panel connected to main board by SPI or I2C interface.
+// See https://github.com/Serhiy-K/TFTGLCDAdapter
+//
+//#define TFTGLCD_PANEL_SPI
+//#define TFTGLCD_PANEL_I2C
+
//=============================================================================
//======================= LCD / Controller Selection =======================
//========================= (Graphical LCDs) ========================
@@ -2242,6 +2230,9 @@ EEPROM_W25Q
// Touch-screen LCD for Malyan M200/M300 printers
//
//#define MALYAN_LCD
+#if ENABLED(MALYAN_LCD)
+ #define LCD_SERIAL_PORT 1 // Default is 1 for Malyan M200
+#endif
//
// Touch UI for FTDI EVE (FT800/FT810) displays
@@ -2255,7 +2246,7 @@ EEPROM_W25Q
//#define ANYCUBIC_LCD_I3MEGA
//#define ANYCUBIC_LCD_CHIRON
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
- #define ANYCUBIC_LCD_SERIAL_PORT 3
+ #define LCD_SERIAL_PORT 3 // Default is 3 for Anycubic
//#define ANYCUBIC_LCD_DEBUG
#endif
@@ -2412,7 +2403,6 @@ EEPROM_W25Q
* *** CAUTION ***
*
* LED Type. Enable only one of the following two options.
- *
*/
//#define RGB_LED
//#define RGBW_LED
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index b27932bb8e..6816524389 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -29,9 +29,8 @@
* Some of these settings can damage your printer if improperly set!
*
* Basic settings can be found in Configuration.h
- *
*/
-#define CONFIGURATION_ADV_H_VERSION 020006
+#define CONFIGURATION_ADV_H_VERSION 020007
// @section temperature
@@ -738,7 +737,6 @@
* | 4 3 | 1 4 | 2 1 | 3 2 |
* | | | | |
* | 1 2 | 2 3 | 3 4 | 4 1 |
- *
*/
#ifndef Z_STEPPER_ALIGN_XY
//#define Z_STEPPERS_ORIENTATION 0
@@ -771,9 +769,8 @@
//
// Add the G35 command to read bed corners to help adjust screws. Requires a bed probe.
//
-//#define ASSISTED_TRAMMING
+#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 } }
@@ -786,6 +783,9 @@
// Enable to restore leveling setup after operation
#define RESTORE_LEVELING_AFTER_G35
+ // Add a menu item for Assisted Tramming
+ //#define ASSISTED_TRAMMING_MENU_ITEM
+
/**
* Screw thread:
* M3: 30 = Clockwise, 31 = Counter-Clockwise
@@ -793,7 +793,6 @@
* M5: 50 = Clockwise, 51 = Counter-Clockwise
*/
#define TRAMMING_SCREW_THREAD 30
-
#endif
// @section motion
@@ -1025,7 +1024,7 @@
// @section lcd
#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
- #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
+ #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
#define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm)
#if ENABLED(ULTIPANEL)
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
@@ -1036,8 +1035,8 @@
// Change values more rapidly when the encoder is rotated faster
#define ENCODER_RATE_MULTIPLIER
#if ENABLED(ENCODER_RATE_MULTIPLIER)
- #define ENCODER_10X_STEPS_PER_SEC 50 // (steps/s) Encoder rate for 10x speed
- #define ENCODER_100X_STEPS_PER_SEC 200 // (steps/s) Encoder rate for 100x speed
+ #define ENCODER_10X_STEPS_PER_SEC 30 // (steps/s) Encoder rate for 10x speed
+ #define ENCODER_100X_STEPS_PER_SEC 80 // (steps/s) Encoder rate for 100x speed
#endif
// Play a beep when the feedrate is changed from the Status Screen
@@ -1105,23 +1104,26 @@
#define BOOTSCREEN_TIMEOUT 200 // (ms) Total Duration to display the boot screen(s)
#endif
-#if HAS_GRAPHICAL_LCD && EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
- //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
- //#define SHOW_REMAINING_TIME // Display estimated time to completion
+#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
+ //#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
+ //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
+ //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
#endif
-#endif
-#if HAS_CHARACTER_LCD && EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
- //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
- #if ENABLED(LCD_PROGRESS_BAR)
- #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar
- #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message
- #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever)
- //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it
- //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar
+ #if HAS_MARLINUI_U8GLIB
+ //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
+ #endif
+
+ #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
+ //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
+ #if ENABLED(LCD_PROGRESS_BAR)
+ #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar
+ #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message
+ #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever)
+ //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it
+ //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar
+ #endif
#endif
#endif
@@ -1164,6 +1166,7 @@
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
+ //#define POWER_LOSS_RECOVER_ZHOME // Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
//#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
@@ -1394,18 +1397,18 @@
//#define MARLIN_SNAKE
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
//
// Additional options for DGUS / DWIN displays
//
#if HAS_DGUS_LCD
- #define DGUS_SERIAL_PORT 3
- #define DGUS_BAUDRATE 115200
+ #define LCD_SERIAL_PORT 3
+ #define LCD_BAUDRATE 115200
#define DGUS_RX_BUFFER_SIZE 128
#define DGUS_TX_BUFFER_SIZE 48
- //#define DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR)
+ //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR)
#define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates
@@ -1571,6 +1574,7 @@
#if ENABLED(BABYSTEPPING)
//#define INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR
//#define BABYSTEP_WITHOUT_HOMING
+ #define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement).
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
#define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way
//#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps
@@ -1581,8 +1585,7 @@
#if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING)
#define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
// Note: Extra time may be added to mitigate controller latency.
- //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement).
- #define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle.
+ //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle.
#if ENABLED(MOVE_Z_WHEN_IDLE)
#define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size.
#endif
@@ -1949,7 +1952,6 @@
* Be sure to turn off auto-retract during filament change.
*
* Note that M207 / M208 / M209 settings are saved to EEPROM.
- *
*/
//#define FWRETRACT
#if ENABLED(FWRETRACT)
@@ -1975,7 +1977,7 @@
* Universal tool change settings.
* Applies to all types of extruders except where explicitly noted.
*/
-#if EXTRUDERS > 1
+#if HAS_MULTI_EXTRUDER
// Z raise distance for tool-change, as needed for some extruders
#define TOOLCHANGE_ZRAISE 2 // (mm)
//#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled)
@@ -2039,7 +2041,7 @@
//#define TOOLCHANGE_PARK_X_ONLY // X axis only move
//#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move
#endif
-#endif // EXTRUDERS > 1
+#endif // HAS_MULTI_EXTRUDER
/**
* Advanced Pause
@@ -2486,7 +2488,7 @@
#define E7_HYBRID_THRESHOLD 30
/**
- * Use StallGuard2 to home / probe X, Y, Z.
+ * Use StallGuard to home / probe X, Y, Z.
*
* TMC2130, TMC2160, TMC2209, TMC2660, TMC5130, and TMC5160 only
* Connect the stepper driver's DIAG1 pin to the X/Y endstop pin.
@@ -2507,6 +2509,8 @@
*
* IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when
* homing and adds a guard period for endstop triggering.
+ *
+ * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis.
*/
//#define SENSORLESS_HOMING // StallGuard capable drivers only
@@ -3227,6 +3231,7 @@
//#define HOST_ACTION_COMMANDS
#if ENABLED(HOST_ACTION_COMMANDS)
//#define HOST_PROMPT_SUPPORT
+ //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
#endif
/**
@@ -3334,6 +3339,7 @@
#define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max
#define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 }
#define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 }
+ //#define JOYSTICK_DEBUG
#endif
/**
@@ -3411,10 +3417,10 @@
#if ENABLED(PRUSA_MMU2)
// Serial port used for communication with MMU2.
- // For AVR enable the UART port used for the MMU. (e.g., internalSerial)
+ // 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 INTERNAL_SERIAL_PORT 2
- #define MMU2_SERIAL internalSerial
+ #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
@@ -3465,7 +3471,7 @@
*/
//#define MMU_EXTRUDER_SENSOR
#if ENABLED(MMU_EXTRUDER_SENSOR)
- #define MMU_LOADING_ATTEMPTS_NR 5 //max. number of attempts to load filament if first load fail
+ #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
#endif
/**
diff --git a/Marlin/Makefile b/Marlin/Makefile
index 95135ab594..68dd05bdfb 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -170,110 +170,114 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1100)
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
# Velleman K8400 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),1102)
-# Velleman K8600 Controller (derived from 3Drag Controller)
+# Velleman K8600 Controller (Vertex Nano)
else ifeq ($(HARDWARE_MOTHERBOARD),1103)
-# 2PrintBeta BAM&DICE with STK drivers
+# Velleman K8800 Controller (Vertex Delta)
else ifeq ($(HARDWARE_MOTHERBOARD),1104)
-# 2PrintBeta BAM&DICE Due with STK drivers
+# 2PrintBeta BAM&DICE with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
-# MKS BASE v1.0
+# 2PrintBeta BAM&DICE Due with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
-# MKS v1.4 with A4982 stepper drivers
+# MKS BASE v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
-# MKS v1.5 with Allegro A4982 stepper drivers
+# MKS v1.4 with A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
-# MKS v1.6 with Allegro A4982 stepper drivers
+# MKS v1.5 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
-# MKS BASE 1.0 with Heroic HR4982 stepper drivers
+# MKS v1.6 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
-# MKS GEN v1.3 or 1.4
+# MKS BASE 1.0 with Heroic HR4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
-# MKS GEN L
+# MKS GEN v1.3 or 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
-# zrib V2.0 control board (Chinese knock off RAMPS replica)
+# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
-# BigTreeTech or BIQU KFB2.0
+# zrib V2.0 control board (Chinese knock off RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
-# Felix 2.0+ Electronics Board (RAMPS like)
+# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
-# Invent-A-Part RigidBoard
+# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
-# Invent-A-Part RigidBoard V2
+# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
-# Sainsmart 2-in-1 board
+# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
-# Ultimaker
+# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
-# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
+# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
+# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
+else ifeq ($(HARDWARE_MOTHERBOARD),1121)
MCU ?= atmega1280
# Azteeg X3
-else ifeq ($(HARDWARE_MOTHERBOARD),1121)
-# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
-# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
+# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
-# Rumba
+# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
-# Raise3D Rumba
+# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
-# Rapide Lite RL200 Rumba
+# Raise3D Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
-# Formbot T-Rex 2 Plus
+# Rapide Lite RL200 Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
-# Formbot T-Rex 3
+# Formbot T-Rex 2 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
-# Formbot Raptor
+# Formbot T-Rex 3
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
-# Formbot Raptor 2
+# Formbot Raptor
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
-# bq ZUM Mega 3D
+# Formbot Raptor 2
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
-# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
+# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
-# TriGorilla Anycubic version 1.3 based on RAMPS EFB
+# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
-# TriGorilla Anycubic version 1.4 based on RAMPS EFB
+# TriGorilla Anycubic version 1.3 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
-# TriGorilla Anycubic version 1.4 Rev 1.1
+# TriGorilla Anycubic version 1.4 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
-# Creality: Ender-4, CR-8
+# TriGorilla Anycubic version 1.4 Rev 1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
-# Creality: CR10S, CR20, CR-X
+# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
-# Dagoma F5
+# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
-# FYSETC F6 1.3
+# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
-# FYSETC F6 1.5
+# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
-# Duplicator i3 Plus
+# FYSETC F6 1.5
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
-# VORON
+# Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
-# TRONXY V3 1.0
+# VORON
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
-# Z-Bolt X Series
+# TRONXY V3 1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
-# TT OSCAR
+# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
-# Overlord/Overlord Pro
+# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
-# ADIMLab Gantry v1
+# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
-# ADIMLab Gantry v2
+# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
-# BIQU Tango V1
+# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
-# MKS GEN L V2
+# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
-# Copymaster 3D
+# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
-# Ortur 4
+# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
-# Tenlog D3 Hero
+# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
+# Ortur 4
+else ifeq ($(HARDWARE_MOTHERBOARD),1154)
+# Tenlog D3 Hero
+else ifeq ($(HARDWARE_MOTHERBOARD),1155)
#
# RAMBo and derivatives
@@ -694,7 +698,7 @@ ifeq ($(HARDWARE_VARIANT), Teensy)
LIB_CXXSRC += usb_api.cpp
else ifeq ($(HARDWARE_VARIANT), archim)
- CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT="Archim"'
+ CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"'
LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp USBCore.cpp
LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
diff --git a/Marlin/Version.h b/Marlin/Version.h
index 5ce04b2903..5759771f7f 100644
--- a/Marlin/Version.h
+++ b/Marlin/Version.h
@@ -28,7 +28,7 @@
/**
* Marlin release version identifier
*/
-//#define SHORT_BUILD_VERSION "2.0.6.1"
+//#define SHORT_BUILD_VERSION "2.0.7"
/**
* Verbose version identifier which should contain a reference to the location
diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h
index 609375e386..b606d0c231 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
@@ -81,54 +82,29 @@ typedef int8_t pin_t;
// Serial ports
#ifdef USBCON
- #if ENABLED(BLUETOOTH)
- #define MYSERIAL0 bluetoothSerial
- #else
- #define MYSERIAL0 Serial
- #endif
- #define NUM_SERIAL 1
+ #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
-
#define MYSERIAL0 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
- #elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#endif
#define MYSERIAL1 customizedSerial2
- #define NUM_SERIAL 2
- #else
- #define NUM_SERIAL 1
#endif
#endif
-#ifdef DGUS_SERIAL_PORT
- #if !WITHIN(DGUS_SERIAL_PORT, -1, 3)
- #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
- #elif DGUS_SERIAL_PORT == SERIAL_PORT
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
+#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."
#endif
- #define DGUS_SERIAL internalDgusSerial
-
- #define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.get_tx_buffer_free
-#endif
-
-#ifdef ANYCUBIC_LCD_SERIAL_PORT
- #if !WITHIN(ANYCUBIC_LCD_SERIAL_PORT, -1, 3)
- #error "ANYCUBIC_LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
- #elif ANYCUBIC_LCD_SERIAL_PORT == SERIAL_PORT
- #error "ANYCUBIC_LCD_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && ANYCUBIC_LCD_SERIAL_PORT == SERIAL_PORT_2
- #error "ANYCUBIC_LCD_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
+ #define LCD_SERIAL lcdSerial
+ #if HAS_DGUS_LCD
+ #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
#endif
- #define ANYCUBIC_LCD_SERIAL anycubicLcdSerial
#endif
// ------------------------
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp
index 3d44a3f59f..63599efd41 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.cpp
+++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp
@@ -40,407 +40,370 @@
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
- #include "MarlinSerial.h"
- #include "../../MarlinCore.h"
+#include "MarlinSerial.h"
+#include "../../MarlinCore.h"
+
+#if ENABLED(DIRECT_STEPPING)
+ #include "../../feature/direct_stepping.h"
+#endif
+
+template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } };
+template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 };
+template bool MarlinSerial::_written = false;
+template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR;
+template uint8_t MarlinSerial::rx_dropped_bytes = 0;
+template uint8_t MarlinSerial::rx_buffer_overruns = 0;
+template uint8_t MarlinSerial::rx_framing_errors = 0;
+template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0;
+
+// A SW memory barrier, to ensure GCC does not overoptimize loops
+#define sw_barrier() asm volatile("": : :"memory");
+
+#include "../../feature/e_parser.h"
+
+// "Atomically" read the RX head index value without disabling interrupts:
+// This MUST be called with RX interrupts enabled, and CAN'T be called
+// from the RX ISR itself!
+template
+FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_head() {
+ if (Cfg::RX_SIZE > 256) {
+ // Keep reading until 2 consecutive reads return the same value,
+ // meaning there was no update in-between caused by an interrupt.
+ // This works because serial RX interrupts happen at a slower rate
+ // than successive reads of a variable, so 2 consecutive reads with
+ // the same value means no interrupt updated it.
+ ring_buffer_pos_t vold, vnew = rx_buffer.head;
+ sw_barrier();
+ do {
+ vold = vnew;
+ vnew = rx_buffer.head;
+ sw_barrier();
+ } while (vold != vnew);
+ return vnew;
+ }
+ else {
+ // With an 8bit index, reads are always atomic. No need for special handling
+ return rx_buffer.head;
+ }
+}
+
+template
+volatile bool MarlinSerial::rx_tail_value_not_stable = false;
+template
+volatile uint16_t MarlinSerial::rx_tail_value_backup = 0;
+
+// Set RX tail index, taking into account the RX ISR could interrupt
+// the write to this variable in the middle - So a backup strategy
+// is used to ensure reads of the correct values.
+// -Must NOT be called from the RX ISR -
+template
+FORCE_INLINE void MarlinSerial::atomic_set_rx_tail(typename MarlinSerial::ring_buffer_pos_t value) {
+ if (Cfg::RX_SIZE > 256) {
+ // Store the new value in the backup
+ rx_tail_value_backup = value;
+ sw_barrier();
+ // Flag we are about to change the true value
+ rx_tail_value_not_stable = true;
+ sw_barrier();
+ // Store the new value
+ rx_buffer.tail = value;
+ sw_barrier();
+ // Signal the new value is completely stored into the value
+ rx_tail_value_not_stable = false;
+ sw_barrier();
+ }
+ else
+ rx_buffer.tail = value;
+}
+
+// Get the RX tail index, taking into account the read could be
+// interrupting in the middle of the update of that index value
+// -Called from the RX ISR -
+template
+FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_tail() {
+ if (Cfg::RX_SIZE > 256) {
+ // If the true index is being modified, return the backup value
+ if (rx_tail_value_not_stable) return rx_tail_value_backup;
+ }
+ // The true index is stable, return it
+ return rx_buffer.tail;
+}
+
+// (called with RX interrupts disabled)
+template
+FORCE_INLINE void MarlinSerial::store_rxd_char() {
+
+ static EmergencyParser::State emergency_state; // = EP_RESET
+
+ // This must read the R_UCSRA register before reading the received byte to detect error causes
+ if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes;
+ if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns;
+ if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors;
+
+ // Read the character from the USART
+ uint8_t c = R_UDR;
#if ENABLED(DIRECT_STEPPING)
- #include "../../feature/direct_stepping.h"
+ if (page_manager.maybe_store_rxd_char(c)) return;
#endif
- template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } };
- template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 };
- template bool MarlinSerial::_written = false;
- template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR;
- template uint8_t MarlinSerial::rx_dropped_bytes = 0;
- template uint8_t MarlinSerial::rx_buffer_overruns = 0;
- template uint8_t MarlinSerial::rx_framing_errors = 0;
- template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0;
-
- // A SW memory barrier, to ensure GCC does not overoptimize loops
- #define sw_barrier() asm volatile("": : :"memory");
-
- #include "../../feature/e_parser.h"
-
- // "Atomically" read the RX head index value without disabling interrupts:
- // This MUST be called with RX interrupts enabled, and CAN'T be called
- // from the RX ISR itself!
- template
- FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_head() {
- if (Cfg::RX_SIZE > 256) {
- // Keep reading until 2 consecutive reads return the same value,
- // meaning there was no update in-between caused by an interrupt.
- // This works because serial RX interrupts happen at a slower rate
- // than successive reads of a variable, so 2 consecutive reads with
- // the same value means no interrupt updated it.
- ring_buffer_pos_t vold, vnew = rx_buffer.head;
- sw_barrier();
- do {
- vold = vnew;
- vnew = rx_buffer.head;
- sw_barrier();
- } while (vold != vnew);
- return vnew;
- }
- else {
- // With an 8bit index, reads are always atomic. No need for special handling
- return rx_buffer.head;
- }
- }
+ // Get the tail - Nothing can alter its value while this ISR is executing, but there's
+ // a chance that this ISR interrupted the main process while it was updating the index.
+ // The backup mechanism ensures the correct value is always returned.
+ const ring_buffer_pos_t t = atomic_read_rx_tail();
- template
- volatile bool MarlinSerial::rx_tail_value_not_stable = false;
- template
- volatile uint16_t MarlinSerial::rx_tail_value_backup = 0;
-
- // Set RX tail index, taking into account the RX ISR could interrupt
- // the write to this variable in the middle - So a backup strategy
- // is used to ensure reads of the correct values.
- // -Must NOT be called from the RX ISR -
- template
- FORCE_INLINE void MarlinSerial::atomic_set_rx_tail(typename MarlinSerial::ring_buffer_pos_t value) {
- if (Cfg::RX_SIZE > 256) {
- // Store the new value in the backup
- rx_tail_value_backup = value;
- sw_barrier();
- // Flag we are about to change the true value
- rx_tail_value_not_stable = true;
- sw_barrier();
- // Store the new value
- rx_buffer.tail = value;
- sw_barrier();
- // Signal the new value is completely stored into the value
- rx_tail_value_not_stable = false;
- sw_barrier();
- }
- else
- rx_buffer.tail = value;
- }
+ // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here
+ ring_buffer_pos_t h = rx_buffer.head;
- // Get the RX tail index, taking into account the read could be
- // interrupting in the middle of the update of that index value
- // -Called from the RX ISR -
- template
- FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_tail() {
- if (Cfg::RX_SIZE > 256) {
- // If the true index is being modified, return the backup value
- if (rx_tail_value_not_stable) return rx_tail_value_backup;
- }
- // The true index is stable, return it
- return rx_buffer.tail;
- }
+ // Get the next element
+ ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- // (called with RX interrupts disabled)
- template
- FORCE_INLINE void MarlinSerial::store_rxd_char() {
+ if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
+
+ // If the character is to be stored at the index just before the tail
+ // (such that the head would advance to the current tail), the RX FIFO is
+ // full, so don't write the character or advance the head.
+ if (i != t) {
+ rx_buffer.buffer[h] = c;
+ h = i;
+ }
+ else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
+ --rx_dropped_bytes;
- static EmergencyParser::State emergency_state; // = EP_RESET
+ if (Cfg::MAX_RX_QUEUED) {
+ // Calculate count of bytes stored into the RX buffer
+ const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- // This must read the R_UCSRA register before reading the received byte to detect error causes
- if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes;
- if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns;
- if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors;
+ // Keep track of the maximum count of enqueued bytes
+ NOLESS(rx_max_enqueued, rx_count);
+ }
- // Read the character from the USART
- uint8_t c = R_UDR;
+ if (Cfg::XONOFF) {
+ // If the last char that was sent was an XON
+ if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
- #if ENABLED(DIRECT_STEPPING)
- if (page_manager.maybe_store_rxd_char(c)) return;
- #endif
+ // Bytes stored into the RX buffer
+ const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- // Get the tail - Nothing can alter its value while this ISR is executing, but there's
- // a chance that this ISR interrupted the main process while it was updating the index.
- // The backup mechanism ensures the correct value is always returned.
- const ring_buffer_pos_t t = atomic_read_rx_tail();
+ // If over 12.5% of RX buffer capacity, send XOFF before running out of
+ // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react
+ // and stop sending bytes. This translates to 13mS propagation time.
+ if (rx_count >= (Cfg::RX_SIZE) / 8) {
- // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here
- ring_buffer_pos_t h = rx_buffer.head;
+ // At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted.
+ // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens
+ // to be in the middle of trying to disable the RX interrupt in the main program, eventually the
+ // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure
+ // the sending of the XOFF char is to send it HERE AND NOW.
- // Get the next element
- ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
+ // About to send the XOFF char
+ xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
- if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
+ // Wait until the TX register becomes empty and send it - Here there could be a problem
+ // - While waiting for the TX register to empty, the RX register could receive a new
+ // character. This must also handle that situation!
+ while (!B_UDRE) {
- // If the character is to be stored at the index just before the tail
- // (such that the head would advance to the current tail), the RX FIFO is
- // full, so don't write the character or advance the head.
- if (i != t) {
- rx_buffer.buffer[h] = c;
- h = i;
- }
- else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
- --rx_dropped_bytes;
+ if (B_RXC) {
+ // A char arrived while waiting for the TX buffer to be empty - Receive and process it!
- if (Cfg::MAX_RX_QUEUED) {
- // Calculate count of bytes stored into the RX buffer
- const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
+ i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- // Keep track of the maximum count of enqueued bytes
- NOLESS(rx_max_enqueued, rx_count);
- }
+ // Read the character from the USART
+ c = R_UDR;
- if (Cfg::XONOFF) {
- // If the last char that was sent was an XON
- if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
-
- // Bytes stored into the RX buffer
- const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
-
- // If over 12.5% of RX buffer capacity, send XOFF before running out of
- // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react
- // and stop sending bytes. This translates to 13mS propagation time.
- if (rx_count >= (Cfg::RX_SIZE) / 8) {
-
- // At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted.
- // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens
- // to be in the middle of trying to disable the RX interrupt in the main program, eventually the
- // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure
- // the sending of the XOFF char is to send it HERE AND NOW.
-
- // About to send the XOFF char
- xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
-
- // Wait until the TX register becomes empty and send it - Here there could be a problem
- // - While waiting for the TX register to empty, the RX register could receive a new
- // character. This must also handle that situation!
- while (!B_UDRE) {
-
- if (B_RXC) {
- // A char arrived while waiting for the TX buffer to be empty - Receive and process it!
-
- i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
-
- // Read the character from the USART
- c = R_UDR;
-
- if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
-
- // If the character is to be stored at the index just before the tail
- // (such that the head would advance to the current tail), the FIFO is
- // full, so don't write the character or advance the head.
- if (i != t) {
- rx_buffer.buffer[h] = c;
- h = i;
- }
- else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
- --rx_dropped_bytes;
- }
- sw_barrier();
- }
+ if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
- R_UDR = XOFF_CHAR;
-
- // Clear the TXC bit -- "can be cleared by writing a one to its bit
- // location". This makes sure flush() won't return until the bytes
- // actually got written
- B_TXC = 1;
-
- // At this point there could be a race condition between the write() function
- // and this sending of the XOFF char. This interrupt could happen between the
- // wait to be empty TX buffer loop and the actual write of the character. Since
- // the TX buffer is full because it's sending the XOFF char, the only way to be
- // sure the write() function will succeed is to wait for the XOFF char to be
- // completely sent. Since an extra character could be received during the wait
- // it must also be handled!
- while (!B_UDRE) {
-
- if (B_RXC) {
- // A char arrived while waiting for the TX buffer to be empty - Receive and process it!
-
- i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
-
- // Read the character from the USART
- c = R_UDR;
-
- if (Cfg::EMERGENCYPARSER)
- emergency_parser.update(emergency_state, c);
-
- // If the character is to be stored at the index just before the tail
- // (such that the head would advance to the current tail), the FIFO is
- // full, so don't write the character or advance the head.
- if (i != t) {
- rx_buffer.buffer[h] = c;
- h = i;
- }
- else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
- --rx_dropped_bytes;
+ // If the character is to be stored at the index just before the tail
+ // (such that the head would advance to the current tail), the FIFO is
+ // full, so don't write the character or advance the head.
+ if (i != t) {
+ rx_buffer.buffer[h] = c;
+ h = i;
}
- sw_barrier();
+ else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
+ --rx_dropped_bytes;
}
-
- // At this point everything is ready. The write() function won't
- // have any issues writing to the UART TX register if it needs to!
+ sw_barrier();
}
- }
- }
- // Store the new head value - The main loop will retry until the value is stable
- rx_buffer.head = h;
- }
+ R_UDR = XOFF_CHAR;
- // (called with TX irqs disabled)
- template
- FORCE_INLINE void MarlinSerial::_tx_udr_empty_irq() {
- if (Cfg::TX_SIZE > 0) {
- // Read positions
- uint8_t t = tx_buffer.tail;
- const uint8_t h = tx_buffer.head;
+ // Clear the TXC bit -- "can be cleared by writing a one to its bit
+ // location". This makes sure flush() won't return until the bytes
+ // actually got written
+ B_TXC = 1;
- if (Cfg::XONOFF) {
- // If an XON char is pending to be sent, do it now
- if (xon_xoff_state == XON_CHAR) {
+ // At this point there could be a race condition between the write() function
+ // and this sending of the XOFF char. This interrupt could happen between the
+ // wait to be empty TX buffer loop and the actual write of the character. Since
+ // the TX buffer is full because it's sending the XOFF char, the only way to be
+ // sure the write() function will succeed is to wait for the XOFF char to be
+ // completely sent. Since an extra character could be received during the wait
+ // it must also be handled!
+ while (!B_UDRE) {
- // Send the character
- R_UDR = XON_CHAR;
+ if (B_RXC) {
+ // A char arrived while waiting for the TX buffer to be empty - Receive and process it!
- // clear the TXC bit -- "can be cleared by writing a one to its bit
- // location". This makes sure flush() won't return until the bytes
- // actually got written
- B_TXC = 1;
+ i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- // Remember we sent it.
- xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
+ // Read the character from the USART
+ c = R_UDR;
- // If nothing else to transmit, just disable TX interrupts.
- if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
+ if (Cfg::EMERGENCYPARSER)
+ emergency_parser.update(emergency_state, c);
- return;
+ // If the character is to be stored at the index just before the tail
+ // (such that the head would advance to the current tail), the FIFO is
+ // full, so don't write the character or advance the head.
+ if (i != t) {
+ rx_buffer.buffer[h] = c;
+ h = i;
+ }
+ else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
+ --rx_dropped_bytes;
+ }
+ sw_barrier();
}
- }
- // If nothing to transmit, just disable TX interrupts. This could
- // happen as the result of the non atomicity of the disabling of RX
- // interrupts that could end reenabling TX interrupts as a side effect.
- if (h == t) {
- B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
- return;
+ // At this point everything is ready. The write() function won't
+ // have any issues writing to the UART TX register if it needs to!
}
-
- // There is something to TX, Send the next byte
- const uint8_t c = tx_buffer.buffer[t];
- t = (t + 1) & (Cfg::TX_SIZE - 1);
- R_UDR = c;
- tx_buffer.tail = t;
-
- // Clear the TXC bit (by writing a one to its bit location).
- // Ensures flush() won't return until the bytes are actually written/
- B_TXC = 1;
-
- // Disable interrupts if there is nothing to transmit following this byte
- if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
- }
- }
-
- // Public Methods
- template
- void MarlinSerial::begin(const long baud) {
- uint16_t baud_setting;
- bool useU2X = true;
-
- #if F_CPU == 16000000UL && SERIAL_PORT == 0
- // Hard-coded exception for compatibility with the bootloader shipped
- // with the Duemilanove and previous boards, and the firmware on the
- // 8U2 on the Uno and Mega 2560.
- if (baud == 57600) useU2X = false;
- #endif
-
- R_UCSRA = 0;
- if (useU2X) {
- B_U2X = 1;
- baud_setting = (F_CPU / 4 / baud - 1) / 2;
}
- else
- baud_setting = (F_CPU / 8 / baud - 1) / 2;
-
- // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
- R_UBRRH = baud_setting >> 8;
- R_UBRRL = baud_setting;
-
- B_RXEN = 1;
- B_TXEN = 1;
- B_RXCIE = 1;
- if (Cfg::TX_SIZE > 0) B_UDRIE = 0;
- _written = false;
}
- template
- void MarlinSerial::end() {
- B_RXEN = 0;
- B_TXEN = 0;
- B_RXCIE = 0;
- B_UDRIE = 0;
- }
+ // Store the new head value - The main loop will retry until the value is stable
+ rx_buffer.head = h;
+}
- template
- int MarlinSerial::peek() {
- const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
- return h == t ? -1 : rx_buffer.buffer[t];
- }
+// (called with TX irqs disabled)
+template
+FORCE_INLINE void MarlinSerial::_tx_udr_empty_irq() {
+ if (Cfg::TX_SIZE > 0) {
+ // Read positions
+ uint8_t t = tx_buffer.tail;
+ const uint8_t h = tx_buffer.head;
- template
- int MarlinSerial::read() {
- const ring_buffer_pos_t h = atomic_read_rx_head();
+ if (Cfg::XONOFF) {
+ // If an XON char is pending to be sent, do it now
+ if (xon_xoff_state == XON_CHAR) {
- // Read the tail. Main thread owns it, so it is safe to directly read it
- ring_buffer_pos_t t = rx_buffer.tail;
+ // Send the character
+ R_UDR = XON_CHAR;
- // If nothing to read, return now
- if (h == t) return -1;
+ // clear the TXC bit -- "can be cleared by writing a one to its bit
+ // location". This makes sure flush() won't return until the bytes
+ // actually got written
+ B_TXC = 1;
- // Get the next char
- const int v = rx_buffer.buffer[t];
- t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1);
+ // Remember we sent it.
+ xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
- // Advance tail - Making sure the RX ISR will always get an stable value, even
- // if it interrupts the writing of the value of that variable in the middle.
- atomic_set_rx_tail(t);
+ // If nothing else to transmit, just disable TX interrupts.
+ if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
- if (Cfg::XONOFF) {
- // If the XOFF char was sent, or about to be sent...
- if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
- // Get count of bytes in the RX buffer
- const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
- if (rx_count < (Cfg::RX_SIZE) / 10) {
- if (Cfg::TX_SIZE > 0) {
- // Signal we want an XON character to be sent.
- xon_xoff_state = XON_CHAR;
- // Enable TX ISR. Non atomic, but it will eventually enable them
- B_UDRIE = 1;
- }
- else {
- // If not using TX interrupts, we must send the XON char now
- xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
- while (!B_UDRE) sw_barrier();
- R_UDR = XON_CHAR;
- }
- }
+ return;
}
}
- return v;
- }
+ // If nothing to transmit, just disable TX interrupts. This could
+ // happen as the result of the non atomicity of the disabling of RX
+ // interrupts that could end reenabling TX interrupts as a side effect.
+ if (h == t) {
+ B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
+ return;
+ }
- template
- typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() {
- const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
- return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1);
+ // There is something to TX, Send the next byte
+ const uint8_t c = tx_buffer.buffer[t];
+ t = (t + 1) & (Cfg::TX_SIZE - 1);
+ R_UDR = c;
+ tx_buffer.tail = t;
+
+ // Clear the TXC bit (by writing a one to its bit location).
+ // Ensures flush() won't return until the bytes are actually written/
+ B_TXC = 1;
+
+ // Disable interrupts if there is nothing to transmit following this byte
+ if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
}
+}
- template
- void MarlinSerial::flush() {
+// Public Methods
+template
+void MarlinSerial::begin(const long baud) {
+ uint16_t baud_setting;
+ bool useU2X = true;
- // Set the tail to the head:
- // - Read the RX head index in a safe way. (See atomic_read_rx_head.)
- // - Set the tail, making sure the RX ISR will always get a stable value, even
- // if it interrupts the writing of the value of that variable in the middle.
- atomic_set_rx_tail(atomic_read_rx_head());
+ #if F_CPU == 16000000UL && SERIAL_PORT == 0
+ // Hard-coded exception for compatibility with the bootloader shipped
+ // with the Duemilanove and previous boards, and the firmware on the
+ // 8U2 on the Uno and Mega 2560.
+ if (baud == 57600) useU2X = false;
+ #endif
- if (Cfg::XONOFF) {
- // If the XOFF char was sent, or about to be sent...
- if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
+ R_UCSRA = 0;
+ if (useU2X) {
+ B_U2X = 1;
+ baud_setting = (F_CPU / 4 / baud - 1) / 2;
+ }
+ else
+ baud_setting = (F_CPU / 8 / baud - 1) / 2;
+
+ // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
+ R_UBRRH = baud_setting >> 8;
+ R_UBRRL = baud_setting;
+
+ B_RXEN = 1;
+ B_TXEN = 1;
+ B_RXCIE = 1;
+ if (Cfg::TX_SIZE > 0) B_UDRIE = 0;
+ _written = false;
+}
+
+template
+void MarlinSerial::end() {
+ B_RXEN = 0;
+ B_TXEN = 0;
+ B_RXCIE = 0;
+ B_UDRIE = 0;
+}
+
+template
+int MarlinSerial::peek() {
+ const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
+ return h == t ? -1 : rx_buffer.buffer[t];
+}
+
+template
+int MarlinSerial::read() {
+ const ring_buffer_pos_t h = atomic_read_rx_head();
+
+ // Read the tail. Main thread owns it, so it is safe to directly read it
+ ring_buffer_pos_t t = rx_buffer.tail;
+
+ // If nothing to read, return now
+ if (h == t) return -1;
+
+ // Get the next char
+ const int v = rx_buffer.buffer[t];
+ t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1);
+
+ // Advance tail - Making sure the RX ISR will always get an stable value, even
+ // if it interrupts the writing of the value of that variable in the middle.
+ atomic_set_rx_tail(t);
+
+ if (Cfg::XONOFF) {
+ // If the XOFF char was sent, or about to be sent...
+ if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
+ // Get count of bytes in the RX buffer
+ const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
+ if (rx_count < (Cfg::RX_SIZE) / 10) {
if (Cfg::TX_SIZE > 0) {
// Signal we want an XON character to be sent.
xon_xoff_state = XON_CHAR;
- // Enable TX ISR. Non atomic, but it will eventually enable it.
+ // Enable TX ISR. Non atomic, but it will eventually enable them
B_UDRIE = 1;
}
else {
@@ -453,363 +416,384 @@
}
}
- template
- void MarlinSerial::write(const uint8_t c) {
- if (Cfg::TX_SIZE == 0) {
-
- _written = true;
- while (!B_UDRE) sw_barrier();
- R_UDR = c;
-
- }
- else {
-
- _written = true;
-
- // If the TX interrupts are disabled and the data register
- // is empty, just write the byte to the data register and
- // be done. This shortcut helps significantly improve the
- // effective datarate at high (>500kbit/s) bitrates, where
- // interrupt overhead becomes a slowdown.
- // Yes, there is a race condition between the sending of the
- // XOFF char at the RX ISR, but it is properly handled there
- if (!B_UDRIE && B_UDRE) {
- R_UDR = c;
-
- // clear the TXC bit -- "can be cleared by writing a one to its bit
- // location". This makes sure flush() won't return until the bytes
- // actually got written
- B_TXC = 1;
- return;
- }
-
- const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
-
- // If global interrupts are disabled (as the result of being called from an ISR)...
- if (!ISRS_ENABLED()) {
-
- // Make room by polling if it is possible to transmit, and do so!
- while (i == tx_buffer.tail) {
-
- // If we can transmit another byte, do it.
- if (B_UDRE) _tx_udr_empty_irq();
-
- // Make sure compiler rereads tx_buffer.tail
- sw_barrier();
- }
+ return v;
+}
+
+template
+typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() {
+ const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
+ return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1);
+}
+
+template
+void MarlinSerial::flush() {
+
+ // Set the tail to the head:
+ // - Read the RX head index in a safe way. (See atomic_read_rx_head.)
+ // - Set the tail, making sure the RX ISR will always get a stable value, even
+ // if it interrupts the writing of the value of that variable in the middle.
+ atomic_set_rx_tail(atomic_read_rx_head());
+
+ if (Cfg::XONOFF) {
+ // If the XOFF char was sent, or about to be sent...
+ if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
+ if (Cfg::TX_SIZE > 0) {
+ // Signal we want an XON character to be sent.
+ xon_xoff_state = XON_CHAR;
+ // Enable TX ISR. Non atomic, but it will eventually enable it.
+ B_UDRIE = 1;
}
else {
- // Interrupts are enabled, just wait until there is space
- while (i == tx_buffer.tail) sw_barrier();
+ // If not using TX interrupts, we must send the XON char now
+ xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
+ while (!B_UDRE) sw_barrier();
+ R_UDR = XON_CHAR;
}
-
- // Store new char. head is always safe to move
- tx_buffer.buffer[tx_buffer.head] = c;
- tx_buffer.head = i;
-
- // Enable TX ISR - Non atomic, but it will eventually enable TX ISR
- B_UDRIE = 1;
}
}
+}
- template
- void MarlinSerial::flushTX() {
+template
+void MarlinSerial::write(const uint8_t c) {
+ if (Cfg::TX_SIZE == 0) {
- if (Cfg::TX_SIZE == 0) {
- // No bytes written, no need to flush. This special case is needed since there's
- // no way to force the TXC (transmit complete) bit to 1 during initialization.
- if (!_written) return;
+ _written = true;
+ while (!B_UDRE) sw_barrier();
+ R_UDR = c;
- // Wait until everything was transmitted
- while (!B_TXC) sw_barrier();
+ }
+ else {
- // At this point nothing is queued anymore (DRIE is disabled) and
- // the hardware finished transmission (TXC is set).
+ _written = true;
- }
- else {
+ // If the TX interrupts are disabled and the data register
+ // is empty, just write the byte to the data register and
+ // be done. This shortcut helps significantly improve the
+ // effective datarate at high (>500kbit/s) bitrates, where
+ // interrupt overhead becomes a slowdown.
+ // Yes, there is a race condition between the sending of the
+ // XOFF char at the RX ISR, but it is properly handled there
+ if (!B_UDRIE && B_UDRE) {
+ R_UDR = c;
- // No bytes written, no need to flush. This special case is needed since there's
- // no way to force the TXC (transmit complete) bit to 1 during initialization.
- if (!_written) return;
+ // clear the TXC bit -- "can be cleared by writing a one to its bit
+ // location". This makes sure flush() won't return until the bytes
+ // actually got written
+ B_TXC = 1;
+ return;
+ }
- // If global interrupts are disabled (as the result of being called from an ISR)...
- if (!ISRS_ENABLED()) {
+ const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
- // Wait until everything was transmitted - We must do polling, as interrupts are disabled
- while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
+ // If global interrupts are disabled (as the result of being called from an ISR)...
+ if (!ISRS_ENABLED()) {
- // If there is more space, send an extra character
- if (B_UDRE) _tx_udr_empty_irq();
+ // Make room by polling if it is possible to transmit, and do so!
+ while (i == tx_buffer.tail) {
- sw_barrier();
- }
+ // If we can transmit another byte, do it.
+ if (B_UDRE) _tx_udr_empty_irq();
+ // Make sure compiler rereads tx_buffer.tail
+ sw_barrier();
}
- else {
- // Wait until everything was transmitted
- while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier();
- }
-
- // At this point nothing is queued anymore (DRIE is disabled) and
- // the hardware finished transmission (TXC is set).
}
- }
-
- /**
- * 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 {
+ // Interrupts are enabled, just wait until there is space
+ while (i == tx_buffer.tail) sw_barrier();
}
- else
- printNumber(n, base);
- }
- template
- void MarlinSerial::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
- }
+ // Store new char. head is always safe to move
+ tx_buffer.buffer[tx_buffer.head] = c;
+ tx_buffer.head = i;
- template
- void MarlinSerial::print(double n, int digits) {
- printFloat(n, digits);
+ // Enable TX ISR - Non atomic, but it will eventually enable TX ISR
+ B_UDRIE = 1;
}
+}
- 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::flushTX() {
- template
- void MarlinSerial::println(char c, int base) {
- print(c, base);
- println();
- }
+ if (Cfg::TX_SIZE == 0) {
+ // No bytes written, no need to flush. This special case is needed since there's
+ // no way to force the TXC (transmit complete) bit to 1 during initialization.
+ if (!_written) return;
- template
- void MarlinSerial::println(unsigned char b, int base) {
- print(b, base);
- println();
- }
+ // Wait until everything was transmitted
+ while (!B_TXC) sw_barrier();
- template
- void MarlinSerial::println(int n, int base) {
- print(n, base);
- println();
- }
+ // At this point nothing is queued anymore (DRIE is disabled) and
+ // the hardware finished transmission (TXC is set).
- template
- void MarlinSerial::println(unsigned int n, int base) {
- print(n, base);
- println();
}
+ else {
- template
- void MarlinSerial::println(long n, int base) {
- print(n, base);
- println();
- }
+ // No bytes written, no need to flush. This special case is needed since there's
+ // no way to force the TXC (transmit complete) bit to 1 during initialization.
+ if (!_written) return;
- template
- void MarlinSerial::println(unsigned long n, int base) {
- print(n, base);
- println();
- }
+ // If global interrupts are disabled (as the result of being called from an ISR)...
+ if (!ISRS_ENABLED()) {
- template
- void MarlinSerial::println(double n, int digits) {
- print(n, digits);
- println();
- }
+ // Wait until everything was transmitted - We must do polling, as interrupts are disabled
+ while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
- // Private Methods
+ // If there is more space, send an extra character
+ if (B_UDRE) _tx_udr_empty_irq();
- 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;
+ sw_barrier();
}
- 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;
- }
+ else {
+ // Wait until everything was transmitted
+ while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier();
}
- }
- // Hookup ISR handlers
- ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)) {
- MarlinSerial>::store_rxd_char();
+ // At this point nothing is queued anymore (DRIE is disabled) and
+ // the hardware finished transmission (TXC is set).
}
+}
- ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)) {
- MarlinSerial>::_tx_udr_empty_irq();
- }
-
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> customizedSerial1;
-
- #ifdef SERIAL_PORT_2
+/**
+ * Imports from print.h
+ */
- // Hookup ISR handlers
- ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_RX_vect)) {
- MarlinSerial>::store_rxd_char();
+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;
}
-
- ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_UDRE_vect)) {
- MarlinSerial>::_tx_udr_empty_irq();
+ 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;
}
+ }
+}
- // Preinstantiate
- template class MarlinSerial>;
+// Hookup ISR handlers
+ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) {
+ MarlinSerial>::store_rxd_char();
+}
- // Instantiate
- MarlinSerial> customizedSerial2;
+ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
+ MarlinSerial>::_tx_udr_empty_irq();
+}
- #endif
+// Preinstantiate
+template class MarlinSerial>;
-#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
+// Instantiate
+MarlinSerial> customizedSerial1;
-#ifdef INTERNAL_SERIAL_PORT
+#ifdef SERIAL_PORT_2
- ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_RX_vect)) {
- MarlinSerial>::store_rxd_char();
+ // Hookup ISR handlers
+ ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _RX_vect)) {
+ MarlinSerial>::store_rxd_char();
}
- ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_UDRE_vect)) {
- MarlinSerial>::_tx_udr_empty_irq();
+ ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _UDRE_vect)) {
+ MarlinSerial>::_tx_udr_empty_irq();
}
// Preinstantiate
- template class MarlinSerial>;
+ template class MarlinSerial>;
// Instantiate
- MarlinSerial> internalSerial;
+ MarlinSerial> customizedSerial2;
#endif
-#ifdef DGUS_SERIAL_PORT
-
- template
- typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() {
- const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
- h = tx_buffer.head; // next pos for queue.
- int ret = t - h - 1;
- if (ret < 0) ret += Cfg::TX_SIZE + 1;
- return ret;
- }
+#ifdef MMU2_SERIAL_PORT
- ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_RX_vect)) {
- MarlinSerial>::store_rxd_char();
+ ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) {
+ MarlinSerial>::store_rxd_char();
}
- ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_UDRE_vect)) {
- MarlinSerial>::_tx_udr_empty_irq();
+ ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _UDRE_vect)) {
+ MarlinSerial>::_tx_udr_empty_irq();
}
// Preinstantiate
- template class MarlinSerial>;
+ template class MarlinSerial>;
// Instantiate
- MarlinSerial> internalDgusSerial;
+ MarlinSerial> mmuSerial;
#endif
-#ifdef ANYCUBIC_LCD_SERIAL_PORT
+#ifdef LCD_SERIAL_PORT
- ISR(SERIAL_REGNAME(USART,ANYCUBIC_LCD_SERIAL_PORT,_RX_vect)) {
- MarlinSerial>::store_rxd_char();
+ ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _RX_vect)) {
+ MarlinSerial>::store_rxd_char();
}
- ISR(SERIAL_REGNAME(USART,ANYCUBIC_LCD_SERIAL_PORT,_UDRE_vect)) {
- MarlinSerial>::_tx_udr_empty_irq();
+ ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _UDRE_vect)) {
+ MarlinSerial>::_tx_udr_empty_irq();
}
// Preinstantiate
- template class MarlinSerial>;
+ template class MarlinSerial>;
// Instantiate
- MarlinSerial> anycubicLcdSerial;
+ MarlinSerial> lcdSerial;
+
+ #if HAS_DGUS_LCD
+ template
+ typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() {
+ const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
+ h = tx_buffer.head; // next pos for queue.
+ int ret = t - h - 1;
+ if (ret < 0) ret += Cfg::TX_SIZE + 1;
+ return ret;
+ }
+ #endif
#endif
+#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
+
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h
index e8bfc5583a..8a0423d143 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.h
+++ b/Marlin/src/HAL/AVR/MarlinSerial.h
@@ -48,11 +48,11 @@
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
// requires two levels of indirection to expand macro values properly)
- #define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
+ #define SERIAL_REGNAME(registerbase,number,suffix) _SERIAL_REGNAME(registerbase,number,suffix)
#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
- #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix
+ #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##suffix
#else
- #define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
+ #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##number##suffix
#endif
// Registers used by MarlinSerial class (expanded depending on selected serial port)
@@ -217,10 +217,12 @@
static ring_buffer_pos_t available();
static void write(const uint8_t c);
static void flushTX();
- #ifdef DGUS_SERIAL_PORT
+ #if HAS_DGUS_LCD
static ring_buffer_pos_t get_tx_buffer_free();
#endif
+ 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; }
@@ -278,55 +280,50 @@
#endif // !USBCON
-#ifdef INTERNAL_SERIAL_PORT
+#ifdef MMU2_SERIAL_PORT
template
- struct MarlinInternalSerialCfg {
+ struct MMU2SerialCfg {
static constexpr int PORT = serial;
- static constexpr unsigned int RX_SIZE = 32;
- static constexpr unsigned int TX_SIZE = 32;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
- static constexpr bool RX_OVERRUNS = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
+ static constexpr unsigned int RX_SIZE = 32;
+ static constexpr unsigned int TX_SIZE = 32;
+ static constexpr bool RX_OVERRUNS = false;
};
- extern MarlinSerial> internalSerial;
+ extern MarlinSerial> mmuSerial;
#endif
-#ifdef DGUS_SERIAL_PORT
- template
- struct MarlinInternalSerialCfg {
- static constexpr int PORT = serial;
- static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
- static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
- static constexpr bool XONOFF = false;
- static constexpr bool EMERGENCYPARSER = false;
- static constexpr bool DROPPED_RX = false;
- static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS);
- static constexpr bool RX_FRAMING_ERRORS = false;
- static constexpr bool MAX_RX_QUEUED = false;
- };
-
- extern MarlinSerial> internalDgusSerial;
-#endif
+#ifdef LCD_SERIAL_PORT
-#ifdef ANYCUBIC_LCD_SERIAL_PORT
template
- struct AnycubicLcdSerialCfg {
- static constexpr int PORT = serial;
- static constexpr unsigned int RX_SIZE = 64;
- static constexpr unsigned int TX_SIZE = 128;
- static constexpr bool XONOFF = false;
- static constexpr bool EMERGENCYPARSER = false;
- static constexpr bool DROPPED_RX = false;
- static constexpr bool RX_OVERRUNS = false;
- static constexpr bool RX_FRAMING_ERRORS = false;
- static constexpr bool MAX_RX_QUEUED = false;
+ struct LCDSerialCfg {
+ static constexpr int PORT = serial;
+ static constexpr bool XONOFF = false;
+ static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
+ static constexpr bool DROPPED_RX = false;
+ static constexpr bool RX_FRAMING_ERRORS = false;
+ static constexpr bool MAX_RX_QUEUED = false;
+ #if HAS_DGUS_LCD
+ static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
+ static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
+ static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
+ #elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
+ static constexpr unsigned int RX_SIZE = 64;
+ static constexpr unsigned int TX_SIZE = 128;
+ static constexpr bool RX_OVERRUNS = false;
+ #else
+ static constexpr unsigned int RX_SIZE = 64;
+ static constexpr unsigned int TX_SIZE = 128;
+ static constexpr bool RX_OVERRUNS = false
+ #endif
};
- extern MarlinSerial> anycubicLcdSerial;
+ extern MarlinSerial> lcdSerial;
+
#endif
// Use the UART for Bluetooth in AT90USB configurations
diff --git a/Marlin/src/HAL/AVR/Servo.cpp b/Marlin/src/HAL/AVR/Servo.cpp
index 66ed993c6f..526352b773 100644
--- a/Marlin/src/HAL/AVR/Servo.cpp
+++ b/Marlin/src/HAL/AVR/Servo.cpp
@@ -48,7 +48,6 @@
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
* attached() - Return true if a servo is attached.
* detach() - Stop an attached servo from pulsing its i/o pin.
- *
*/
#ifdef __AVR__
diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h
index bd6935aaf0..dd01634661 100644
--- a/Marlin/src/HAL/AVR/fastio.h
+++ b/Marlin/src/HAL/AVR/fastio.h
@@ -29,11 +29,17 @@
#include
-#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__))
-#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
-#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
-#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
-#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
+#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__)
+ #define AVR_AT90USB1286_FAMILY 1
+#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
+ #define AVR_ATmega1284_FAMILY 1
+#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+ #define AVR_ATmega2560_FAMILY 1
+#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
+ #define AVR_ATmega2561_FAMILY 1
+#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
+ #define AVR_ATmega328_FAMILY 1
+#endif
/**
* Include Ports and Functions
diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h
index d73f520d14..dac6b1b150 100644
--- a/Marlin/src/HAL/AVR/pinsDebug.h
+++ b/Marlin/src/HAL/AVR/pinsDebug.h
@@ -26,7 +26,9 @@
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
-#define AVR_ATmega2560_FAMILY_PLUS_70 MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H)
+#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
+ #define AVR_ATmega2560_FAMILY_PLUS_70 1
+#endif
#if AVR_AT90USB1286_FAMILY
diff --git a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
index 46c03088d2..db3fdf1f76 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
@@ -22,15 +22,12 @@
* Structures for 2560 family boards that use more than 70 pins
*/
-#undef NUM_DIGITAL_PINS
-#if MB(BQ_ZUM_MEGA_3D)
+#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
+ #undef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 85
#elif MB(MIGHTYBOARD_REVE)
+ #undef NUM_DIGITAL_PINS
#define NUM_DIGITAL_PINS 80
-#elif MB(MINIRAMBO)
- #define NUM_DIGITAL_PINS 85
-#elif MB(SCOOVO_X9H)
- #define NUM_DIGITAL_PINS 85
#endif
#define PA 1
diff --git a/Marlin/src/HAL/AVR/timers.h b/Marlin/src/HAL/AVR/timers.h
index 6c40d32209..82eb8b14b1 100644
--- a/Marlin/src/HAL/AVR/timers.h
+++ b/Marlin/src/HAL/AVR/timers.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
diff --git a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
index c29b195578..cb95a48ccc 100644
--- a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
+++ b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include "../shared/Marduino.h"
#include "../shared/Delay.h"
@@ -189,5 +189,5 @@ uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h
index 31409c76dd..7a057fdae4 100644
--- a/Marlin/src/HAL/DUE/HAL.h
+++ b/Marlin/src/HAL/DUE/HAL.h
@@ -38,59 +38,36 @@
#include
+#define _MSERIAL(X) Serial##X
+#define MSERIAL(X) _MSERIAL(X)
+#define Serial0 Serial
+
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL0 customizedSerial1
-#elif SERIAL_PORT == 0
- #define MYSERIAL0 Serial
-#elif SERIAL_PORT == 1
- #define MYSERIAL0 Serial1
-#elif SERIAL_PORT == 2
- #define MYSERIAL0 Serial2
-#elif SERIAL_PORT == 3
- #define MYSERIAL0 Serial3
+#elif WITHIN(SERIAL_PORT, 0, 3)
+ #define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #if SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
- #elif SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
+ #if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL1 customizedSerial2
- #elif SERIAL_PORT_2 == 0
- #define MYSERIAL1 Serial
- #elif SERIAL_PORT_2 == 1
- #define MYSERIAL1 Serial1
- #elif SERIAL_PORT_2 == 2
- #define MYSERIAL1 Serial2
- #elif SERIAL_PORT_2 == 3
- #define MYSERIAL1 Serial3
+ #elif WITHIN(SERIAL_PORT_2, 0, 3)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
- #define NUM_SERIAL 2
-#else
- #define NUM_SERIAL 1
#endif
-#ifdef DGUS_SERIAL_PORT
- #if DGUS_SERIAL_PORT == SERIAL_PORT
- #error "DGUS_SERIAL_PORT must be different from SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
- #elif DGUS_SERIAL_PORT == -1
- #define DGUS_SERIAL internalDgusSerial
- #elif DGUS_SERIAL_PORT == 0
- #define DGUS_SERIAL Serial
- #elif DGUS_SERIAL_PORT == 1
- #define DGUS_SERIAL Serial1
- #elif DGUS_SERIAL_PORT == 2
- #define DGUS_SERIAL Serial2
- #elif DGUS_SERIAL_PORT == 3
- #define DGUS_SERIAL Serial3
+#ifdef LCD_SERIAL_PORT
+ #if LCD_SERIAL_PORT == -1
+ #define LCD_SERIAL lcdSerial
+ #elif WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
diff --git a/Marlin/src/HAL/DUE/HAL_SPI.cpp b/Marlin/src/HAL/DUE/HAL_SPI.cpp
index 6d8f7ef819..54ae8eceb1 100644
--- a/Marlin/src/HAL/DUE/HAL_SPI.cpp
+++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp
@@ -595,7 +595,7 @@
SPI_Enable(SPI0);
SET_OUTPUT(DAC0_SYNC);
- #if EXTRUDERS > 1
+ #if HAS_MULTI_EXTRUDER
SET_OUTPUT(DAC1_SYNC);
WRITE(DAC1_SYNC, HIGH);
#endif
@@ -759,7 +759,6 @@
*
* All of the above can be avoided by defining FORCE_SOFT_SPI to force the
* display to use software SPI.
- *
*/
void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified)
diff --git a/Marlin/src/HAL/DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h
index dfafa15141..a194eba2f3 100644
--- a/Marlin/src/HAL/DUE/MarlinSerial.h
+++ b/Marlin/src/HAL/DUE/MarlinSerial.h
@@ -122,6 +122,8 @@ public:
static void write(const uint8_t c);
static void flushTX();
+ 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; }
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 2ef7011b1c..be4b49c0f9 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
@@ -52,14 +52,13 @@
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#ifdef __SAM3X8E__
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
@@ -145,6 +144,6 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
-#endif //__SAM3X8E__
+#endif // __SAM3X8E__
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
index 54c244d4f6..ea7204fa36 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
@@ -144,5 +144,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
index 960df1bd86..615a386c35 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include "../../shared/Delay.h"
@@ -108,5 +108,5 @@ void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
}
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/eeprom_flash.cpp b/Marlin/src/HAL/DUE/eeprom_flash.cpp
index d98f06039f..67f1f9e40f 100644
--- a/Marlin/src/HAL/DUE/eeprom_flash.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_flash.cpp
@@ -53,7 +53,6 @@
* per page. We can't emulate EE endurance with FLASH for all
* bytes, but we can emulate endurance for a given percent of
* bytes.
- *
*/
//#define EE_EMU_DEBUG
diff --git a/Marlin/src/HAL/DUE/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h
index 28687ff267..a99ca8ecce 100644
--- a/Marlin/src/HAL/DUE/pinsDebug.h
+++ b/Marlin/src/HAL/DUE/pinsDebug.h
@@ -179,5 +179,4 @@ void pwm_details(int32_t pin) {
* ----------------+--------
* ID | PB11
* VBOF | PB10
- *
*/
diff --git a/Marlin/src/HAL/DUE/usb/compiler.h b/Marlin/src/HAL/DUE/usb/compiler.h
index 7b746543c4..879007fa2a 100644
--- a/Marlin/src/HAL/DUE/usb/compiler.h
+++ b/Marlin/src/HAL/DUE/usb/compiler.h
@@ -173,11 +173,11 @@
# define __always_inline __forceinline
#elif (defined __GNUC__)
#ifdef __always_inline
-# undef __always_inline
+# undef __always_inline
#endif
-# define __always_inline inline __attribute__((__always_inline__))
+# define __always_inline inline __attribute__((__always_inline__))
#elif (defined __ICCARM__)
-# define __always_inline _Pragma("inline=forced")
+# define __always_inline _Pragma("inline=forced")
#endif
/**
@@ -188,11 +188,11 @@
* heuristics and not inline the function.
*/
#ifdef __CC_ARM
-# define __no_inline __attribute__((noinline))
+# define __no_inline __attribute__((noinline))
#elif (defined __GNUC__)
-# define __no_inline __attribute__((__noinline__))
+# define __no_inline __attribute__((__noinline__))
#elif (defined __ICCARM__)
-# define __no_inline _Pragma("inline=never")
+# define __no_inline _Pragma("inline=never")
#endif
/*! \brief This macro is used to test fatal errors.
@@ -211,9 +211,9 @@
# else
#undef TEST_SUITE_DEFINE_ASSERT_MACRO
# define Assert(expr) \
- {\
- if (!(expr)) while (true);\
- }
+ {\
+ if (!(expr)) while (true);\
+ }
# endif
#else
# define Assert(expr) ((void) 0)
@@ -1106,17 +1106,16 @@ static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data)
/* Converts a 8 Byte array into a 32-Bit value */
static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data)
{
- union
- {
- uint32_t u32;
- uint8_t u8[8];
- }long_addr;
- uint8_t index;
- for (index = 0; index < 4; index++)
- {
- long_addr.u8[index] = *data++;
- }
- return long_addr.u32;
+ union
+ {
+ uint32_t u32;
+ uint8_t u8[8];
+ }long_addr;
+ uint8_t index;
+ for (index = 0; index < 4; index++) {
+ long_addr.u8[index] = *data++;
+ }
+ return long_addr.u32;
}
/**
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index c91f9efff0..f6fa46dd93 100644
--- a/Marlin/src/HAL/ESP32/HAL.h
+++ b/Marlin/src/HAL/ESP32/HAL.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
@@ -58,9 +59,6 @@ extern portMUX_TYPE spinlock;
#else
#define MYSERIAL1 webSocketSerial
#endif
- #define NUM_SERIAL 2
-#else
- #define NUM_SERIAL 1
#endif
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock)
diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
index 533f873e4f..ca7f47a1f8 100644
--- a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
+++ b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
@@ -86,7 +86,7 @@ int RingBuffer::read() {
ring_buffer_pos_t RingBuffer::read(uint8_t *buffer) {
ring_buffer_pos_t len = available();
- for(ring_buffer_pos_t i = 0; read_index != write_index; i++) {
+ for (ring_buffer_pos_t i = 0; read_index != write_index; i++) {
buffer[i] = data[read_index];
read_index = NEXT_INDEX(read_index, size);
}
@@ -139,9 +139,8 @@ size_t WebSocketSerial::write(const uint8_t c) {
size_t WebSocketSerial::write(const uint8_t* buffer, size_t size) {
size_t written = 0;
- for(size_t i = 0; i < size; i++) {
+ for (size_t i = 0; i < size; i++)
written += write(buffer[i]);
- }
return written;
}
diff --git a/Marlin/src/HAL/ESP32/ota.h b/Marlin/src/HAL/ESP32/ota.h
index 7f9b237aa6..546ace82db 100644
--- a/Marlin/src/HAL/ESP32/ota.h
+++ b/Marlin/src/HAL/ESP32/ota.h
@@ -15,6 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#pragma once
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index c7b7531442..8b6a978d21 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -25,6 +25,12 @@
#include HAL_PATH(.,HAL.h)
+#ifdef SERIAL_PORT_2
+ #define NUM_SERIAL 2
+#else
+ #define NUM_SERIAL 1
+#endif
+
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
diff --git a/Marlin/src/HAL/LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h
index 96e121d915..778ba2db4d 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -62,7 +62,6 @@ uint8_t _getc();
extern HalSerial usb_serial;
#define MYSERIAL0 usb_serial
-#define NUM_SERIAL 1
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
diff --git a/Marlin/src/HAL/LINUX/include/serial.h b/Marlin/src/HAL/LINUX/include/serial.h
index 154e95aec2..e916249389 100644
--- a/Marlin/src/HAL/LINUX/include/serial.h
+++ b/Marlin/src/HAL/LINUX/include/serial.h
@@ -33,7 +33,6 @@
* Generic RingBuffer
* T type of the buffer array
* S size of the buffer (must be power of 2)
- *
*/
template class RingBuffer {
public:
@@ -79,6 +78,7 @@ public:
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
+ static inline bool emergency_parser_enabled() { return true; }
#endif
HalSerial() { host_connected = true; }
diff --git a/Marlin/src/HAL/LINUX/main.cpp b/Marlin/src/HAL/LINUX/main.cpp
index 4eeef318e7..481f059030 100644
--- a/Marlin/src/HAL/LINUX/main.cpp
+++ b/Marlin/src/HAL/LINUX/main.cpp
@@ -107,7 +107,7 @@ int main() {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
- #if NUM_SERIAL > 0
+ #ifdef MYSERIAL0
MYSERIAL0.begin(BAUDRATE);
SERIAL_ECHOLNPGM("x86_64 Initialized");
SERIAL_FLUSHTX();
diff --git a/Marlin/src/HAL/LINUX/servo_private.h b/Marlin/src/HAL/LINUX/servo_private.h
index 122cfef3ea..bcc8d2037f 100644
--- a/Marlin/src/HAL/LINUX/servo_private.h
+++ b/Marlin/src/HAL/LINUX/servo_private.h
@@ -45,7 +45,6 @@
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
- *
*/
#include
diff --git a/Marlin/src/HAL/LINUX/spi_pins.h b/Marlin/src/HAL/LINUX/spi_pins.h
index a444196f04..01ba28e5b6 100644
--- a/Marlin/src/HAL/LINUX/spi_pins.h
+++ b/Marlin/src/HAL/LINUX/spi_pins.h
@@ -24,7 +24,7 @@
#include "../../core/macros.h"
#include "../../inc/MarlinConfigPre.h"
-#if BOTH(HAS_GRAPHICAL_LCD, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == 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
diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h
index 0153bacf42..3118aed1b2 100644
--- a/Marlin/src/HAL/LPC1768/HAL.h
+++ b/Marlin/src/HAL/LPC1768/HAL.h
@@ -63,58 +63,35 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
+#define _MSERIAL(X) MSerial##X
+#define MSERIAL(X) _MSERIAL(X)
+#define MSerial0 MSerial
+
#if SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
-#elif SERIAL_PORT == 0
- #define MYSERIAL0 MSerial
-#elif SERIAL_PORT == 1
- #define MYSERIAL0 MSerial1
-#elif SERIAL_PORT == 2
- #define MYSERIAL0 MSerial2
-#elif SERIAL_PORT == 3
- #define MYSERIAL0 MSerial3
+#elif WITHIN(SERIAL_PORT, 0, 3)
+ #define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #if SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
- #elif SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
- #elif SERIAL_PORT_2 == 0
- #define MYSERIAL1 MSerial
- #elif SERIAL_PORT_2 == 1
- #define MYSERIAL1 MSerial1
- #elif SERIAL_PORT_2 == 2
- #define MYSERIAL1 MSerial2
- #elif SERIAL_PORT_2 == 3
- #define MYSERIAL1 MSerial3
+ #elif WITHIN(SERIAL_PORT_2, 0, 3)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
- #define NUM_SERIAL 2
-#else
- #define NUM_SERIAL 1
#endif
-#ifdef DGUS_SERIAL_PORT
- #if DGUS_SERIAL_PORT == SERIAL_PORT
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
- #elif DGUS_SERIAL_PORT == -1
- #define DGUS_SERIAL UsbSerial
- #elif DGUS_SERIAL_PORT == 0
- #define DGUS_SERIAL MSerial
- #elif DGUS_SERIAL_PORT == 1
- #define DGUS_SERIAL MSerial1
- #elif DGUS_SERIAL_PORT == 2
- #define DGUS_SERIAL MSerial2
- #elif DGUS_SERIAL_PORT == 3
- #define DGUS_SERIAL MSerial3
+#ifdef LCD_SERIAL_PORT
+ #if LCD_SERIAL_PORT == -1
+ #define LCD_SERIAL UsbSerial
+ #elif WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
index 00b4310d1d..b3d2908ac9 100644
--- a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
@@ -39,10 +39,10 @@
* Some of the LCD interfaces/adapters result in the LCD SPI and the SD card
* SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with
* WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is
- * active. If any of these pins are shared then the software SPI must be used.
+ * active. If any of these pins are shared then the software SPI must be used.
*
- * A more sophisticated hardware SPI can be found at the following link. This
- * implementation has not been fully debugged.
+ * A more sophisticated hardware SPI can be found at the following link.
+ * This implementation has not been fully debugged.
* https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
*/
@@ -100,72 +100,25 @@
#else
- // decide which HW SPI device to use
- #ifndef LPC_HW_SPI_DEV
- #if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
- #define LPC_HW_SPI_DEV 1
- #else
- #if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18)
- #define LPC_HW_SPI_DEV 0
- #else
- #error "Invalid pins selected for hardware SPI"
- #endif
- #endif
- #endif
- #if LPC_HW_SPI_DEV == 0
- #define LPC_SSPn LPC_SSP0
- #else
- #define LPC_SSPn LPC_SSP1
- #endif
-
void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
- PINSEL_CFG_Type PinCfg; // data structure to hold init values
- PinCfg.Funcnum = 2;
- PinCfg.OpenDrain = 0;
- PinCfg.Pinmode = 0;
- PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN);
- PinCfg.Portnum = LPC176x::pin_port(SCK_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(SCK_PIN);
-
- PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN);
- PinCfg.Portnum = LPC176x::pin_port(MISO_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_INPUT(MISO_PIN);
-
- PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN);
- PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(MOSI_PIN);
- // divide PCLK by 2 for SSP0
- CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
- spiInit(0);
- SSP_Cmd(LPC_SSPn, ENABLE); // start SSP running
+ spiInit(SPI_SPEED);
}
void spiInit(uint8_t spiRate) {
- // table to convert Marlin spiRates (0-5 plus default) into bit rates
- uint32_t Marlin_speed[7]; // CPSR is always 2
- Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
- Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
- Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
- Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
- Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
- Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
- Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
- // setup for SPI mode
- SSP_CFG_Type HW_SPI_init; // data structure to hold init values
- SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode
- HW_SPI_init.ClockRate = Marlin_speed[_MIN(spiRate, 6)]; // put in the specified bit rate
- HW_SPI_init.Mode |= SSP_CR1_SSP_EN;
- SSP_Init(LPC_SSPn, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
+ #if MISO_PIN == BOARD_SPI1_MISO_PIN
+ SPI.setModule(1);
+ #elif MISO_PIN == BOARD_SPI2_MISO_PIN
+ SPI.setModule(2);
+ #endif
+ SPI.setDataSize(DATA_SIZE_8BIT);
+ SPI.setDataMode(SPI_MODE0);
+
+ SPI.setClock(SPISettings::spiRate2Clock(spiRate));
+ SPI.begin();
}
static uint8_t doio(uint8_t b) {
- /* send and receive a single byte */
- SSP_SendData(LPC_SSPn, b & 0x00FF);
- while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY)); // wait for it to finish
- return SSP_ReceiveData(LPC_SSPn) & 0x00FF;
+ return SPI.transfer(b & 0x00FF) & 0x00FF;
}
void spiSend(uint8_t b) { doio(b); }
@@ -217,63 +170,74 @@ static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) {
while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
}
+// Retain the pin init state of the SPI, to avoid init more than once,
+// even if more instances of SPIClass exist
+static bool spiInitialised[BOARD_NR_SPI] = { false };
+
SPIClass::SPIClass(uint8_t device) {
// Init things specific to each SPI device
// clock divider setup is a bit of hack, and needs to be improved at a later date.
- PINSEL_CFG_Type PinCfg; // data structure to hold init values
#if BOARD_NR_SPI >= 1
_settings[0].spi_d = LPC_SSP0;
- // _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
- PinCfg.Funcnum = 2;
- PinCfg.OpenDrain = 0;
- PinCfg.Pinmode = 0;
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_SCK_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_SCK_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(BOARD_SPI1_SCK_PIN);
-
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MISO_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MISO_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_INPUT(BOARD_SPI1_MISO_PIN);
-
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI1_MOSI_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI1_MOSI_PIN);
- PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(BOARD_SPI1_MOSI_PIN);
+ _settings[0].dataMode = SPI_MODE0;
+ _settings[0].dataSize = DATA_SIZE_8BIT;
+ _settings[0].clock = SPI_CLOCK_MAX;
+ //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
#endif
#if BOARD_NR_SPI >= 2
_settings[1].spi_d = LPC_SSP1;
- // _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
+ _settings[1].dataMode = SPI_MODE0;
+ _settings[1].dataSize = DATA_SIZE_8BIT;
+ _settings[1].clock = SPI_CLOCK_MAX;
+ //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
+ #endif
+
+ setModule(device);
+
+ // Init the GPDMA controller
+ // TODO: call once in the constructor? or each time?
+ GPDMA_Init();
+}
+
+void SPIClass::begin() {
+ // Init the SPI pins in the first begin call
+ if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
+ (_currentSetting->spi_d == LPC_SSP1 && spiInitialised[1] == false)) {
+ pin_t sck, miso, mosi;
+ if (_currentSetting->spi_d == LPC_SSP0) {
+ sck = BOARD_SPI1_SCK_PIN;
+ miso = BOARD_SPI1_MISO_PIN;
+ mosi = BOARD_SPI1_MOSI_PIN;
+ spiInitialised[0] = true;
+ }
+ else if (_currentSetting->spi_d == LPC_SSP1) {
+ sck = BOARD_SPI2_SCK_PIN;
+ miso = BOARD_SPI2_MISO_PIN;
+ mosi = BOARD_SPI2_MOSI_PIN;
+ spiInitialised[1] = true;
+ }
+ PINSEL_CFG_Type PinCfg; // data structure to hold init values
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_SCK_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_SCK_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(sck);
+ PinCfg.Portnum = LPC176x::pin_port(sck);
PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(BOARD_SPI2_SCK_PIN);
+ SET_OUTPUT(sck);
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MISO_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MISO_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(miso);
+ PinCfg.Portnum = LPC176x::pin_port(miso);
PINSEL_ConfigPin(&PinCfg);
- SET_INPUT(BOARD_SPI2_MISO_PIN);
+ SET_INPUT(miso);
- PinCfg.Pinnum = LPC176x::pin_bit(BOARD_SPI2_MOSI_PIN);
- PinCfg.Portnum = LPC176x::pin_port(BOARD_SPI2_MOSI_PIN);
+ PinCfg.Pinnum = LPC176x::pin_bit(mosi);
+ PinCfg.Portnum = LPC176x::pin_port(mosi);
PINSEL_ConfigPin(&PinCfg);
- SET_OUTPUT(BOARD_SPI2_MOSI_PIN);
- #endif
-
- setModule(device);
-
- /* Initialize GPDMA controller */
- //TODO: call once in the constructor? or each time?
- GPDMA_Init();
-}
+ SET_OUTPUT(mosi);
+ }
-void SPIClass::begin() {
updateSettings();
SSP_Cmd(_currentSetting->spi_d, ENABLE); // start SSP running
}
@@ -287,7 +251,7 @@ void SPIClass::beginTransaction(const SPISettings &cfg) {
}
uint8_t SPIClass::transfer(const uint16_t b) {
- /* send and receive a single byte */
+ // Send and receive a single byte
SSP_ReceiveData(_currentSetting->spi_d); // read any previous data
SSP_SendData(_currentSetting->spi_d, b);
waitSpiTxEnd(_currentSetting->spi_d); // wait for it to finish
@@ -295,8 +259,7 @@ uint8_t SPIClass::transfer(const uint16_t b) {
}
uint16_t SPIClass::transfer16(const uint16_t data) {
- return (transfer((data >> 8) & 0xFF) << 8)
- | (transfer(data & 0xFF) & 0xFF);
+ return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF);
}
void SPIClass::end() {
@@ -320,7 +283,7 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
// Destination memory - Not used
GPDMACfg.DstMemAddr = 0;
// Transfer size
- GPDMACfg.TransferSize = (minc ? length : 1);
+ GPDMACfg.TransferSize = length;
// Transfer width
GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
// Transfer type
@@ -335,26 +298,24 @@ void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
// Enable dma on SPI
SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
- // if minc=false, I'm repeating the same byte 'length' times, as I could not find yet how do GPDMA without memory increment
- do {
- // Setup channel with given parameter
- GPDMA_Setup(&GPDMACfg);
+ // Only increase memory if minc is true
+ GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
- // enabled dma
- GPDMA_ChannelCmd(0, ENABLE);
+ // Setup channel with given parameter
+ GPDMA_Setup(&GPDMACfg);
- // wait data transfer
- while (!GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) { }
+ // Enable DMA
+ GPDMA_ChannelCmd(0, ENABLE);
- // clear err and int
- GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
- GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
+ // Wait for data transfer
+ while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
- // dma disable
- GPDMA_ChannelCmd(0, DISABLE);
+ // Clear err and int
+ GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
+ GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
- --length;
- } while (!minc && length > 0);
+ // Disable DMA
+ GPDMA_ChannelCmd(0, DISABLE);
waitSpiTxEnd(_currentSetting->spi_d);
@@ -382,7 +343,7 @@ void SPIClass::setBitOrder(uint8_t bitOrder) {
}
void SPIClass::setDataMode(uint8_t dataMode) {
- _currentSetting->dataSize = dataMode;
+ _currentSetting->dataMode = dataMode;
}
void SPIClass::setDataSize(uint32_t ds) {
@@ -413,19 +374,19 @@ void SPIClass::updateSettings() {
switch (_currentSetting->dataMode) {
case SPI_MODE0:
HW_SPI_init.CPHA = SSP_CPHA_FIRST;
- HW_SPI_init.CPOL = SSP_CPOL_HI;
+ HW_SPI_init.CPOL = SSP_CPOL_HI;
break;
case SPI_MODE1:
HW_SPI_init.CPHA = SSP_CPHA_SECOND;
- HW_SPI_init.CPOL = SSP_CPOL_HI;
+ HW_SPI_init.CPOL = SSP_CPOL_HI;
break;
case SPI_MODE2:
HW_SPI_init.CPHA = SSP_CPHA_FIRST;
- HW_SPI_init.CPOL = SSP_CPOL_LO;
+ HW_SPI_init.CPOL = SSP_CPOL_LO;
break;
case SPI_MODE3:
HW_SPI_init.CPHA = SSP_CPHA_SECOND;
- HW_SPI_init.CPOL = SSP_CPOL_LO;
+ HW_SPI_init.CPOL = SSP_CPOL_LO;
break;
default:
break;
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
index c3fb3bd0e4..5374e005d3 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
@@ -24,28 +24,28 @@
#include "../../inc/MarlinConfigPre.h"
#include "MarlinSerial.h"
-#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0)
+#if USING_SERIAL_0
MarlinSerial MSerial(LPC_UART0);
extern "C" void UART0_IRQHandler() {
MSerial.IRQHandler();
}
#endif
-#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
+#if USING_SERIAL_1
MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() {
MSerial1.IRQHandler();
}
#endif
-#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
+#if USING_SERIAL_2
MarlinSerial MSerial2(LPC_UART2);
extern "C" void UART2_IRQHandler() {
MSerial2.IRQHandler();
}
#endif
-#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
+#if USING_SERIAL_3
MarlinSerial MSerial3(LPC_UART3);
extern "C" void UART3_IRQHandler() {
MSerial3.IRQHandler();
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.h b/Marlin/src/HAL/LPC1768/MarlinSerial.h
index 98ce73d377..8d6b64378a 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.h
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.h
@@ -57,6 +57,7 @@ public:
}
EmergencyParser::State emergency_state;
+ static inline bool emergency_parser_enabled() { return true; }
#endif
};
diff --git a/Marlin/src/HAL/LPC1768/Servo.h b/Marlin/src/HAL/LPC1768/Servo.h
index e953cb9204..eb12fd20f4 100644
--- a/Marlin/src/HAL/LPC1768/Servo.h
+++ b/Marlin/src/HAL/LPC1768/Servo.h
@@ -46,7 +46,6 @@
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
- *
*/
#include
diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
index 0a4e59c6c4..fd82e2884a 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 < 2002
+#if PIO_FRAMEWORK_VERSION < 2005
#error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
#endif
@@ -89,7 +89,10 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
* Serial2 | P0_10 | P0_11 |
* Serial3 | P0_00 | P0_01 |
*/
-#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0)
+#define ANY_TX(N,V...) DO(IS_TX##N,||,V)
+#define ANY_RX(N,V...) DO(IS_RX##N,||,V)
+
+#if USING_SERIAL_0
#define IS_TX0(P) (P == P0_02)
#define IS_RX0(P) (P == P0_03)
#if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
@@ -103,60 +106,67 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#undef IS_RX0
#endif
-#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
+#if USING_SERIAL_1
#define IS_TX1(P) (P == P0_15)
#define IS_RX1(P) (P == P0_16)
+ #define _IS_TX1_1 IS_TX1
+ #define _IS_RX1_1 IS_RX1
#if IS_TX1(TMC_SW_SCK)
#error "Serial port pins (1) conflict with other pins!"
- #elif HAS_SPI_LCD
+ #elif HAS_WIRED_LCD
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
- #elif IS_TX1(SCK_PIN) || IS_TX1(LCD_PINS_D4) || IS_TX1(DOGLCD_SCK) || IS_TX1(LCD_RESET_PIN) || IS_TX1(LCD_PINS_RS) || IS_TX1(SHIFT_CLK) \
- || IS_RX1(LCD_SDSS) || IS_RX1(LCD_PINS_RS) || IS_RX1(MISO_PIN) || IS_RX1(DOGLCD_A0) || IS_RX1(SS_PIN) || IS_RX1(LCD_SDSS) || IS_RX1(DOGLCD_CS) || IS_RX1(LCD_RESET_PIN) || IS_RX1(LCD_BACKLIGHT_PIN)
+ #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)
#error "Serial port pins (1) conflict with LCD pins!"
#endif
#endif
#undef IS_TX1
#undef IS_RX1
+ #undef _IS_TX1_1
+ #undef _IS_RX1_1
#endif
-#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
+#if USING_SERIAL_2
#define IS_TX2(P) (P == P0_10)
#define IS_RX2(P) (P == P0_11)
- #if IS_TX2(X2_ENABLE_PIN) || IS_RX2(X2_DIR_PIN) || IS_RX2(X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN))
+ #define _IS_TX2_1 IS_TX2
+ #define _IS_RX2_1 IS_RX2
+ #if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN))
#error "Serial port pins (2) conflict with X2 pins!"
- #elif IS_TX2(Y2_ENABLE_PIN) || IS_RX2(Y2_DIR_PIN) || IS_RX2(Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN))
+ #elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN))
#error "Serial port pins (2) conflict with Y2 pins!"
- #elif IS_TX2(Z2_ENABLE_PIN) || IS_RX2(Z2_DIR_PIN) || IS_RX2(Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN))
+ #elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN))
#error "Serial port pins (2) conflict with Z2 pins!"
- #elif IS_TX2(Z3_ENABLE_PIN) || IS_RX2(Z3_DIR_PIN) || IS_RX2(Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN))
+ #elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN))
#error "Serial port pins (2) conflict with Z3 pins!"
- #elif IS_TX2(Z4_ENABLE_PIN) || IS_RX2(Z4_DIR_PIN) || IS_RX2(Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN))
+ #elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN))
#error "Serial port pins (2) conflict with Z4 pins!"
- #elif IS_RX2(X_DIR_PIN) || IS_RX2(Y_DIR_PIN)
+ #elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
#error "Serial port pins (2) conflict with other pins!"
#elif Y_HOME_DIR < 0 && IS_TX2(Y_STOP_PIN)
#error "Serial port pins (2) conflict with Y endstop pin!"
#elif HAS_CUSTOM_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN)
#error "Serial port pins (2) conflict with probe pin!"
- #elif IS_TX2(X_ENABLE_PIN) || IS_RX2(X_DIR_PIN) || IS_TX2(Y_ENABLE_PIN) || IS_RX2(Y_DIR_PIN)
+ #elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
#error "Serial port pins (2) conflict with X/Y stepper pins!"
- #elif EXTRUDERS > 1 && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN)))
+ #elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN)))
#error "Serial port pins (2) conflict with E1 stepper pins!"
- #elif EXTRUDERS && (IS_RX2(E0_DIR_PIN) || IS_RX2(E0_STEP_PIN))
+ #elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN)
#error "Serial port pins (2) conflict with E stepper pins!"
#endif
#undef IS_TX2
#undef IS_RX2
+ #undef _IS_TX2_1
+ #undef _IS_RX2_1
#endif
-#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
+#if USING_SERIAL_3
#define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00)
#define PIN_IS_RX3(P) (P##_PIN == P0_01)
#if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX)
#error "Serial port pins (3) conflict with X endstop pins!"
- #elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) \
- || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX)
+ #elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX)
#error "Serial port pins (3) conflict with X/Y axis UART pins!"
#elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP)
#error "Serial port pins (3) conflict with X2 pins!"
@@ -168,13 +178,16 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "Serial port pins (3) conflict with Z3 pins!"
#elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP)
#error "Serial port pins (3) conflict with Z4 pins!"
- #elif EXTRUDERS > 1 && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP))
+ #elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP))
#error "Serial port pins (3) conflict with E1 pins!"
#endif
#undef PIN_IS_TX3
#undef PIN_IS_RX3
#endif
+#undef ANY_TX
+#undef ANY_RX
+
//
// Flag any i2c pin conflicts
//
@@ -214,7 +227,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals."
#elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP)
#error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals."
- #elif EXTRUDERS > 1 && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP))
+ #elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP))
#error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals."
#endif
#undef PIN_IS_SDA1
@@ -240,9 +253,9 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals."
#elif PIN_IS_SDA2(Z4_ENABLE)
#error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals."
- #elif EXTRUDERS > 1 && PIN_IS_SDA2(E1_ENABLE)
+ #elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE)
#error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals."
- #elif EXTRUDERS > 1 && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS)
+ #elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS)
#error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals."
#elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR))
#error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals."
diff --git a/Marlin/src/HAL/LPC1768/include/SPI.h b/Marlin/src/HAL/LPC1768/include/SPI.h
index e2645b9290..9da2a32556 100644
--- a/Marlin/src/HAL/LPC1768/include/SPI.h
+++ b/Marlin/src/HAL/LPC1768/include/SPI.h
@@ -61,7 +61,9 @@
class SPISettings {
public:
- SPISettings(uint32_t speed, int, int) : spi_speed(speed) {};
+ SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) {
+ init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT);
+ }
SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
if (__builtin_constant_p(inClock))
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
@@ -72,7 +74,19 @@ public:
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
}
- uint32_t spiRate() const { return spi_speed; }
+ //uint32_t spiRate() const { return spi_speed; }
+
+ static inline uint32_t spiRate2Clock(uint32_t spiRate) {
+ uint32_t Marlin_speed[7]; // CPSR is always 2
+ Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
+ Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
+ Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
+ Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
+ Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
+ Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
+ Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
+ return Marlin_speed[spiRate > 6 ? 6 : spiRate];
+ }
private:
void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
@@ -85,7 +99,7 @@ private:
dataSize = inDataSize;
}
- uint32_t spi_speed;
+ //uint32_t spi_speed;
uint32_t clock;
uint32_t dataSize;
//uint32_t clockDivider;
@@ -122,7 +136,7 @@ public:
void end();
void beginTransaction(const SPISettings&);
- void endTransaction() {};
+ void endTransaction() {}
// Transfer using 1 "Data Size"
uint8_t transfer(uint16_t data);
diff --git a/Marlin/src/HAL/LPC1768/spi_pins.h b/Marlin/src/HAL/LPC1768/spi_pins.h
index 2e6749bf57..b4da5d4df2 100644
--- a/Marlin/src/HAL/LPC1768/spi_pins.h
+++ b/Marlin/src/HAL/LPC1768/spi_pins.h
@@ -23,7 +23,7 @@
#include "../../core/macros.h"
-#if BOTH(SDSUPPORT, HAS_GRAPHICAL_LCD) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == 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
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
index c72e5f0eac..5f96630043 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
@@ -72,7 +72,6 @@ bool XPT2046::getRawPoint(int16_t *x, int16_t *y) {
if (!isTouched()) return false;
*x = getRawData(XPT2046_X);
*y = getRawData(XPT2046_Y);
- SERIAL_ECHOLNPAIR("X: ", *x, ", Y: ", *y);
return isTouched();
}
diff --git a/Marlin/src/HAL/LPC1768/timers.h b/Marlin/src/HAL/LPC1768/timers.h
index 23dc20e2eb..e6744fb005 100644
--- a/Marlin/src/HAL/LPC1768/timers.h
+++ b/Marlin/src/HAL/LPC1768/timers.h
@@ -21,7 +21,6 @@
#pragma once
/**
- *
* HAL For LPC1768
*/
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
index befc348fab..057e10e0f5 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
#include "../../shared/HAL_SPI.h"
@@ -124,6 +124,6 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
index f03be9ab34..6f7efba4ae 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
@@ -77,7 +77,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
@@ -193,6 +193,6 @@ uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_v
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
index 1500c22a0d..592e27f6c0 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD
+#if HAS_MARLINUI_U8GLIB
#include
#include "../../shared/HAL_SPI.h"
@@ -133,6 +133,6 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
return 1;
}
-#endif // HAS_GRAPHICAL_LCD
+#endif // HAS_MARLINUI_U8GLIB
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index 4f52f7dd01..ca9d6ecfbe 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -57,7 +57,7 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include
@@ -203,5 +203,5 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/usb_serial.cpp b/Marlin/src/HAL/LPC1768/usb_serial.cpp
index 63a570efdf..d225ce4188 100644
--- a/Marlin/src/HAL/LPC1768/usb_serial.cpp
+++ b/Marlin/src/HAL/LPC1768/usb_serial.cpp
@@ -26,7 +26,9 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
+
EmergencyParser::State emergency_state;
+
bool CDC_RecvCallback(const char buffer) {
emergency_parser.update(emergency_state, buffer);
return true;
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index ea0f694cdc..7fd826a1b6 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -35,58 +35,34 @@
// MYSERIAL0 required before MarlinSerial includes!
+ #define _MSERIAL(X) Serial##X
+ #define MSERIAL(X) _MSERIAL(INCREMENT(X))
+
#if SERIAL_PORT == -1
#define MYSERIAL0 Serial
- #elif SERIAL_PORT == 0
- #define MYSERIAL0 Serial1
- #elif SERIAL_PORT == 1
- #define MYSERIAL0 Serial2
- #elif SERIAL_PORT == 2
- #define MYSERIAL0 Serial3
- #elif SERIAL_PORT == 3
- #define MYSERIAL0 Serial4
+ #elif WITHIN(SERIAL_PORT, 0, 3)
+ #define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #if SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
- #elif SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == -1
#define MYSERIAL1 Serial
- #elif SERIAL_PORT_2 == 0
- #define MYSERIAL1 Serial1
- #elif SERIAL_PORT_2 == 1
- #define MYSERIAL1 Serial2
- #elif SERIAL_PORT_2 == 2
- #define MYSERIAL1 Serial3
- #elif SERIAL_PORT_2 == 3
- #define MYSERIAL1 Serial4
+ #elif WITHIN(SERIAL_PORT_2, 0, 3)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
- #define NUM_SERIAL 2
- #else
- #define NUM_SERIAL 1
#endif
- #ifdef DGUS_SERIAL_PORT
- #if DGUS_SERIAL_PORT == SERIAL_PORT
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
- #elif DGUS_SERIAL_PORT == -1
- #define DGUS_SERIAL Serial
- #elif DGUS_SERIAL_PORT == 0
- #define DGUS_SERIAL Serial1
- #elif DGUS_SERIAL_PORT == 1
- #define DGUS_SERIAL Serial2
- #elif DGUS_SERIAL_PORT == 2
- #define DGUS_SERIAL Serial3
- #elif DGUS_SERIAL_PORT == 2
- #define DGUS_SERIAL Serial4
+ #ifdef LCD_SERIAL_PORT
+ #if LCD_SERIAL_PORT == -1
+ #define LCD_SERIAL Serial
+ #elif WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.h b/Marlin/src/HAL/SAMD51/QSPIFlash.h
index b6f22769ff..db4abec91c 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.h
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.h
@@ -24,7 +24,6 @@
* THE SOFTWARE.
*
* Derived from Adafruit_SPIFlash class with no SdFat references
- *
*/
#pragma once
diff --git a/Marlin/src/HAL/SAMD51/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h
index c28937d6c6..81376db79a 100644
--- a/Marlin/src/HAL/SAMD51/pinsDebug.h
+++ b/Marlin/src/HAL/SAMD51/pinsDebug.h
@@ -150,5 +150,4 @@ void pwm_details(int32_t pin) {
* 93 | PA10 | QSPI: IO2
* 94 | PA11 | QSPI: IO3
* 95 | PB31 | SD: DETECT
- *
*/
diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h
index 08081331b7..60ab45374a 100644
--- a/Marlin/src/HAL/STM32/HAL.h
+++ b/Marlin/src/HAL/STM32/HAL.h
@@ -43,83 +43,40 @@
// ------------------------
// Defines
// ------------------------
+#define _MSERIAL(X) MSerial##X
+#define MSERIAL(X) _MSERIAL(X)
-#if SERIAL_PORT == 0
- #error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
-#elif SERIAL_PORT == -1
+#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
-#elif SERIAL_PORT == 1
- #define MYSERIAL0 MSerial1
-#elif SERIAL_PORT == 2
- #define MYSERIAL0 MSerial2
-#elif SERIAL_PORT == 3
- #define MYSERIAL0 MSerial3
-#elif SERIAL_PORT == 4
- #define MYSERIAL0 MSerial4
-#elif SERIAL_PORT == 5
- #define MYSERIAL0 MSerial5
-#elif SERIAL_PORT == 6
- #define MYSERIAL0 MSerial6
+#elif WITHIN(SERIAL_PORT, 1, 6)
+ #define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
- #error "SERIAL_PORT must be from -1 to 6. Please update your configuration."
+ #error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
- #define NUM_SERIAL 2
- #if SERIAL_PORT_2 == 0
- #error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
- #elif SERIAL_PORT_2 == SERIAL_PORT
- #error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
- #elif SERIAL_PORT_2 == -1
+ #if SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
- #elif SERIAL_PORT_2 == 1
- #define MYSERIAL1 MSerial1
- #elif SERIAL_PORT_2 == 2
- #define MYSERIAL1 MSerial2
- #elif SERIAL_PORT_2 == 3
- #define MYSERIAL1 MSerial3
- #elif SERIAL_PORT_2 == 4
- #define MYSERIAL1 MSerial4
- #elif SERIAL_PORT_2 == 5
- #define MYSERIAL1 MSerial5
- #elif SERIAL_PORT_2 == 6
- #define MYSERIAL1 MSerial6
+ #elif WITHIN(SERIAL_PORT_2, 1, 6)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
- #error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration."
+ #error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
#endif
-#else
- #define NUM_SERIAL 1
#endif
-#if HAS_DGUS_LCD
- #if DGUS_SERIAL_PORT == 0
- #error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
- #elif DGUS_SERIAL_PORT == SERIAL_PORT
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
- #elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
- #error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
- #elif DGUS_SERIAL_PORT == -1
- #define DGUS_SERIAL SerialUSB
- #elif DGUS_SERIAL_PORT == 1
- #define DGUS_SERIAL MSerial1
- #elif DGUS_SERIAL_PORT == 2
- #define DGUS_SERIAL MSerial2
- #elif DGUS_SERIAL_PORT == 3
- #define DGUS_SERIAL MSerial3
- #elif DGUS_SERIAL_PORT == 4
- #define DGUS_SERIAL MSerial4
- #elif DGUS_SERIAL_PORT == 5
- #define DGUS_SERIAL MSerial5
- #elif DGUS_SERIAL_PORT == 6
- #define DGUS_SERIAL MSerial6
+#ifdef LCD_SERIAL_PORT
+ #if LCD_SERIAL_PORT == -1
+ #define LCD_SERIAL SerialUSB
+ #elif WITHIN(LCD_SERIAL_PORT, 1, 6)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "DGUS_SERIAL_PORT must be from -1 to 6. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
+ #endif
+ #if HAS_DGUS_LCD
+ #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
#endif
-
- #define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.availableForWrite
#endif
-
/**
* TODO: review this to return 1 for pins that are not analog input
*/
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp
index 8d99ab7855..a146664366 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp
@@ -49,16 +49,14 @@
DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2)
#endif
-#if defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT >= 0
- DECLARE_SERIAL_PORT_EXP(DGUS_SERIAL_PORT)
+#if defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT >= 0
+ DECLARE_SERIAL_PORT_EXP(LCD_SERIAL_PORT)
#endif
void MarlinSerial::begin(unsigned long baud, uint8_t config) {
HardwareSerial::begin(baud, config);
- // replace the IRQ callback with the one we have defined
- #if ENABLED(EMERGENCY_PARSER)
- _serial.rx_callback = _rx_callback;
- #endif
+ // Replace the IRQ callback with the one we have defined
+ TERN_(EMERGENCY_PARSER, _serial.rx_callback = _rx_callback);
}
// This function is Copyright (c) 2006 Nicholas Zambetti.
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h
index 5ab97ff3a9..3611cc78d7 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.h
+++ b/Marlin/src/HAL/STM32/MarlinSerial.h
@@ -35,6 +35,10 @@ public:
#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); }
diff --git a/Marlin/src/HAL/STM32/SoftwareSerial.cpp b/Marlin/src/HAL/STM32/SoftwareSerial.cpp
deleted file mode 100644
index 2228a177be..0000000000
--- a/Marlin/src/HAL/STM32/SoftwareSerial.cpp
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
- *
- * Multi-instance software serial library for Arduino/Wiring
- * -- Interrupt-driven receive and other improvements by ladyada
- *
- * -- Tuning, circular buffer, derivation from class Print/Stream,
- * multi-instance support, porting to 8MHz processors,
- * various optimizations, PROGMEM delay tables, inverse logic and
- * direct port writing by Mikal Hart
- * -- Pin change interrupt macros by Paul Stoffregen
- * -- 20MHz processor support by Garrett Mace
- * -- ATmega1280/2560 support by Brett Hagman
- * -- STM32 support by Armin van der Togt
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The latest version of this library can always be found at
- * http://arduiniana.org.
- */
-
-//
-// Includes
-//
-#if defined(PLATFORMIO) && defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
-
-#include "../../inc/MarlinConfig.h"
-
-#include "SoftwareSerial.h"
-
-#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge).
-
-// defined in bit-periods
-#define HALFDUPLEX_SWITCH_DELAY 5
-// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
-// The order is based on (lack of) features and compare channels, we choose the simplest available
-// because we only need an update interrupt
-#if !defined(TIMER_SERIAL)
-#if defined(TIM18_BASE)
-#define TIMER_SERIAL TIM18
-#elif defined(TIM7_BASE)
-#define TIMER_SERIAL TIM7
-#elif defined(TIM6_BASE)
-#define TIMER_SERIAL TIM6
-#elif defined(TIM22_BASE)
-#define TIMER_SERIAL TIM22
-#elif defined(TIM21_BASE)
-#define TIMER_SERIAL TIM21
-#elif defined(TIM17_BASE)
-#define TIMER_SERIAL TIM17
-#elif defined(TIM16_BASE)
-#define TIMER_SERIAL TIM16
-#elif defined(TIM15_BASE)
-#define TIMER_SERIAL TIM15
-#elif defined(TIM14_BASE)
-#define TIMER_SERIAL TIM14
-#elif defined(TIM13_BASE)
-#define TIMER_SERIAL TIM13
-#elif defined(TIM11_BASE)
-#define TIMER_SERIAL TIM11
-#elif defined(TIM10_BASE)
-#define TIMER_SERIAL TIM10
-#elif defined(TIM12_BASE)
-#define TIMER_SERIAL TIM12
-#elif defined(TIM19_BASE)
-#define TIMER_SERIAL TIM19
-#elif defined(TIM9_BASE)
-#define TIMER_SERIAL TIM9
-#elif defined(TIM5_BASE)
-#define TIMER_SERIAL TIM5
-#elif defined(TIM4_BASE)
-#define TIMER_SERIAL TIM4
-#elif defined(TIM3_BASE)
-#define TIMER_SERIAL TIM3
-#elif defined(TIM2_BASE)
-#define TIMER_SERIAL TIM2
-#elif defined(TIM20_BASE)
-#define TIMER_SERIAL TIM20
-#elif defined(TIM8_BASE)
-#define TIMER_SERIAL TIM8
-#elif defined(TIM1_BASE)
-#define TIMER_SERIAL TIM1
-#else
-#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
-#endif
-#endif
-//
-// Statics
-//
-HardwareTimer SoftwareSerial::timer(TIMER_SERIAL);
-const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast(getTimerUpIrq(TIMER_SERIAL));
-uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO);
-SoftwareSerial *SoftwareSerial::active_listener = nullptr;
-SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
-SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
-int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
-int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
-uint32_t SoftwareSerial::tx_buffer = 0;
-int32_t SoftwareSerial::tx_bit_cnt = 0;
-uint32_t SoftwareSerial::rx_buffer = 0;
-int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
-uint32_t SoftwareSerial::cur_speed = 0;
-
-void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) {
- timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority);
-}
-
-//
-// Private methods
-//
-
-void SoftwareSerial::setSpeed(uint32_t speed) {
- if (speed != cur_speed) {
- timer.pause();
- if (speed != 0) {
- // Disable the timer
- uint32_t clock_rate, cmp_value;
- // Get timer clock
- clock_rate = timer.getTimerClkFreq();
- int pre = 1;
- // Calculate prescale an compare value
- do {
- cmp_value = clock_rate / (speed * OVERSAMPLE);
- if (cmp_value >= UINT16_MAX) {
- clock_rate /= 2;
- pre *= 2;
- }
- } while (cmp_value >= UINT16_MAX);
- timer.setPrescaleFactor(pre);
- timer.setOverflow(cmp_value);
- timer.setCount(0);
- timer.attachInterrupt(&handleInterrupt);
- timer.resume();
- NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority);
- }
- else
- timer.detachInterrupt();
- cur_speed = speed;
- }
-}
-
-// This function sets the current object as the "listening"
-// one and returns true if it replaces another
-bool SoftwareSerial::listen() {
- if (active_listener != this) {
- // wait for any transmit to complete as we may change speed
- while (active_out);
- active_listener->stopListening();
- rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
- rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
- setSpeed(_speed);
- active_listener = this;
- if (!_half_duplex) active_in = this;
- return true;
- }
- return false;
-}
-
-// Stop listening. Returns true if we were actually listening.
-bool SoftwareSerial::stopListening() {
- if (active_listener == this) {
- // wait for any output to complete
- while (active_out);
- if (_half_duplex) setRXTX(false);
- active_listener = nullptr;
- active_in = nullptr;
- // turn off ints
- setSpeed(0);
- return true;
- }
- return false;
-}
-
-inline void SoftwareSerial::setTX() {
- if (_inverse_logic)
- LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
- else
- LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
- pinMode(_transmitPin, OUTPUT);
-}
-
-inline void SoftwareSerial::setRX() {
- pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
-}
-
-inline void SoftwareSerial::setRXTX(bool input) {
- if (_half_duplex) {
- if (input) {
- if (active_in != this) {
- setRX();
- rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
- rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
- active_in = this;
- }
- }
- else {
- if (active_in == this) {
- setTX();
- active_in = nullptr;
- }
- }
- }
-}
-
-inline void SoftwareSerial::send() {
- if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set.
- if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop)
- // Send data (including start and stop bits)
- if (tx_buffer & 1)
- LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
- else
- LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
- tx_buffer >>= 1;
- tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit
- }
- else { // Transmission finished
- tx_tick_cnt = 1;
- if (_output_pending) {
- active_out = nullptr;
-
- // In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
- // been transmitted before allowing the switch to RX mode
- }
- else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
- if (_half_duplex && active_listener == this) setRXTX(true);
- active_out = nullptr;
- }
- }
- }
-}
-
-//
-// The receive routine called by the interrupt handler
-//
-inline void SoftwareSerial::recv() {
- if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered
- bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
- if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
- if (!inbit) {
- // got start bit
- rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
- rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
- rx_buffer = 0;
- }
- else
- rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level
- }
- else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
- if (inbit) {
- // Stop-bit read complete. Add to buffer.
- uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
- if (next != _receive_buffer_head) {
- // save new data in buffer: tail points to byte destination
- _receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
- _receive_buffer_tail = next;
- }
- else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
- _buffer_overflow = true;
- }
- // Full trame received. Restart waiting for start bit at next interrupt
- rx_tick_cnt = 1;
- rx_bit_cnt = -1;
- }
- else {
- // data bits
- rx_buffer >>= 1;
- if (inbit) rx_buffer |= 0x80;
- rx_bit_cnt++; // Prepare for next bit
- rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
- }
- }
-}
-
-//
-// Interrupt handling
-//
-
-/* static */
-inline void SoftwareSerial::handleInterrupt(HardwareTimer*) {
- if (active_in) active_in->recv();
- if (active_out) active_out->send();
-}
-
-//
-// Constructor
-//
-SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
- _receivePin(receivePin),
- _transmitPin(transmitPin),
- _receivePinPort(digitalPinToPort(receivePin)),
- _receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))),
- _transmitPinPort(digitalPinToPort(transmitPin)),
- _transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))),
- _speed(0),
- _buffer_overflow(false),
- _inverse_logic(inverse_logic),
- _half_duplex(receivePin == transmitPin),
- _output_pending(0),
- _receive_buffer_tail(0),
- _receive_buffer_head(0)
-{
- if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) {
- /* Enable GPIO clock for tx and rx pin*/
- set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin)));
- set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin)));
- }
- else
- _Error_Handler("ERROR: invalid pin number\n", -1);
-}
-
-//
-// Destructor
-//
-SoftwareSerial::~SoftwareSerial() { end(); }
-
-//
-// Public methods
-//
-
-void SoftwareSerial::begin(long speed) {
- #ifdef FORCE_BAUD_RATE
- speed = FORCE_BAUD_RATE;
- #endif
- _speed = speed;
- if (!_half_duplex) {
- setTX();
- setRX();
- listen();
- }
- else
- setTX();
-}
-
-void SoftwareSerial::end() {
- stopListening();
-}
-
-// Read data from buffer
-int SoftwareSerial::read() {
- // Empty buffer?
- if (_receive_buffer_head == _receive_buffer_tail) return -1;
-
- // Read from "head"
- uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
- _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
- return d;
-}
-
-int SoftwareSerial::available() {
- return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
-}
-
-size_t SoftwareSerial::write(uint8_t b) {
- // wait for previous transmit to complete
- _output_pending = 1;
- while (active_out) { /* nada */ }
- // add start and stop bits.
- tx_buffer = b << 1 | 0x200;
- if (_inverse_logic) tx_buffer = ~tx_buffer;
- tx_bit_cnt = 0;
- tx_tick_cnt = OVERSAMPLE;
- setSpeed(_speed);
- if (_half_duplex) setRXTX(false);
- _output_pending = 0;
- // make us active
- active_out = this;
- return 1;
-}
-
-void SoftwareSerial::flush() {
- noInterrupts();
- _receive_buffer_head = _receive_buffer_tail = 0;
- interrupts();
-}
-
-int SoftwareSerial::peek() {
- // Empty buffer?
- if (_receive_buffer_head == _receive_buffer_tail) return -1;
-
- // Read from "head"
- return _receive_buffer[_receive_buffer_head];
-}
-
-#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
diff --git a/Marlin/src/HAL/STM32/SoftwareSerial.h b/Marlin/src/HAL/STM32/SoftwareSerial.h
deleted file mode 100644
index 1a4f742c32..0000000000
--- a/Marlin/src/HAL/STM32/SoftwareSerial.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * SoftwareSerial.h (formerly NewSoftSerial.h)
- *
- * Multi-instance software serial library for Arduino/Wiring
- * -- Interrupt-driven receive and other improvements by ladyada
- * (https://ladyada.net)
- * -- Tuning, circular buffer, derivation from class Print/Stream,
- * multi-instance support, porting to 8MHz processors,
- * various optimizations, PROGMEM delay tables, inverse logic and
- * direct port writing by Mikal Hart (http://www.arduiniana.org)
- * -- Pin change interrupt macros by Paul Stoffregen (https://www.pjrc.com)
- * -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
- * -- ATmega1280/2560 support by Brett Hagman (https://www.roguerobotics.com/)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The latest version of this library can always be found at
- * http://arduiniana.org.
- */
-#pragma once
-
-#include