diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index b573d2d9ec..b21eba76a0 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -3107,13 +3107,17 @@
* - Download https://github.com/InsanityAutomation/Marlin/raw/CrealityDwin_2.0/TM3D_Combined480272_Landscape_V7.7z
* - Copy the downloaded DWIN_SET folder to the SD card.
*
+ * E3S1PRO (T5UID1)
+ * - Download https://github.com/CrealityOfficial/Ender-3S1/archive/3S1_Plus_Screen.zip
+ * - Copy the downloaded DWIN_SET folder to the SD card.
+ *
* Flash display with DGUS Displays for Marlin:
* - Format the SD card to FAT32 with an allocation size of 4kb.
* - Download files as specified for your type of display.
* - Plug the microSD card into the back of the display.
* - Boot the display and wait for the update to complete.
*
- * :[ 'ORIGIN', 'FYSETC', 'HYPRECY', 'MKS', 'RELOADED', 'IA_CREALITY' ]
+ * :[ 'ORIGIN', 'FYSETC', 'HYPRECY', 'MKS', 'RELOADED', 'IA_CREALITY', 'E3S1PRO' ]
*/
//#define DGUS_LCD_UI ORIGIN
#if DGUS_UI_IS(MKS)
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index be54354d5c..4d0791c341 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -2015,6 +2015,22 @@
#define DGUS_UI_WAITING_STATUS 10
#define DGUS_UI_WAITING_STATUS_PERIOD 8 // Increase to slower waiting status looping
#endif
+
+ #elif DGUS_UI_IS(E3S1PRO)
+ /**
+ * The stock Ender-3 S1 Pro/Plus display firmware has rather poor SD file handling.
+ *
+ * The autoscroll is mainly useful for status messages, filenames, and the "About" page.
+ *
+ * NOTE: The Advanced SD Card option is affected by the stock touchscreen firmware, so
+ * pages 5 and up will display "4/4". This may get fixed in a screen firmware update.
+ */
+ #define DGUS_SOFTWARE_AUTOSCROLL // Enable long text software auto-scroll
+ #define DGUS_AUTOSCROLL_START_CYCLES 1 // Refresh cycles without scrolling at the beginning of text strings
+ #define DGUS_AUTOSCROLL_END_CYCLES 1 // ... at the end of text strings
+
+ #define DGUS_ADVANCED_SDCARD // Allow more than 20 files and navigating directories
+ #define DGUS_USERCONFIRM // Reuse the SD Card page to show various messages
#endif
#endif // HAS_DGUS_LCD
diff --git a/Marlin/src/core/endianness.h b/Marlin/src/core/endianness.h
new file mode 100644
index 0000000000..8fa8e40078
--- /dev/null
+++ b/Marlin/src/core/endianness.h
@@ -0,0 +1,76 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../core/types.h"
+#include "../core/macros.h"
+
+#ifdef __cplusplus
+
+namespace Endianness {
+ static constexpr uint32_t _dword = 0x01020304;
+ static constexpr uint8_t _lsb = (const uint8_t&)_dword;
+
+ static constexpr bool cpuIsLittleEndian = _lsb == 0x04;
+ static constexpr bool cpuIsBigEndian = _lsb == 0x01;
+ static_assert(cpuIsLittleEndian ^ cpuIsBigEndian, "Unknown CPU endianness");
+
+ // constexpr byte swapping for integral types
+ template static constexpr typename Private::enable_if::value, T>::type swap(T V, T swappedV=(T)0, size_t byteIndex=0) {
+ return byteIndex == sizeof(T)
+ ? swappedV
+ : swap((T)(V >> 8), (swappedV << 8) | (V & (T)0xFF), byteIndex + 1);
+ }
+
+ // constexpr byte swapping for types derived from integral types (e.g. enums)
+ template static constexpr typename Private::enable_if<
+ Private::is_same::type>::value, T>::type swap(T V) { return (T)swap((uint16_t)V); }
+ template static constexpr typename Private::enable_if<
+ Private::is_same::type>::value, T>::type swap(T V) { return (T)swap((uint32_t)V); }
+ template static constexpr typename Private::enable_if<
+ Private::is_same::type>::value, T>::type swap(T V) { return (T)swap((uint64_t)V); }
+
+ // Generic byte swapping
+ // CANNOT be used to initialize constexpr declarations
+ template static constexpr typename Private::enable_if::value && !Private::is_enum::value, T>::type swap(T V) {
+ union {
+ T val;
+ char byte[sizeof(T)];
+ } src{}, dst{};
+
+ src.val = V;
+ for (uint8_t i = 0; i < sizeof(T); ++i) dst.byte[i] = src.byte[sizeof(T) - i - 1];
+ return dst.val;
+ }
+
+ // Convert to / from known endianness, depending on the host endianness
+ template static constexpr T toBE(T V) { return cpuIsLittleEndian ? swap(V) : V; }
+ template static constexpr T toLE(T V) { return cpuIsLittleEndian ? V : swap(V); }
+ template static constexpr T fromBE(T V) { return cpuIsLittleEndian ? swap(V) : V; }
+ template static constexpr T fromLE(T V) { return cpuIsLittleEndian ? V : swap(V); }
+
+ // Reads a big/little endian from a pointer and converts it to the host endianness
+ template static constexpr T fromBE_P(void* V) { return fromBE(*(T*)V); }
+ template static constexpr T fromLE_P(void* V) { return fromLE(*(T*)V); }
+};
+
+#endif // __cplusplus
diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h
index 565de2436c..e4b9d479c4 100644
--- a/Marlin/src/core/macros.h
+++ b/Marlin/src/core/macros.h
@@ -408,7 +408,41 @@
template struct first_type_of { typedef T type; };
template struct first_type_of { typedef T type; };
+
+ // remove const/volatile type qualifiers
+ template struct remove_const { typedef T type; };
+ template struct remove_const { typedef T type; };
+
+ template struct remove_volatile { typedef T type; };
+ template struct remove_volatile { typedef T type; };
+
+ template struct remove_cv { typedef typename remove_const::type>::type type; };
+
+ // test if type is integral
+ template struct _is_integral { enum { value = false }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template<> struct _is_integral { enum { value = true }; };
+ template struct is_integral : public _is_integral::type> {};
}
+
+ // enum type check and regression to its underlying integral.
+ namespace Private {
+ template struct is_enum { enum { value = __is_enum(T) }; };
+
+ template::value> struct _underlying_type { using type = __underlying_type(T); };
+ template struct _underlying_type { };
+
+ template struct underlying_type : public _underlying_type { };
+ }
+
// C++11 solution using SFINAE to detect the existence of a member in a class at compile time.
// It creates a HasMember structure containing 'value' set to true if the member exists
#define HAS_MEMBER_IMPL(Member) \
@@ -712,5 +746,6 @@
#define _UI_MKS 104
#define _UI_RELOADED 105
#define _UI_IA_CREALITY 106
+#define _UI_E3S1PRO 107
#define _DGUS_UI_IS(N) || (CAT(_UI_, DGUS_LCD_UI) == CAT(_UI_, N))
#define DGUS_UI_IS(V...) (0 MAP(_DGUS_UI_IS, V))
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index db325dee7a..b34e87ca5e 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -101,13 +101,16 @@ void event_filament_runout(const uint8_t extruder) {
const bool run_runout_script = !runout.host_handling;
+ const bool park_or_pause = (false
+ #ifdef FILAMENT_RUNOUT_SCRIPT
+ || strstr(FILAMENT_RUNOUT_SCRIPT, "M600")
+ || strstr(FILAMENT_RUNOUT_SCRIPT, "M125")
+ || TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25"))
+ #endif
+ );
+
#if ENABLED(HOST_ACTION_COMMANDS)
- if (run_runout_script
- && ( strstr(FILAMENT_RUNOUT_SCRIPT, "M600")
- || strstr(FILAMENT_RUNOUT_SCRIPT, "M125")
- || TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25"))
- )
- ) {
+ if (run_runout_script && park_or_pause) {
hostui.paused(false);
}
else {
@@ -126,22 +129,24 @@ void event_filament_runout(const uint8_t extruder) {
SERIAL_EOL();
#endif // HOST_ACTION_COMMANDS
- if (run_runout_script) {
- #if MULTI_FILAMENT_SENSOR
- MString script;
- script.setf(F(FILAMENT_RUNOUT_SCRIPT), AS_CHAR(tool));
- #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
- SERIAL_ECHOLNPGM("Runout Command: ", &script);
+ #ifdef FILAMENT_RUNOUT_SCRIPT
+ if (run_runout_script) {
+ #if MULTI_FILAMENT_SENSOR
+ MString script;
+ script.setf(F(FILAMENT_RUNOUT_SCRIPT), AS_CHAR(tool));
+ #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
+ SERIAL_ECHOLNPGM("Runout Command: ", &script);
+ #endif
+ queue.inject(&script);
+ #else
+ #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
+ SERIAL_ECHOPGM("Runout Command: ");
+ SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT);
+ #endif
+ queue.inject(F(FILAMENT_RUNOUT_SCRIPT));
#endif
- queue.inject(&script);
- #else
- #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
- SERIAL_ECHOPGM("Runout Command: ");
- SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT);
- #endif
- queue.inject(F(FILAMENT_RUNOUT_SCRIPT));
- #endif
- }
+ }
+ #endif
}
#endif // HAS_FILAMENT_SENSOR
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 0ab42cb22f..bfc5bfd0ff 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -53,6 +53,8 @@
#define DGUS_LCD_UI_RELOADED 1
#elif DGUS_UI_IS(IA_CREALITY)
#define DGUS_LCD_UI_IA_CREALITY 1
+#elif DGUS_UI_IS(E3S1PRO)
+ #define DGUS_LCD_UI_E3S1PRO 1
#endif
/**
diff --git a/Marlin/src/inc/MarlinConfig.h b/Marlin/src/inc/MarlinConfig.h
index d61a6b55e7..8f6519dbaf 100644
--- a/Marlin/src/inc/MarlinConfig.h
+++ b/Marlin/src/inc/MarlinConfig.h
@@ -57,6 +57,7 @@
#include "../core/utility.h"
#include "../core/mstring.h"
#include "../core/serial.h"
+ #include "../core/endianness.h"
#endif
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 9fdd0d603e..4a948ceba3 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -545,7 +545,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#error "You can't enable FIL_RUNOUT8_PULLUP and FIL_RUNOUT8_PULLDOWN at the same time."
#elif FILAMENT_RUNOUT_DISTANCE_MM < 0
#error "FILAMENT_RUNOUT_DISTANCE_MM must be greater than or equal to zero."
- #elif DISABLED(ADVANCED_PAUSE_FEATURE)
+ #elif DISABLED(ADVANCED_PAUSE_FEATURE) && defined(FILAMENT_RUNOUT_SCRIPT)
static_assert(nullptr == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR.");
#endif
#endif
@@ -3994,6 +3994,41 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive."
#endif
#endif
+/**
+ * Require certain features for DGUS_LCD_UI E3S1PRO.
+ */
+#if DGUS_UI_IS(E3S1PRO)
+ #if BUFSIZE < 4
+ #error "DGUS_LCD_UI E3S1PRO requires a BUFSIZE of at least 4."
+ #elif !(HOTENDS == 1)
+ #error "DGUS_LCD_UI E3S1PRO requires 1 hotend."
+ #elif !(EXTRUDERS == 1)
+ #error "DGUS_LCD_UI E3S1PRO requires at least 1 extruder."
+ #elif !HAS_HEATED_BED
+ #error "DGUS_LCD_UI E3S1PRO requires a heated bed."
+ #elif FAN_COUNT < 1
+ #error "DGUS_LCD_UI E3S1PRO requires a fan."
+ #elif !HAS_BED_PROBE
+ #error "DGUS_LCD_UI E3S1PRO requires a bed probe."
+ #elif !HAS_MESH
+ #error "DGUS_LCD_UI E3S1PRO requires mesh leveling."
+ #elif !HAS_MEDIA
+ #error "DGUS_LCD_UI E3S1PRO requires SDSUPPORT."
+ #elif DISABLED(POWER_LOSS_RECOVERY)
+ #error "DGUS_LCD_UI E3S1PRO requires POWER_LOSS_RECOVERY."
+ #elif DISABLED(LCD_BED_TRAMMING)
+ #error "DGUS_LCD_UI E3S1PRO requires LCD_BED_TRAMMING."
+ #elif DISABLED(BABYSTEP_ALWAYS_AVAILABLE)
+ #error "DGUS_LCD_UI E3S1PRO requires BABYSTEP_ALWAYS_AVAILABLE."
+ #elif DISABLED(BABYSTEP_ZPROBE_OFFSET)
+ #error "DGUS_LCD_UI E3S1PRO requires BABYSTEP_ZPROBE_OFFSET."
+ #elif !defined(PREHEAT_1_TEMP_HOTEND) || !defined(PREHEAT_2_TEMP_HOTEND)
+ #error "DGUS_LCD_UI E3S1PRO requires 2 preheating presets."
+ #elif ENABLED(AUTO_BED_LEVELING_UBL) && DISABLED(UBL_SAVE_ACTIVE_ON_M500)
+ #warning "Without UBL_SAVE_ACTIVE_ON_M500, your mesh will not be saved when using the touchscreen."
+ #endif
+#endif
+
// JTAG support in the HAL
#if ENABLED(DISABLE_DEBUG) && !defined(JTAGSWD_DISABLE)
#error "DISABLE_DEBUG is not supported for the selected MCU/Board."
diff --git a/Marlin/src/lcd/extui/dgus/fysetc/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus/fysetc/DGUSScreenHandler.cpp
index 768092633e..8c26066b28 100644
--- a/Marlin/src/lcd/extui/dgus/fysetc/DGUSScreenHandler.cpp
+++ b/Marlin/src/lcd/extui/dgus/fysetc/DGUSScreenHandler.cpp
@@ -77,20 +77,18 @@
if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes.
switch (swap16(*(uint16_t*)val_ptr)) {
- case 0: { // Resume
- if (ExtUI::isPrintingFromMediaPaused()) {
- ExtUI::resumePrint();
- }
- } break;
+ case 0: // Resume
+ if (ExtUI::isPrintingFromMediaPaused()) ExtUI::resumePrint();
+ break;
case 1: // Pause
-
gotoScreen(DGUS_SCREEN_SDPRINTMANIPULATION);
if (!ExtUI::isPrintingFromMediaPaused()) {
ExtUI::pausePrint();
//ExtUI::mks_pausePrint();
}
break;
+
case 2: // Abort
handleUserConfirmationPopUp(VP_SD_AbortPrintConfirmed, nullptr, PSTR("Abort printing"), filelist.filename(), PSTR("?"), true, true, false, true);
break;
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.cpp
new file mode 100644
index 0000000000..b897466c6a
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.cpp
@@ -0,0 +1,381 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/* DGUS implementation written by coldtobi in 2019 for Marlin */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSDisplay.h"
+
+#include "config/DGUS_Addr.h"
+#include "config/DGUS_Constants.h"
+#include "definition/DGUS_VPList.h"
+
+#include "../ui_api.h"
+
+long map_precise(float x, long in_min, long in_max, long out_min, long out_max) {
+ return LROUND((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
+}
+
+uint8_t DGUSDisplay::gui_version = 0;
+uint8_t DGUSDisplay::os_version = 0;
+
+uint8_t DGUSDisplay::volume = 255;
+uint8_t DGUSDisplay::brightness = 100;
+
+DGUSDisplay::rx_datagram_state_t DGUSDisplay::rx_datagram_state = DGUS_IDLE;
+uint8_t DGUSDisplay::rx_datagram_len = 0;
+
+bool DGUSDisplay::initialized = false;
+
+void DGUSDisplay::loop() {
+ processRx();
+}
+
+void DGUSDisplay::init() {
+ LCD_SERIAL.begin(LCD_BAUDRATE);
+
+ readVersions();
+}
+
+void DGUSDisplay::read(uint16_t addr, uint8_t size) {
+ writeHeader(addr, DGUS_READVAR, size);
+
+ LCD_SERIAL.write(size);
+}
+
+void DGUSDisplay::write(uint16_t addr, const void* data_ptr, uint8_t size) {
+ if (!data_ptr) return;
+
+ writeHeader(addr, DGUS_WRITEVAR, size);
+
+ const char* data = static_cast(data_ptr);
+
+ while (size--) LCD_SERIAL.write(*data++);
+}
+
+void DGUSDisplay::writeString(uint16_t addr, const void* data_ptr, uint8_t size, bool left, bool right, bool use_space) {
+ if (!data_ptr) return;
+
+ writeHeader(addr, DGUS_WRITEVAR, size);
+
+ const char* data = static_cast(data_ptr);
+ size_t len = strlen(data);
+ uint8_t left_spaces = 0;
+ uint8_t right_spaces = 0;
+
+ if (len < size) {
+ if (!len) {
+ right_spaces = size;
+ }
+ else {
+ const uint8_t rem = size - len;
+ if ((left && right) || (!left && !right)) {
+ left_spaces = rem / 2;
+ right_spaces = rem - left_spaces;
+ }
+ else if (left)
+ right_spaces = rem;
+ else
+ left_spaces = rem;
+ }
+ }
+ else {
+ len = size;
+ }
+
+ while (left_spaces--) LCD_SERIAL.write(' ');
+ while (len--) LCD_SERIAL.write(*data++);
+ while (right_spaces--) LCD_SERIAL.write(use_space ? ' ' : '\0');
+}
+
+void DGUSDisplay::writeStringPGM(uint16_t addr, const void* data_ptr, uint8_t size, bool left, bool right, bool use_space) {
+ if (!data_ptr) return;
+
+ writeHeader(addr, DGUS_WRITEVAR, size);
+
+ const char* data = static_cast(data_ptr);
+ size_t len = strlen_P(data);
+ uint8_t left_spaces = 0, right_spaces = 0;
+
+ if (len < size) {
+ if (!len) {
+ right_spaces = size;
+ }
+ else if ((left && right) || (!left && !right)) {
+ left_spaces = (size - len) / 2;
+ right_spaces = size - len - left_spaces;
+ }
+ else if (left) {
+ right_spaces = size - len;
+ }
+ else {
+ left_spaces = size - len;
+ }
+ }
+ else {
+ len = size;
+ }
+
+ while (left_spaces--) LCD_SERIAL.write(' ');
+ while (len--) LCD_SERIAL.write(pgm_read_byte(data++));
+ while (right_spaces--) LCD_SERIAL.write(use_space ? ' ' : '\0');
+}
+
+void DGUSDisplay::readVersions() {
+ if (gui_version != 0 && os_version != 0) return;
+ read(DGUS_VERSION, 1);
+}
+
+void DGUSDisplay::switchScreen(DGUS_ScreenID screen) {
+ const uint8_t command[] = { 0x5A, 0x01, 0x00, (uint8_t)screen };
+ write(0x84, command, sizeof(command));
+}
+
+void DGUSDisplay::playSound(uint8_t start, uint8_t len, uint8_t volume) {
+ if (volume == 0) volume = DGUSDisplay::volume;
+ else volume = map_precise(constrain(volume, 0, 100), 0, 100, 0, 0x40);
+
+ if (volume == 0) return;
+ const uint8_t command[] = { start, len, volume, 0x00 };
+ write(0xA0, command, sizeof(command));
+}
+
+void DGUSDisplay::enableControl(DGUS_ScreenID screen, DGUS_ControlType type, DGUS_Control control) {
+ const uint8_t command[] = { 0x5A, 0xA5, 0x00, (uint8_t)screen, (uint8_t)control, type, 0x00, 0x01 };
+ write(0xB0, command, sizeof(command));
+
+ flushTx();
+ delay(50);
+}
+
+void DGUSDisplay::disableControl(DGUS_ScreenID screen, DGUS_ControlType type, DGUS_Control control) {
+ const uint8_t command[] = { 0x5A, 0xA5, 0x00, (uint8_t)screen, (uint8_t)control, type, 0x00, 0x00 };
+ write(0xB0, command, sizeof(command));
+
+ flushTx();
+ delay(50);
+}
+
+uint8_t DGUSDisplay::getBrightness() {
+ return brightness;
+}
+
+uint8_t DGUSDisplay::getVolume() {
+ return map_precise(volume, 0, 0x40, 0, 100);
+}
+
+void DGUSDisplay::setBrightness(uint8_t new_brightness) {
+ brightness = constrain(new_brightness, 0, 100);
+ new_brightness = map_precise(brightness, 0, 100, 5, 100);
+ const uint8_t command[] = { new_brightness, new_brightness };
+ write(0x82, command, sizeof(command));
+}
+
+void DGUSDisplay::setVolume(uint8_t new_volume) {
+ volume = map_precise(constrain(new_volume, 0, 100), 0, 100, 0, 0x40);
+ const uint8_t command[] = { volume, 0x00 };
+ write(0xA1, command, sizeof(command));
+}
+
+void DGUSDisplay::processRx() {
+
+ #if ENABLED(LCD_SERIAL_STATS_RX_BUFFER_OVERRUNS)
+ if (!LCD_SERIAL.available() && LCD_SERIAL.buffer_overruns()) {
+ // Overrun, but reset the flag only when the buffer is empty
+ // We want to extract as many as valid datagrams possible...
+ rx_datagram_state = DGUS_IDLE;
+ //LCD_SERIAL.reset_rx_overun();
+ LCD_SERIAL.flush();
+ }
+ #endif
+
+ uint8_t receivedbyte;
+ while (LCD_SERIAL.available()) {
+ switch (rx_datagram_state) {
+ case DGUS_IDLE: // Waiting for the first header byte
+ receivedbyte = LCD_SERIAL.read();
+ if (DGUS_HEADER1 == receivedbyte) rx_datagram_state = DGUS_HEADER1_SEEN;
+ break;
+
+ case DGUS_HEADER1_SEEN: // Waiting for the second header byte
+ receivedbyte = LCD_SERIAL.read();
+ rx_datagram_state = (DGUS_HEADER2 == receivedbyte) ? DGUS_HEADER2_SEEN : DGUS_IDLE;
+ break;
+
+ case DGUS_HEADER2_SEEN: // Waiting for the length byte
+ rx_datagram_len = LCD_SERIAL.read();
+ // Telegram min len is 3 (command and one word of payload)
+ rx_datagram_state = WITHIN(rx_datagram_len, 3, DGUS_RX_BUFFER_SIZE) ? DGUS_WAIT_TELEGRAM : DGUS_IDLE;
+ break;
+
+ case DGUS_WAIT_TELEGRAM: // wait for complete datagram to arrive.
+ if (LCD_SERIAL.available() < rx_datagram_len) return;
+
+ initialized = true; // We've talked to it, so we defined it as initialized.
+ uint8_t command = LCD_SERIAL.read();
+ uint8_t readlen = rx_datagram_len - 1; // command is part of len.
+ unsigned char tmp[rx_datagram_len - 1];
+ unsigned char *ptmp = tmp;
+
+ while (readlen--) {
+ receivedbyte = LCD_SERIAL.read();
+ *ptmp++ = receivedbyte;
+ }
+ // mostly we'll get this: 5A A5 03 82 4F 4B -- ACK on 0x82, so discard it.
+ if (command == DGUS_WRITEVAR && 'O' == tmp[0] && 'K' == tmp[1]) {
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ /**
+ * AutoUpload, (and answer to) Command 0x83 :
+ * tmp[0 1 2 3 4 ... ]
+ * Example 5A A5 06 83 20 01 01 78 01 ……
+ * / / | | \ / | \ \
+ * Header | | | | \_____\_ DATA (Words!)
+ * DatagramLen / VPAdr |
+ * Command DataLen (in Words)
+ */
+ if (command == DGUS_READVAR) {
+ const uint16_t addr = Endianness::fromBE_P(tmp);
+ const uint8_t dlen = tmp[2] << 1; // Convert to Bytes. (Display works with words)
+ if (addr == DGUS_VERSION && dlen == 2) {
+ gui_version = tmp[3];
+ os_version = tmp[4];
+
+ #if ENABLED(DEBUG_DGUSLCD)
+ DEBUG_ECHOLNPGM("DGUS version: GUI ", gui_version, "OS ", os_version);
+ #endif
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ DGUS_VP vp;
+ if (!DGUS_PopulateVP((DGUS_Addr)addr, &vp)) {
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ if (!vp.rx_handler) {
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ gcode.reset_stepper_timeout();
+
+ if (!vp.size) {
+ DEBUG_EOL();
+ vp.rx_handler(vp, nullptr);
+
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ if (vp.flags & VPFLAG_RXSTRING) {
+ unsigned char buffer[vp.size];
+ memset(buffer, 0, vp.size);
+
+ for (uint8_t i = 0; i < dlen; i++) {
+ if (i >= vp.size) break;
+
+ if (i + 1 < dlen && tmp[i + 3] == 0xFF && tmp[i + 4] == 0xFF)
+ break;
+
+ buffer[i] = tmp[i + 3];
+ }
+
+ DEBUG_EOL();
+ vp.rx_handler(vp, buffer);
+
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ if (dlen != vp.size) {
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ DEBUG_EOL();
+ vp.rx_handler(vp, &tmp[3]);
+
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+
+ #if ENABLED(DEBUG_DGUSLCD)
+ DEBUG_ECHOLNPGM("DGUS unknown command ", command);
+ #endif
+
+ rx_datagram_state = DGUS_IDLE;
+ break;
+ }
+ }
+}
+
+size_t DGUSDisplay::getFreeTxBuffer() {
+ return (
+ #ifdef LCD_SERIAL_GET_TX_BUFFER_FREE
+ LCD_SERIAL_GET_TX_BUFFER_FREE()
+ #else
+ SIZE_MAX
+ #endif
+ );
+}
+
+void DGUSDisplay::flushTx() {
+ TERN(ARDUINO_ARCH_STM32, LCD_SERIAL.flush(), LCD_SERIAL.flushTX());
+}
+
+void DGUSDisplay::writeHeader(uint16_t addr, uint8_t command, uint8_t len) {
+ LCD_SERIAL.write(DGUS_HEADER1);
+ LCD_SERIAL.write(DGUS_HEADER2);
+ LCD_SERIAL.write(len + 3);
+ LCD_SERIAL.write(command);
+
+ union {
+ uint16_t u16;
+ uint8_t u8[2];
+ } data = { Endianness::toBE(addr) };
+
+ for (uint8_t i = 0; i < sizeof(data.u8); ++i) LCD_SERIAL.write(data.u8[i]);
+}
+
+bool DGUS_PopulateVP(const DGUS_Addr addr, DGUS_VP * const buffer) {
+ const DGUS_VP *ret = vp_list;
+
+ do {
+ const uint16_t *paddr = (uint16_t *)(&ret->addr);
+ const uint16_t addrcheck = pgm_read_word(paddr);
+ if (addrcheck == 0) break;
+ if ((DGUS_Addr)addrcheck == addr) {
+ memcpy_P(buffer, ret, sizeof(*ret));
+ return true;
+ }
+ } while (++ret);
+ return false;
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.h
new file mode 100644
index 0000000000..8d8a3cf013
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSDisplay.h
@@ -0,0 +1,163 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * DGUS implementation written by coldtobi in 2019.
+ * Updated for STM32G0B1RE by Protomosh in 2022.
+ */
+
+#include "config/DGUS_Screen.h"
+#include "config/DGUS_Control.h"
+#include "definition/DGUS_VP.h"
+
+#include "../ui_api.h"
+#include "../../../inc/MarlinConfigPre.h"
+#include "../../../MarlinCore.h"
+
+//#define DEBUG_DGUSLCD // Uncomment for debug messages
+#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD)
+#include "../../../core/debug_out.h"
+
+// Low-Level access to the display.
+class DGUSDisplay {
+public:
+
+ enum DGUS_ControlType : uint8_t {
+ VARIABLE_DATA_INPUT = 0x00,
+ POPUP_WINDOW = 0x01,
+ INCREMENTAL_ADJUST = 0x02,
+ SLIDER_ADJUST = 0x03,
+ RTC_SETTINGS = 0x04,
+ RETURN_KEY_CODE = 0x05,
+ TEXT_INPUT = 0x06,
+ FIRMWARE_SETTINGS = 0x07
+ };
+
+ DGUSDisplay() = default;
+
+ static void init();
+
+ static void read(uint16_t addr, uint8_t size);
+ static void write(uint16_t addr, const void* data_ptr, uint8_t size);
+
+ static void writeString(uint16_t addr, const void* data_ptr, uint8_t size, bool left=true, bool right=false, bool use_space=true);
+ static void writeStringPGM(uint16_t addr, const void* data_ptr, uint8_t size, bool left=true, bool right=false, bool use_space=true);
+ static void writeString(uint16_t addr, FSTR_P const fstr, uint8_t size, bool left=true, bool right=false, bool use_space=true) {
+ writeStringPGM(addr, FTOP(fstr), size, left, right, use_space);
+ }
+
+ template
+ static void write(uint16_t addr, T data) {
+ write(addr, static_cast(&data), sizeof(T));
+ }
+
+ // Until now I did not need to actively read from the display. That's why there is no ReadVariable
+ // (I extensively use the auto upload of the display)
+
+ // Read GUI and OS version from screen
+ static void readVersions();
+
+ // Force display into another screen.
+ static void switchScreen(DGUS_ScreenID screen);
+ // Play sounds using the display speaker.
+ // start: position at which the sound was stored on the display.
+ // len: how many sounds to play. Sounds will play consecutively from start to start+len-1.
+ // volume: playback volume. 0 keeps the current volume.
+ static void playSound(uint8_t start, uint8_t len=1, uint8_t volume=0);
+ // Enable/disable a specific touch control.
+ // type: control type.
+ // control: index of the control on the page (set during screen development).
+ static void enableControl(DGUS_ScreenID screen, DGUS_ControlType type, DGUS_Control control);
+ static void disableControl(DGUS_ScreenID screen, DGUS_ControlType type, DGUS_Control control);
+
+ static uint8_t getBrightness();
+ static uint8_t getVolume();
+
+ // Set the display brightness/volume, ranging 0 - 100
+ static void setBrightness(uint8_t brightness);
+ static void setVolume(uint8_t volume);
+
+ // Periodic tasks, eg. Rx-Queue handling.
+ static void loop();
+
+ // Helper for users of this class to estimate if an interaction would be blocking.
+ static size_t getFreeTxBuffer();
+ static void flushTx();
+
+ // Checks two things: Can we confirm the presence of the display and has we initialized it.
+ // (both boils down that the display answered to our chatting)
+ static bool isInitialized() {
+ return initialized;
+ }
+
+ static uint8_t gui_version;
+ static uint8_t os_version;
+
+ template
+ T_out fromFixedPoint(const T_in value) {
+ return (T_out)((float)value / POW(10, decimals));
+ }
+
+ template
+ T_out toFixedPoint(const T_in value) {
+ return (T_out)LROUND((float)value * POW(10, decimals));
+ }
+
+private:
+ enum dgus_header : uint8_t {
+ DGUS_HEADER1 = 0x5A,
+ DGUS_HEADER2 = 0xA5
+ };
+
+ enum dgus_command : uint8_t {
+ DGUS_WRITEVAR = 0x82,
+ DGUS_READVAR = 0x83
+ };
+
+ enum rx_datagram_state_t : uint8_t {
+ DGUS_IDLE, //< waiting for DGUS_HEADER1.
+ DGUS_HEADER1_SEEN, //< DGUS_HEADER1 received
+ DGUS_HEADER2_SEEN, //< DGUS_HEADER2 received
+ DGUS_WAIT_TELEGRAM, //< LEN received, Waiting for to receive all bytes.
+ };
+
+ enum dgus_system_addr : uint16_t {
+ DGUS_VERSION = 0x000F // OS/GUI version
+ };
+
+ static void writeHeader(uint16_t addr, uint8_t command, uint8_t len);
+ static void processRx();
+
+ static uint8_t volume;
+ static uint8_t brightness;
+
+ static rx_datagram_state_t rx_datagram_state;
+ static uint8_t rx_datagram_len;
+
+ static bool initialized;
+};
+
+extern DGUSDisplay dgus;
+
+/// Helper to populate a DGUS_VP for a given VP. Return false if not found.
+extern bool DGUS_PopulateVP(const DGUS_Addr addr, DGUS_VP * const buffer);
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.cpp
new file mode 100644
index 0000000000..f6d2e2bb89
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.cpp
@@ -0,0 +1,684 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSReturnKeyCodeHandler.h"
+
+#include "DGUSDisplay.h"
+#include "DGUSScreenHandler.h"
+#include "config/DGUS_Screen.h"
+
+#include "../ui_api.h"
+#include "../../../core/language.h"
+#include "../../../module/temperature.h"
+#include "../../../module/printcounter.h"
+#include "../../../module/stepper.h"
+#include "../../../gcode/queue.h"
+#if ENABLED(ADVANCED_PAUSE_FEATURE)
+ #include "../../../feature/pause.h"
+#endif
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../feature/powerloss.h"
+#endif
+
+#define DGUS_UNKNOWN_COMMAND_DEBUG // uncomment to debug unknown commands
+
+static uint16_t plaExtruderTempSave = 0;
+static uint16_t plaBedTempSave = 0;
+static uint16_t absExtruderTempSave = 0;
+static uint16_t absBedTempSave = 0;
+
+static DGUS_ScreenID GetJogScreenForSavedJogLength() {
+ DGUS_ScreenID jogscreen = DGUS_ScreenID::MOVEAXIS_10;
+ switch (screen.config.jogLength) {
+ case DGUS_Data::AxisControlCommand::Jog_10mm: jogscreen = DGUS_ScreenID::MOVEAXIS_10; break;
+ case DGUS_Data::AxisControlCommand::Jog_1mm: jogscreen = DGUS_ScreenID::MOVEAXIS_1; break;
+ case DGUS_Data::AxisControlCommand::Jog_0_1mm: jogscreen = DGUS_ScreenID::MOVEAXIS_01; break;
+ default: break;
+ }
+
+ return jogscreen;
+}
+
+// 1002
+void DGUSReturnKeyCodeHandler::Command_MenuSelect(DGUS_VP &vp, void *data) {
+ DGUS_Data::MenuSelectCommand submenu = Endianness::fromBE_P(data);
+
+ switch (submenu) {
+ case DGUS_Data::MenuSelectCommand::Main:
+ screen.triggerScreenChange(DGUS_ScreenID::MAIN);
+ break;
+
+ case DGUS_Data::MenuSelectCommand::Print:
+ if (ExtUI::isMediaInserted()) {
+ dgus_sdcard_handler.Reset();
+ screen.triggerScreenChange(DGUS_ScreenID::FILE1);
+ }
+ else
+ screen.triggerTempScreenChange(DGUS_ScreenID::SDCARDCHECK, screen.getCurrentScreen());
+ break;
+
+ case DGUS_Data::MenuSelectCommand::Ready: {
+ DGUS_ScreenID jogscreen = GetJogScreenForSavedJogLength();
+ if (ExtUI::isPositionKnown())
+ screen.triggerScreenChange(jogscreen);
+ else
+ screen.homeThenChangeScreen(jogscreen);
+ } break;
+
+ case DGUS_Data::MenuSelectCommand::Settings:
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ case DGUS_Data::MenuSelectCommand::StartAutoLevel:
+ if (!ExtUI::isPositionKnown())
+ screen.homeThenChangeScreen(screen.getCurrentScreen());
+
+ ExtUI::injectCommands(F("M420 S0\n" TERN(AUTO_BED_LEVELING_UBL, "G29 P1", "G29")));
+ break;
+
+ case DGUS_Data::MenuSelectCommand::PrintFinished:
+ screen.triggerScreenChange(DGUS_ScreenID::HOME);
+ break;
+
+ case DGUS_Data::MenuSelectCommand::PausePrint:
+ screen.triggerTempScreenChange(DGUS_ScreenID::PAUSE_STOP, DGUS_ScreenID::PAUSE);
+ break;
+
+ case DGUS_Data::MenuSelectCommand::PauseStopPrint:
+ screen.triggerTempScreenChange(DGUS_ScreenID::CONTINUE_STOP, DGUS_ScreenID::RESUME);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_MenuSelect: unknown id ", (uint16_t)submenu);
+ #endif
+ break;
+ }
+}
+
+// 1004
+void DGUSReturnKeyCodeHandler::Command_Adjust(DGUS_VP &vp, void *data) {
+ DGUS_Data::AdjustCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::AdjustCommand::Show_Adjust:
+ screen.triggerScreenChange(DGUS_ScreenID::ADJUST);
+ break;
+
+ case DGUS_Data::AdjustCommand::Show_PrintStatus:
+ screen.triggerScreenChange(DGUS_ScreenID::PAUSE);
+ break;
+
+ case DGUS_Data::AdjustCommand::Show_Adjust_ZOffset:
+ screen.triggerScreenChange(DGUS_ScreenID::PREPARE);
+ break;
+
+ case DGUS_Data::AdjustCommand::Validate_ZOffset:
+ screen.triggerScreenChange(DGUS_ScreenID::ADJUST);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_Adjust: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 1008
+void DGUSReturnKeyCodeHandler::Command_CheckKO(DGUS_VP &vp, void *data) {
+ DGUS_Data::CheckKOCommand command = Endianness::fromBE_P(data);
+
+ if (command != DGUS_Data::CheckKOCommand::KO && command != DGUS_Data::CheckKOCommand::SDCard_No) {
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_CheckKO: unknown id ", (uint16_t)command);
+ #endif
+ return;
+ }
+
+ switch (screen.getCurrentScreen()) {
+ case DGUS_ScreenID::CONTINUE_STOP:
+ case DGUS_ScreenID::STOP_CONFIRM:
+ case DGUS_ScreenID::PAUSE_STOP:
+ case DGUS_ScreenID::FILAMENTUSEUP:
+ case DGUS_ScreenID::FILAMENTLOAD:
+ ExtUI::stopPrint();
+ TERN_(HAS_FILAMENT_SENSOR,ExtUI::setFilamentRunoutState(false));
+ screen.triggerScreenChange(DGUS_ScreenID::FINISH);
+ break;
+
+ case DGUS_ScreenID::SDCARDCHECK:
+ case DGUS_ScreenID::PAUSE_LASER:
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_CheckKO: unknown src screen ", (uint16_t)screen.getCurrentScreen());
+ #endif
+ return;
+ }
+
+ screen.triggerScreenChange(DGUS_ScreenID::HOME);
+}
+
+// 100A
+void DGUSReturnKeyCodeHandler::Command_StopPause(DGUS_VP &vp, void *data) {
+ DGUS_Data::StopPauseCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::StopPauseCommand::Pause:
+ ExtUI::pausePrint();
+ screen.triggerScreenChange(DGUS_ScreenID::RESUME);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_StopPause: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 100C
+void DGUSReturnKeyCodeHandler::Command_CheckOK(DGUS_VP &vp, void *data) {
+ DGUS_Data::CheckOKCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::CheckOKCommand::ContinueStop_Continue:
+ #if HAS_FILAMENT_SENSOR
+ if (ExtUI::getFilamentRunoutEnabled() && READ(FIL_RUNOUT1_PIN) == FIL_RUNOUT1_STATE) {
+ screen.triggerScreenChange(DGUS_ScreenID::FILAMENTUSEUP);
+ break;
+ }
+ #endif
+ ExtUI::resumePrint();
+ screen.triggerScreenChange(DGUS_ScreenID::PAUSE);
+ break;
+
+ #if HAS_FILAMENT_SENSOR
+ case DGUS_Data::CheckOKCommand::FilamentRunout_Yes:
+ if (ExtUI::getTargetTemp_celsius(ExtUI::E0) < EXTRUDE_MINTEMP)
+ ExtUI::setTargetTemp_celsius(EXTRUDE_MINTEMP, ExtUI::E0);
+
+ if (ExtUI::getFilamentRunoutEnabled() && READ(FIL_RUNOUT1_PIN) == FIL_RUNOUT1_STATE)
+ screen.triggerScreenChange(DGUS_ScreenID::FILAMENTUSEUP);
+ else
+ screen.triggerScreenChange(DGUS_ScreenID::FILAMENTLOAD);
+ break;
+
+ case DGUS_Data::CheckOKCommand::FilamentLoad_Yes:
+ if (ExtUI::getFilamentRunoutEnabled() && READ(FIL_RUNOUT1_PIN) == FIL_RUNOUT1_STATE) {
+ screen.triggerScreenChange(DGUS_ScreenID::FILAMENTLOAD);
+ break;
+ }
+
+ ExtUI::setFilamentRunoutState(false);
+ ExtUI::resumePrint();
+ break;
+ #endif // HAS_FILAMENT_SENSOR
+
+ case DGUS_Data::CheckOKCommand::SDCardCheck_Yes:
+ if (ExtUI::isMediaInserted()) {
+ dgus_sdcard_handler.Reset();
+ screen.triggerScreenChange(DGUS_ScreenID::FILE1);
+ }
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_CheckOK: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 1030
+void DGUSReturnKeyCodeHandler::Command_PresetControl(DGUS_VP &vp, void *data) {
+ DGUS_Data::PresetControlCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::PresetControlCommand::Show_Ready_Manual:
+ screen.triggerScreenChange(DGUS_ScreenID::CONTROL);
+ break;
+
+ case DGUS_Data::PresetControlCommand::Show_Settings_PLA_Settings:
+ plaExtruderTempSave = screen.config.plaExtruderTemp;
+ plaBedTempSave = screen.config.plaBedTemp;
+ absExtruderTempSave = screen.config.absExtruderTemp;
+ absBedTempSave = screen.config.absBedTemp;
+ screen.triggerScreenChange(DGUS_ScreenID::PLA_TEMP);
+ break;
+
+ case DGUS_Data::PresetControlCommand::Show_Settings_ABS_Settings:
+ plaExtruderTempSave = screen.config.plaExtruderTemp;
+ plaBedTempSave = screen.config.plaBedTemp;
+ absExtruderTempSave = screen.config.absExtruderTemp;
+ absBedTempSave = screen.config.absBedTemp;
+ screen.triggerScreenChange(DGUS_ScreenID::ABS_TEMP);
+ break;
+
+ case DGUS_Data::PresetControlCommand::Apply_PLA_Settings:
+ ExtUI::setTargetTemp_celsius(screen.config.plaExtruderTemp, ExtUI::E0);
+ ExtUI::setTargetTemp_celsius(screen.config.plaBedTemp, ExtUI::BED);
+ break;
+
+ case DGUS_Data::PresetControlCommand::Apply_ABS_Settings:
+ ExtUI::setTargetTemp_celsius(screen.config.absExtruderTemp, ExtUI::E0);
+ ExtUI::setTargetTemp_celsius(screen.config.absBedTemp, ExtUI::BED);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Settings_Submenu: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 1032
+void DGUSReturnKeyCodeHandler::Control_TemperatureCommand(DGUS_VP &vp, void *data) {
+ DGUS_Data::TemperatureControlCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::TemperatureControlCommand::Cooldown:
+ ExtUI::coolDown();
+ break;
+
+ case DGUS_Data::TemperatureControlCommand::Exit_Temperature_Preset_And_Discard_Temperature:
+ screen.config.plaExtruderTemp = plaExtruderTempSave;
+ screen.config.plaBedTemp = plaBedTempSave;
+ screen.config.absExtruderTemp = absExtruderTempSave;
+ screen.config.absBedTemp = absBedTempSave;
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Control_TemperatureCommand: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 103E
+void DGUSReturnKeyCodeHandler::Command_SettingsMenu(DGUS_VP &vp, void *data) {
+ DGUS_Data::SettingsMenuCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::SettingsMenuCommand::DisableStepperMotors: {
+ const bool areSteppersEnabled = stepper.axis_enabled.bits & (_BV(NUM_AXES) - 1);
+ if (areSteppersEnabled)
+ stepper.disable_all_steppers();
+ else
+ stepper.enable_all_steppers();
+ } break;
+
+ case DGUS_Data::SettingsMenuCommand::Reset_All_Settings:
+ screen.triggerScreenChange(DGUS_ScreenID::FACTORYRESET_CONFIRM);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::FactoryReset_Validate:
+ ExtUI::injectCommands(F("M502"));
+
+ case DGUS_Data::SettingsMenuCommand::FactoryReset_Cancel:
+ screen.triggerScreenChange(DGUS_ScreenID::CONTROL_DEVICE);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Settings_Device_and_Save_Temperatures:
+ screen.triggerEEPROMSave();
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Settings_Device_and_Discard_Temperatures:
+ screen.config.plaExtruderTemp = plaExtruderTempSave;
+ screen.config.plaBedTemp = plaBedTempSave;
+ screen.config.absExtruderTemp = absExtruderTempSave;
+ screen.config.absBedTemp = absBedTempSave;
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Settings_Device_Language:
+ screen.triggerScreenChange(DGUS_ScreenID::LANGUAGE);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Settings_About:
+ screen.triggerScreenChange(DGUS_ScreenID::INFORMATION);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Settings_Advanced:
+ screen.triggerScreenChange(DGUS_ScreenID::CONTROL_DEVICE);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Show_Ready_Jog:
+ screen.triggerScreenChange(GetJogScreenForSavedJogLength());
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Exit_Settings_Tramming:
+ screen.triggerEEPROMSave();
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ case DGUS_Data::SettingsMenuCommand::Exit_Settings_Leveling:
+ screen.triggerEEPROMSave();
+ screen.triggerScreenChange(DGUS_ScreenID::TEMP);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_SettingsMenu: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+static void _gotoTrammingPoint(unsigned char point) {
+ constexpr float lfrb[4] = BED_TRAMMING_INSET_LFRB;
+ float x, y;
+
+ switch (point) {
+ default: return;
+ case 1: x = X_CENTER; y = Y_CENTER; break;
+ case 2: x = X_MIN_POS + lfrb[0]; y = Y_MIN_POS + lfrb[1]; break;
+ case 3: x = X_MAX_POS - lfrb[2]; y = Y_MIN_POS + lfrb[1]; break;
+ case 4: x = X_MAX_POS - lfrb[2]; y = Y_MAX_POS - lfrb[3]; break;
+ case 5: x = X_MIN_POS + lfrb[0]; y = Y_MAX_POS - lfrb[3]; break;
+ }
+
+ if (ExtUI::getAxisPosition_mm(ExtUI::Z) < (Z_MIN_POS) + (BED_TRAMMING_Z_HOP))
+ ExtUI::setAxisPosition_mm((Z_MIN_POS) + (BED_TRAMMING_Z_HOP), ExtUI::Z);
+
+ ExtUI::setAxisPosition_mm(x, ExtUI::X);
+ ExtUI::setAxisPosition_mm(y, ExtUI::Y);
+ ExtUI::setAxisPosition_mm((Z_MIN_POS) + (BED_TRAMMING_HEIGHT), ExtUI::Z);
+}
+
+// 1044
+void DGUSReturnKeyCodeHandler::Command_Leveling(DGUS_VP &vp, void *data) {
+ DGUS_Data::LevelingCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::LevelingCommand::Show_AuxLeveling:
+ if (ExtUI::isPositionKnown())
+ screen.triggerScreenChange(DGUS_ScreenID::LEVELINGMODE);
+ _gotoTrammingPoint(1);
+ break;
+
+ case DGUS_Data::LevelingCommand::Show_Settings_Leveling:
+ case DGUS_Data::LevelingCommand::Show_AutoLeveling:
+ screen.homeThenChangeScreen(DGUS_ScreenID::LEVELING);
+ break;
+
+ case DGUS_Data::LevelingCommand::Goto_Center:
+ _gotoTrammingPoint(1);
+ break;
+
+ case DGUS_Data::LevelingCommand::Goto_LF:
+ _gotoTrammingPoint(2);
+ break;
+
+ case DGUS_Data::LevelingCommand::Goto_RF:
+ _gotoTrammingPoint(3);
+ break;
+
+ case DGUS_Data::LevelingCommand::Goto_RB:
+ _gotoTrammingPoint(4);
+ break;
+
+ case DGUS_Data::LevelingCommand::Goto_LB:
+ _gotoTrammingPoint(5);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_Leveling: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 1046
+void DGUSReturnKeyCodeHandler::Command_AxisControl(DGUS_VP &vp, void *data) {
+ DGUS_Data::AxisControlCommand control = Endianness::fromBE_P(data);
+
+ switch (control) {
+ case DGUS_Data::AxisControlCommand::Jog_10mm:
+ case DGUS_Data::AxisControlCommand::Jog_1mm:
+ case DGUS_Data::AxisControlCommand::Jog_0_1mm:
+ screen.config.jogLength = control;
+ break;
+
+ case DGUS_Data::AxisControlCommand::Home_XY:
+ ExtUI::injectCommands(F("G28XY"));
+ break;
+
+ case DGUS_Data::AxisControlCommand::Home_Z:
+ ExtUI::injectCommands(F("G28Z"));
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_AxisControl: unknown id ", (uint16_t)control);
+ #endif
+ break;
+ }
+}
+
+// 1056
+void DGUSReturnKeyCodeHandler::Command_FilamentIO(DGUS_VP &vp, void *data) {
+ DGUS_Data::FilamentIoCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::FilamentIoCommand::FilamentCheck_Yes:
+ case DGUS_Data::FilamentIoCommand::FilamentCheck_No:
+ screen.triggerReturnScreen();
+ break;
+
+ case DGUS_Data::FilamentIoCommand::Show_Ready_IO:
+ screen.triggerScreenChange(DGUS_ScreenID::FEEDRETURN);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_FilamentIO: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 105F
+void DGUSReturnKeyCodeHandler::Command_PowerLoss(DGUS_VP &vp, void *data) {
+ DGUS_Data::PowerLossCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::PowerLossCommand::PowerLoss_Continue:
+ if (!recovery.valid()) {
+ screen.setStatusMessage(GET_TEXT_F(DGUS_MSG_INVALID_RECOVERY_DATA));
+ screen.triggerScreenChange(DGUS_ScreenID::HOME);
+ return;
+ }
+
+ screen.triggerScreenChange(DGUS_ScreenID::PAUSE);
+ ExtUI::injectCommands(F("M1000"));
+ break;
+
+ case DGUS_Data::PowerLossCommand::PowerLoss_No:
+ screen.triggerScreenChange(DGUS_ScreenID::HOME);
+ ExtUI::injectCommands(F("M1000 C"));
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_PowerLoss: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 1098
+void DGUSReturnKeyCodeHandler::Command_AdvancedSettings(DGUS_VP &vp, void *data) {
+ DGUS_Data::AdvancedSettingsCommand command = Endianness::fromBE_P(data);
+
+ switch (command) {
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_Movement:
+ screen.triggerScreenChange(DGUS_ScreenID::MOTION);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_PID:
+ #if NONE(PIDTEMP, PIDTEMPBED)
+ screen.angryBeeps(2);
+ screen.triggerScreenChange(DGUS_ScreenID::CONTROL_DEVICE);
+ #else
+ screen.triggerScreenChange(DGUS_ScreenID::PIDCONTROL);
+ #endif
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_Movement_MaxFeedrate:
+ screen.triggerScreenChange(DGUS_ScreenID::MAX_FEEDRATE);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_Movement_Acceleration:
+ screen.triggerScreenChange(DGUS_ScreenID::ACCELERATION);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_Movement_Jerk:
+ screen.triggerScreenChange(DGUS_ScreenID::JERK);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings_Movement_StepsPerMm:
+ screen.triggerScreenChange(DGUS_ScreenID::STEPSMM);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Exit_AdvSettings_Movement_Submenu:
+ screen.triggerScreenChange(DGUS_ScreenID::MOTION);
+ break;
+
+ case DGUS_Data::AdvancedSettingsCommand::Show_AdvSettings:
+ screen.triggerScreenChange(DGUS_ScreenID::CONTROL_DEVICE);
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_AdvancedSettings: unknown id ", (uint16_t)command);
+ #endif
+ break;
+ }
+}
+
+// 2198
+void DGUSReturnKeyCodeHandler::Command_FilelistControl(DGUS_VP &vp, void *data) {
+ DGUS_Data::FilelistControlCommand control = Endianness::fromBE_P(data);
+ DGUS_SDCardHandler::page_t newPage;
+
+ switch (control) {
+ #if HAS_MEDIA
+ case DGUS_Data::FilelistControlCommand::Start_Print:
+ if (!screen.getSDCardPrintFilename()[0]) {
+ screen.angryBeeps(2);
+ return;
+ }
+
+ #if HAS_FILAMENT_SENSOR
+ if (ExtUI::getFilamentRunoutEnabled() && READ(FIL_RUNOUT1_PIN) == FIL_RUNOUT1_STATE) {
+ screen.triggerTempScreenChange(DGUS_ScreenID::FILAMENTCHECK, DGUS_ScreenID::HOME);
+ return;
+ }
+ #endif
+
+ ExtUI::printFile(screen.getSDCardPrintFilename());
+ screen.triggerScreenChange(DGUS_ScreenID::PAUSE);
+ return;
+ #endif
+
+ case DGUS_Data::FilelistControlCommand::F1_Up:
+ //case DGUS_Data::FilelistControlCommand::F2_Up:
+ case DGUS_Data::FilelistControlCommand::F3_Up:
+ case DGUS_Data::FilelistControlCommand::F4_Up:
+ newPage = dgus_sdcard_handler.onPreviousPage();
+ break;
+
+ case DGUS_Data::FilelistControlCommand::F1_Down:
+ case DGUS_Data::FilelistControlCommand::F2_Down:
+ case DGUS_Data::FilelistControlCommand::F3_Down:
+ case DGUS_Data::FilelistControlCommand::F4_Down:
+ newPage = dgus_sdcard_handler.onNextPage();
+ break;
+
+ case DGUS_Data::FilelistControlCommand::Begin:
+ newPage = dgus_sdcard_handler.onFirstPage();
+ break;
+
+ case DGUS_Data::FilelistControlCommand::End:
+ newPage = dgus_sdcard_handler.onLastPage();
+ break;
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_FilelistControl: unknown id ", (uint16_t)control);
+ #endif
+ return;
+ }
+
+ screen.triggerScreenChange(DGUS_PAGE_TO_SCREEN(newPage));
+}
+
+// 2201
+void DGUSReturnKeyCodeHandler::Command_LaserControl(DGUS_VP &vp, void *data) {
+ DGUS_Data::LaserControlCommand control = Endianness::fromBE_P(data);
+
+ switch (control) {
+ case DGUS_Data::LaserControlCommand::Mode_FDM:
+ screen.triggerScreenChange(DGUS_ScreenID::SW_FDM_TIPS);
+ break;
+ case DGUS_Data::LaserControlCommand::Mode_FDM_Confirm:
+ screen.triggerScreenChange(DGUS_ScreenID::SW_FDM_TIPS);
+ break;
+
+ #if HAS_CUTTER
+ case DGUS_Data::LaserControlCommand::Mode_Cutter:
+ screen.triggerScreenChange(DGUS_ScreenID::SW_LASER_TIPS);
+ break;
+
+ case DGUS_Data::LaserControlCommand::Mode_Cutter_Confirm:
+ screen.triggerScreenChange(DGUS_ScreenID::SW_LASER_TIPS);
+ break;
+ #endif
+
+ case DGUS_Data::LaserControlCommand::Mode_Change:
+ #if HAS_CUTTER
+ screen.triggerScreenChange(DGUS_ScreenID::LASER_FDM);
+ #else
+ screen.angryBeeps(2);
+ #endif
+
+ default:
+ #if ALL(DEBUG_DGUSLCD, DGUS_UNKNOWN_COMMAND_DEBUG)
+ DEBUG_ECHOLNPGM("Command_LaserControl: unknown id ", (uint16_t)control);
+ #endif
+ return;
+ }
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.h
new file mode 100644
index 0000000000..03a7224ca6
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSReturnKeyCodeHandler.h
@@ -0,0 +1,42 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "definition/DGUS_VP.h"
+
+namespace DGUSReturnKeyCodeHandler {
+ void Command_MenuSelect(DGUS_VP &vp, void *data);
+ void Command_Adjust(DGUS_VP &vp, void *data);
+ void Command_CheckKO(DGUS_VP &vp, void *data);
+ void Command_StopPause(DGUS_VP &vp, void *data);
+ void Command_CheckOK(DGUS_VP &vp, void *data);
+ void Command_PresetControl(DGUS_VP &vp, void *data);
+ void Control_TemperatureCommand(DGUS_VP &vp, void *data);
+ void Command_SettingsMenu(DGUS_VP &vp, void *data);
+ void Command_Leveling(DGUS_VP &vp, void *data);
+ void Command_AxisControl(DGUS_VP &vp, void *data);
+ void Command_FilamentIO(DGUS_VP &vp, void *data);
+ void Command_PowerLoss(DGUS_VP &vp, void *data);
+ void Command_AdvancedSettings(DGUS_VP &vp, void *data);
+ void Command_FilelistControl(DGUS_VP &vp, void *data);
+ void Command_LaserControl(DGUS_VP &vp, void *data);
+}
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp
new file mode 100644
index 0000000000..118cfd3514
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.cpp
@@ -0,0 +1,168 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSRxHandler.h"
+
+#include "DGUSScreenHandler.h"
+#include "config/DGUS_Screen.h"
+
+#include "../ui_api.h"
+#include "../../../core/language.h"
+#include "../../../module/stepper.h"
+
+void DGUSRxHandler::printSpeedPercentage(DGUS_VP &vp, void *data) {
+ const_float_t feedratePercentage = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setFeedrate_percent(feedratePercentage);
+}
+
+void DGUSRxHandler::zOffset(DGUS_VP &vp, void *data) {
+ const_float_t zoffset = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ const_float_t currentzOffset = ExtUI::getZOffset_mm();
+ const_float_t zStepsPerMm = ExtUI::getAxisSteps_per_mm(ExtUI::Z);
+ int16_t zStepsDiff = zStepsPerMm * (zoffset - currentzOffset);
+
+ ExtUI::babystepAxis_steps(zStepsDiff, ExtUI::Z);
+ ExtUI::setZOffset_mm(zoffset);
+}
+
+void DGUSRxHandler::extruderTargetTemp(DGUS_VP &vp, void *data) {
+ const_float_t temperature = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setTargetTemp_celsius(temperature, ExtUI::H0);
+}
+
+void DGUSRxHandler::bedTargetTemp(DGUS_VP &vp, void *data) {
+ const_float_t temperature = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setTargetTemp_celsius(temperature, ExtUI::BED);
+}
+
+void DGUSRxHandler::axis_X(DGUS_VP &vp, void *data) {
+ const_float_t axisValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setAxisPosition_mm(axisValue, ExtUI::X);
+}
+
+void DGUSRxHandler::axis_Y(DGUS_VP &vp, void *data) {
+ const_float_t axisValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setAxisPosition_mm(axisValue, ExtUI::Y);
+}
+
+void DGUSRxHandler::axis_Z(DGUS_VP &vp, void *data) {
+ const_float_t axisValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setAxisPosition_mm(axisValue, ExtUI::Z);
+}
+
+void DGUSRxHandler::extrudeLength(DGUS_VP &vp, void *data) {
+ const_float_t length = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ const_float_t currentPosition = ExtUI::getAxisPosition_mm(ExtUI::E0);
+
+ #if HAS_FILAMENT_SENSOR
+ if (ExtUI::getFilamentRunoutEnabled() && ExtUI::getFilamentRunoutState()) {
+ screen.triggerTempScreenChange(DGUS_ScreenID::FILAMENTCHECK, DGUS_ScreenID::CONTROL_DEVICE);
+ return;
+ }
+ #endif
+ ExtUI::setAxisPosition_mm(currentPosition+length, ExtUI::E0);
+}
+
+void DGUSRxHandler::retractLength(DGUS_VP &vp, void *data) {
+ const_float_t length = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ const_float_t currentPosition = ExtUI::getAxisPosition_mm(ExtUI::E0);
+
+ #if HAS_FILAMENT_SENSOR
+ if (ExtUI::getFilamentRunoutEnabled() && ExtUI::getFilamentRunoutState()) {
+ screen.triggerTempScreenChange(DGUS_ScreenID::FILAMENTCHECK, DGUS_ScreenID::CONTROL_DEVICE);
+ return;
+ }
+ #endif
+ ExtUI::setAxisPosition_mm(currentPosition-length, ExtUI::E0);
+}
+
+void DGUSRxHandler::setLanguage(DGUS_VP &vp, void *data) {
+ DGUS_Data::Language language = (DGUS_Data::Language)Endianness::fromBE_P(data);
+ screen.config.language = language;
+ screen.triggerEEPROMSave();
+ screen.triggerFullUpdate();
+}
+
+#if ENABLED(PIDTEMPBED)
+
+ void DGUSRxHandler::bed_PID_P(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setBedPID(
+ pidValue,
+ ExtUI::getBedPID_Ki(),
+ ExtUI::getBedPID_Kd()
+ );
+ }
+
+ void DGUSRxHandler::bed_PID_I(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setBedPID(
+ ExtUI::getBedPID_Kp(),
+ pidValue,
+ ExtUI::getBedPID_Kd()
+ );
+ }
+
+ void DGUSRxHandler::bed_PID_D(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setBedPID(
+ ExtUI::getBedPID_Kp(),
+ ExtUI::getBedPID_Ki(),
+ pidValue
+ );
+ }
+
+#endif // PIDTEMPBED
+
+void DGUSRxHandler::fanSpeed(DGUS_VP &vp, void *data) {
+ const_float_t percentage = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setTargetFan_percent(percentage, ExtUI::FAN0);
+}
+
+void DGUSRxHandler::sdCardFileSection(DGUS_VP &vp, void *data) {
+ uint8_t sdFileIndex = Endianness::fromBE_P(data) - 1;
+
+ #if ENABLED(DGUS_USERCONFIRM)
+ if (screen.isOnUserConfirmationScreen()) {
+ screen.userConfirmation();
+ return;
+ }
+ #endif
+ dgus_sdcard_handler.onFileSelect(DGUS_FILE_FROM_INDEX(sdFileIndex % 5));
+}
+
+void DGUSRxHandler::stringToExtra(DGUS_VP &vp, void *data_ptr) {
+ if (!vp.size || !vp.extra) return;
+ memcpy(vp.extra, data_ptr, vp.size);
+}
+
+void DGUSRxHandler::disabled(DGUS_VP &vp, void *data_ptr) {
+ UNUSED(vp);
+ UNUSED(data_ptr);
+ screen.angryBeeps(2);
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.h
new file mode 100644
index 0000000000..562edf9509
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSRxHandler.h
@@ -0,0 +1,128 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "DGUSDisplay.h"
+#include "definition/DGUS_VP.h"
+
+namespace DGUSRxHandler {
+ void printSpeedPercentage(DGUS_VP &vp, void *data);
+ void zOffset(DGUS_VP &vp, void *data);
+ void extruderTargetTemp(DGUS_VP &vp, void *data);
+ void bedTargetTemp(DGUS_VP &vp, void *data);
+ void axis_X(DGUS_VP &vp, void *data);
+ void axis_Y(DGUS_VP &vp, void *data);
+ void axis_Z(DGUS_VP &vp, void *data);
+ void extrudeLength(DGUS_VP &vp, void *data);
+ void retractLength(DGUS_VP &vp, void *data);
+ void setLanguage(DGUS_VP &vp, void *data);
+
+ template
+ void maxFeedrate(DGUS_VP &vp, void *data) {
+ feedRate_t maxSpeed = (float)Endianness::fromBE_P(data);
+ ExtUI::setAxisMaxFeedrate_mm_s(maxSpeed, axis);
+ }
+ template
+ void maxAcceleration(DGUS_VP &vp, void *data) {
+ float maxAcceleration = (float)Endianness::fromBE_P(data);
+ ExtUI::setAxisMaxAcceleration_mm_s2(maxAcceleration, axis);
+ }
+ template
+ void maxJerk(DGUS_VP &vp, void *data) {
+ float maxJerk = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setAxisMaxJerk_mm_s(maxJerk, axis);
+ }
+ template
+ void stepsPerMM(DGUS_VP &vp, void *data) {
+ float stepsPerMm = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setAxisSteps_per_mm(stepsPerMm, axis);
+ }
+
+ #if ENABLED(PIDTEMP)
+ template
+ void PID_P(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setPID(
+ pidValue,
+ ExtUI::getPID_Ki(extruder),
+ ExtUI::getPID_Kd(extruder),
+ extruder
+ );
+ }
+ template
+ void PID_I(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setPID(
+ ExtUI::getPID_Kp(extruder),
+ pidValue,
+ ExtUI::getPID_Kd(extruder),
+ extruder
+ );
+ }
+ template
+ void PID_D(DGUS_VP &vp, void *data) {
+ float pidValue = dgus.fromFixedPoint(Endianness::fromBE_P(data));
+ ExtUI::setPID(
+ ExtUI::getPID_Kp(extruder),
+ ExtUI::getPID_Ki(extruder),
+ pidValue,
+ extruder
+ );
+ }
+ #endif // PIDTEMP
+
+ #if ENABLED(PIDTEMPBED)
+ void bed_PID_P(DGUS_VP &vp, void *data);
+ void bed_PID_I(DGUS_VP &vp, void *data);
+ void bed_PID_D(DGUS_VP &vp, void *data);
+ #endif
+
+ void fanSpeed(DGUS_VP &vp, void *data);
+ void sdCardFileSection(DGUS_VP &vp, void *data);
+
+ void stringToExtra(DGUS_VP &vp, void *data);
+ void disabled(DGUS_VP &vp, void *data);
+
+ template
+ void integerToExtra(DGUS_VP &vp, void *data_ptr) {
+ if (!vp.size || !vp.extra) return;
+ switch (vp.size) {
+ default: return;
+ case 1: {
+ const uint8_t data = *(uint8_t*)data_ptr;
+ *(T*)vp.extra = (T)data;
+ break;
+ }
+ case 2: {
+ const uint16_t data = Endianness::fromBE_P(data_ptr);
+ *(T*)vp.extra = (T)data;
+ break;
+ }
+ case 4: {
+ const uint32_t data = Endianness::fromBE_P(data_ptr);
+ *(T*)vp.extra = (T)data;
+ break;
+ }
+ }
+ }
+
+}
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.cpp
new file mode 100644
index 0000000000..17a05ae655
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.cpp
@@ -0,0 +1,39 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "../../../sd/cardreader.h"
+#include "DGUSSDCardHandler.h"
+
+char DGUS_SDCardHandler::filenames[5][LONG_FILENAME_LENGTH] = {0};
+
+void DGUS_SDCardHandler::setFilename(file_t file, const char* filename, bool isDir) {
+ const uint8_t fileIndex = DGUS_FILE_TO_INDEX(file);
+ filenames[fileIndex][0] = '\0';
+ if (filename) strcat(filenames[fileIndex], filename);
+ if (isDir) strcat(filenames[fileIndex], "/");
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.h
new file mode 100644
index 0000000000..8844184271
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler.h
@@ -0,0 +1,75 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+#include "../../../sd/cardreader.h"
+
+#define DGUS_E3S1PRO_BASIC_SDCARD_MAX_FILES 20
+#define DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE 5
+
+#define DGUS_PAGE_TO_SCREEN(page) (DGUS_ScreenID)((uint8_t)DGUS_ScreenID::FILE1 + ((uint8_t)page - (uint8_t)DGUS_SDCardHandler::page_t::PAGE_1))
+#define DGUS_SCREEN_TO_PAGE(screen) (DGUS_SDCardHandler::page_t)((uint8_t)DGUS_SDCardHandler::page_t::PAGE_1 + ((uint8_t)screen - (uint8_t)DGUS_ScreenID::FILE1))
+
+#define DGUS_PAGE_TO_INDEX(page) (uint8_t)((uint8_t)page - (uint8_t)DGUS_SDCardHandler::page_t::PAGE_1)
+#define DGUS_FILE_TO_INDEX(file) (uint8_t)((uint8_t)file - (uint8_t)DGUS_SDCardHandler::file_t::FILE_1)
+
+#define DGUS_PAGE_FROM_INDEX(index) (DGUS_SDCardHandler::page_t)(index + (uint8_t)DGUS_SDCardHandler::page_t::PAGE_1)
+#define DGUS_FILE_FROM_INDEX(index) (DGUS_SDCardHandler::file_t)(index + (uint8_t)DGUS_SDCardHandler::file_t::FILE_1)
+
+class DGUS_SDCardHandler {
+ public:
+ enum class page_t : uint8_t {
+ PAGE_1 = 1,
+ PAGE_2,
+ PAGE_3,
+ PAGE_4
+ };
+
+ enum class file_t : uint8_t {
+ FILE_1 = 1,
+ FILE_2,
+ FILE_3,
+ FILE_4,
+ FILE_5,
+ FILE_Max = FILE_5,
+ FILE_Count
+ };
+
+ static char filenames[5][LONG_FILENAME_LENGTH];
+
+public:
+ static void Reset();
+
+ static void onPageLoad(page_t page);
+ static bool onFileSelect(file_t file);
+
+ static page_t onFirstPage();
+ static page_t onLastPage();
+ static page_t onPreviousPage();
+ static page_t onNextPage();
+
+private:
+ static void setFilename(file_t file, const char* filename, bool isDir = false) PROGMEM;
+};
+
+extern DGUS_SDCardHandler dgus_sdcard_handler;
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Advanced.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Advanced.cpp
new file mode 100644
index 0000000000..e53f9b84e7
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Advanced.cpp
@@ -0,0 +1,157 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ALL(DGUS_LCD_UI_E3S1PRO, DGUS_ADVANCED_SDCARD)
+
+#include "DGUSSDCardHandler.h"
+#include "DGUSScreenHandler.h"
+#include "DGUSDisplay.h"
+
+static DGUS_SDCardHandler::page_t currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+static uint8_t currentVirtualPage = 0;
+static size_t fileCount = 0;
+static ExtUI::FileList fileList = ExtUI::FileList();
+
+void DGUS_SDCardHandler::Reset() {
+ currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+ currentVirtualPage = 0;
+
+ while (!fileList.isAtRootDir())
+ fileList.upDir();
+
+ fileList.refresh();
+ fileCount = fileList.count();
+}
+
+void DGUS_SDCardHandler::onPageLoad(DGUS_SDCardHandler::page_t page) {
+ setFilename(file_t::FILE_1, NULL);
+ setFilename(file_t::FILE_2, NULL);
+ setFilename(file_t::FILE_3, NULL);
+ setFilename(file_t::FILE_4, NULL);
+ setFilename(file_t::FILE_5, NULL);
+
+ uint8_t pageIndex = currentVirtualPage;
+ uint16_t currentSeekPos = 0;
+
+ currentSeekPos += pageIndex * DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE;
+
+ file_t currentFile = file_t::FILE_1;
+ if (!fileList.isAtRootDir()) {
+ if (currentPage == page_t::PAGE_1) {
+ setFilename(currentFile, "-- dir up --");
+ currentFile = DGUS_FILE_FROM_INDEX(DGUS_FILE_TO_INDEX(currentFile) + 1);
+ }
+ else
+ currentSeekPos -= 1; // account for the updir entry on page 1
+ }
+
+ while (currentFile <= file_t::FILE_5
+ && fileList.seek(currentSeekPos, true)
+ && currentSeekPos < fileCount) {
+ ++currentSeekPos;
+ setFilename(currentFile, fileList.filename(), fileList.isDir());
+ currentFile = DGUS_FILE_FROM_INDEX(DGUS_FILE_TO_INDEX(currentFile) + 1);
+ }
+}
+
+bool DGUS_SDCardHandler::onFileSelect(DGUS_SDCardHandler::file_t file) {
+ uint8_t fileIndex = DGUS_FILE_TO_INDEX(file);
+ if (!filenames[fileIndex][0])
+ return false;
+
+ bool changeDir = false;
+ if (!fileList.isAtRootDir()
+ && currentPage == page_t::PAGE_1
+ && file == file_t::FILE_1) {
+ fileList.upDir();
+ changeDir = true;
+ }
+ else if (filenames[fileIndex][strlen(filenames[fileIndex])-1] == '/') {
+ filenames[fileIndex][strlen(filenames[fileIndex])-1] = '\0';
+ fileList.changeDir(filenames[fileIndex]);
+ changeDir = true;
+ }
+
+ if (changeDir) {
+ fileList.refresh();
+ currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+ currentVirtualPage = 0;
+ fileCount = fileList.count();
+
+ if (currentPage == page_t::PAGE_1)
+ onPageLoad(page_t::PAGE_1);
+ else
+ screen.triggerScreenChange(DGUS_ScreenID::FILE1);
+ return true;
+ }
+
+ screen.startPrintFromSD(filenames[fileIndex]);
+ return true;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onFirstPage() {
+ currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+ currentVirtualPage = 0;
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onLastPage() {
+ currentVirtualPage = (fileCount - 1 + (fileList.isAtRootDir() ? 0 : 1)) / DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE;
+
+ if (currentVirtualPage >= 4) {
+ currentPage = page_t::PAGE_4;
+ onPageLoad(page_t::PAGE_4);
+ }
+ else
+ currentPage = DGUS_PAGE_FROM_INDEX(currentVirtualPage);
+
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onPreviousPage() {
+ if (currentVirtualPage > 0) {
+ currentVirtualPage -= 1;
+
+ if (currentVirtualPage >= 4)
+ currentPage = page_t::PAGE_4;
+ else
+ currentPage = DGUS_PAGE_FROM_INDEX(currentVirtualPage);
+ }
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onNextPage() {
+ if (currentVirtualPage < (fileCount - 1 + (fileList.isAtRootDir() ? 0 : 1)) / DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE) {
+ if (++currentVirtualPage >= 4) {
+ currentPage = page_t::PAGE_4;
+ onPageLoad(page_t::PAGE_4);
+ }
+ else
+ currentPage = DGUS_PAGE_FROM_INDEX(currentVirtualPage);
+ }
+
+ return currentPage;
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO && DGUS_ADVANCED_SDCARD
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Basic.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Basic.cpp
new file mode 100644
index 0000000000..85c7b660a7
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSDCardHandler_Basic.cpp
@@ -0,0 +1,137 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#define DGUS_E3S1PRO_BASIC_SDCARD_MAX_FILES 20
+#define DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE 5
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO) && DISABLED(DGUS_ADVANCED_SDCARD)
+
+#include "DGUSSDCardHandler.h"
+#include "DGUSScreenHandler.h"
+#include "DGUSDisplay.h"
+
+static DGUS_SDCardHandler::page_t currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+static size_t fileCount = 0;
+static ExtUI::FileList fileList = ExtUI::FileList();
+
+void DGUS_SDCardHandler::Reset() {
+ currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+
+ while (!fileList.isAtRootDir())
+ fileList.upDir();
+
+ fileCount = 0;
+ uint16_t currentSeekPos = 0;
+ uint16_t entriesCount = fileList.count();
+ while (currentSeekPos < entriesCount
+ && fileCount < DGUS_E3S1PRO_BASIC_SDCARD_MAX_FILES
+ && fileList.seek(currentSeekPos, true)
+ ) {
+ if (!fileList.isDir()) fileCount++;
+ currentSeekPos++;
+ }
+
+ #ifdef DEBUG_DGUSLCD
+ DEBUG_ECHOPGM("Reset() :", fileCount);
+ DEBUG_CHAR('/');
+ DEBUG_ECHOLN(currentSeekPos);
+ #endif
+}
+
+void DGUS_SDCardHandler::onPageLoad(DGUS_SDCardHandler::page_t page) {
+ setFilename(file_t::FILE_1, NULL);
+ setFilename(file_t::FILE_2, NULL);
+ setFilename(file_t::FILE_3, NULL);
+ setFilename(file_t::FILE_4, NULL);
+ setFilename(file_t::FILE_5, NULL);
+
+ uint8_t pageIndex = DGUS_PAGE_TO_INDEX(page);
+ uint16_t currentFilePos = 0;
+ uint16_t currentSeekPos = 0;
+ uint16_t entriesCount = fileList.count();
+
+ #ifdef DEBUG_DGUSLCD
+ DEBUG_ECHOLNPGM("onPageLoad(): seek page ", pageIndex);
+ #endif
+ while (currentFilePos < pageIndex * DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE
+ && fileList.seek(currentSeekPos, true)
+ && currentSeekPos < entriesCount
+ ) {
+ ++currentSeekPos;
+ if (!fileList.isDir())
+ currentFilePos++;
+ }
+
+ #ifdef DEBUG_DGUSLCD
+ DEBUG_ECHOPGM("onPageLoad() :", currentFilePos);
+ DEBUG_CHAR('/');
+ DEBUG_ECHOLN(currentSeekPos - 1);
+ #endif
+
+ file_t currentFile = file_t::FILE_1;
+ while (currentFilePos < (pageIndex + 1) * DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE
+ && fileList.seek(currentSeekPos, true)
+ && currentSeekPos < entriesCount
+ ) {
+ ++currentSeekPos;
+ if (!fileList.isDir()) {
+ ++currentFilePos;
+ setFilename(currentFile, fileList.longFilename());
+ currentFile = DGUS_FILE_FROM_INDEX(DGUS_FILE_TO_INDEX(currentFile) + 1);
+ }
+ }
+}
+
+bool DGUS_SDCardHandler::onFileSelect(DGUS_SDCardHandler::file_t file) {
+ uint8_t fileIndex = DGUS_FILE_TO_INDEX(file);
+ if (!filenames[fileIndex][0])
+ return false;
+
+ screen.startPrintFromSD(filenames[fileIndex]);
+ return true;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onFirstPage() {
+ currentPage = DGUS_SDCardHandler::page_t::PAGE_1;
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onLastPage() {
+ currentPage = DGUS_PAGE_FROM_INDEX(fileCount / DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE);
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onPreviousPage() {
+ if (currentPage > page_t::PAGE_1)
+ currentPage = DGUS_PAGE_FROM_INDEX(DGUS_PAGE_TO_INDEX(currentPage) - 1);
+ return currentPage;
+}
+
+DGUS_SDCardHandler::page_t DGUS_SDCardHandler::onNextPage() {
+ if (DGUS_PAGE_TO_INDEX(currentPage) < (fileCount / DGUS_E3S1PRO_BASIC_SDCARD_FILES_PER_PAGE) - 1)
+ currentPage = DGUS_PAGE_FROM_INDEX(DGUS_PAGE_TO_INDEX(currentPage) + 1);
+ return currentPage;
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO && !DGUS_ADVANCED_SDCARD
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.cpp
new file mode 100644
index 0000000000..37c52d86cd
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.cpp
@@ -0,0 +1,549 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSDisplay.h"
+#include "DGUSScreenHandler.h"
+#include "DGUSSDCardHandler.h"
+
+#include "definition/DGUS_ScreenAddrList.h"
+#include "definition/DGUS_ScreenSetup.h"
+
+#include "../../../gcode/queue.h"
+
+#define DGUS_SCREEN_PAGE_DEBUG // uncomment to debug page changes
+
+DGUSScreenHandler::eeprom_data_t DGUSScreenHandler::config = {};
+uint16_t DGUSScreenHandler::currentMeshPointIndex = 0;
+bool DGUSScreenHandler::isLeveling = false;
+char DGUSScreenHandler::homeStatusMessage[128];
+
+bool DGUSScreenHandler::settings_ready = false;
+bool DGUSScreenHandler::booted = false;
+
+DGUS_ScreenID DGUSScreenHandler::current_screen = DGUS_ScreenID::BOOT;
+DGUS_ScreenID DGUSScreenHandler::new_screen = DGUS_ScreenID::BOOT;
+DGUS_ScreenID DGUSScreenHandler::wait_return_screen = DGUS_ScreenID::BOOT;
+DGUS_ScreenID DGUSScreenHandler::confirm_return_screen = DGUS_ScreenID::BOOT;
+bool DGUSScreenHandler::full_update = false;
+uint8_t DGUSScreenHandler::angry_beeps = 0;
+
+#if HAS_MEDIA
+ static const char* const noFileSelected = "";
+ const char* DGUSScreenHandler::sdPrintFilename = noFileSelected;
+#endif
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ bool DGUSScreenHandler::powerLossRecoveryAvailable = false;
+#endif
+
+#if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ ssize_t DGUSScreenHandler::currentScrollIndex = 0;
+ size_t DGUSScreenHandler::pageMaxStringLen = 0;
+ size_t DGUSScreenHandler::pageMaxControlLen = 0;
+#endif
+
+millis_t DGUSScreenHandler::status_expire = 0;
+millis_t DGUSScreenHandler::eeprom_save = 0;
+
+void DGUSScreenHandler::init() {
+ dgus.init();
+ moveToScreen(DGUS_ScreenID::BOOT, true);
+}
+
+void DGUSScreenHandler::ready() {
+ dgus.playSound(1);
+}
+
+void DGUSScreenHandler::loop() {
+ const millis_t ms = ExtUI::safe_millis();
+ static millis_t next_event_ms = 0, next_beep_ms = 0;
+ static bool wasLeveling = isLeveling;
+
+ if (new_screen != DGUS_ScreenID::BOOT) {
+ const DGUS_ScreenID screen = new_screen;
+ new_screen = DGUS_ScreenID::BOOT;
+
+ #if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ currentScrollIndex = -DGUS_AUTOSCROLL_START_CYCLES;
+ pageMaxStringLen = 0;
+ pageMaxControlLen = 0;
+ #endif
+
+ if (current_screen == screen)
+ triggerFullUpdate();
+ else
+ moveToScreen(screen);
+ return;
+ }
+
+ if (!booted && current_screen == DGUS_ScreenID::HOME) {
+ // Boot complete
+ booted = true;
+ dgus.readVersions();
+ return;
+ }
+
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ if (booted && powerLossRecoveryAvailable)
+ {
+ triggerScreenChange(DGUS_ScreenID::POWERCONTINUE);
+ powerLossRecoveryAvailable = false;
+ }
+ #endif
+
+ if (ELAPSED(ms, next_event_ms) || full_update) {
+ next_event_ms = ms + (booted ? DGUS_UPDATE_INTERVAL_MS : 50);
+
+ #if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ currentScrollIndex += 1;
+ if (currentScrollIndex > (ssize_t)(pageMaxStringLen - pageMaxControlLen) + DGUS_AUTOSCROLL_END_CYCLES)
+ currentScrollIndex = -DGUS_AUTOSCROLL_START_CYCLES;
+ #endif
+
+ if (angry_beeps) {
+ --angry_beeps;
+ dgus.playSound(3);
+ }
+
+ if (!sendScreenVPData(current_screen, full_update))
+ DEBUG_ECHOLNPGM("SendScreenVPData failed");
+
+ return;
+ }
+
+ if (ELAPSED(ms, next_beep_ms)) {
+ next_beep_ms = ms + 300;
+
+ if (angry_beeps) {
+ --angry_beeps;
+ dgus.playSound(0, 500/8, 100);
+ }
+ }
+
+ if (wasLeveling && !isLeveling) {
+ #if ENABLED(AUTO_BED_LEVELING_UBL)
+ ExtUI::injectCommands(ExtUI::getLevelingIsValid() ? F("G29 S0") : F("G29 S1\nG29 P3\nG29 S0"));
+ #endif
+
+ config.levelingEnabled = ExtUI::getLevelingIsValid();
+ ExtUI::setLevelingActive(config.levelingEnabled);
+ triggerEEPROMSave();
+ }
+ wasLeveling = isLeveling;
+
+ if (!settings_ready && booted) return;
+
+ if (status_expire > 0 && ELAPSED(ms, status_expire)) {
+ setStatusMessage(FPSTR(NUL_STR), 0);
+ return;
+ }
+
+ if (eeprom_save > 0 && ELAPSED(ms, eeprom_save) && isPrinterIdle()) {
+ eeprom_save = 0;
+ ExtUI::injectCommands(F("M500"));
+ return;
+ }
+
+ dgus.loop();
+}
+
+void DGUSScreenHandler::printerKilled(FSTR_P const error, FSTR_P const component) {
+ dgus.playSound(0, (uint8_t)(3000/8), 100);
+ setStatusMessage(error);
+ moveToScreen(DGUS_ScreenID::ABNORMAL);
+}
+
+void DGUSScreenHandler::userConfirmRequired(const char * const msg) {
+ #if ENABLED(DGUS_USERCONFIRM)
+ if (confirm_return_screen == DGUS_ScreenID::BOOT)
+ confirm_return_screen = getCurrentScreen();
+
+ strcpy(dgus_sdcard_handler.filenames[0], msg);
+ dgus_sdcard_handler.filenames[1][0] = '\0';
+ dgus_sdcard_handler.filenames[2][0] = '\0';
+ dgus_sdcard_handler.filenames[3][0] = '\0';
+
+ strcpy(dgus_sdcard_handler.filenames[4], "[");
+ strcat(dgus_sdcard_handler.filenames[4], GET_TEXT(MSG_BUTTON_CONFIRM));
+ strcat(dgus_sdcard_handler.filenames[4], "]");
+
+ new_screen = DGUS_ScreenID::FILE1;
+ #if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
+ DEBUG_ECHOLNPGM("trig confirm: ", msg, ", ret: ", (uint16_t)confirm_return_screen);
+ #endif
+ #else
+ UNUSED(msg);
+ #endif
+}
+
+void DGUSScreenHandler::userConfirmation() {
+ #if ENABLED(DGUS_USERCONFIRM)
+ if (confirm_return_screen == DGUS_ScreenID::BOOT) {
+ DEBUG_ECHOLNPGM("DGUS: User confirmation triggered but no return screen");
+ return;
+ }
+
+ if (confirm_return_screen >= DGUS_ScreenID::FILE1 && confirm_return_screen <= DGUS_ScreenID::FILE4)
+ dgus_sdcard_handler.onPageLoad(DGUS_SCREEN_TO_PAGE(confirm_return_screen));
+
+ #ifdef DEBUG_DGUSLCD
+ DEBUG_ECHOLNPGM("trig confirmed, ret:", (uint16_t)confirm_return_screen);
+ #endif
+
+ new_screen = confirm_return_screen;
+ confirm_return_screen = DGUS_ScreenID::BOOT;
+ ExtUI::setUserConfirmed();
+ #endif
+}
+
+void DGUSScreenHandler::settingsReset() {
+ config.initialized = true;
+ config.volume = DGUS_DEFAULT_VOLUME;
+ config.brightness = DGUS_DEFAULT_BRIGHTNESS;
+ config.language = DGUS_Data::Language::Default;
+ config.jogLength = DGUS_Data::AxisControlCommand::Jog_1mm;
+ config.plaExtruderTemp = PREHEAT_1_TEMP_HOTEND;
+ config.plaBedTemp = PREHEAT_1_TEMP_BED;
+ config.absExtruderTemp = PREHEAT_2_TEMP_HOTEND;
+ config.absBedTemp = PREHEAT_2_TEMP_BED;
+ config.levelingEnabled = ExtUI::getLevelingActive();
+
+ if (!settings_ready) {
+ settings_ready = true;
+ ready();
+ }
+
+ setStatusMessage(GET_TEXT_F(DGUS_MSG_RESET_EEPROM));
+}
+
+void DGUSScreenHandler::storeSettings(char *buff) {
+ static_assert(sizeof(config) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size.");
+
+ config.initialized = true;
+ config.volume = dgus.getVolume();
+ config.brightness = dgus.getBrightness();
+
+ memcpy(buff, &config, sizeof(config));
+}
+
+void DGUSScreenHandler::loadSettings(const char *buff) {
+ static_assert(sizeof(config) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size.");
+ memcpy(&config, buff, sizeof(config));
+
+ if (!config.initialized
+ || config.language < DGUS_Data::Language::Chinese_Simplified
+ || config.language > DGUS_Data::Language::Turkish
+ || config.jogLength < DGUS_Data::AxisControlCommand::Jog_10mm
+ || config.jogLength > DGUS_Data::AxisControlCommand::Jog_0_1mm) {
+ DEBUG_ECHOLNPGM("invalid DGUS settings, resetting");
+ settingsReset();
+ }
+
+ ExtUI::setLevelingActive(config.levelingEnabled);
+ dgus.setVolume(config.volume);
+ dgus.setBrightness(config.brightness);
+}
+
+void DGUSScreenHandler::configurationStoreWritten(bool success) {
+ if (!success)
+ setStatusMessage(GET_TEXT_F(DGUS_MSG_WRITE_EEPROM_FAILED));
+}
+
+void DGUSScreenHandler::configurationStoreRead(bool success) {
+ if (!success) {
+ setStatusMessage(GET_TEXT_F(DGUS_MSG_READ_EEPROM_FAILED));
+ }
+ else if (!settings_ready) {
+ settings_ready = true;
+ ready();
+ }
+}
+
+void DGUSScreenHandler::playTone(const uint16_t frequency, const uint16_t duration) {
+ if (WITHIN(frequency, 1, 255)) {
+ if (WITHIN(duration, 1, 255))
+ dgus.playSound((uint8_t)frequency, (uint8_t)duration);
+ else
+ dgus.playSound((uint8_t)frequency);
+ }
+}
+
+void DGUSScreenHandler::angryBeeps(const uint8_t beepCount) {
+ angry_beeps = beepCount;
+}
+
+void DGUSScreenHandler::levelingStart() {
+ isLeveling = true;
+ currentMeshPointIndex = 0;
+ triggerFullUpdate();
+}
+
+void DGUSScreenHandler::levelingEnd() {
+ if (!isLeveling) return;
+
+ #if ENABLED(DEBUG_DGUSLCD)
+ DEBUG_ECHOLNPGM("levelingEnd(), valid=", ExtUI::getLevelingIsValid());
+ #endif
+
+ isLeveling = false;
+ currentMeshPointIndex = 0;
+ triggerFullUpdate();
+}
+
+void DGUSScreenHandler::meshUpdate(const int8_t xpos, const int8_t ypos) {
+ if (!isLeveling) return;
+
+ currentMeshPointIndex++;
+ triggerFullUpdate();
+}
+
+void DGUSScreenHandler::printTimerStarted() {
+ TERN_(HAS_FILAMENT_SENSOR, ExtUI::setFilamentRunoutState(false));
+ triggerScreenChange(DGUS_ScreenID::PAUSE);
+}
+
+void DGUSScreenHandler::printTimerPaused() {
+ dgus.playSound(3);
+ triggerScreenChange(DGUS_ScreenID::RESUME);
+}
+
+void DGUSScreenHandler::printTimerStopped() {
+ dgus.playSound(3);
+ triggerScreenChange(DGUS_ScreenID::FINISH);
+}
+
+void DGUSScreenHandler::filamentRunout(const ExtUI::extruder_t extruder) {
+ triggerScreenChange(DGUS_ScreenID::FILAMENTUSEUP);
+ dgus.playSound(3);
+}
+
+ssize_t DGUSScreenHandler::getScrollIndex() {
+ return currentScrollIndex;
+}
+
+void DGUSScreenHandler::addCurrentPageStringLength(size_t stringLength, size_t textControlLength) {
+ NOLESS(pageMaxStringLen, stringLength);
+ NOLESS(pageMaxControlLen, textControlLength);
+}
+
+#if HAS_MEDIA
+
+ void DGUSScreenHandler::sdCardInserted() {}
+
+ void DGUSScreenHandler::sdCardRemoved() {
+ sdPrintFilename = noFileSelected;
+
+ if (getCurrentScreen() >= DGUS_ScreenID::FILE1
+ && getCurrentScreen() <= DGUS_ScreenID::FILE4) {
+ triggerTempScreenChange(DGUS_ScreenID::SDCARDCHECK, DGUS_ScreenID::HOME);
+ }
+ }
+
+ void DGUSScreenHandler::sdCardError() {}
+
+#endif // HAS_MEDIA
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ void DGUSScreenHandler::powerLossResume() {
+ powerLossRecoveryAvailable = true;
+ }
+#endif
+
+#if HAS_PID_HEATING
+ void DGUSScreenHandler::pidTuning(const ExtUI::result_t rst) {
+ dgus.playSound(3);
+ }
+#endif
+
+void DGUSScreenHandler::steppersStatusChanged(bool steppersEnabled) {
+ refreshVP(DGUS_Addr::AXIS_StepperStatus);
+}
+
+void DGUSScreenHandler::homingDone() {
+ if (isOnTempScreen(DGUS_ScreenID::AUTOHOME))
+ triggerReturnScreen();
+}
+
+void DGUSScreenHandler::startPrintFromSD(const char* const filename) {
+ triggerScreenChange(DGUS_ScreenID::HOME);
+ sdPrintFilename = filename;
+ setStatusMessage(sdPrintFilename, 0);
+}
+
+void DGUSScreenHandler::setStatusMessage(FSTR_P msg, const millis_t duration) {
+ setStatusMessage(FTOP(msg), duration);
+}
+
+void DGUSScreenHandler::setStatusMessage(const char* msg, const millis_t duration) {
+ homeStatusMessage[0] = '\0';
+ strncat(homeStatusMessage, msg, sizeof(homeStatusMessage) / sizeof(char) - 1);
+ status_expire = duration ? ExtUI::safe_millis() + duration : 0;
+}
+
+DGUS_ScreenID DGUSScreenHandler::getCurrentScreen() { return current_screen; }
+
+void DGUSScreenHandler::homeThenChangeScreen(DGUS_ScreenID screen) {
+ triggerTempScreenChange(DGUS_ScreenID::AUTOHOME, screen);
+ ExtUI::injectCommands(F("G28"));
+}
+
+void DGUSScreenHandler::triggerScreenChange(DGUS_ScreenID screen) {
+ if (confirm_return_screen != DGUS_ScreenID::BOOT)
+ confirm_return_screen = screen;
+ else
+ new_screen = screen;
+ wait_return_screen = DGUS_ScreenID::BOOT; // cancel temp screen
+
+ #if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
+ DEBUG_ECHOLNPGM("trig scr: ", (uint16_t)screen);
+ #endif
+}
+
+void DGUSScreenHandler::triggerTempScreenChange(DGUS_ScreenID screen, DGUS_ScreenID returnScreen) {
+ if (confirm_return_screen != DGUS_ScreenID::BOOT)
+ confirm_return_screen = screen;
+ else
+ new_screen = screen;
+ wait_return_screen = returnScreen;
+
+ #if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
+ DEBUG_ECHOLNPGM("trig tmp: ", (uint16_t)screen, " ret: ", (uint16_t)returnScreen);
+ #endif
+}
+
+void DGUSScreenHandler::triggerReturnScreen() {
+ new_screen = wait_return_screen;
+ wait_return_screen = DGUS_ScreenID::BOOT;
+ #if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
+ DEBUG_ECHOLNPGM("trig ret scr");
+ #endif
+}
+
+bool DGUSScreenHandler::isOnTempScreen(DGUS_ScreenID screen) {
+ return wait_return_screen != DGUS_ScreenID::BOOT
+ && (screen == DGUS_ScreenID::BOOT || current_screen == screen);
+}
+
+void DGUSScreenHandler::triggerFullUpdate() {
+ full_update = true;
+}
+
+void DGUSScreenHandler::triggerEEPROMSave() {
+ eeprom_save = ExtUI::safe_millis() + 500;
+}
+
+bool DGUSScreenHandler::isPrinterIdle() {
+ return (!ExtUI::commandsInQueue() && !ExtUI::isMoving());
+}
+
+const DGUS_Addr* DGUSScreenHandler::findScreenAddrList(DGUS_ScreenID screen) {
+ DGUS_ScreenAddrList list;
+ const DGUS_ScreenAddrList *map = screen_addr_list_map;
+
+ do {
+ memcpy_P(&list, map, sizeof(*map));
+ if (!list.addr_list) break;
+ if (list.screen == screen) return list.addr_list;
+ } while (++map);
+
+ return nullptr;
+}
+
+bool DGUSScreenHandler::callScreenSetup(DGUS_ScreenID screen) {
+ DGUS_ScreenSetup setup;
+ const DGUS_ScreenSetup *list = screen_setup_list;
+
+ do {
+ memcpy_P(&setup, list, sizeof(*list));
+ if (!setup.setup_fn) break;
+ if (setup.screen == screen) return setup.setup_fn();
+ } while (++list);
+
+ return true;
+}
+
+void DGUSScreenHandler::moveToScreen(DGUS_ScreenID screen, bool abort_wait) {
+ current_screen = screen;
+
+ if (!callScreenSetup(screen)) return;
+ if (!sendScreenVPData(screen, true)) return;
+
+ dgus.switchScreen(current_screen);
+}
+
+bool DGUSScreenHandler::sendScreenVPData(DGUS_ScreenID screen, bool complete_update) {
+ if (complete_update) full_update = false;
+
+ const DGUS_Addr *list = findScreenAddrList(screen);
+
+ while (true) {
+ if (!list) return true; // Nothing left to send
+
+ const uint16_t addr = pgm_read_word(list++);
+ if (!addr) return true; // Nothing left to send
+
+ DGUS_VP vp;
+ if (!DGUS_PopulateVP((DGUS_Addr)addr, &vp)) continue; // Invalid VP
+ if (!vp.tx_handler) continue; // Nothing to send
+ if (!complete_update
+ && !(vp.flags & VPFLAG_AUTOUPLOAD)
+ && TERN1(DGUS_SOFTWARE_AUTOSCROLL, !(vp.flags & VPFLAG_TXSTRING_AUTOSCROLL))
+ ) continue; // Unnecessary VP
+
+ uint8_t expected_tx = 6 + vp.size; // 6 bytes header + payload.
+ const millis_t try_until = ExtUI::safe_millis() + 1000;
+
+ while (expected_tx > dgus.getFreeTxBuffer()) {
+ if (ELAPSED(ExtUI::safe_millis(), try_until)) return false; // Stop trying after 1 second
+
+ dgus.flushTx(); // Flush the TX buffer
+ delay(50);
+ }
+
+ vp.tx_handler(vp);
+ }
+}
+
+bool DGUSScreenHandler::refreshVP(DGUS_Addr vpAddr) {
+ const DGUS_Addr *list = findScreenAddrList(current_screen);
+
+ while (list && (uint16_t)*list) {
+ if (*list == vpAddr) {
+ DGUS_VP vp;
+ if (!DGUS_PopulateVP((DGUS_Addr)vpAddr, &vp) || !vp.tx_handler)
+ return false;
+
+ vp.tx_handler(vp);
+ return true;
+ }
+
+ list++;
+ }
+
+ return false;
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.h
new file mode 100644
index 0000000000..9220f09aa3
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSScreenHandler.h
@@ -0,0 +1,166 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#include "config/DGUS_Addr.h"
+#include "config/DGUS_Data.h"
+#include "config/DGUS_Screen.h"
+#include "config/DGUS_Constants.h"
+
+#include "DGUSSDCardHandler.h"
+
+#include "../ui_api.h"
+
+class DGUSScreenHandler {
+public:
+ typedef struct {
+ bool initialized;
+ bool levelingEnabled;
+ uint8_t volume;
+ uint8_t brightness;
+ DGUS_Data::Language language;
+ DGUS_Data::AxisControlCommand jogLength;
+ uint16_t plaExtruderTemp;
+ uint16_t plaBedTemp;
+ uint16_t absExtruderTemp;
+ uint16_t absBedTemp;
+ } eeprom_data_t;
+
+public:
+ static eeprom_data_t config;
+ static uint16_t currentMeshPointIndex;
+ static bool isLeveling;
+
+ static char homeStatusMessage[128];
+
+private:
+ static bool settings_ready;
+ static bool booted;
+
+ static DGUS_ScreenID current_screen;
+ static DGUS_ScreenID new_screen;
+ static DGUS_ScreenID wait_return_screen;
+ static DGUS_ScreenID confirm_return_screen;
+ static bool full_update;
+ static uint8_t angry_beeps;
+
+ #if HAS_MEDIA
+ static const char* sdPrintFilename;
+ #endif
+
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ static bool powerLossRecoveryAvailable;
+ #endif
+
+ #if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ static ssize_t currentScrollIndex;
+ static size_t pageMaxStringLen;
+ static size_t pageMaxControlLen;
+ #endif
+
+ static millis_t status_expire;
+ static millis_t eeprom_save;
+
+public:
+ DGUSScreenHandler() = default;
+
+ static void init();
+ static void ready();
+ static void loop();
+
+ static void printerKilled(FSTR_P const error, FSTR_P const component);
+ static bool isOnUserConfirmationScreen() { return confirm_return_screen != DGUS_ScreenID::BOOT; }
+ static void userConfirmRequired(const char * const msg);
+ static void userConfirmation();
+ static void settingsReset();
+ static void storeSettings(char *buff);
+ static void loadSettings(const char *buff);
+ static void configurationStoreWritten(bool success);
+ static void configurationStoreRead(bool success);
+
+ static void playTone(const uint16_t frequency, const uint16_t duration);
+ static void angryBeeps(const uint8_t beepCount);
+
+ static void levelingStart();
+ static void levelingEnd();
+ static void meshUpdate(const int8_t xpos, const int8_t ypos);
+
+ static void printTimerStarted();
+ static void printTimerPaused();
+ static void printTimerStopped();
+ static void filamentRunout(const ExtUI::extruder_t extruder);
+
+ #if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ static ssize_t getScrollIndex();
+ static void addCurrentPageStringLength(size_t stringLength, size_t textControlLength);
+ #endif
+
+ #if HAS_MEDIA
+ /// Marlin informed us that a new SD has been inserted.
+ static void sdCardInserted();
+ /// Marlin informed us that the SD Card has been removed().
+ static void sdCardRemoved();
+ /// Marlin informed us about a bad SD Card.
+ static void sdCardError();
+
+ static const char* getSDCardPrintFilename() { return sdPrintFilename; }
+ #endif
+
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ static void powerLossResume();
+ #endif
+
+ #if HAS_PID_HEATING
+ static void pidTuning(const ExtUI::result_t rst);
+ #endif
+
+ static void steppersStatusChanged(bool steppersEnabled);
+ static void homingDone();
+
+ static void startPrintFromSD(const char* const filename);
+ static void setStatusMessage(FSTR_P msg, const millis_t duration=DGUS_STATUS_EXPIRATION_MS);
+ static void setStatusMessage(const char* msg, const millis_t duration=DGUS_STATUS_EXPIRATION_MS);
+
+ static DGUS_ScreenID getCurrentScreen();
+ static void homeThenChangeScreen(DGUS_ScreenID screen);
+ static void triggerScreenChange(DGUS_ScreenID screen);
+ static void triggerTempScreenChange(DGUS_ScreenID screen, DGUS_ScreenID returnScreen);
+ static void triggerReturnScreen();
+ static bool isOnTempScreen(DGUS_ScreenID screen = DGUS_ScreenID::BOOT);
+ static void triggerFullUpdate();
+
+ static void triggerEEPROMSave();
+
+ static bool isPrinterIdle();
+
+private:
+ static const DGUS_Addr* findScreenAddrList(DGUS_ScreenID screen);
+ static bool callScreenSetup(DGUS_ScreenID screen);
+
+ static void moveToScreen(DGUS_ScreenID screen, bool abort_wait=false);
+ static bool sendScreenVPData(DGUS_ScreenID screen, bool complete_update);
+ static bool refreshVP(DGUS_Addr vpAddr);
+};
+
+extern DGUSScreenHandler screen;
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.cpp
new file mode 100644
index 0000000000..ddde2689de
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.cpp
@@ -0,0 +1,60 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSSetupHandler.h"
+
+#include "DGUSDisplay.h"
+#include "DGUSScreenHandler.h"
+
+typedef void (*controlSet_t)(const DGUS_ScreenID, DGUSDisplay::DGUS_ControlType, DGUS_Control);
+
+bool DGUSSetupHandler::sdCardPrepare() {
+ bool isConfirm = false;
+
+ #if ENABLED(DGUS_USERCONFIRM)
+ isConfirm = screen.isOnUserConfirmationScreen();
+ controlSet_t controlSet = isConfirm ? dgus.disableControl : dgus.enableControl;
+
+ // Only allow the fifth line used as the confirm button to be clicked
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_File1);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_File2);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_File3);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_File4);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Start);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_End);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Prev);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Next);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Home);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Print);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Ready);
+ controlSet(DGUS_ScreenID::FILE1, DGUSDisplay::DGUS_ControlType::RETURN_KEY_CODE, DGUS_Control::FILE1_Settings);
+ #endif
+
+ if (!isConfirm) dgus_sdcard_handler.onPageLoad(DGUS_SCREEN_TO_PAGE(screen.getCurrentScreen()));
+ return true;
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.h
new file mode 100644
index 0000000000..f8e3b33da8
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSSetupHandler.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+namespace DGUSSetupHandler {
+ bool sdCardPrepare();
+}
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp
new file mode 100644
index 0000000000..0dd12b1612
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.cpp
@@ -0,0 +1,223 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUSTxHandler.h"
+
+#include "DGUSScreenHandler.h"
+#include "config/DGUS_Data.h"
+
+#include "../../../module/stepper.h" // for axis_enabled
+#include "../../../libs/duration_t.h"
+
+void DGUSTxHandler::bootAnimation(DGUS_VP &vp) {
+ static uint16_t bootIcon = 0;
+
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(bootIcon));
+
+ if (++bootIcon > 100) {
+ bootIcon = 0;
+ screen.triggerScreenChange(DGUS_ScreenID::HOME);
+ }
+}
+
+void DGUSTxHandler::zOffset(DGUS_VP &vp) {
+ const float position = ExtUI::getZOffset_mm();
+ const int16_t data = dgus.toFixedPoint(position); // Round to 0.01
+ dgus.write((int16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::elapsedHours(DGUS_VP &vp) {
+ const duration_t elapsedtime = ExtUI::getProgress_seconds_elapsed();
+ const int16_t data = elapsedtime.hour();
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::elapsedMinutes(DGUS_VP &vp) {
+ const duration_t elapsedtime = ExtUI::getProgress_seconds_elapsed();
+ const int16_t data = elapsedtime.minute() % 60;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::levelingProgress(DGUS_VP &vp) {
+ const uint16_t data = (100 * screen.currentMeshPointIndex) / GRID_MAX_POINTS;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::fanSpeed(DGUS_VP &vp) {
+ const int16_t data = (int16_t)ExtUI::getActualFan_percent(ExtUI::FAN0);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::levelingProgressIcon(DGUS_VP &vp) {
+ const uint16_t data = 1 + (50 * screen.currentMeshPointIndex) / GRID_MAX_POINTS;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+#if HAS_FILAMENT_SENSOR
+ void DGUSTxHandler::filamentInsertionStatus(DGUS_VP &vp) {
+ const uint16_t data = ExtUI::getFilamentRunoutState() ? 1 : 0;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+#endif
+
+void DGUSTxHandler::sdCardInsertionStatus(DGUS_VP &vp) {
+ const uint16_t data = ExtUI::isMediaInserted() ? 1 : 0;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+#if ENABLED(PIDTEMPBED)
+ void DGUSTxHandler::bed_PID_P(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getBedPID_Kp());
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+
+ void DGUSTxHandler::bed_PID_I(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getBedPID_Ki());
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+
+ void DGUSTxHandler::bed_PID_D(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getBedPID_Kd());
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+#endif // PIDTEMPBED
+
+static duration_t _PrintRemainingDurationEstimate() {
+ duration_t remainingDuration = 0;
+
+ if (ExtUI::isPrinting()) {
+ const uint8_t progressPercentage = ExtUI::getProgress_percent();
+ remainingDuration = duration_t(3600);
+
+ if (progressPercentage >= 2)
+ remainingDuration = ExtUI::getProgress_seconds_elapsed() * ((100.0 / (float)progressPercentage) - 1.0);
+ }
+
+ return remainingDuration;
+}
+
+void DGUSTxHandler::printRemainingHours(DGUS_VP &vp) {
+ const int16_t data = _PrintRemainingDurationEstimate().hour();
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::printRemainingMinutes(DGUS_VP &vp) {
+ const int16_t data = _PrintRemainingDurationEstimate().minute() % 60;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::printPercentage(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getProgress_percent();
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::printSpeedPercentage(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getFeedrate_percent();
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::extruderTargetTemp(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getTargetTemp_celsius(ExtUI::H0);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::extruderCurrentTemp(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getActualTemp_celsius(ExtUI::H0);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::bedTargetTemp(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getTargetTemp_celsius(ExtUI::BED);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::bedCurrentTemp(DGUS_VP &vp) {
+ const int16_t data = ExtUI::getActualTemp_celsius(ExtUI::BED);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::axis_X(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getAxisPosition_mm(ExtUI::X));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::axis_Y(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getAxisPosition_mm(ExtUI::Y));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::axis_Z(DGUS_VP &vp) {
+ const int16_t data = dgus.toFixedPoint(ExtUI::getAxisPosition_mm(ExtUI::Z));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::stepperStatus(DGUS_VP &vp) {
+ const bool areSteppersEnabled = stepper.axis_enabled.bits & (_BV(NUM_AXES) - 1);
+ const uint16_t data = areSteppersEnabled ? 1 : 0;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::enableIfLanguageMatchesExtra(DGUS_VP &vp) {
+ const DGUS_Data::Language targetLanguage = (DGUS_Data::Language)reinterpret_cast(vp.extra);
+ const uint16_t data = targetLanguage == screen.config.language ? 1 : 0;
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+}
+
+void DGUSTxHandler::extraToString(DGUS_VP &vp) {
+ if (!vp.size || !vp.extra) return;
+
+ #if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ if (vp.flags & VPFLAG_TXSTRING_AUTOSCROLL) {
+ const char* stringStart = (const char*)vp.extra;
+ const size_t stringLength = strlen(stringStart);
+ screen.addCurrentPageStringLength(stringLength, vp.size);
+
+ if (stringLength <= vp.size || screen.getScrollIndex() <= 0) {
+ // no scroll needed
+ }
+ else if ((ssize_t)stringLength - screen.getScrollIndex() <= vp.size) {
+ stringStart += (stringLength - vp.size);
+ }
+ else
+ stringStart += screen.getScrollIndex();
+
+ dgus.writeString((uint16_t)vp.addr,
+ stringStart,
+ vp.size, true, false, false);
+ return;
+ }
+ #endif // DGUS_SOFTWARE_AUTOSCROLL
+
+ dgus.writeString((uint16_t)vp.addr, vp.extra, vp.size, true, false, false);
+}
+
+void DGUSTxHandler::extraPGMToString(DGUS_VP &vp) {
+ if (!vp.size || !vp.extra) return;
+
+ dgus.writeStringPGM((uint16_t)vp.addr, vp.extra, vp.size, true, false, false);
+}
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.h b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.h
new file mode 100644
index 0000000000..2b22c7a62e
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/DGUSTxHandler.h
@@ -0,0 +1,150 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "DGUSDisplay.h"
+#include "definition/DGUS_VP.h"
+
+#define Swap16(val) (uint16_t((uint16_t(val) >> 8) | (uint16_t(val) << 8)))
+
+namespace DGUSTxHandler {
+ void bootAnimation(DGUS_VP &);
+
+ void zOffset(DGUS_VP &);
+ void elapsedHours(DGUS_VP &);
+ void elapsedMinutes(DGUS_VP &);
+ void levelingProgress(DGUS_VP &vp);
+ void fanSpeed(DGUS_VP &vp);
+ void levelingProgressIcon(DGUS_VP &vp);
+ #if HAS_FILAMENT_SENSOR
+ void filamentInsertionStatus(DGUS_VP &vp);
+ #endif
+ void sdCardInsertionStatus(DGUS_VP &vp);
+
+ template
+ void maxFeedrate(DGUS_VP &vp) {
+ const uint16_t data = (uint16_t)ExtUI::getAxisMaxFeedrate_mm_s(axis);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ template
+ void maxAcceleration(DGUS_VP &vp) {
+ const uint16_t data = (uint16_t)ExtUI::getAxisMaxAcceleration_mm_s2(axis);
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ template
+ void maxJerk(DGUS_VP &vp) {
+ const uint16_t data = dgus.toFixedPoint(ExtUI::getAxisMaxJerk_mm_s(axis));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ template
+ void stepsPerMM(DGUS_VP &vp) {
+ const uint16_t data = dgus.toFixedPoint(ExtUI::getAxisSteps_per_mm(axis));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+
+ #if ENABLED(PIDTEMP)
+ template
+ void PID_P(DGUS_VP &vp) {
+ const uint16_t data = dgus.toFixedPoint(ExtUI::getPID_Kp(extruder));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ template
+ void PID_I(DGUS_VP &vp) {
+ const uint16_t data = dgus.toFixedPoint(ExtUI::getPID_Ki(extruder));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ template
+ void PID_D(DGUS_VP &vp) {
+ const uint16_t data = dgus.toFixedPoint(ExtUI::getPID_Kd(extruder));
+ dgus.write((uint16_t)vp.addr, Endianness::toBE(data));
+ }
+ #endif // PIDTEMP
+
+ #if ENABLED(PIDTEMPBED)
+ void bed_PID_P(DGUS_VP &vp);
+ void bed_PID_I(DGUS_VP &vp);
+ void bed_PID_D(DGUS_VP &vp);
+ #endif
+
+ void printRemainingHours(DGUS_VP &);
+ void printRemainingMinutes(DGUS_VP &);
+ void printPercentage(DGUS_VP &);
+ void printSpeedPercentage(DGUS_VP &);
+ void extruderTargetTemp(DGUS_VP &);
+ void extruderCurrentTemp(DGUS_VP &);
+ void bedTargetTemp(DGUS_VP &);
+ void bedCurrentTemp(DGUS_VP &);
+ void axis_X(DGUS_VP &);
+ void axis_Y(DGUS_VP &);
+ void axis_Z(DGUS_VP &);
+ void stepperStatus(DGUS_VP &);
+ void enableIfLanguageMatchesExtra(DGUS_VP &);
+
+ void extraToString(DGUS_VP &);
+ void extraPGMToString(DGUS_VP &);
+
+ template
+ void extraToInteger(DGUS_VP &vp) {
+ if (!vp.size || !vp.extra) return;
+ switch (vp.size) {
+ default: return;
+ case 1: {
+ const uint8_t data = uint8_t(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), data);
+ break;
+ }
+ case 2: {
+ const uint16_t data = uint16_t(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), Endianness::toBE(data));
+ break;
+ }
+ case 4: {
+ const uint32_t data = uint32_t(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), Endianness::toBE(data));
+ break;
+ }
+ }
+ }
+
+ template
+ void extraToFixedPoint(DGUS_VP &vp) {
+ if (!vp.size || !vp.extra) return;
+ switch (vp.size) {
+ default: return;
+ case 1: {
+ const uint8_t data = dgus.toFixedPoint(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), data);
+ break;
+ }
+ case 2: {
+ const uint16_t data = dgus.toFixedPoint(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), Endianness::toBE(data));
+ break;
+ }
+ case 4: {
+ const uint32_t data = dgus.toFixedPoint(*(T*)vp.extra);
+ dgus.write(uint16_t(vp.addr), Endianness::toBE(data));
+ break;
+ }
+ }
+ }
+}
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Addr.h b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Addr.h
new file mode 100644
index 0000000000..73694a4e09
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Addr.h
@@ -0,0 +1,251 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#define DGUS_MAIN_STATUS_LEN 20
+#define DGUS_FILENAME_LEN 20
+#define DGUS_INFOSTRING_LEN 16 // 20 in the firmware, but really only shows 16 characters
+
+enum class DGUS_Addr : uint16_t {
+ END = 0,
+ BOOT_Logo = 0x1000,
+ CMD_MenuSelect = 0x1002, // r, int, DGUS_Data::MenuSelectCommand
+ CMD_Adjust = 0x1004, // r, int, DGUS_Data::AdjustCommand
+ MAIN_PrintSpeedPercentage = 0x1006, // rw, int, 3.0
+ CMD_CheckKO = 0x1008, // r, int, DGUS_Data::CheckKOCommand
+ CMD_StopPause = 0x100A, // r, int, DGUS_Data::StopPauseCommand
+ CMD_CheckOK = 0x100C, // r, int, DGUS_Data::CheckOKCommand
+ MAIN_Icon_Percentage = 0x100E, // w, icon, 0-100
+ MAIN_ElapsedHours = 0x1010, // w, int, 3.0
+ MAIN_ElapsedMinutes = 0x1012, // w, int, 2.0
+ MAIN_PrintPercentage = 0x1016, // w, int, 3.0
+ MAIN_ZOffset = 0x1026, // w, int, 2.2
+ CMD_PresetControl = 0x1030, // r, int, DGUS_Data::PresetControlCommand
+ CMD_TemperatureControl = 0x1032, // r, int, DGUS_Data::TemperatureControlCommand
+ MAIN_ExtruderTargetTemp = 0x1034, // rw, int, 3.0
+ MAIN_ExtruderCurrentTemp = 0x1036, // w, int, 3.0
+ MAIN_BedTargetTemp = 0x103A, // rw, int, 3.0
+ MAIN_BedCurrentTemp = 0x103C, // w, int, 3.0
+ CMD_SettingsMenu = 0x103E, // r, int, DGUS_Data::SettingsMenuCommand
+ CMD_Leveling = 0x1044, // r, int, DGUS_Data::LevelingCommand
+ CMD_AxisControl = 0x1046, // r, int, DGUS_Data::AxisControlCommand
+ AXIS_X = 0x1048, // rw, int, 3.1
+ AXIS_Y = 0x104A, // rw, int, 3.1
+ AXIS_Z = 0x104C, // rw, int, 3.1
+ IO_ExtrudeLength = 0x1052, // r, int, 3.1
+ IO_RetractLength = 0x1054, // r, int, 3.1
+ CMD_AxisIO = 0x1056, // r, int, DGUS_Data::FilamentIoCommand
+ LANGUAGE_SetLanguage = 0x105C, // r, int, 1-9
+ CMD_PowerLoss = 0x105F, // r, int, DGUS_Data::PowerLossCommand
+ LEVELING_Progress_Icon = 0x108D, // w, icon, progress 1-50
+ FILAMENT_Icon_Inserted = 0x108E, // w, icon, on-off 0-1
+ TEMP_PLA_ExtruderTemp = 0x1090, // rw, int, 3.0
+ TEMP_PLA_BedTemp = 0x1092, // rw, int, 3.0
+ TEMP_ABS_ExtruderTemp = 0x1094, // rw, int, 3.0
+ TEMP_ABS_BedTemp = 0x1096, // rw, int, 3.0
+ CMD_AdvancedSettings = 0x1098, // r, int, DGUS_Data::AdvancedSettingsCommand
+ LEVELING_Progress = 0x109C, // w, int, 3.0
+ MOTION_MaxSpeed_X = 0x109E, // rw, int, 4.0
+ MOTION_MaxSpeed_Y = 0x10A0, // rw, int, 4.0
+ MOTION_MaxSpeed_Z = 0x10A2, // rw, int, 4.0
+ MOTION_MaxSpeed_E = 0x10A4, // rw, int, 4.0
+ MOTION_Acceleration_X = 0x10A6, // rw, int, 4.0
+ MOTION_Acceleration_Y = 0x10A8, // rw, int, 4.0
+ MOTION_Acceleration_Z = 0x10AA, // rw, int, 4.0
+ MOTION_Acceleration_E = 0x10AC, // rw, int, 4.0
+ MOTION_MaxJerk_X = 0x10AE, // rw, int, 2.2
+ MOTION_MaxJerk_Y = 0x10B0, // rw, int, 2.2
+ MOTION_MaxJerk_Z = 0x10B2, // rw, int, 2.2
+ MOTION_MaxJerk_E = 0x10B4, // rw, int, 2.2
+ MOTION_StepsPerMm_X = 0x10B6, // rw, int, 4.1
+ MOTION_StepsPerMm_Y = 0x10B8, // rw, int, 4.1
+ MOTION_StepsPerMm_Z = 0x10BA, // rw, int, 4.1
+ MOTION_StepsPerMm_E = 0x10BC, // rw, int, 4.1
+ PID_Extruder_P = 0x10BE, // rw, int, 3.2
+ PID_Extruder_I = 0x10C0, // rw, int, 3.2
+ PID_Extruder_D = 0x10C2, // rw, int, 3.2
+ PID_Bed_P = 0x10C4, // rw, int, 3.2
+ PID_Bed_I = 0x10C6, // rw, int, 3.2
+ PID_Bed_D = 0x10C8, // rw, int, 4.1
+ CONTROL_FanSpeed = 0x10CA, // rw, int, 3.0
+ SDCard_InsertionStatus = 0x1168, // w, icon, on off 0-1
+ FINISH_Icon_Finished = 0x1170, // w, icon, translated 1-9
+ MAIN_RemainingHours = 0x1171, // w, int, 3.0
+ MAIN_RemainingMinutes = 0x1173, // w, int, 2.0
+
+ AXIS_StepperStatus = 0x1200, // w, icon, on off 0-1
+ SDCARD_Selection_File1 = 0x1221, // w, icon, on off 0-1
+ SDCARD_Selection_File2 = 0x1222, // w, icon, on off 0-1
+ SDCARD_Selection_File3 = 0x1223, // w, icon, on off 0-1
+ SDCARD_Selection_File4 = 0x1224, // w, icon, on off 0-1
+ SDCARD_Selection_File5 = 0x1225, // w, icon, on off 0-1
+ SDCARD_Selection_File6 = 0x1226, // w, icon, on off 0-1
+ SDCARD_Selection_File7 = 0x1227, // w, icon, on off 0-1
+ SDCARD_Selection_File8 = 0x1228, // w, icon, on off 0-1
+ SDCARD_Selection_File9 = 0x1229, // w, icon, on off 0-1
+ SDCARD_Selection_File10 = 0x122A, // w, icon, on off 0-1
+ SDCARD_Selection_File11 = 0x122B, // w, icon, on off 0-1
+ SDCARD_Selection_File12 = 0x122C, // w, icon, on off 0-1
+ SDCARD_Selection_File13 = 0x122D, // w, icon, on off 0-1
+ SDCARD_Selection_File14 = 0x122E, // w, icon, on off 0-1
+ SDCARD_Selection_File15 = 0x122F, // w, icon, on off 0-1
+ SDCARD_Selection_File16 = 0x1230, // w, icon, on off 0-1
+ SDCARD_Selection_File17 = 0x1231, // w, icon, on off 0-1
+ SDCARD_Selection_File18 = 0x1232, // w, icon, on off 0-1
+ SDCARD_Selection_File19 = 0x1233, // w, icon, on off 0-1
+ SDCARD_Selection_File20 = 0x1234, // w, icon, on off 0-1
+ MENU_Icon_Home_S = 0x1300, // w, icon, translated 1-9
+ MENU_Icon_Print_S = 0x1301, // w, icon, translated 1-9
+ MENU_Icon_Ready_S = 0x1302, // w, icon, translated 1-9
+ MENU_Icon_Settings_S = 0x1303, // w, icon, translated 1-9
+ MENU_Icon_Home = 0x1304, // w, icon, translated 1-9
+ MENU_Icon_Print = 0x1305, // w, icon, translated 1-9
+ MENU_Icon_Ready = 0x1306, // w, icon, translated 1-9
+ MENU_Icon_Settings = 0x1307, // w, icon, translated 1-9
+ ADJUST_Icon_Adjust = 0x130D, // w, icon, translated 1-9
+ ADJUST_Icon_Feedrate = 0x130E, // w, icon, translated 1-9
+ IO_Icon_ExtruderTemp = 0x130F, // w, icon, translated 1-9
+ CONTROL_Icon_BedTemp = 0x1310, // w, icon, translated 1-9
+ ADJUST_Icon_ZOffset = 0x1311, // w, icon, translated 1-9
+ CONTROL_Icon_FanControl = 0x1312, // w, icon, translated 1-9
+ ADJUST_Icon_FanControl = 0x1313, // w, icon, translated 1-9
+ AXIS_Icon_MoveAxis = 0x1314, // w, icon, translated 1-9
+ AXIS_Icon_IO = 0x1318, // w, icon, translated 1-9
+ AXIS_Icon_Manual = 0x1319, // w, icon, translated 1-9
+ CONTROL_Icon_Cooling = 0x131A, // w, icon, translated 1-9
+ IO_Icon_Extrude = 0x1321, // w, icon, translated 1-9
+ IO_Icon_Retract = 0x1322, // w, icon, translated 1-9
+ SETTINGS_Icon_Language = 0x1323, // w, icon, translated 1-9
+ SETTINGS_Icon_Leveling = 0x1325, // w, icon, translated 1-9
+ SETTINGS_Icon_Device = 0x1326, // w, icon, translated 1-9
+ ADV_Icon_ResetSettings = 0x1327, // w, icon, translated 1-9
+ INFO_Icon_About = 0x1328, // w, icon, translated 1-9
+ INFO_Icon_Device = 0x1329, // w, icon, translated 1-9
+ SETTINGS_Icon_Advanced = 0x132A, // w, icon, translated 1-9
+ SETTINGS_Icon_About = 0x132B, // w, icon, translated 1-9
+ SETTINGS_Icon_PLA = 0x132D, // w, icon, translated 1-9
+ SETTINGS_Icon_ABS = 0x132E, // w, icon, translated 1-9
+ RUNOUT_Icon_Stop = 0x133E, // w, icon, translated 1-9
+ RUNOUT_Icon_Message = 0x133F, // w, icon, translated 1-9
+ RESET_Icon_Yes = 0x1340, // w, icon, translated 1-9
+ RESET_Icon_No = 0x1341, // w, icon, translated 1-9
+ LOAD_Icon_Message = 0x1342, // w, icon, translated 1-9
+ LOAD_Icon_Continue = 0x1343, // w, icon, translated 1-9
+ PAUSE_Icon_Message = 0x1344, // w, icon, translated 1-9
+ RESUME_Icon_Message = 0x1347, // w, icon, translated 1-9
+ POWERLOSS_Icon_Message = 0x1348, // w, icon, translated 1-9
+ AUTOHOME_Icon_WaitMessage = 0x1349, // w, icon, translated 1-9
+ LEVELING_Icon_Leveling = 0x134B, // w, icon, translated 1-9
+ RESET_Icon_InfoMessage = 0x134D, // w, icon, translated 1-9
+ LEVELING_Icon_Start = 0x1356, // w, icon, translated 1-9
+ LEVELING_Icon_AuxLevel = 0x1357, // w, icon, translated 1-9
+ LEVELING_Icon_AutoLevel = 0x1358, // w, icon, translated 1-9
+ LEVELING_Icon_AuxLevel_S = 0x1359, // w, icon, translated 1-9
+ LEVELING_Icon_AutoLevel_S = 0x135A, // w, icon, translated 1-9
+ LANGUAGE_Icon_Language = 0x135B, // w, icon, translated 1-9
+ ADV_Icon_Movement = 0x135C, // w, icon, translated 1-9
+ ADV_Icon_PID = 0x135D, // w, icon, translated 1-9
+ ADV_Icon_MotionSettings = 0x135F, // w, icon, translated 1-9
+ ADV_Icon_MaxFeedrate = 0x1360, // w, icon, translated 1-9
+ ADV_Icon_Acceleration = 0x1361, // w, icon, translated 1-9
+ ADV_Icon_Jerk = 0x1362, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMm = 0x1363, // w, icon, translated 1-9
+ ADV_Icon_MaxSpeed = 0x1364, // w, icon, translated 1-9
+ ADV_Icon_MaxSpeed_X = 0x1365, // w, icon, translated 1-9
+ ADV_Icon_MaxSpeed_Y = 0x1366, // w, icon, translated 1-9
+ ADV_Icon_MaxSpeed_Z = 0x1367, // w, icon, translated 1-9
+ ADV_Icon_MaxSpeed_E = 0x1368, // w, icon, translated 1-9
+ ADV_Icon_AccelerationMenu = 0x1369, // w, icon, translated 1-9
+ ADV_Icon_Acceleration_X = 0x136A, // w, icon, translated 1-9
+ ADV_Icon_Acceleration_Y = 0x136B, // w, icon, translated 1-9
+ ADV_Icon_Acceleration_Z = 0x136C, // w, icon, translated 1-9
+ ADV_Icon_Acceleration_E = 0x136D, // w, icon, translated 1-9
+ ADV_Icon_MaxJerkMenu = 0x136E, // w, icon, translated 1-9
+ ADV_Icon_MaxJerk_X = 0x136F, // w, icon, translated 1-9
+ ADV_Icon_MaxJerk_Y = 0x1370, // w, icon, translated 1-9
+ ADV_Icon_MaxJerk_Z = 0x1371, // w, icon, translated 1-9
+ ADV_Icon_MaxJerk_E = 0x1372, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMmMenu = 0x1373, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMm_X = 0x1374, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMm_Y = 0x1375, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMm_Z = 0x1376, // w, icon, translated 1-9
+ ADV_Icon_StepsPerMm_E = 0x1377, // w, icon, translated 1-9
+ PID_Icon_PIDMenu = 0x1378, // w, icon, translated 1-9
+ PID_Icon_Extruder_P = 0x1379, // w, icon, translated 1-9
+ PID_Icon_Extruder_I = 0x137A, // w, icon, translated 1-9
+ PID_Icon_Extruder_D = 0x137B, // w, icon, translated 1-9
+ PID_Icon_Bed_P = 0x137C, // w, icon, translated 1-9
+ PID_Icon_Bed_I = 0x137D, // w, icon, translated 1-9
+ PID_Icon_Bed_D = 0x137E, // w, icon, translated 1-9
+ CUTTER_Icon_Message = 0x1381, // w, icon, translated 1-9
+ FDM_Icon_Message = 0x1382, // w, icon, translated 1-9
+ ADV_Icon_SwitchToLaser = 0x1388, // w, icon, translated 1-9
+ PRTMODE_Icon_Message = 0x1389, // w, icon, translated 1-9
+ PRTMODE_Icon_FDM = 0x138D, // w, icon, translated 1-9
+ PRTMODE_Icon_Cutter = 0x138E, // w, icon, translated 1-9
+ INFO_Icon_Model = 0x1400, // w, icon, translated 1-9
+ INFO_Icon_FW_Version = 0x1401, // w, icon, translated 1-9
+ INFO_Icon_Screen_Version = 0x1402, // w, icon, translated 1-9
+ INFO_Icon_HW_Version = 0x1403, // w, icon, translated 1-9
+ INFO_Icon_Website = 0x1405, // w, icon, translated 1-9
+ INFO_Icon_Print_Size = 0x1406, // w, icon, translated 1-9
+ LANGUAGE_Icon_Chinese = 0x1411, // w, icon, on off 0-1
+ LANGUAGE_Icon_English = 0x1412, // w, icon, on off 0-1
+ LANGUAGE_Icon_German = 0x1413, // w, icon, on off 0-1
+ LANGUAGE_Icon_Spanish = 0x1414, // w, icon, on off 0-1
+ LANGUAGE_Icon_French = 0x1415, // w, icon, on off 0-1
+ LANGUAGE_Icon_Italian = 0x1416, // w, icon, on off 0-1
+ LANGUAGE_Icon_Portuguese = 0x1417, // w, icon, on off 0-1
+ LANGUAGE_Icon_Russian = 0x1418, // w, icon, on off 0-1
+ LANGUAGE_Icon_Turkish = 0x1419, // w, icon, on off 0-1
+ INFO_Model = 0x17B0, // w, text, 20
+ INFO_FW_Version = 0x17C4, // w, text, 20
+ INFO_Screen_Version = 0x17D8, // w, text, 20
+ INFO_HW_Version = 0x17EC, // w, text, 20
+ INFO_Print_Size = 0x1800, // w, text, 20
+ INFO_Website = 0x1814, // w, text, 20
+ SDCARD_Filename1 = 0x200A, // w, text, 20
+ SDCARD_Filename2 = 0x201E, // w, text, 20
+ SDCARD_Filename3 = 0x2032, // w, text, 20
+ SDCARD_Filename4 = 0x2046, // w, text, 20
+ SDCARD_Filename5 = 0x205A, // w, text, 20
+ SDCARD_Filename6 = 0x206E, // w, text, 20
+ SDCARD_Filename7 = 0x2082, // w, text, 20
+ SDCARD_Filename8 = 0x2096, // w, text, 20
+ SDCARD_Filename9 = 0x20AA, // w, text, 20
+ SDCARD_Filename10 = 0x20BE, // w, text, 20
+ SDCARD_Filename11 = 0x20D2, // w, text, 20
+ SDCARD_Filename12 = 0x20E6, // w, text, 20
+ SDCARD_Filename13 = 0x20FA, // w, text, 20
+ SDCARD_Filename14 = 0x210E, // w, text, 20
+ SDCARD_Filename15 = 0x2122, // w, text, 20
+ SDCARD_Filename16 = 0x2136, // w, text, 20
+ SDCARD_Filename17 = 0x214A, // w, text, 20
+ SDCARD_Filename18 = 0x215E, // w, text, 20
+ SDCARD_Filename19 = 0x2172, // w, text, 20
+ SDCARD_Filename20 = 0x2186, // w, text, 20
+ CMD_FilelistControl = 0x2198, // w, int, DGUS_Data::FilelistControlCommand
+ SDCARD_FileSelection = 0x2199, // r, int 1-20
+ MAIN_StatusMessage = 0x219A, // w, text, 20
+ ABNORMAL_StatusMessage = 0x21D4, // w, text, 30
+ CMD_LaserControl = 0x2201, // w, int, DGUS_Data::LaserControlCommand
+};
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Constants.h b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Constants.h
new file mode 100644
index 0000000000..3c89f7ad8a
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Constants.h
@@ -0,0 +1,57 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#define DGUS_BED_SIZE_STR STRINGIFY(X_BED_SIZE) "x" STRINGIFY(Y_BED_SIZE) "mm"
+
+#if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
+ #ifndef DGUS_AUTOSCROLL_START_CYCLES
+ // Additional refresh cycles where strings beginnings are shown
+ #define DGUS_AUTOSCROLL_START_CYCLES 1
+ #endif
+ #ifndef DGUS_AUTOSCROLL_END_CYCLES
+ // Additional refresh cycles where strings endings are shown
+ #define DGUS_AUTOSCROLL_END_CYCLES 1
+ #endif
+#endif
+
+#ifndef DGUS_DEFAULT_VOLUME
+ #define DGUS_DEFAULT_VOLUME 50
+#endif
+
+#ifndef DGUS_DEFAULT_BRIGHTNESS
+ #define DGUS_DEFAULT_BRIGHTNESS 100
+#endif
+
+#ifndef DGUS_STATUS_EXPIRATION_MS
+ #define DGUS_STATUS_EXPIRATION_MS 30000
+#endif
+
+#ifndef BED_TRAMMING_Z_HOP
+ #define BED_TRAMMING_Z_HOP 4.0
+#endif
+
+#ifndef BED_TRAMMING_HEIGHT
+ #define BED_TRAMMING_HEIGHT 0.0
+#endif
+
+static_assert(BED_TRAMMING_Z_HOP >= 0, "BED_TRAMMING_Z_HOP must be >= 0. Please update your configuration.");
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Control.h b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Control.h
new file mode 100644
index 0000000000..c846b56bf4
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Control.h
@@ -0,0 +1,41 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+enum class DGUS_Control : uint8_t {
+ // FILE1
+ FILE1_File1 = 4, // RETURN_KEY_CODE
+ FILE1_File2 = 3, // RETURN_KEY_CODE
+ FILE1_File3 = 2, // RETURN_KEY_CODE
+ FILE1_File4 = 1, // RETURN_KEY_CODE
+ FILE1_File5 = 0, // RETURN_KEY_CODE
+ FILE1_Start = 8, // RETURN_KEY_CODE
+ FILE1_End = 7, // RETURN_KEY_CODE
+ FILE1_Prev = 5, // RETURN_KEY_CODE
+ FILE1_Next = 6, // RETURN_KEY_CODE
+ FILE1_Home = 9, // RETURN_KEY_CODE
+ FILE1_Print = 12, // RETURN_KEY_CODE
+ FILE1_Ready = 10, // RETURN_KEY_CODE
+ FILE1_Settings = 11, // RETURN_KEY_CODE
+};
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Data.h b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Data.h
new file mode 100644
index 0000000000..237cec7795
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Data.h
@@ -0,0 +1,199 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include
+
+namespace DGUS_Data {
+
+ // RX constants
+
+ enum class Language : uint16_t {
+ Chinese_Simplified = 1,
+ English,
+ German,
+ Spanish,
+ French,
+ Italian,
+ Portuguese,
+ Russian,
+ Turkish,
+
+ // Compatibility with LCD_LANGUAGE
+ zh_CN = Chinese_Simplified,
+ en = English,
+ de = German,
+ es = Spanish,
+ fr = French,
+ fr_na = French,
+ it = Italian,
+ pt = Portuguese,
+ ru = Russian,
+ tr = Turkish,
+
+ Default = LCD_LANGUAGE
+ };
+
+ // 1002
+ enum class MenuSelectCommand : uint16_t {
+ Print = 1,
+ Ready = 2,
+ Settings = 3,
+ PrintFinished = 5,
+ StartAutoLevel = 6,
+ Main = 8,
+ PausePrint = 9,
+ PauseStopPrint = 10
+ };
+
+ // 1004
+ enum class AdjustCommand : uint16_t {
+ Show_Adjust = 1,
+ Show_PrintStatus = 2,
+ Show_Adjust_ZOffset = 5,
+ Validate_ZOffset = 7,
+ };
+
+ // 1008
+ enum class CheckKOCommand : uint16_t {
+ KO = 2,
+ SDCard_No = 4, // screen fw 1.0.3
+ };
+
+ // 100A
+ enum class StopPauseCommand : uint16_t {
+ Pause_Laser = 1,
+ Pause = 2,
+ Stop_Confirm = 3
+ };
+
+ // 100C
+ enum class CheckOKCommand : uint16_t {
+ ContinueStop_Continue = 1,
+ FilamentRunout_Yes = 2,
+ FilamentLoad_Yes = 3,
+ SDCardCheck_Yes = 4,
+ };
+
+ // 1030
+ enum class PresetControlCommand : uint16_t {
+ Show_Settings_PLA_Settings = 3,
+ Show_Settings_ABS_Settings = 4,
+ Apply_PLA_Settings = 5,
+ Apply_ABS_Settings = 6,
+ Show_Ready_Manual = 8,
+ };
+
+ // 1032
+ enum class TemperatureControlCommand : uint16_t {
+ Cooldown = 1,
+ Exit_Temperature_Preset_And_Discard_Temperature = 2
+ };
+
+ // 103E
+ enum class SettingsMenuCommand : uint16_t {
+ Show_Settings_Device_Language = 1,
+ Show_Settings_Advanced = 2,
+ Show_Ready_Jog = 3,
+ Show_Settings_About = 5,
+ DisableStepperMotors = 6,
+ Reset_All_Settings = 7,
+ Show_Settings_Device_and_Save_Temperatures = 8,
+ FactoryReset_Validate = 11,
+ FactoryReset_Cancel = 14,
+ Exit_Settings_Tramming = 15,
+ Exit_Settings_Leveling = 16,
+ Show_Settings_Device_and_Discard_Temperatures = 17
+ };
+
+ // 1044
+ enum class LevelingCommand : uint16_t {
+ Show_Settings_Leveling = 1,
+ Show_AuxLeveling = 4,
+ Goto_Center = 5,
+ Goto_LF = 6,
+ Goto_RF = 7,
+ Goto_RB = 8,
+ Goto_LB = 9,
+ Show_AutoLeveling = 10,
+ };
+
+ // 1046
+ enum class AxisControlCommand : uint16_t {
+ Jog_10mm = 1,
+ Jog_1mm = 2,
+ Jog_0_1mm = 3,
+ Home_XY = 4,
+ Home_Z = 5,
+ };
+
+ // 1056
+ enum class FilamentIoCommand : uint16_t {
+ FilamentCheck_Yes = 1,
+ FilamentCheck_No = 2,
+ Show_Ready_IO = 3
+ };
+
+ // 105F
+ enum class PowerLossCommand : uint16_t {
+ PowerLoss_Continue = 1,
+ PowerLoss_No = 2
+ };
+
+ // 1098
+ enum class AdvancedSettingsCommand : uint16_t {
+ Show_AdvSettings_Movement = 4,
+ Show_AdvSettings_PID = 5,
+ Show_AdvSettings_Movement_StepsPerMm = 7,
+ Show_AdvSettings_Movement_Acceleration = 8,
+ Show_AdvSettings_Movement_Jerk = 9,
+ Show_AdvSettings_Movement_MaxFeedrate = 10,
+ Exit_AdvSettings_Movement_Submenu = 12,
+ Show_AdvSettings = 13,
+ };
+
+ // 2198
+ enum class FilelistControlCommand : uint16_t {
+ Start_Print = 1,
+ F1_Down = 2,
+ F1_Up = 3,
+ F2_Down = 4,
+ F2_Up = F1_Up,
+ F3_Down = 6,
+ F3_Up = 5,
+ F4_Down = 8,
+ F4_Up = 7,
+ Begin = 9,
+ End = 10
+ };
+
+ // 2198
+ enum class LaserControlCommand : uint16_t {
+ Mode_FDM = 1,
+ Mode_Cutter = 2,
+ Mode_FDM_Confirm = 3,
+ Mode_FDM_Cancel = 4,
+ Mode_Cutter_Confirm = 5,
+ Mode_Cutter_Cancel = 6,
+ Mode_Change = 0xB
+ };
+};
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Screen.h b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Screen.h
new file mode 100644
index 0000000000..8e890aa14f
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/config/DGUS_Screen.h
@@ -0,0 +1,106 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+enum class DGUS_ScreenID : uint8_t {
+ START = 0,
+ MAIN,
+ FILE1,
+ FILE2,
+ FILE3,
+ FILE4,
+ FILE5,
+ FILAMENTUSEUP,
+ FILAMENTLOAD,
+ FINISH,
+ PAUSE,
+ PAUSE_STOP,
+ RESUME,
+ CONTINUE_STOP,
+ ADJUST,
+ PREPARE,
+ MOVEAXIS_10,
+ MOVEAXIS_1,
+ MOVEAXIS_01,
+ FEEDRETURN,
+ CONTROL,
+ TEMP,
+ PLA_TEMP,
+ ABS_TEMP,
+ INFORMATION,
+ LEVELINGMODE,
+ LEVELING,
+ POWERCONTINUE,
+ LANGUAGE,
+ KEYBOARD,
+ KEYBOARD_CONFIRM,
+ THERMAL_RUNAWAY,
+ LEVEL_OFFSET,
+ CONTROL_DEVICE,
+ MOTION,
+ MAX_FEEDRATE,
+ ACCELERATION,
+ JERK,
+ STEPSMM,
+ PIDCONTROL,
+ AUTOHOME,
+ ABNORMAL,
+ WIFI_CONFIRM,
+ FACTORYRESET_CONFIRM,
+ SHUTDOWN,
+ SMOKE_ALARM,
+ FILAMENTCHECK,
+ SDCARDCHECK,
+ LASER_FDM,
+ MAIN_LASER,
+ _52_FILE1,
+ _53_FILE2,
+ _54_FILE3,
+ _55_FILE4,
+ SW_LASER_TIPS,
+ SW_FDM_TIPS,
+ STOP_CONFIRM,
+ PAUSE_LASER,
+ FINISH_LASER,
+ RESUME_LASER,
+ PAUSE_CONFIRM,
+ FOCUS,
+ DEVICE_LASER,
+ LANGE,
+ LASER_INFORMATION,
+ ACCEL_LASER,
+ JERK_SPEED_LASER,
+ MAX_SPEED_LASER,
+ AXIS_MOVE_10,
+ AXIS_MOVE_1,
+ AXIS_MOVE_01,
+ ADJUST_LASER,
+ ENGRAVE_TIPS,
+ RATIO,
+ SW_FOCUS,
+ AXIS_ADJUST_10,
+ AXIS_ADJUST_1,
+ AXIS_ADJUST_01,
+
+ BOOT = START,
+ HOME = MAIN
+};
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.cpp
new file mode 100644
index 0000000000..00083ced8c
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.cpp
@@ -0,0 +1,505 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUS_ScreenAddrList.h"
+
+#include "../../ui_api.h"
+
+constexpr DGUS_Addr LIST_BOOT[] PROGMEM = {
+ DGUS_Addr::BOOT_Logo,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_HOME[] PROGMEM = {
+ DGUS_Addr::MAIN_PrintSpeedPercentage,
+ DGUS_Addr::MAIN_Icon_Percentage,
+ DGUS_Addr::MAIN_ElapsedHours,
+ DGUS_Addr::MAIN_ElapsedMinutes,
+ DGUS_Addr::MAIN_PrintPercentage,
+ DGUS_Addr::MAIN_ZOffset,
+ DGUS_Addr::MAIN_ExtruderTargetTemp,
+ DGUS_Addr::MAIN_ExtruderCurrentTemp,
+ DGUS_Addr::MAIN_BedTargetTemp,
+ DGUS_Addr::MAIN_BedCurrentTemp,
+ DGUS_Addr::MAIN_RemainingHours,
+ DGUS_Addr::MAIN_RemainingMinutes,
+ DGUS_Addr::MAIN_StatusMessage,
+ DGUS_Addr::MENU_Icon_Home_S,
+ DGUS_Addr::MENU_Icon_Print,
+ DGUS_Addr::MENU_Icon_Ready,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::FINISH_Icon_Finished,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_PRINTING[] PROGMEM = {
+ DGUS_Addr::MAIN_PrintSpeedPercentage,
+ DGUS_Addr::MAIN_Icon_Percentage,
+ DGUS_Addr::MAIN_ElapsedHours,
+ DGUS_Addr::MAIN_ElapsedMinutes,
+ DGUS_Addr::MAIN_PrintPercentage,
+ DGUS_Addr::MAIN_ZOffset,
+ DGUS_Addr::MAIN_ExtruderTargetTemp,
+ DGUS_Addr::MAIN_ExtruderCurrentTemp,
+ DGUS_Addr::MAIN_BedTargetTemp,
+ DGUS_Addr::MAIN_BedCurrentTemp,
+ DGUS_Addr::MAIN_RemainingHours,
+ DGUS_Addr::MAIN_RemainingMinutes,
+ DGUS_Addr::MAIN_StatusMessage,
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::FINISH_Icon_Finished,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_RUNOUT[] PROGMEM = {
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RUNOUT_Icon_Stop,
+ DGUS_Addr::RUNOUT_Icon_Message,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_FILAMENTLOAD[] PROGMEM = {
+ DGUS_Addr::LOAD_Icon_Continue,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::LOAD_Icon_Message,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_PAUSE_STOP[] PROGMEM = {
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::PAUSE_Icon_Message,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_CONTINUE_STOP[] PROGMEM = {
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::RESUME_Icon_Message,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_MOVEAXIS[] PROGMEM = {
+ DGUS_Addr::AXIS_StepperStatus,
+ DGUS_Addr::AXIS_X,
+ DGUS_Addr::AXIS_Y,
+ DGUS_Addr::AXIS_Z,
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::AXIS_Icon_MoveAxis,
+ DGUS_Addr::AXIS_Icon_IO,
+ DGUS_Addr::AXIS_Icon_Manual,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_IO[] PROGMEM = {
+ DGUS_Addr::AXIS_Icon_MoveAxis,
+ DGUS_Addr::AXIS_Icon_IO,
+ DGUS_Addr::AXIS_Icon_Manual,
+ DGUS_Addr::MAIN_ExtruderTargetTemp,
+ DGUS_Addr::MAIN_ExtruderCurrentTemp,
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_CONTROL[] PROGMEM = {
+ DGUS_Addr::AXIS_Icon_MoveAxis,
+ DGUS_Addr::AXIS_Icon_IO,
+ DGUS_Addr::AXIS_Icon_Manual,
+ DGUS_Addr::MAIN_ExtruderTargetTemp,
+ DGUS_Addr::MAIN_BedTargetTemp,
+ DGUS_Addr::IO_Icon_ExtruderTemp,
+ DGUS_Addr::CONTROL_Icon_BedTemp,
+ DGUS_Addr::AXIS_Icon_IO, // bogus, it's for "PLA temp" icon
+ DGUS_Addr::AXIS_Icon_Manual, // bogus, it's for "ABS temp" icon
+ DGUS_Addr::CONTROL_FanSpeed,
+ DGUS_Addr::ADJUST_Icon_FanControl,
+ DGUS_Addr::CONTROL_Icon_Cooling,
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::END
+};
+
+
+constexpr DGUS_Addr LIST_ADJUST[] PROGMEM = {
+ DGUS_Addr::ADJUST_Icon_Adjust,
+ DGUS_Addr::IO_Icon_ExtruderTemp,
+ DGUS_Addr::CONTROL_Icon_BedTemp,
+ DGUS_Addr::ADJUST_Icon_Feedrate,
+ DGUS_Addr::ADJUST_Icon_FanControl,
+ DGUS_Addr::ADJUST_Icon_ZOffset,
+ DGUS_Addr::MAIN_ExtruderTargetTemp,
+ DGUS_Addr::MAIN_BedTargetTemp,
+ DGUS_Addr::MAIN_PrintSpeedPercentage,
+ DGUS_Addr::CONTROL_FanSpeed,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_ADJUST_ZOFFSET[] PROGMEM = {
+ DGUS_Addr::MAIN_ZOffset,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_AUTOHOME[] PROGMEM = {
+ DGUS_Addr::AUTOHOME_Icon_WaitMessage,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_ABNORMAL[] PROGMEM = {
+ DGUS_Addr::ABNORMAL_StatusMessage,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_SETTINGS[] PROGMEM = {
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings_S,
+ DGUS_Addr::SETTINGS_Icon_Language,
+ DGUS_Addr::SETTINGS_Icon_Leveling,
+ DGUS_Addr::SETTINGS_Icon_Device,
+ DGUS_Addr::SETTINGS_Icon_Advanced,
+ DGUS_Addr::SETTINGS_Icon_About,
+ DGUS_Addr::SETTINGS_Icon_PLA,
+ DGUS_Addr::SETTINGS_Icon_ABS,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_TEMPERATURE_PRESETS[] PROGMEM = {
+ DGUS_Addr::SETTINGS_Icon_PLA,
+ DGUS_Addr::SETTINGS_Icon_ABS,
+ DGUS_Addr::IO_Icon_ExtruderTemp,
+ DGUS_Addr::CONTROL_Icon_BedTemp,
+ DGUS_Addr::TEMP_PLA_ExtruderTemp,
+ DGUS_Addr::TEMP_PLA_BedTemp,
+ DGUS_Addr::TEMP_ABS_ExtruderTemp,
+ DGUS_Addr::TEMP_ABS_BedTemp,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_TRAMMING[] PROGMEM = {
+ DGUS_Addr::LEVELING_Icon_Leveling,
+ DGUS_Addr::LEVELING_Icon_AutoLevel,
+ DGUS_Addr::LEVELING_Icon_AuxLevel_S,
+ DGUS_Addr::MAIN_ZOffset,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_AUTOLEVEL[] PROGMEM = {
+ DGUS_Addr::LEVELING_Icon_Start,
+ DGUS_Addr::LEVELING_Icon_Leveling,
+ DGUS_Addr::LEVELING_Icon_AutoLevel_S,
+ DGUS_Addr::LEVELING_Icon_AuxLevel,
+ DGUS_Addr::LEVELING_Progress_Icon,
+ DGUS_Addr::LEVELING_Progress,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_POWERLOSS[] PROGMEM = {
+ DGUS_Addr::POWERLOSS_Icon_Message,
+ DGUS_Addr::LOAD_Icon_Continue,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_LANGUAGE[] PROGMEM = {
+ DGUS_Addr::LANGUAGE_Icon_Language,
+ DGUS_Addr::LANGUAGE_Icon_Chinese,
+ DGUS_Addr::LANGUAGE_Icon_English,
+ DGUS_Addr::LANGUAGE_Icon_German,
+ DGUS_Addr::LANGUAGE_Icon_Spanish,
+ DGUS_Addr::LANGUAGE_Icon_French,
+ DGUS_Addr::LANGUAGE_Icon_Italian,
+ DGUS_Addr::LANGUAGE_Icon_Portuguese,
+ DGUS_Addr::LANGUAGE_Icon_Russian,
+ DGUS_Addr::LANGUAGE_Icon_Turkish,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_INFO[] PROGMEM = {
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings_S,
+ DGUS_Addr::INFO_Icon_Device,
+ DGUS_Addr::SETTINGS_Icon_Advanced,
+ DGUS_Addr::INFO_Icon_About,
+ DGUS_Addr::INFO_Icon_Model,
+ DGUS_Addr::INFO_Icon_FW_Version,
+ DGUS_Addr::INFO_Icon_Screen_Version,
+ DGUS_Addr::INFO_Icon_HW_Version,
+ DGUS_Addr::INFO_Icon_Print_Size,
+ DGUS_Addr::INFO_Icon_Website,
+ DGUS_Addr::INFO_Model,
+ DGUS_Addr::INFO_FW_Version,
+ DGUS_Addr::INFO_Screen_Version,
+ DGUS_Addr::INFO_HW_Version,
+ DGUS_Addr::INFO_Print_Size,
+ DGUS_Addr::INFO_Website,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_ADV_SETTINGS[] PROGMEM = {
+ DGUS_Addr::MENU_Icon_Home,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready_S,
+ DGUS_Addr::MENU_Icon_Settings_S,
+ DGUS_Addr::SETTINGS_Icon_Device,
+ DGUS_Addr::SETTINGS_Icon_Advanced,
+ DGUS_Addr::INFO_Icon_About,
+ DGUS_Addr::ADV_Icon_Movement,
+ DGUS_Addr::ADV_Icon_ResetSettings,
+ DGUS_Addr::ADV_Icon_PID,
+ DGUS_Addr::ADV_Icon_SwitchToLaser,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_MOTION[] PROGMEM = {
+ DGUS_Addr::ADV_Icon_MotionSettings,
+ DGUS_Addr::ADV_Icon_MaxFeedrate,
+ DGUS_Addr::ADV_Icon_Acceleration,
+ DGUS_Addr::ADV_Icon_Jerk,
+ DGUS_Addr::ADV_Icon_StepsPerMm,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_MAX_FEEDRATE[] PROGMEM = {
+ DGUS_Addr::ADV_Icon_MaxSpeed,
+ DGUS_Addr::ADV_Icon_MaxSpeed_X,
+ DGUS_Addr::ADV_Icon_MaxSpeed_Y,
+ DGUS_Addr::ADV_Icon_MaxSpeed_Z,
+ DGUS_Addr::ADV_Icon_MaxSpeed_E,
+ DGUS_Addr::MOTION_MaxSpeed_X,
+ DGUS_Addr::MOTION_MaxSpeed_Y,
+ DGUS_Addr::MOTION_MaxSpeed_Z,
+ DGUS_Addr::MOTION_MaxSpeed_E,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_ACCELERATION[] PROGMEM = {
+ DGUS_Addr::ADV_Icon_AccelerationMenu,
+ DGUS_Addr::ADV_Icon_Acceleration_X,
+ DGUS_Addr::ADV_Icon_Acceleration_Y,
+ DGUS_Addr::ADV_Icon_Acceleration_Z,
+ DGUS_Addr::ADV_Icon_Acceleration_E,
+ DGUS_Addr::MOTION_Acceleration_X,
+ DGUS_Addr::MOTION_Acceleration_Y,
+ DGUS_Addr::MOTION_Acceleration_Z,
+ DGUS_Addr::MOTION_Acceleration_E,
+
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_JERK[] PROGMEM = {
+ DGUS_Addr::ADV_Icon_MaxJerkMenu,
+ DGUS_Addr::ADV_Icon_MaxJerk_X,
+ DGUS_Addr::ADV_Icon_MaxJerk_Y,
+ DGUS_Addr::ADV_Icon_MaxJerk_Z,
+ DGUS_Addr::ADV_Icon_MaxJerk_E,
+ DGUS_Addr::MOTION_MaxJerk_X,
+ DGUS_Addr::MOTION_MaxJerk_Y,
+ DGUS_Addr::MOTION_MaxJerk_Z,
+ DGUS_Addr::MOTION_MaxJerk_E,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_STEPSMM[] PROGMEM = {
+ DGUS_Addr::ADV_Icon_StepsPerMmMenu,
+ DGUS_Addr::ADV_Icon_StepsPerMm_X,
+ DGUS_Addr::ADV_Icon_StepsPerMm_Y,
+ DGUS_Addr::ADV_Icon_StepsPerMm_Z,
+ DGUS_Addr::ADV_Icon_StepsPerMm_E,
+ DGUS_Addr::MOTION_StepsPerMm_X,
+ DGUS_Addr::MOTION_StepsPerMm_Y,
+ DGUS_Addr::MOTION_StepsPerMm_Z,
+ DGUS_Addr::MOTION_StepsPerMm_E,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_PIDCONTROL[] PROGMEM = {
+ DGUS_Addr::PID_Icon_PIDMenu,
+ DGUS_Addr::PID_Icon_Extruder_P,
+ DGUS_Addr::PID_Icon_Extruder_I,
+ DGUS_Addr::PID_Icon_Extruder_D,
+ DGUS_Addr::PID_Icon_Bed_P,
+ DGUS_Addr::PID_Icon_Bed_I,
+ DGUS_Addr::PID_Icon_Bed_D,
+ DGUS_Addr::PID_Extruder_P,
+ DGUS_Addr::PID_Extruder_I,
+ DGUS_Addr::PID_Extruder_D,
+ DGUS_Addr::PID_Bed_P,
+ DGUS_Addr::PID_Bed_I,
+ DGUS_Addr::PID_Bed_D,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_RESET_CONFIRM[] PROGMEM = {
+ DGUS_Addr::RESET_Icon_InfoMessage,
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_FILAMENTCHECK[] PROGMEM = {
+ DGUS_Addr::FILAMENT_Icon_Inserted,
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_SDCARDCHECK[] PROGMEM = {
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::SDCard_InsertionStatus,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_PRINTMODE[] PROGMEM = {
+ DGUS_Addr::PRTMODE_Icon_Message,
+ DGUS_Addr::PRTMODE_Icon_FDM,
+ DGUS_Addr::PRTMODE_Icon_Cutter,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_PRINTMODE_CONFIRM[] PROGMEM = {
+ DGUS_Addr::CUTTER_Icon_Message,
+ DGUS_Addr::FDM_Icon_Message,
+ DGUS_Addr::RESET_Icon_Yes,
+ DGUS_Addr::RESET_Icon_No,
+ DGUS_Addr::END
+};
+
+constexpr DGUS_Addr LIST_SDCARD[] PROGMEM = {
+ DGUS_Addr::MENU_Icon_Home_S,
+ DGUS_Addr::MENU_Icon_Print_S,
+ DGUS_Addr::MENU_Icon_Ready,
+ DGUS_Addr::MENU_Icon_Settings,
+ DGUS_Addr::SDCARD_Filename1,
+ DGUS_Addr::SDCARD_Filename2,
+ DGUS_Addr::SDCARD_Filename3,
+ DGUS_Addr::SDCARD_Filename4,
+ DGUS_Addr::SDCARD_Filename5,
+ DGUS_Addr::SDCARD_Filename6,
+ DGUS_Addr::SDCARD_Filename7,
+ DGUS_Addr::SDCARD_Filename8,
+ DGUS_Addr::SDCARD_Filename9,
+ DGUS_Addr::SDCARD_Filename10,
+ DGUS_Addr::SDCARD_Filename11,
+ DGUS_Addr::SDCARD_Filename12,
+ DGUS_Addr::SDCARD_Filename13,
+ DGUS_Addr::SDCARD_Filename14,
+ DGUS_Addr::SDCARD_Filename15,
+ DGUS_Addr::SDCARD_Filename16,
+ DGUS_Addr::SDCARD_Filename17,
+ DGUS_Addr::SDCARD_Filename18,
+ DGUS_Addr::SDCARD_Filename19,
+ DGUS_Addr::SDCARD_Filename20,
+ DGUS_Addr::SDCARD_Selection_File1,
+ DGUS_Addr::SDCARD_Selection_File2,
+ DGUS_Addr::SDCARD_Selection_File3,
+ DGUS_Addr::SDCARD_Selection_File4,
+ DGUS_Addr::SDCARD_Selection_File5,
+ DGUS_Addr::SDCARD_Selection_File6,
+ DGUS_Addr::SDCARD_Selection_File7,
+ DGUS_Addr::SDCARD_Selection_File8,
+ DGUS_Addr::SDCARD_Selection_File9,
+ DGUS_Addr::SDCARD_Selection_File10,
+ DGUS_Addr::SDCARD_Selection_File11,
+ DGUS_Addr::SDCARD_Selection_File12,
+ DGUS_Addr::SDCARD_Selection_File13,
+ DGUS_Addr::SDCARD_Selection_File14,
+ DGUS_Addr::SDCARD_Selection_File15,
+ DGUS_Addr::SDCARD_Selection_File16,
+ DGUS_Addr::SDCARD_Selection_File17,
+ DGUS_Addr::SDCARD_Selection_File18,
+ DGUS_Addr::SDCARD_Selection_File19,
+ DGUS_Addr::SDCARD_Selection_File20,
+ DGUS_Addr::END
+};
+
+#define MAP_HELPER(SCREEN, LIST) \
+ { .screen = SCREEN, \
+ .addr_list = LIST }
+
+const struct DGUS_ScreenAddrList screen_addr_list_map[] PROGMEM = {
+ MAP_HELPER(DGUS_ScreenID::BOOT, LIST_BOOT),
+ MAP_HELPER(DGUS_ScreenID::HOME, LIST_HOME),
+ MAP_HELPER(DGUS_ScreenID::FILE1, LIST_SDCARD),
+ MAP_HELPER(DGUS_ScreenID::FILE2, LIST_SDCARD),
+ MAP_HELPER(DGUS_ScreenID::FILE3, LIST_SDCARD),
+ MAP_HELPER(DGUS_ScreenID::FILE4, LIST_SDCARD),
+ MAP_HELPER(DGUS_ScreenID::FILAMENTUSEUP, LIST_RUNOUT),
+ MAP_HELPER(DGUS_ScreenID::FILAMENTLOAD, LIST_FILAMENTLOAD),
+ MAP_HELPER(DGUS_ScreenID::FINISH, LIST_PRINTING),
+ MAP_HELPER(DGUS_ScreenID::PAUSE, LIST_PRINTING),
+ MAP_HELPER(DGUS_ScreenID::PAUSE_STOP, LIST_PAUSE_STOP),
+ MAP_HELPER(DGUS_ScreenID::RESUME, LIST_PRINTING),
+ MAP_HELPER(DGUS_ScreenID::CONTINUE_STOP, LIST_CONTINUE_STOP),
+ MAP_HELPER(DGUS_ScreenID::ADJUST, LIST_ADJUST),
+ MAP_HELPER(DGUS_ScreenID::PREPARE, LIST_ADJUST_ZOFFSET),
+ MAP_HELPER(DGUS_ScreenID::MOVEAXIS_01, LIST_MOVEAXIS),
+ MAP_HELPER(DGUS_ScreenID::MOVEAXIS_1, LIST_MOVEAXIS),
+ MAP_HELPER(DGUS_ScreenID::MOVEAXIS_10, LIST_MOVEAXIS),
+ MAP_HELPER(DGUS_ScreenID::FEEDRETURN, LIST_IO),
+ MAP_HELPER(DGUS_ScreenID::CONTROL, LIST_CONTROL),
+ MAP_HELPER(DGUS_ScreenID::TEMP, LIST_SETTINGS),
+ MAP_HELPER(DGUS_ScreenID::PLA_TEMP, LIST_TEMPERATURE_PRESETS),
+ MAP_HELPER(DGUS_ScreenID::ABS_TEMP, LIST_TEMPERATURE_PRESETS),
+ MAP_HELPER(DGUS_ScreenID::AUTOHOME, LIST_AUTOHOME),
+ MAP_HELPER(DGUS_ScreenID::ABNORMAL, LIST_ABNORMAL),
+ MAP_HELPER(DGUS_ScreenID::LEVELINGMODE, LIST_TRAMMING),
+ MAP_HELPER(DGUS_ScreenID::LEVELING, LIST_AUTOLEVEL),
+ MAP_HELPER(DGUS_ScreenID::POWERCONTINUE, LIST_POWERLOSS),
+ MAP_HELPER(DGUS_ScreenID::LANGUAGE, LIST_LANGUAGE),
+ MAP_HELPER(DGUS_ScreenID::INFORMATION, LIST_INFO),
+ MAP_HELPER(DGUS_ScreenID::CONTROL_DEVICE, LIST_ADV_SETTINGS),
+ MAP_HELPER(DGUS_ScreenID::MOTION, LIST_MOTION),
+ MAP_HELPER(DGUS_ScreenID::MAX_FEEDRATE, LIST_MAX_FEEDRATE),
+ MAP_HELPER(DGUS_ScreenID::ACCELERATION, LIST_ACCELERATION),
+ MAP_HELPER(DGUS_ScreenID::JERK, LIST_JERK),
+ MAP_HELPER(DGUS_ScreenID::STEPSMM, LIST_STEPSMM),
+ MAP_HELPER(DGUS_ScreenID::PIDCONTROL, LIST_PIDCONTROL),
+ MAP_HELPER(DGUS_ScreenID::FACTORYRESET_CONFIRM, LIST_RESET_CONFIRM),
+ MAP_HELPER(DGUS_ScreenID::FILAMENTCHECK, LIST_FILAMENTCHECK),
+ MAP_HELPER(DGUS_ScreenID::SDCARDCHECK, LIST_SDCARDCHECK),
+ MAP_HELPER(DGUS_ScreenID::LASER_FDM, LIST_PRINTMODE),
+ MAP_HELPER(DGUS_ScreenID::SW_LASER_TIPS, LIST_PRINTMODE_CONFIRM),
+ MAP_HELPER(DGUS_ScreenID::SW_FDM_TIPS, LIST_PRINTMODE_CONFIRM),
+
+ MAP_HELPER((DGUS_ScreenID)0, nullptr)
+};
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.h b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.h
new file mode 100644
index 0000000000..b20bab1336
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenAddrList.h
@@ -0,0 +1,32 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../config/DGUS_Screen.h"
+#include "../config/DGUS_Addr.h"
+
+struct DGUS_ScreenAddrList {
+ DGUS_ScreenID screen;
+ const DGUS_Addr *addr_list;
+};
+
+extern const struct DGUS_ScreenAddrList screen_addr_list_map[];
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.cpp
new file mode 100644
index 0000000000..3e4d191c8d
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.cpp
@@ -0,0 +1,44 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUS_ScreenSetup.h"
+#include "../DGUSSetupHandler.h"
+
+#include "../../ui_api.h"
+
+#define SETUP_HELPER(SCREEN, SETUP) \
+ { .screen = SCREEN, \
+ .setup_fn = SETUP }
+
+const struct DGUS_ScreenSetup screen_setup_list[] PROGMEM = {
+ SETUP_HELPER(DGUS_ScreenID::FILE1, &DGUSSetupHandler::sdCardPrepare),
+ SETUP_HELPER(DGUS_ScreenID::FILE2, &DGUSSetupHandler::sdCardPrepare),
+ SETUP_HELPER(DGUS_ScreenID::FILE3, &DGUSSetupHandler::sdCardPrepare),
+ SETUP_HELPER(DGUS_ScreenID::FILE4, &DGUSSetupHandler::sdCardPrepare),
+ SETUP_HELPER((DGUS_ScreenID)0, nullptr)
+};
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.h b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.h
new file mode 100644
index 0000000000..4321413fd1
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_ScreenSetup.h
@@ -0,0 +1,31 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../config/DGUS_Screen.h"
+
+struct DGUS_ScreenSetup {
+ DGUS_ScreenID screen;
+ bool (*setup_fn)(void);
+};
+
+extern const struct DGUS_ScreenSetup screen_setup_list[];
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VP.h b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VP.h
new file mode 100644
index 0000000000..60eb9cfae2
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VP.h
@@ -0,0 +1,43 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "../config/DGUS_Addr.h"
+
+#define VPFLAG_NONE 0
+#define VPFLAG_AUTOUPLOAD (1U << 0) // Upload on every DGUS update
+#define VPFLAG_RXSTRING (1U << 1) // Treat the received data as a string (terminated with 0xFFFF)
+#define VPFLAG_TXSTRING_AUTOSCROLL (1U << 2)
+
+#define VP_U16_FROM_EXTRA(N) (*(uint16_t*)N)
+
+struct DGUS_VP {
+ DGUS_Addr addr;
+ uint8_t size;
+ uint8_t flags;
+ void *extra;
+
+ // Callback that will be called if the display modified the value.
+ // nullptr makes it readonly for the display.
+ void (*rx_handler)(DGUS_VP &, void *);
+ void (*tx_handler)(DGUS_VP &);
+};
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.cpp
new file mode 100644
index 0000000000..dddc6f889e
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.cpp
@@ -0,0 +1,589 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "DGUS_VPList.h"
+
+#include "../config/DGUS_Addr.h"
+#include "../DGUSScreenHandler.h"
+#include "../DGUSReturnKeyCodeHandler.h"
+#include "../DGUSRxHandler.h"
+#include "../DGUSTxHandler.h"
+
+#include "../../ui_api.h"
+
+const char DGUS_MACHINENAME[] PROGMEM = MACHINE_NAME;
+const char DGUS_MARLINVERSION[] PROGMEM = SHORT_BUILD_VERSION;
+const char DGUS_BOARD[] PROGMEM = BOARD_INFO_NAME;
+const char DGUS_BEDSIZE[] PROGMEM = DGUS_BED_SIZE_STR;
+const char DGUS_WEBSITE[] PROGMEM = "http://marlinfw.org";
+const uint16_t DGUS_ZERO = 0;
+
+#define VP_HELPER(ADDR, SIZE, FLAGS, EXTRA, RXHANDLER, TXHANDLER) \
+ { .addr = ADDR, \
+ .size = SIZE, \
+ .flags = FLAGS, \
+ .extra = EXTRA, \
+ .rx_handler = RXHANDLER, \
+ .tx_handler = TXHANDLER }
+
+#define VP_HELPER_WORD(ADDR, FLAGS, EXTRA, RXHANDLER, TXHANDLER) \
+ VP_HELPER(ADDR, 2, FLAGS, EXTRA, RXHANDLER, TXHANDLER)
+
+#define VP_HELPER_DWORD(ADDR, FLAGS, EXTRA, RXHANDLER, TXHANDLER) \
+ VP_HELPER(ADDR, 4, FLAGS, EXTRA, RXHANDLER, TXHANDLER)
+
+#define VP_HELPER_RX(ADDR, RXHANDLER) \
+ VP_HELPER_WORD(ADDR, VPFLAG_NONE, nullptr, RXHANDLER, nullptr)
+
+#define VP_HELPER_RX_EXTRA(ADDR, EXTRA, RXHANDLER) \
+ VP_HELPER_WORD(ADDR, VPFLAG_NONE, EXTRA, RXHANDLER, nullptr)
+
+#define VP_HELPER_RX_NODATA(ADDR, RXHANDLER) \
+ VP_HELPER(ADDR, 0, VPFLAG_NONE, nullptr, RXHANDLER, nullptr)
+
+#define VP_HELPER_TX(ADDR, TXHANDLER) \
+ VP_HELPER_WORD(ADDR, VPFLAG_NONE, nullptr, nullptr, TXHANDLER)
+
+#define VP_HELPER_TX_SIZE(ADDR, SIZE, TXHANDLER) \
+ VP_HELPER(ADDR, SIZE, VPFLAG_NONE, nullptr, nullptr, TXHANDLER)
+
+#define VP_HELPER_TX_EXTRA(ADDR, EXTRA, TXHANDLER) \
+ VP_HELPER_WORD(ADDR, VPFLAG_NONE, EXTRA, nullptr, TXHANDLER)
+
+#define VP_HELPER_TX_AUTO(ADDR, EXTRA, TXHANDLER) \
+ VP_HELPER_WORD(ADDR, VPFLAG_AUTOUPLOAD, EXTRA, nullptr, TXHANDLER)
+
+#define VP_HELPER_LANG_ICON(ADDR) \
+ VP_HELPER_TX_EXTRA(ADDR, &screen.config.language, (&DGUSTxHandler::extraToInteger))
+
+#define VP_HELPER_FILENAME(ADDR, filenameIndex) \
+ VP_HELPER(ADDR, DGUS_FILENAME_LEN, VPFLAG_TXSTRING_AUTOSCROLL, \
+ VP_EXTRA_TO_STR(DGUS_SDCardHandler::filenames[filenameIndex]), \
+ nullptr, DGUSTxHandler::extraToString)
+
+const struct DGUS_VP vp_list[] PROGMEM = {
+ VP_HELPER_TX_AUTO( DGUS_Addr::BOOT_Logo,
+ nullptr,
+ &DGUSTxHandler::bootAnimation),
+ VP_HELPER_RX( DGUS_Addr::CMD_MenuSelect,
+ &DGUSReturnKeyCodeHandler::Command_MenuSelect),
+ VP_HELPER_RX( DGUS_Addr::CMD_Adjust,
+ &DGUSReturnKeyCodeHandler::Command_Adjust),
+ VP_HELPER_WORD( DGUS_Addr::MAIN_PrintSpeedPercentage,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::printSpeedPercentage,
+ &DGUSTxHandler::printSpeedPercentage),
+ VP_HELPER_RX( DGUS_Addr::CMD_CheckKO,
+ &DGUSReturnKeyCodeHandler::Command_CheckKO),
+ VP_HELPER_RX( DGUS_Addr::CMD_StopPause,
+ &DGUSReturnKeyCodeHandler::Command_StopPause),
+ VP_HELPER_RX( DGUS_Addr::CMD_CheckOK,
+ &DGUSReturnKeyCodeHandler::Command_CheckOK),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_Icon_Percentage, nullptr,
+ &DGUSTxHandler::printPercentage),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_ElapsedHours,
+ nullptr,
+ &DGUSTxHandler::elapsedHours),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_ElapsedMinutes,
+ nullptr,
+ &DGUSTxHandler::elapsedMinutes),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_PrintPercentage,
+ nullptr,
+ &DGUSTxHandler::printPercentage),
+ VP_HELPER_WORD( DGUS_Addr::MAIN_ZOffset,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::zOffset,
+ &DGUSTxHandler::zOffset),
+ VP_HELPER_RX( DGUS_Addr::CMD_PresetControl,
+ &DGUSReturnKeyCodeHandler::Command_PresetControl),
+ VP_HELPER_RX( DGUS_Addr::CMD_TemperatureControl,
+ &DGUSReturnKeyCodeHandler::Control_TemperatureCommand),
+ VP_HELPER_WORD( DGUS_Addr::MAIN_ExtruderTargetTemp,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::extruderTargetTemp,
+ &DGUSTxHandler::extruderTargetTemp),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_ExtruderCurrentTemp,
+ nullptr,
+ &DGUSTxHandler::extruderCurrentTemp),
+ VP_HELPER_WORD( DGUS_Addr::MAIN_BedTargetTemp,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::bedTargetTemp,
+ &DGUSTxHandler::bedTargetTemp),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_BedCurrentTemp,
+ nullptr,
+ &DGUSTxHandler::bedCurrentTemp),
+ VP_HELPER_RX( DGUS_Addr::CMD_SettingsMenu,
+ &DGUSReturnKeyCodeHandler::Command_SettingsMenu),
+ VP_HELPER_RX( DGUS_Addr::CMD_Leveling,
+ &DGUSReturnKeyCodeHandler::Command_Leveling),
+ VP_HELPER_RX( DGUS_Addr::CMD_AxisControl,
+ &DGUSReturnKeyCodeHandler::Command_AxisControl),
+ VP_HELPER_WORD( DGUS_Addr::AXIS_X,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::axis_X,
+ &DGUSTxHandler::axis_X),
+ VP_HELPER_WORD( DGUS_Addr::AXIS_Y,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::axis_Y,
+ &DGUSTxHandler::axis_Y),
+ VP_HELPER_WORD( DGUS_Addr::AXIS_Z,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::axis_Z,
+ &DGUSTxHandler::axis_Z),
+ VP_HELPER_RX( DGUS_Addr::IO_ExtrudeLength,
+ &DGUSRxHandler::extrudeLength),
+ VP_HELPER_RX( DGUS_Addr::IO_RetractLength,
+ &DGUSRxHandler::retractLength),
+ VP_HELPER_RX( DGUS_Addr::CMD_AxisIO,
+ &DGUSReturnKeyCodeHandler::Command_FilamentIO),
+ VP_HELPER_RX( DGUS_Addr::LANGUAGE_SetLanguage,
+ &DGUSRxHandler::setLanguage),
+ VP_HELPER_RX( DGUS_Addr::CMD_PowerLoss,
+ &DGUSReturnKeyCodeHandler::Command_PowerLoss),
+ VP_HELPER_TX( DGUS_Addr::LEVELING_Progress_Icon,
+ &DGUSTxHandler::levelingProgressIcon),
+ #if HAS_FILAMENT_SENSOR
+ VP_HELPER_TX_AUTO( DGUS_Addr::FILAMENT_Icon_Inserted,
+ nullptr,
+ &DGUSTxHandler::filamentInsertionStatus),
+ #endif
+ VP_HELPER_WORD( DGUS_Addr::TEMP_PLA_ExtruderTemp,
+ VPFLAG_NONE,
+ &screen.config.plaExtruderTemp,
+ &DGUSRxHandler::integerToExtra,
+ &DGUSTxHandler::extraToInteger),
+ VP_HELPER_WORD( DGUS_Addr::TEMP_PLA_BedTemp,
+ VPFLAG_NONE,
+ &screen.config.plaBedTemp,
+ &DGUSRxHandler::integerToExtra,
+ &DGUSTxHandler::extraToInteger),
+ VP_HELPER_WORD( DGUS_Addr::TEMP_ABS_ExtruderTemp,
+ VPFLAG_NONE,
+ &screen.config.absExtruderTemp,
+ &DGUSRxHandler::integerToExtra,
+ &DGUSTxHandler::extraToInteger),
+ VP_HELPER_WORD( DGUS_Addr::TEMP_ABS_BedTemp,
+ VPFLAG_NONE,
+ &screen.config.absBedTemp,
+ &DGUSRxHandler::integerToExtra,
+ &DGUSTxHandler::extraToInteger),
+ VP_HELPER_RX( DGUS_Addr::CMD_AdvancedSettings,
+ &DGUSReturnKeyCodeHandler::Command_AdvancedSettings),
+ VP_HELPER_TX( DGUS_Addr::LEVELING_Progress,
+ &DGUSTxHandler::levelingProgress),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxSpeed_X,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxFeedrate),
+ (&DGUSTxHandler::maxFeedrate)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxSpeed_Y,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxFeedrate),
+ (&DGUSTxHandler::maxFeedrate)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxSpeed_Z,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxFeedrate),
+ (&DGUSTxHandler::maxFeedrate)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxSpeed_E,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxFeedrate),
+ (&DGUSTxHandler::maxFeedrate)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_Acceleration_X,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxAcceleration),
+ (&DGUSTxHandler::maxAcceleration)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_Acceleration_Y,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxAcceleration),
+ (&DGUSTxHandler::maxAcceleration)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_Acceleration_Z,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxAcceleration),
+ (&DGUSTxHandler::maxAcceleration)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_Acceleration_E,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxAcceleration),
+ (&DGUSTxHandler::maxAcceleration)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxJerk_X,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxJerk),
+ (&DGUSTxHandler::maxJerk)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxJerk_Y,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxJerk),
+ (&DGUSTxHandler::maxJerk)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxJerk_Z,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxJerk),
+ (&DGUSTxHandler::maxJerk)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_MaxJerk_E,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::maxJerk),
+ (&DGUSTxHandler::maxJerk)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_StepsPerMm_X,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::stepsPerMM),
+ (&DGUSTxHandler::stepsPerMM)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_StepsPerMm_Y,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::stepsPerMM),
+ (&DGUSTxHandler::stepsPerMM)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_StepsPerMm_Z,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::stepsPerMM),
+ (&DGUSTxHandler::stepsPerMM)),
+ VP_HELPER_WORD( DGUS_Addr::MOTION_StepsPerMm_E,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::stepsPerMM),
+ (&DGUSTxHandler::stepsPerMM)),
+ #if ENABLED(PIDTEMP)
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_P,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::PID_P),
+ (&DGUSTxHandler::PID_P)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_I,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::PID_I),
+ (&DGUSTxHandler::PID_I)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_D,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::PID_D),
+ (&DGUSTxHandler::PID_D)),
+ #else
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_P,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_I,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Extruder_D,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ #endif // PIDTEMP
+ #if ENABLED(PIDTEMPBED)
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_P,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::bed_PID_P),
+ (&DGUSTxHandler::bed_PID_P)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_I,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::bed_PID_I),
+ (&DGUSTxHandler::bed_PID_I)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_D,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ (&DGUSRxHandler::bed_PID_D),
+ (&DGUSTxHandler::bed_PID_D)),
+ #else
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_P,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_I,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ VP_HELPER_WORD( DGUS_Addr::PID_Bed_D,
+ VPFLAG_AUTOUPLOAD,
+ const_cast(&DGUS_ZERO),
+ DGUSRxHandler::disabled,
+ (DGUSTxHandler::extraToFixedPoint)),
+ #endif // PIDTEMPBED
+ VP_HELPER_WORD( DGUS_Addr::CONTROL_FanSpeed,
+ VPFLAG_AUTOUPLOAD,
+ nullptr,
+ &DGUSRxHandler::fanSpeed,
+ &DGUSTxHandler::fanSpeed),
+ VP_HELPER_TX( DGUS_Addr::SDCard_InsertionStatus,
+ DGUSTxHandler::sdCardInsertionStatus),
+ VP_HELPER_LANG_ICON(DGUS_Addr::FINISH_Icon_Finished),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_RemainingHours,
+ nullptr,
+ &DGUSTxHandler::printRemainingHours),
+ VP_HELPER_TX_AUTO( DGUS_Addr::MAIN_RemainingMinutes,
+ nullptr,
+ &DGUSTxHandler::printRemainingMinutes),
+ VP_HELPER_TX_AUTO( DGUS_Addr::AXIS_StepperStatus,
+ nullptr,
+ &DGUSTxHandler::stepperStatus),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Home_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Print_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Ready_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Settings_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Home),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Print),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Ready),
+ VP_HELPER_LANG_ICON(DGUS_Addr::MENU_Icon_Settings),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADJUST_Icon_Adjust),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADJUST_Icon_Feedrate),
+ VP_HELPER_LANG_ICON(DGUS_Addr::IO_Icon_ExtruderTemp),
+ VP_HELPER_LANG_ICON(DGUS_Addr::CONTROL_Icon_BedTemp),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADJUST_Icon_ZOffset),
+ VP_HELPER_LANG_ICON(DGUS_Addr::CONTROL_Icon_FanControl),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADJUST_Icon_FanControl),
+ VP_HELPER_LANG_ICON(DGUS_Addr::AXIS_Icon_MoveAxis),
+ VP_HELPER_LANG_ICON(DGUS_Addr::AXIS_Icon_IO),
+ VP_HELPER_LANG_ICON(DGUS_Addr::AXIS_Icon_Manual),
+ VP_HELPER_LANG_ICON(DGUS_Addr::CONTROL_Icon_Cooling),
+ VP_HELPER_LANG_ICON(DGUS_Addr::IO_Icon_Extrude),
+ VP_HELPER_LANG_ICON(DGUS_Addr::IO_Icon_Retract),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_Language),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_Leveling),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_Device),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_ResetSettings),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_About),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_Device),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_Advanced),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_About),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_PLA),
+ VP_HELPER_LANG_ICON(DGUS_Addr::SETTINGS_Icon_ABS),
+ VP_HELPER_LANG_ICON(DGUS_Addr::RUNOUT_Icon_Stop),
+ VP_HELPER_LANG_ICON(DGUS_Addr::RUNOUT_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::RESET_Icon_Yes),
+ VP_HELPER_LANG_ICON(DGUS_Addr::RESET_Icon_No),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LOAD_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LOAD_Icon_Continue),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PAUSE_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::RESUME_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::POWERLOSS_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::AUTOHOME_Icon_WaitMessage),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_Leveling),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_Start),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_AuxLevel),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_AutoLevel),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_AuxLevel_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LEVELING_Icon_AutoLevel_S),
+ VP_HELPER_LANG_ICON(DGUS_Addr::LANGUAGE_Icon_Language),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Movement),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_PID),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MotionSettings),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxFeedrate),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Acceleration),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Jerk),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMm),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxSpeed),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxSpeed_X),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxSpeed_Y),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxSpeed_Z),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxSpeed_E),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_AccelerationMenu),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Acceleration_X),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Acceleration_Y),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Acceleration_Z),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_Acceleration_E),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxJerkMenu),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxJerk_X),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxJerk_Y),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxJerk_Z),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_MaxJerk_E),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMmMenu),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMm_X),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMm_Y),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMm_Z),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_StepsPerMm_E),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_PIDMenu),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Extruder_P),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Extruder_I),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Extruder_D),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Bed_P),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Bed_I),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PID_Icon_Bed_D),
+ VP_HELPER_LANG_ICON(DGUS_Addr::CUTTER_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::FDM_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::ADV_Icon_SwitchToLaser),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PRTMODE_Icon_Message),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PRTMODE_Icon_FDM),
+ VP_HELPER_LANG_ICON(DGUS_Addr::PRTMODE_Icon_Cutter),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_Model),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_FW_Version),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_Screen_Version),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_HW_Version),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_Website),
+ VP_HELPER_LANG_ICON(DGUS_Addr::INFO_Icon_Print_Size),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Chinese,
+ (void*)DGUS_Data::Language::Chinese_Simplified,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_English,
+ (void*)DGUS_Data::Language::English,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_German,
+ (void*)DGUS_Data::Language::German,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Spanish,
+ (void*)DGUS_Data::Language::Spanish,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_French,
+ (void*)DGUS_Data::Language::French,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Italian,
+ (void*)DGUS_Data::Language::Italian,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Portuguese,
+ (void*)DGUS_Data::Language::Portuguese,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Russian,
+ (void*)DGUS_Data::Language::Russian,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+ VP_HELPER_TX_AUTO( DGUS_Addr::LANGUAGE_Icon_Turkish,
+ (void*)DGUS_Data::Language::Turkish,
+ &DGUSTxHandler::enableIfLanguageMatchesExtra),
+
+ VP_HELPER( DGUS_Addr::INFO_Model,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(DGUS_MACHINENAME),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER( DGUS_Addr::INFO_FW_Version,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(DGUS_MARLINVERSION),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ //already set in the screen memory:
+ /*
+ VP_HELPER(DGUS_Addr::INFO_Screen_Version,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_NONE,
+ (void*)"",
+ nullptr,
+ DGUSTxHandler::extraToString),
+ */
+ VP_HELPER( DGUS_Addr::INFO_HW_Version,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(DGUS_BOARD),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER( DGUS_Addr::INFO_Print_Size,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(DGUS_BEDSIZE),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER( DGUS_Addr::INFO_Website,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(DGUS_WEBSITE),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename1,
+ 0),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename2,
+ 1),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename3,
+ 2),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename4,
+ 3),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename5,
+ 4),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename6,
+ 0),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename7,
+ 1),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename8,
+ 2),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename9,
+ 3),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename10,
+ 4),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename11,
+ 0),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename12,
+ 1),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename13,
+ 2),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename14,
+ 3),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename15,
+ 4),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename16,
+ 0),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename17,
+ 1),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename18,
+ 2),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename19,
+ 3),
+ VP_HELPER_FILENAME( DGUS_Addr::SDCARD_Filename20,
+ 4),
+ VP_HELPER_RX( DGUS_Addr::CMD_FilelistControl,
+ &DGUSReturnKeyCodeHandler::Command_FilelistControl),
+ VP_HELPER_RX( DGUS_Addr::SDCARD_FileSelection,
+ &DGUSRxHandler::sdCardFileSection),
+ VP_HELPER( DGUS_Addr::MAIN_StatusMessage,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(screen.homeStatusMessage),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER( DGUS_Addr::ABNORMAL_StatusMessage,
+ DGUS_INFOSTRING_LEN,
+ VPFLAG_TXSTRING_AUTOSCROLL,
+ VP_EXTRA_TO_STR(screen.homeStatusMessage),
+ nullptr,
+ DGUSTxHandler::extraToString),
+ VP_HELPER_RX( DGUS_Addr::CMD_LaserControl,
+ &DGUSReturnKeyCodeHandler::Command_LaserControl),
+ VP_HELPER((DGUS_Addr)0, 0, VPFLAG_NONE, nullptr, nullptr, nullptr)
+};
+
+#endif // DGUS_LCD_UI_E3S1PRO
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.h b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.h
new file mode 100644
index 0000000000..8ca16e924e
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/definition/DGUS_VPList.h
@@ -0,0 +1,31 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+#include "DGUS_VP.h"
+
+#define VP_EXTRA_TO_U16(N) (void*)(uint16_t)(N)
+#define VP_U16_FROM_EXTRA(N) (*(uint16_t*)N)
+
+#define VP_EXTRA_TO_STR(N) (void*)(N)
+
+extern const struct DGUS_VP vp_list[];
diff --git a/Marlin/src/lcd/extui/dgus_e3s1pro/dgus_e3s1pro_extui.cpp b/Marlin/src/lcd/extui/dgus_e3s1pro/dgus_e3s1pro_extui.cpp
new file mode 100644
index 0000000000..530ce9bcf0
--- /dev/null
+++ b/Marlin/src/lcd/extui/dgus_e3s1pro/dgus_e3s1pro_extui.cpp
@@ -0,0 +1,165 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp
+ */
+
+#include "../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(DGUS_LCD_UI_E3S1PRO)
+
+#include "../ui_api.h"
+#include "DGUSScreenHandler.h"
+
+#define DEBUG_OUT 1
+#include "../../../core/debug_out.h"
+
+namespace ExtUI {
+
+ void onStartup() {
+ screen.init();
+ }
+
+ void onIdle() {
+ static bool processing = false;
+
+ // Prevent recursion
+ if (!processing) {
+ processing = true;
+ screen.loop();
+ processing = false;
+ }
+ }
+
+ void onPrinterKilled(FSTR_P const error, FSTR_P const component) {
+ screen.printerKilled(error, component);
+ }
+
+ void onMediaInserted() { TERN_(HAS_MEDIA, screen.sdCardInserted()); }
+ void onMediaError() { TERN_(HAS_MEDIA, screen.sdCardError()); }
+ void onMediaRemoved() { TERN_(HAS_MEDIA, screen.sdCardRemoved()); }
+
+ void onPlayTone(const uint16_t frequency, const uint16_t duration) {
+ screen.playTone(frequency, duration);
+ }
+
+ void onPrintTimerStarted() {
+ screen.printTimerStarted();
+ }
+
+ void onPrintTimerPaused() {
+ screen.printTimerPaused();
+ }
+
+ void onPrintTimerStopped() {
+ screen.printTimerStopped();
+ }
+
+ void onFilamentRunout(const extruder_t extruder) {
+ screen.filamentRunout(extruder);
+ }
+
+ void onUserConfirmRequired(const char * const msg) {
+ screen.userConfirmRequired(msg);
+ }
+
+ void onStatusChanged(const char * const msg) {
+ screen.setStatusMessage(msg);
+ }
+
+ void onHomingStart() {}
+
+ void onHomingDone() {
+ screen.homingDone();
+ }
+
+ void onPrintDone() {}
+
+ void onFactoryReset() {
+ screen.settingsReset();
+ }
+
+ void onStoreSettings(char *buff) {
+ screen.storeSettings(buff);
+ }
+
+ void onLoadSettings(const char *buff) {
+ screen.loadSettings(buff);
+ }
+
+ void onPostprocessSettings() {}
+
+ void onSettingsStored(const bool success) {
+ screen.configurationStoreWritten(success);
+ }
+
+ void onSettingsLoaded(const bool success) {
+ screen.configurationStoreRead(success);
+ }
+
+ #if HAS_MESH
+ void onLevelingStart() {
+ screen.levelingStart();
+ }
+
+ void onLevelingDone() {
+ screen.levelingEnd();
+ }
+
+ void onMeshUpdate(const int8_t xpos, const int8_t ypos, const_float_t zval) {
+ screen.meshUpdate(xpos, ypos);
+ }
+
+ void onMeshUpdate(const int8_t xpos, const int8_t ypos, const probe_state_t state) { }
+ #endif
+
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ void onSetPowerLoss(const bool onoff) {
+ // Called when power-loss is enabled/disabled
+ }
+ void onPowerLoss() {
+ // Called when power-loss state is detected
+ }
+ void onPowerLossResume() {
+ // Called on resume from power-loss
+ screen.powerLossResume();
+ }
+ #endif
+
+ #if HAS_PID_HEATING
+ void onPidTuning(const result_t rst) {
+ // Called for temperature PID tuning result
+ screen.pidTuning(rst);
+ }
+ #endif
+
+ void onSteppersDisabled() {
+ screen.steppersStatusChanged(false);
+ }
+
+ void onSteppersEnabled() {
+ screen.steppersStatusChanged(true);
+ }
+}
+
+#endif // DGUS_LCD_UI_RELOADED
diff --git a/Marlin/src/lcd/extui/dgus_reloaded/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus_reloaded/DGUSScreenHandler.cpp
index 793a2c1579..76aa3de872 100644
--- a/Marlin/src/lcd/extui/dgus_reloaded/DGUSScreenHandler.cpp
+++ b/Marlin/src/lcd/extui/dgus_reloaded/DGUSScreenHandler.cpp
@@ -80,9 +80,8 @@ void DGUSScreenHandler::ready() {
}
void DGUSScreenHandler::loop() {
- if (!settings_ready || current_screenID == DGUS_ScreenID::KILL) {
+ if (!settings_ready || current_screenID == DGUS_ScreenID::KILL)
return;
- }
const millis_t ms = ExtUI::safe_millis();
static millis_t next_event_ms = 0;
@@ -226,10 +225,8 @@ void DGUSScreenHandler::configurationStoreRead(bool success) {
}
void DGUSScreenHandler::playTone(const uint16_t frequency, const uint16_t duration) {
- UNUSED(duration);
-
- if (frequency >= 1 && frequency <= 255) {
- if (duration >= 1 && duration <= 255)
+ if (WITHIN(frequency, 1, 255)) {
+ if (WITHIN(duration, 1, 255))
dgus.playSound((uint8_t)frequency, (uint8_t)duration);
else
dgus.playSound((uint8_t)frequency);
@@ -301,12 +298,10 @@ void DGUSScreenHandler::filamentRunout(const ExtUI::extruder_t extruder) {
#endif // HAS_MEDIA
#if ENABLED(POWER_LOSS_RECOVERY)
-
void DGUSScreenHandler::powerLossResume() {
moveToScreen(DGUS_ScreenID::POWERLOSS, true);
}
-
-#endif // POWER_LOSS_RECOVERY
+#endif
#if HAS_PID_HEATING
@@ -374,20 +369,18 @@ void DGUSScreenHandler::setMessageLinePGM(PGM_P const msg, const uint8_t line) {
void DGUSScreenHandler::setStatusMessage(const char* msg, const millis_t duration) {
dgus.writeString((uint16_t)DGUS_Addr::MESSAGE_Status, msg, DGUS_STATUS_LEN, false, true);
-
status_expire = (duration > 0 ? ExtUI::safe_millis() + duration : 0);
}
void DGUSScreenHandler::setStatusMessage(FSTR_P const fmsg, const millis_t duration) {
dgus.writeString((uint16_t)DGUS_Addr::MESSAGE_Status, fmsg, DGUS_STATUS_LEN, false, true);
-
status_expire = (duration > 0 ? ExtUI::safe_millis() + duration : 0);
}
void DGUSScreenHandler::showWaitScreen(const DGUS_ScreenID return_screenID, const bool has_continue/*=false*/) {
- if (return_screenID != DGUS_ScreenID::WAIT) {
+ if (return_screenID != DGUS_ScreenID::WAIT)
wait_return_screenID = return_screenID;
- }
+
wait_continue = has_continue;
triggerScreenChange(DGUS_ScreenID::WAIT);
@@ -418,8 +411,7 @@ void DGUSScreenHandler::triggerEEPROMSave() {
}
bool DGUSScreenHandler::isPrinterIdle() {
- return (!ExtUI::commandsInQueue()
- && !ExtUI::isMoving());
+ return (!ExtUI::commandsInQueue() && !ExtUI::isMoving());
}
const DGUS_Addr* DGUSScreenHandler::findScreenAddrList(const DGUS_ScreenID screenID) {
@@ -429,9 +421,7 @@ const DGUS_Addr* DGUSScreenHandler::findScreenAddrList(const DGUS_ScreenID scree
do {
memcpy_P(&list, map, sizeof(*map));
if (!list.addr_list) break;
- if (list.screenID == screenID) {
- return list.addr_list;
- }
+ if (list.screenID == screenID) return list.addr_list;
} while (++map);
return nullptr;
@@ -453,20 +443,16 @@ bool DGUSScreenHandler::callScreenSetup(const DGUS_ScreenID screenID) {
}
void DGUSScreenHandler::moveToScreen(const DGUS_ScreenID screenID, bool abort_wait) {
- if (current_screenID == DGUS_ScreenID::KILL) {
- return;
- }
+ if (current_screenID == DGUS_ScreenID::KILL) return;
if (current_screenID == DGUS_ScreenID::WAIT) {
- if (screenID != DGUS_ScreenID::WAIT) {
+ if (screenID != DGUS_ScreenID::WAIT)
wait_return_screenID = screenID;
- }
if (!abort_wait) return;
- if (wait_continue && wait_for_user) {
+ if (wait_continue && wait_for_user)
ExtUI::setUserConfirmed();
- }
}
if (!callScreenSetup(screenID)) return;
diff --git a/Marlin/src/lcd/extui/dgus_reloaded/config/DGUS_Addr.h b/Marlin/src/lcd/extui/dgus_reloaded/config/DGUS_Addr.h
index 8cec8e59c9..ec4962e6b2 100644
--- a/Marlin/src/lcd/extui/dgus_reloaded/config/DGUS_Addr.h
+++ b/Marlin/src/lcd/extui/dgus_reloaded/config/DGUS_Addr.h
@@ -36,6 +36,7 @@
#define DGUS_GCODE_LEN 32
enum class DGUS_Addr : uint16_t {
+ END = 0,
MESSAGE_Line1 = 0x1100, // 0x1100 - 0x111F
MESSAGE_Line2 = 0x1120, // 0x1120 - 0x113F
MESSAGE_Line3 = 0x1140, // 0x1140 - 0x115F
diff --git a/Marlin/src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp b/Marlin/src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp
index 1a99eceeff..32e95f2508 100644
--- a/Marlin/src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp
+++ b/Marlin/src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp
@@ -33,7 +33,7 @@ constexpr DGUS_Addr LIST_HOME[] PROGMEM = {
DGUS_Addr::TEMP_Target_H0,
DGUS_Addr::TEMP_Current_Bed,
DGUS_Addr::TEMP_Target_Bed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
#if HAS_MEDIA
@@ -46,7 +46,7 @@ constexpr DGUS_Addr LIST_HOME[] PROGMEM = {
DGUS_Addr::SD_FileName4,
DGUS_Addr::SD_ScrollIcons,
DGUS_Addr::SD_SelectedFileName,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
#endif
@@ -59,7 +59,7 @@ constexpr DGUS_Addr LIST_PRINT_STATUS[] PROGMEM = {
DGUS_Addr::STATUS_Elapsed,
DGUS_Addr::STATUS_Percent,
DGUS_Addr::STATUS_Icons,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_PRINT_ADJUST[] PROGMEM = {
@@ -69,7 +69,7 @@ constexpr DGUS_Addr LIST_PRINT_ADJUST[] PROGMEM = {
DGUS_Addr::ADJUST_Feedrate,
DGUS_Addr::ADJUST_Flowrate_CUR,
DGUS_Addr::LEVEL_OFFSET_Current,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_PRINT_FINISHED[] PROGMEM = {
@@ -80,7 +80,7 @@ constexpr DGUS_Addr LIST_PRINT_FINISHED[] PROGMEM = {
DGUS_Addr::STATUS_PositionZ,
DGUS_Addr::STATUS_Elapsed,
DGUS_Addr::STATUS_Percent_Complete,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_TEMP_MENU[] PROGMEM = {
@@ -88,7 +88,7 @@ constexpr DGUS_Addr LIST_TEMP_MENU[] PROGMEM = {
DGUS_Addr::TEMP_Target_H0,
DGUS_Addr::TEMP_Current_Bed,
DGUS_Addr::TEMP_Target_Bed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_TEMP_MANUAL[] PROGMEM = {
@@ -98,23 +98,23 @@ constexpr DGUS_Addr LIST_TEMP_MANUAL[] PROGMEM = {
DGUS_Addr::TEMP_Current_Bed,
DGUS_Addr::TEMP_Target_Bed,
DGUS_Addr::TEMP_Max_Bed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_FAN[] PROGMEM = {
DGUS_Addr::FAN0_Speed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_SETTINGS_MENU[] PROGMEM = {
DGUS_Addr::STEPPER_Status,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_LEVELING_OFFSET[] PROGMEM = {
DGUS_Addr::LEVEL_OFFSET_Current,
DGUS_Addr::LEVEL_OFFSET_StepIcons,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_LEVELING_MANUAL[] PROGMEM = {
@@ -122,7 +122,7 @@ constexpr DGUS_Addr LIST_LEVELING_MANUAL[] PROGMEM = {
DGUS_Addr::TEMP_Target_H0,
DGUS_Addr::TEMP_Current_Bed,
DGUS_Addr::TEMP_Target_Bed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_LEVELING_AUTOMATIC[] PROGMEM = {
@@ -132,13 +132,13 @@ constexpr DGUS_Addr LIST_LEVELING_AUTOMATIC[] PROGMEM = {
DGUS_Addr::TEMP_Target_Bed,
DGUS_Addr::LEVEL_AUTO_DisableIcon,
DGUS_Addr::LEVEL_AUTO_Grid,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_LEVELING_PROBING[] PROGMEM = {
DGUS_Addr::LEVEL_PROBING_Icons1,
DGUS_Addr::LEVEL_PROBING_Icons2,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_FILAMENT[] PROGMEM = {
@@ -146,7 +146,7 @@ constexpr DGUS_Addr LIST_FILAMENT[] PROGMEM = {
DGUS_Addr::TEMP_Target_H0,
DGUS_Addr::FILAMENT_ExtruderIcons,
DGUS_Addr::FILAMENT_Length,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_MOVE[] PROGMEM = {
@@ -154,17 +154,17 @@ constexpr DGUS_Addr LIST_MOVE[] PROGMEM = {
DGUS_Addr::MOVE_CurrentY,
DGUS_Addr::MOVE_CurrentZ,
DGUS_Addr::MOVE_StepIcons,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_GCODE[] PROGMEM = {
DGUS_Addr::GCODE_Data,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_SETTINGS_MENU2[] PROGMEM = {
DGUS_Addr::SETTINGS2_BLTouch,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_PID[] PROGMEM = {
@@ -174,17 +174,17 @@ constexpr DGUS_Addr LIST_PID[] PROGMEM = {
DGUS_Addr::PID_Kp,
DGUS_Addr::PID_Ki,
DGUS_Addr::PID_Kd,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_VOLUME[] PROGMEM = {
DGUS_Addr::VOLUME_Level,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_BRIGHTNESS[] PROGMEM = {
DGUS_Addr::BRIGHTNESS_Level,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_INFOS[] PROGMEM = {
@@ -196,12 +196,12 @@ constexpr DGUS_Addr LIST_INFOS[] PROGMEM = {
DGUS_Addr::INFOS_PrintTime,
DGUS_Addr::INFOS_LongestPrint,
DGUS_Addr::INFOS_FilamentUsed,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
constexpr DGUS_Addr LIST_WAIT[] PROGMEM = {
DGUS_Addr::WAIT_Icons,
- (DGUS_Addr)0
+ DGUS_Addr::END
};
#define MAP_HELPER(SCREEN, LIST) { .screenID = SCREEN, .addr_list = LIST }
diff --git a/ini/features.ini b/ini/features.ini
index 63da77cf76..96a27b3ff9 100644
--- a/ini/features.ini
+++ b/ini/features.ini
@@ -96,6 +96,7 @@ ANYCUBIC_LCD_CHIRON = build_src_filter=+
ANYCUBIC_LCD_I3MEGA = build_src_filter=+
HAS_DGUS_LCD_CLASSIC = build_src_filter=+
+DGUS_LCD_UI_E3S1PRO = build_src_filter=+
DGUS_LCD_UI_RELOADED = build_src_filter=+
DGUS_LCD_UI_FYSETC = build_src_filter=+
DGUS_LCD_UI_HIPRECY = build_src_filter=+