From 736d367e5758970e3da9bedf81c657cce1559e5d Mon Sep 17 00:00:00 2001 From: Desuuuu Date: Fri, 12 Jun 2020 18:20:03 +0200 Subject: [PATCH] Add DGUS_RELOADED extui lib --- Marlin/Configuration.h | 5 + Marlin/src/inc/Conditionals_LCD.h | 4 + Marlin/src/inc/SanityCheck.h | 26 + Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp | 4 +- .../extui/lib/dgus_reloaded/DGUSDisplay.cpp | 379 ++++++ .../lcd/extui/lib/dgus_reloaded/DGUSDisplay.h | 163 +++ .../extui/lib/dgus_reloaded/DGUSRxHandler.cpp | 1028 +++++++++++++++++ .../extui/lib/dgus_reloaded/DGUSRxHandler.h | 121 ++ .../lib/dgus_reloaded/DGUSScreenHandler.cpp | 522 +++++++++ .../lib/dgus_reloaded/DGUSScreenHandler.h | 146 +++ .../lib/dgus_reloaded/DGUSSetupHandler.cpp | 184 +++ .../lib/dgus_reloaded/DGUSSetupHandler.h | 41 + .../extui/lib/dgus_reloaded/DGUSTxHandler.cpp | 632 ++++++++++ .../extui/lib/dgus_reloaded/DGUSTxHandler.h | 127 ++ .../lib/dgus_reloaded/config/DGUS_Addr.h | 172 +++ .../lib/dgus_reloaded/config/DGUS_Constants.h | 96 ++ .../lib/dgus_reloaded/config/DGUS_Control.h | 50 + .../lib/dgus_reloaded/config/DGUS_Data.h | 148 +++ .../lib/dgus_reloaded/config/DGUS_Screen.h | 51 + .../definition/DGUS_ScreenAddrList.cpp | 240 ++++ .../definition/DGUS_ScreenAddrList.h | 32 + .../definition/DGUS_ScreenSetup.cpp | 55 + .../definition/DGUS_ScreenSetup.h | 31 + .../lib/dgus_reloaded/definition/DGUS_VP.h | 40 + .../dgus_reloaded/definition/DGUS_VPList.cpp | 367 ++++++ .../dgus_reloaded/definition/DGUS_VPList.h | 26 + ...ui_dgus_lcd.cpp => extui_dgus_classic.cpp} | 6 +- Marlin/src/lcd/extui_dgus_reloaded.cpp | 144 +++ README.md | 12 + 29 files changed, 4847 insertions(+), 5 deletions(-) create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Addr.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Constants.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Control.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Data.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Screen.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VP.h create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.cpp create mode 100644 Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.h rename Marlin/src/lcd/{extui_dgus_lcd.cpp => extui_dgus_classic.cpp} (98%) create mode 100644 Marlin/src/lcd/extui_dgus_reloaded.cpp diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index f02e69ee5a6f..92a2bba99d60 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2068,6 +2068,11 @@ //#define DGUS_LCD_UI_FYSETC //#define DGUS_LCD_UI_HIPRECY +// +// Alternative DGUS LCD firmware +// +//#define DGUS_LCD_UI_RELOADED + // // Touch-screen LCD for Malyan M200 printers // diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index dd1f13fae0f8..3c83a6eb016f 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -358,6 +358,10 @@ // Aliases for LCD features #if ANY(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY) + #define DGUS_LCD_UI_CLASSIC +#endif + +#if ANY(DGUS_LCD_UI_CLASSIC, DGUS_LCD_UI_RELOADED) #define HAS_DGUS_LCD 1 #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 2fd61d4be10e..d51bdb9d5e42 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2070,6 +2070,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS + ENABLED(DGUS_LCD_UI_ORIGIN) \ + ENABLED(DGUS_LCD_UI_FYSETC) \ + ENABLED(DGUS_LCD_UI_HIPRECY) \ + + ENABLED(DGUS_LCD_UI_RELOADED) \ + ENABLED(MALYAN_LCD) \ + ENABLED(TOUCH_UI_FTDI_EVE) \ + ENABLED(FSMC_GRAPHICAL_TFT) @@ -2833,3 +2834,28 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2) #if SAVED_POSITIONS > 256 #error "SAVED_POSITIONS must be an integer from 0 to 256." #endif + +/** + * Require certain features for DGUS_LCD_UI_RELOADED. + */ +#if ENABLED(DGUS_LCD_UI_RELOADED) + #if HOTENDS < 1 + #error "DGUS_LCD_UI_RELOADED requires at least 1 hotend." + #elif EXTRUDERS < 1 + #error "DGUS_LCD_UI_RELOADED requires at least 1 extruder." + #elif !HAS_HEATED_BED + #error "DGUS_LCD_UI_RELOADED requires a heated bed." + #elif FAN_COUNT < 1 + #error "DGUS_LCD_UI_RELOADED requires a fan." + #elif !HAS_BED_PROBE + #error "DGUS_LCD_UI_RELOADED requires a bed probe." + #elif !HAS_MESH + #error "DGUS_LCD_UI_RELOADED requires mesh leveling." + #elif DISABLED(LEVEL_BED_CORNERS) + #error "DGUS_LCD_UI_RELOADED requires LEVEL_BED_CORNERS." + #elif DISABLED(BABYSTEP_ALWAYS_AVAILABLE) + #error "DGUS_LCD_UI_RELOADED requires BABYSTEP_ALWAYS_AVAILABLE." + #elif DISABLED(BABYSTEP_ZPROBE_OFFSET) + #error "DGUS_LCD_UI_RELOADED requires BABYSTEP_ZPROBE_OFFSET." + #endif +#endif diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp index 6ac84c2bb0af..faf87623b92a 100644 --- a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp +++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.cpp @@ -24,7 +24,7 @@ #include "../../../../inc/MarlinConfigPre.h" -#if HAS_DGUS_LCD +#if ENABLED(DGUS_LCD_UI_CLASSIC) #if HOTENDS > 2 #error "More than 2 hotends not implemented on the Display UI design." @@ -1352,4 +1352,4 @@ void DGUSDisplay::WritePGM(const char str[], uint8_t len) { // A SW memory barrier, to ensure GCC does not overoptimize loops #define sw_barrier() asm volatile("": : :"memory"); -#endif // HAS_DGUS_LCD +#endif // DGUS_LCD_UI_CLASSIC diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.cpp new file mode 100644 index 000000000000..bfa1da236494 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.cpp @@ -0,0 +1,379 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUSDisplay.h" + +#include "config/DGUS_Addr.h" +#include "config/DGUS_Constants.h" +#include "definition/DGUS_VPList.h" + +#include "../../ui_api.h" +#include "../../../../gcode/gcode.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::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() { + DGUS_SERIAL.begin(DGUS_BAUDRATE); +} + +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--) { + DGUS_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 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--) { + DGUS_SERIAL.write(' '); + } + while (len--) { + DGUS_SERIAL.write(*data++); + } + while (right_spaces--) { + DGUS_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; + uint8_t 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--) { + DGUS_SERIAL.write(' '); + } + while (len--) { + DGUS_SERIAL.write(pgm_read_byte(data++)); + } + while (right_spaces--) { + DGUS_SERIAL.write(use_space ? ' ' : '\0'); + } +} + +void DGUSDisplay::SwitchScreen(DGUS_Screen screen) { + DEBUG_ECHOLNPAIR("SwitchScreen ", (uint8_t)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; + if (volume == 0) return; + DEBUG_ECHOLNPAIR("PlaySound ", start, ":", len, "\nVolume ", volume); + const uint8_t command[] = { start, len, volume, 0x00 }; + Write(0xA0, command, sizeof(command)); +} + +void DGUSDisplay::EnableControl(DGUS_Screen screen, DGUS_ControlType type, DGUS_Control control) { + DEBUG_ECHOLNPAIR("EnableControl ", (uint8_t)control, "\nScreen ", (uint8_t)screen, "\nType ", (uint8_t)type); + + const uint8_t command[] = { 0x5A, 0xA5, 0x00, (uint8_t)screen, (uint8_t)control, type, 0x00, 0x01 }; + Write(0xB0, command, sizeof(command)); + + DGUS_SERIAL.flushTX(); + delay(50); +} + +void DGUSDisplay::DisableControl(DGUS_Screen screen, DGUS_ControlType type, DGUS_Control control) { + DEBUG_ECHOLNPAIR("DisableControl ", (uint8_t)control, "\nScreen ", (uint8_t)screen, "\nType ", (uint8_t)type); + + const uint8_t command[] = { 0x5A, 0xA5, 0x00, (uint8_t)screen, (uint8_t)control, type, 0x00, 0x00 }; + Write(0xB0, command, sizeof(command)); + + DGUS_SERIAL.flushTX(); + delay(50); +} + +uint8_t DGUSDisplay::GetBrightness() { + return brightness; +} + +uint8_t DGUSDisplay::GetVolume() { + return map_precise(volume, 0, 255, 0, 100); +} + +void DGUSDisplay::SetBrightness(uint8_t new_brightness) { + brightness = constrain(new_brightness, 0, 100); + new_brightness = map_precise(brightness, 0, 100, 5, 100); + DEBUG_ECHOLNPAIR("SetBrightness ", new_brightness); + 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, 255); + DEBUG_ECHOLNPAIR("SetVolume ", volume); + const uint8_t command[] = { volume, 0x00 }; + Write(0xA1, command, sizeof(command)); +} + +void DGUSDisplay::ProcessRx() { + + #if ENABLED(DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS) + if (!DGUS_SERIAL.available() && DGUS_SERIAL.buffer_overruns()) { + // Overrun, but reset the flag only when the buffer is empty + // We want to extract as many as valid datagrams possible... + DEBUG_ECHOPGM("OVFL"); + rx_datagram_state = DGUS_IDLE; + //DGUS_SERIAL.reset_rx_overun(); + DGUS_SERIAL.flush(); + } + #endif + + uint8_t receivedbyte; + while (DGUS_SERIAL.available()) { + switch (rx_datagram_state) { + + case DGUS_IDLE: // Waiting for the first header byte + receivedbyte = DGUS_SERIAL.read(); + DEBUG_ECHOPAIR("< ", receivedbyte); + if (DGUS_HEADER1 == receivedbyte) rx_datagram_state = DGUS_HEADER1_SEEN; + break; + + case DGUS_HEADER1_SEEN: // Waiting for the second header byte + receivedbyte = DGUS_SERIAL.read(); + DEBUG_ECHOPAIR(" ", receivedbyte); + rx_datagram_state = (DGUS_HEADER2 == receivedbyte) ? DGUS_HEADER2_SEEN : DGUS_IDLE; + break; + + case DGUS_HEADER2_SEEN: // Waiting for the length byte + rx_datagram_len = DGUS_SERIAL.read(); + DEBUG_ECHOPAIR(" (", rx_datagram_len, ") "); + + // 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 (DGUS_SERIAL.available() < rx_datagram_len) return; + + initialized = true; // We've talked to it, so we defined it as initialized. + uint8_t command = DGUS_SERIAL.read(); + + DEBUG_ECHOPAIR("# ", command); + + 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 = DGUS_SERIAL.read(); + DEBUG_ECHOPAIR(" ", receivedbyte); + *ptmp++ = receivedbyte; + } + DEBUG_ECHOPGM(" # "); + // 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]) { + DEBUG_ECHOLNPGM(">"); + 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 = tmp[0] << 8 | tmp[1]; + const uint8_t dlen = tmp[2] << 1; // Convert to Bytes. (Display works with words) + DEBUG_ECHOPAIR("addr=", addr, " dlen=", dlen, "> "); + + DGUS_VP vp; + if (!DGUS_PopulateVP((DGUS_Addr)addr, &vp)) { + DEBUG_ECHOLNPGM("VP not found"); + rx_datagram_state = DGUS_IDLE; + break; + } + + if (!vp.rx_handler) { + DEBUG_ECHOLNPGM("VP found, no handler."); + rx_datagram_state = DGUS_IDLE; + break; + } + + gcode.reset_stepper_timeout(); + + if (!vp.size) { + DEBUG_ECHOLN(); + 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_ECHOLN(); + vp.rx_handler(vp, buffer); + + rx_datagram_state = DGUS_IDLE; + break; + } + + if (dlen != vp.size) { + DEBUG_ECHOLNPGM("VP found, size mismatch."); + rx_datagram_state = DGUS_IDLE; + break; + } + + DEBUG_ECHOLN(); + vp.rx_handler(vp, &tmp[3]); + + rx_datagram_state = DGUS_IDLE; + break; + } + + DEBUG_ECHOLNPGM(">"); + rx_datagram_state = DGUS_IDLE; + break; + } + } +} + +size_t DGUSDisplay::GetFreeTxBuffer() { + return DGUS_SERIAL_GET_TX_BUFFER_FREE(); +} + +void DGUSDisplay::FlushTx() { + DGUS_SERIAL.flushTX(); +} + +void DGUSDisplay::WriteHeader(uint16_t addr, uint8_t command, uint8_t len) { + DGUS_SERIAL.write(DGUS_HEADER1); + DGUS_SERIAL.write(DGUS_HEADER2); + DGUS_SERIAL.write(len + 3); + DGUS_SERIAL.write(command); + DGUS_SERIAL.write(addr >> 8); + DGUS_SERIAL.write(addr & 0xFF); +} + +bool DGUS_PopulateVP(const DGUS_Addr addr, DGUS_VP * const buffer) { + const DGUS_VP *ret = vp_list; + + do { + const uint16_t addrcheck = pgm_read_word(&ret->addr); + if (addrcheck == 0) break; + if ((DGUS_Addr)addrcheck == addr) { + memcpy_P(buffer, ret, sizeof(*ret)); + return true; + } + } while (++ret); + DEBUG_ECHOLNPAIR("VP not found: ", (uint16_t)addr); + return false; +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.h new file mode 100644 index 000000000000..1ea5f440a13c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSDisplay.h @@ -0,0 +1,163 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/* DGUS implementation written by coldtobi in 2019 for Marlin */ + +#include "config/DGUS_Screen.h" +#include "config/DGUS_Control.h" +#include "definition/DGUS_VP.h" + +#include "../../../../inc/MarlinConfigPre.h" +#include "../../../../MarlinCore.h" + +#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD) +#include "../../../../core/debug_out.h" + +#define Swap16(val) ((uint16_t)(((uint16_t)(val) >> 8) |\ + ((uint16_t)(val) << 8))) + +// 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 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); + + 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) + + // Force display into another screen. + static void SwitchScreen(DGUS_Screen 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_Screen screen, DGUS_ControlType type, DGUS_Control control); + static void DisableControl(DGUS_Screen 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 initiliazed it. + // (both boils down that the display answered to our chatting) + static inline bool IsInitialized() { + return initialized; + } + + template + static T SwapBytes(const T value) { + union { + T val; + char byte[sizeof(T)]; + } src, dst; + + src.val = value; + LOOP_L_N(i, sizeof(T)) dst.byte[i] = src.byte[sizeof(T) - i - 1]; + return dst.val; + } + + 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. + }; + + 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; +}; + +template<> inline uint16_t DGUSDisplay::SwapBytes(const uint16_t value) { + return ((value << 8) | (value >> 8)); +} + +extern DGUSDisplay dgus_display; + +/// 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/lib/dgus_reloaded/DGUSRxHandler.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.cpp new file mode 100644 index 000000000000..13413850fac3 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.cpp @@ -0,0 +1,1028 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUSRxHandler.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 "../../../../gcode/queue.h" +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #include "../../../../feature/pause.h" +#endif +#if ENABLED(POWER_LOSS_RECOVERY) + #include "../../../../feature/powerloss.h" +#endif + +void DGUSRxHandler::ScreenChange(DGUS_VP &vp, void *data_ptr) { + const DGUS_Screen screen = (DGUS_Screen)((uint8_t*)data_ptr)[1]; + + if (vp.addr == DGUS_Addr::SCREENCHANGE_SD + #if ENABLED(SDSUPPORT) + && !ExtUI::isMediaInserted() + #endif + ) { + dgus_screen_handler.SetStatusMessagePGM(GET_TEXT(MSG_NO_MEDIA)); + return; + } + + if (vp.addr == DGUS_Addr::SCREENCHANGE_Idle + && (printingIsActive() || printingIsPaused())) { + dgus_screen_handler.SetStatusMessagePGM(PSTR("Impossible while printing")); + return; + } + + if (vp.addr == DGUS_Addr::SCREENCHANGE_Printing + && (!printingIsActive() && !printingIsPaused())) { + dgus_screen_handler.SetStatusMessagePGM(PSTR("Impossible while idle")); + return; + } + + dgus_screen_handler.TriggerScreenChange(screen); +} + +#if ENABLED(SDSUPPORT) + void DGUSRxHandler::Scroll(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Scroll scroll = (DGUS_Data::Scroll)((uint8_t*)data_ptr)[1]; + + switch (scroll) { + case DGUS_Data::Scroll::GO_BACK: + if (dgus_screen_handler.filelist.isAtRootDir()) { + return; + } + + dgus_screen_handler.filelist_offset = 0; + dgus_screen_handler.filelist_selected = -1; + dgus_screen_handler.filelist.upDir(); + break; + case DGUS_Data::Scroll::UP: + if (dgus_screen_handler.filelist_offset < 1) { + return; + } + + --dgus_screen_handler.filelist_offset; + break; + case DGUS_Data::Scroll::DOWN: + if (dgus_screen_handler.filelist_offset + 1 + DGUS_FILE_COUNT > dgus_screen_handler.filelist.count()) { + return; + } + + ++dgus_screen_handler.filelist_offset; + break; + } + + dgus_screen_handler.TriggerFullUpdate(); + } + + void DGUSRxHandler::SelectFile(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const uint8_t index = ((uint8_t*)data_ptr)[1]; + + if (!dgus_screen_handler.filelist.seek(dgus_screen_handler.filelist_offset + index)) { + return; + } + + if (dgus_screen_handler.filelist.isDir()) { + dgus_screen_handler.filelist_offset = 0; + dgus_screen_handler.filelist_selected = -1; + dgus_screen_handler.filelist.changeDir(dgus_screen_handler.filelist.filename()); + } + else { + dgus_screen_handler.filelist_selected = dgus_screen_handler.filelist_offset + index; + } + + dgus_screen_handler.TriggerFullUpdate(); + } + + void DGUSRxHandler::PrintFile(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + if (dgus_screen_handler.filelist_selected < 0) { + dgus_screen_handler.SetStatusMessagePGM(PSTR("No file selected")); + return; + } + + if (!dgus_screen_handler.filelist.seek(dgus_screen_handler.filelist_selected) + || dgus_screen_handler.filelist.isDir()) { + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + ExtUI::printFile(dgus_screen_handler.filelist.shortFilename()); + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::PRINT_STATUS); + } +#endif // SDSUPPORT + +void DGUSRxHandler::PrintAbort(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!printingIsActive() && !printingIsPaused()) { + dgus_screen_handler.TriggerFullUpdate(); + return; + } + + ExtUI::stopPrint(); +} + +void DGUSRxHandler::PrintPause(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!printingIsActive()) { + dgus_screen_handler.TriggerFullUpdate(); + return; + } + + ExtUI::pausePrint(); +} + +void DGUSRxHandler::PrintResume(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!printingIsPaused()) { + dgus_screen_handler.TriggerFullUpdate(); + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + ExtUI::resumePrint(); +} + +void DGUSRxHandler::Feedrate(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const int16_t feedrate = Swap16(*(int16_t*)data_ptr); + + ExtUI::setFeedrate_percent(feedrate); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::Flowrate(DGUS_VP &vp, void *data_ptr) { + const int16_t flowrate = Swap16(*(int16_t*)data_ptr); + + switch (vp.addr) { + default: return; + case DGUS_Addr::ADJUST_SetFlowrate_CUR: + #if EXTRUDERS > 1 + ExtUI::setFlow_percent(flowrate, ExtUI::getActiveTool()); + #else + ExtUI::setFlow_percent(flowrate, ExtUI::E0); + #endif + break; + #if EXTRUDERS > 1 + case DGUS_Addr::ADJUST_SetFlowrate_E0: + ExtUI::setFlow_percent(flowrate, ExtUI::E0); + break; + case DGUS_Addr::ADJUST_SetFlowrate_E1: + ExtUI::setFlow_percent(flowrate, ExtUI::E1); + break; + #endif + } + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::BabystepSet(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const int16_t data = Swap16(*(int16_t*)data_ptr); + const float offset = dgus_display.FromFixedPoint(data); + + const int16_t steps = ExtUI::mmToWholeSteps(offset - ExtUI::getZOffset_mm(), ExtUI::Z); + + ExtUI::smartAdjustAxis_steps(steps, ExtUI::Z, true); + + dgus_screen_handler.TriggerEEPROMSave(); + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::Babystep(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Adjust adjust = (DGUS_Data::Adjust)((uint8_t*)data_ptr)[1]; + int16_t steps; + + switch (adjust) { + case DGUS_Data::Adjust::INCREMENT: + steps = ExtUI::mmToWholeSteps(DGUS_PRINT_BABYSTEP, ExtUI::Z); + break; + case DGUS_Data::Adjust::DECREMENT: + steps = ExtUI::mmToWholeSteps(-DGUS_PRINT_BABYSTEP, ExtUI::Z); + break; + } + + ExtUI::smartAdjustAxis_steps(steps, ExtUI::Z, true); + + dgus_screen_handler.TriggerEEPROMSave(); + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::TempPreset(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::TempPreset preset = (DGUS_Data::TempPreset)((uint8_t*)data_ptr)[1]; + + switch (preset) { + case DGUS_Data::TempPreset::PLA: + #if HOTENDS < 2 + ExtUI::setTargetTemp_celsius(DGUS_PLA_TEMP_HOTEND, ExtUI::H0); + #else + ExtUI::setTargetTemp_celsius(DGUS_PLA_TEMP_HOTEND, ExtUI::getActiveTool()); + #endif + ExtUI::setTargetTemp_celsius(DGUS_PLA_TEMP_BED, ExtUI::BED); + break; + case DGUS_Data::TempPreset::ABS: + #if HOTENDS < 2 + ExtUI::setTargetTemp_celsius(DGUS_ABS_TEMP_HOTEND, ExtUI::H0); + #else + ExtUI::setTargetTemp_celsius(DGUS_ABS_TEMP_HOTEND, ExtUI::getActiveTool()); + #endif + ExtUI::setTargetTemp_celsius(DGUS_ABS_TEMP_BED, ExtUI::BED); + break; + case DGUS_Data::TempPreset::PETG: + #if HOTENDS < 2 + ExtUI::setTargetTemp_celsius(DGUS_PETG_TEMP_HOTEND, ExtUI::H0); + #else + ExtUI::setTargetTemp_celsius(DGUS_PETG_TEMP_HOTEND, ExtUI::getActiveTool()); + #endif + ExtUI::setTargetTemp_celsius(DGUS_PETG_TEMP_BED, ExtUI::BED); + break; + } + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::TempTarget(DGUS_VP &vp, void *data_ptr) { + const int16_t temp = Swap16(*(int16_t*)data_ptr); + + switch (vp.addr) { + default: return; + case DGUS_Addr::TEMP_SetTarget_Bed: + ExtUI::setTargetTemp_celsius(temp, ExtUI::BED); + break; + case DGUS_Addr::TEMP_SetTarget_H0: + ExtUI::setTargetTemp_celsius(temp, ExtUI::H0); + break; + #if HOTENDS > 1 + case DGUS_Addr::TEMP_SetTarget_H1: + ExtUI::setTargetTemp_celsius(temp, ExtUI::H1); + break; + #endif + } + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::TempCool(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Heater heater = (DGUS_Data::Heater)Swap16(*(uint16_t*)data_ptr); + + switch (heater) { + default: return; + case DGUS_Data::Heater::ALL: + ExtUI::setTargetTemp_celsius(0, ExtUI::BED); + ExtUI::setTargetTemp_celsius(0, ExtUI::H0); + #if HOTENDS > 1 + ExtUI::setTargetTemp_celsius(0, ExtUI::H1); + #endif + break; + case DGUS_Data::Heater::BED: + ExtUI::setTargetTemp_celsius(0, ExtUI::BED); + break; + case DGUS_Data::Heater::H0: + ExtUI::setTargetTemp_celsius(0, ExtUI::H0); + break; + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + ExtUI::setTargetTemp_celsius(0, ExtUI::H1); + break; + #endif + } + + dgus_screen_handler.SetStatusMessagePGM(PSTR("Cooling...")); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::Steppers(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Control control = (DGUS_Data::Control)((uint8_t*)data_ptr)[1]; + + switch (control) { + case DGUS_Data::Control::ENABLE: + enable_all_steppers(); + break; + case DGUS_Data::Control::DISABLE: + disable_all_steppers(); + break; + } + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::ZOffset(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!ExtUI::isAxisPositionKnown(ExtUI::Z)) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + const int16_t data = Swap16(*(int16_t*)data_ptr); + const float offset = dgus_display.FromFixedPoint(data); + + const int16_t steps = ExtUI::mmToWholeSteps(offset - ExtUI::getZOffset_mm(), ExtUI::Z); + + ExtUI::smartAdjustAxis_steps(steps, ExtUI::Z, true); + + dgus_screen_handler.TriggerEEPROMSave(); + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::ZOffsetStep(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!ExtUI::isAxisPositionKnown(ExtUI::Z)) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + const DGUS_Data::Adjust adjust = (DGUS_Data::Adjust)((uint8_t*)data_ptr)[1]; + int16_t steps; + + switch (dgus_screen_handler.offset_steps) { + default: return; + case DGUS_Data::StepSize::MMP1: + steps = ExtUI::mmToWholeSteps((adjust == DGUS_Data::Adjust::INCREMENT ? 0.1f : -0.1f), ExtUI::Z); + break; + case DGUS_Data::StepSize::MMP01: + steps = ExtUI::mmToWholeSteps((adjust == DGUS_Data::Adjust::INCREMENT ? 0.01f : -0.01f), ExtUI::Z); + break; + } + + ExtUI::smartAdjustAxis_steps(steps, ExtUI::Z, true); + + dgus_screen_handler.TriggerEEPROMSave(); + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::ZOffsetSetStep(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::StepSize size = (DGUS_Data::StepSize)((uint8_t*)data_ptr)[1]; + + dgus_screen_handler.offset_steps = size; + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::MoveToPoint(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!ExtUI::isPositionKnown()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + const uint8_t point = ((uint8_t*)data_ptr)[1]; + constexpr float lfrb[4] = LEVEL_CORNERS_INSET_LFRB; + float x, y; + + switch (point) { + default: return; + case 1: + x = DGUS_LEVEL_CENTER_X; + y = DGUS_LEVEL_CENTER_Y; + 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 + LEVEL_CORNERS_Z_HOP) { + ExtUI::setAxisPosition_mm(Z_MIN_POS + LEVEL_CORNERS_Z_HOP, ExtUI::Z); + } + ExtUI::setAxisPosition_mm(x, ExtUI::X); + ExtUI::setAxisPosition_mm(y, ExtUI::Y); + ExtUI::setAxisPosition_mm(Z_MIN_POS + LEVEL_CORNERS_HEIGHT, ExtUI::Z); +} + +void DGUSRxHandler::Probe(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + if (!ExtUI::isPositionKnown()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::LEVELING_PROBING); + + queue.enqueue_now_P(PSTR("G29\nM420S1")); + queue.enqueue_now_P(DGUS_CMD_EEPROM_SAVE); +} + +void DGUSRxHandler::DisableABL(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + ExtUI::setLevelingActive(false); + + dgus_screen_handler.TriggerEEPROMSave(); + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::FilamentSelect(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Extruder extruder = (DGUS_Data::Extruder)Swap16(*(uint16_t*)data_ptr); + + switch (extruder) { + default: return; + case DGUS_Data::Extruder::CURRENT: + case DGUS_Data::Extruder::E0: + #if EXTRUDERS > 1 + case DGUS_Data::Extruder::E1: + #endif + dgus_screen_handler.filament_extruder = extruder; + break; + } + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::FilamentLength(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const uint16_t length = Swap16(*(uint16_t*)data_ptr); + + dgus_screen_handler.filament_length = constrain(length, 0, EXTRUDE_MAXLENGTH); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::FilamentMove(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + ExtUI::extruder_t extruder; + + switch (dgus_screen_handler.filament_extruder) { + default: return; + case DGUS_Data::Extruder::CURRENT: + #if EXTRUDERS > 1 + extruder = ExtUI::getActiveTool(); + break; + #endif + case DGUS_Data::Extruder::E0: + extruder = ExtUI::E0; + break; + #if EXTRUDERS > 1 + case DGUS_Data::Extruder::E1: + extruder = ExtUI::E1; + break; + #endif + } + + if (ExtUI::getActualTemp_celsius(extruder) < (float)EXTRUDE_MINTEMP) { + dgus_screen_handler.SetStatusMessagePGM(PSTR("Temperature too low")); + return; + } + + const DGUS_Data::FilamentMove move = (DGUS_Data::FilamentMove)((uint8_t*)data_ptr)[1]; + + switch (move) { + case DGUS_Data::FilamentMove::RETRACT: + UI_DECREMENT_BY(AxisPosition_mm, (float)dgus_screen_handler.filament_length, extruder); + break; + case DGUS_Data::FilamentMove::EXTRUDE: + UI_INCREMENT_BY(AxisPosition_mm, (float)dgus_screen_handler.filament_length, extruder); + break; + } +} + +void DGUSRxHandler::Home(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + DGUS_Data::Axis axis = (DGUS_Data::Axis)((uint8_t*)data_ptr)[1]; + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(DGUS_MSG_HOMING, 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(dgus_screen_handler.GetCurrentScreen()); + + switch (axis) { + case DGUS_Data::Axis::X_Y_Z: + queue.enqueue_now_P(PSTR("G28XYZ")); + break; + case DGUS_Data::Axis::X_Y: + queue.enqueue_now_P(PSTR("G28XY")); + break; + case DGUS_Data::Axis::Z: + queue.enqueue_now_P(PSTR("G28Z")); + break; + } +} + +void DGUSRxHandler::Move(DGUS_VP &vp, void *data_ptr) { + const int16_t data = Swap16(*(int16_t*)data_ptr); + const float position = dgus_display.FromFixedPoint(data); + ExtUI::axis_t axis; + + switch (vp.addr) { + default: return; + case DGUS_Addr::MOVE_SetX: + axis = ExtUI::X; + break; + case DGUS_Addr::MOVE_SetY: + axis = ExtUI::Y; + break; + case DGUS_Addr::MOVE_SetZ: + axis = ExtUI::Z; + break; + } + + if (!ExtUI::isAxisPositionKnown(axis)) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + ExtUI::setAxisPosition_mm(position, axis); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::MoveStep(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + float offset; + + switch (dgus_screen_handler.move_steps) { + default: return; + case DGUS_Data::StepSize::MM10: + offset = 10.0f; + break; + case DGUS_Data::StepSize::MM1: + offset = 1.0f; + break; + case DGUS_Data::StepSize::MMP1: + offset = 0.1f; + break; + } + + const DGUS_Data::MoveDirection direction = (DGUS_Data::MoveDirection)((uint8_t*)data_ptr)[1]; + ExtUI::axis_t axis; + + switch (direction) { + case DGUS_Data::MoveDirection::XP: + axis = ExtUI::X; + break; + case DGUS_Data::MoveDirection::XM: + axis = ExtUI::X; + offset = -offset; + break; + case DGUS_Data::MoveDirection::YP: + axis = ExtUI::Y; + break; + case DGUS_Data::MoveDirection::YM: + axis = ExtUI::Y; + offset = -offset; + break; + case DGUS_Data::MoveDirection::ZP: + axis = ExtUI::Z; + break; + case DGUS_Data::MoveDirection::ZM: + axis = ExtUI::Z; + offset = -offset; + break; + } + + if (!ExtUI::isAxisPositionKnown(axis)) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_HOMING_REQUIRED); + return; + } + + UI_INCREMENT_BY(AxisPosition_mm, offset, axis); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::MoveSetStep(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::StepSize size = (DGUS_Data::StepSize)((uint8_t*)data_ptr)[1]; + + dgus_screen_handler.move_steps = size; + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::GcodeClear(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + ZERO(dgus_screen_handler.gcode); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::GcodeExecute(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + if (!strlen(dgus_screen_handler.gcode)) { + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(PSTR("Executing command..."), 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(DGUS_Screen::GCODE); + + queue.enqueue_one_now(dgus_screen_handler.gcode); +} + +void DGUSRxHandler::ResetEEPROM(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + queue.enqueue_now_P(PSTR("M502")); + queue.enqueue_now_P(DGUS_CMD_EEPROM_SAVE); +} + +void DGUSRxHandler::SettingsExtra(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Extra extra = (DGUS_Data::Extra)((uint8_t*)data_ptr)[1]; + + switch (extra) { + default: return; + case DGUS_Data::Extra::BUTTON1: + #if ENABLED(BLTOUCH) + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + queue.enqueue_now_P(PSTR(DGUS_RESET_BLTOUCH)); + #else + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::INFOS); + #endif + break; + #if ENABLED(BLTOUCH) + case DGUS_Data::Extra::BUTTON2: + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::INFOS); + break; + #endif + } +} + +void DGUSRxHandler::PIDSelect(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Heater heater = (DGUS_Data::Heater)Swap16(*(uint16_t*)data_ptr); + + switch (heater) { + default: return; + case DGUS_Data::Heater::BED: + dgus_screen_handler.pid_temp = DGUS_PLA_TEMP_BED; + dgus_screen_handler.pid_heater = heater; + break; + case DGUS_Data::Heater::H0: + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + #endif + dgus_screen_handler.pid_temp = DGUS_PLA_TEMP_HOTEND; + dgus_screen_handler.pid_heater = heater; + break; + } + + dgus_screen_handler.pid_cycles = 5; + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::PIDSetTemp(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + uint16_t temp = Swap16(*(uint16_t*)data_ptr); + + switch (dgus_screen_handler.pid_heater) { + default: return; + case DGUS_Data::Heater::BED: + temp = constrain(temp, BED_MINTEMP, (BED_MAXTEMP - 10)); + break; + case DGUS_Data::Heater::H0: + temp = constrain(temp, HEATER_0_MINTEMP, (HEATER_0_MAXTEMP - 15)); + break; + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + temp = constrain(temp, HEATER_1_MINTEMP, (HEATER_1_MAXTEMP - 15)); + break; + #endif + } + + dgus_screen_handler.pid_temp = temp; + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::PIDRun(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + heater_ind_t heater; + uint8_t cycles = constrain(dgus_screen_handler.pid_cycles, 3, 10); + + switch (dgus_screen_handler.pid_heater) { + default: return; + case DGUS_Data::Heater::BED: + #if ENABLED(PIDTEMPBED) + heater = H_BED; + break; + #else + dgus_screen_handler.SetStatusMessagePGM(PSTR("Bed PID disabled")); + return; + #endif + case DGUS_Data::Heater::H0: + #if ENABLED(PIDTEMP) + heater = H_E0; + break; + #else + dgus_screen_handler.SetStatusMessagePGM(PSTR("PID disabled")); + return; + #endif + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + #if ENABLED(PIDTEMP) + heater = H_E1; + break; + #else + dgus_screen_handler.SetStatusMessagePGM(PSTR("PID disabled")); + return; + #endif + #endif + } + + char buffer[24]; + snprintf_P(buffer, sizeof(buffer), PSTR("M303C%dE%dS%dU1"), cycles, heater, dgus_screen_handler.pid_temp); + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(PSTR("PID autotuning..."), 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(DGUS_Screen::PID); + + queue.enqueue_one_now(buffer); + queue.enqueue_now_P(DGUS_CMD_EEPROM_SAVE); +} + +#if ENABLED(POWER_LOSS_RECOVERY) + void DGUSRxHandler::PowerLossAbort(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::HOME); + + queue.enqueue_now_P(PSTR("M1000C")); + } + + void DGUSRxHandler::PowerLossResume(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return; + } + + if (!recovery.valid()) { + dgus_screen_handler.SetStatusMessagePGM(PSTR("Invalid recovery data")); + return; + } + + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::PRINT_STATUS); + + queue.enqueue_now_P(PSTR("M1000")); + } +#endif // POWER_LOSS_RECOVERY + +void DGUSRxHandler::WaitAbort(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + const DGUS_Data::Popup result = (DGUS_Data::Popup)((uint8_t*)data_ptr)[1]; + + if (result != DGUS_Data::Popup::CONFIRMED) { + return; + } + + if (!printingIsPaused() + #if ENABLED(ADVANCED_PAUSE_FEATURE) + || !did_pause_print + #endif + ) { + dgus_screen_handler.TriggerFullUpdate(); + return; + } + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + did_pause_print = 0; + #endif + + ExtUI::setUserConfirmed(); + ExtUI::stopPrint(); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::WaitContinue(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + UNUSED(data_ptr); + + ExtUI::setUserConfirmed(); + + dgus_screen_handler.TriggerFullUpdate(); +} + +void DGUSRxHandler::FanSpeed(DGUS_VP &vp, void *data_ptr) { + uint8_t speed = ((uint8_t*)data_ptr)[1]; + switch (vp.addr) { + default: return; + case DGUS_Addr::FAN0_Speed: + ExtUI::setTargetFan_percent(speed, ExtUI::FAN0); + break; + } +} + +void DGUSRxHandler::Volume(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + uint8_t volume = ((uint8_t*)data_ptr)[1]; + dgus_display.SetVolume(volume); + + dgus_screen_handler.TriggerEEPROMSave(); +} + +void DGUSRxHandler::Brightness(DGUS_VP &vp, void *data_ptr) { + UNUSED(vp); + + uint8_t brightness = ((uint8_t*)data_ptr)[1]; + dgus_display.SetBrightness(brightness); + + dgus_screen_handler.TriggerEEPROMSave(); +} + +void DGUSRxHandler::StringToExtra(DGUS_VP &vp, void *data_ptr) { + if (!vp.size || !vp.extra) return; + memcpy(vp.extra, data_ptr, vp.size); +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.h new file mode 100644 index 000000000000..bdb8013c34df --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSRxHandler.h @@ -0,0 +1,121 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include "DGUSDisplay.h" +#include "definition/DGUS_VP.h" + +namespace DGUSRxHandler { + + void ScreenChange(DGUS_VP &, void *); + + #if ENABLED(SDSUPPORT) + void Scroll(DGUS_VP &, void *); + void SelectFile(DGUS_VP &, void *); + void PrintFile(DGUS_VP &, void *); + #endif + + void PrintAbort(DGUS_VP &, void *); + void PrintPause(DGUS_VP &, void *); + void PrintResume(DGUS_VP &, void *); + + void Feedrate(DGUS_VP &, void *); + void Flowrate(DGUS_VP &, void *); + void BabystepSet(DGUS_VP &, void *); + void Babystep(DGUS_VP &, void *); + + void TempPreset(DGUS_VP &, void *); + void TempTarget(DGUS_VP &, void *); + void TempCool(DGUS_VP &, void *); + + void Steppers(DGUS_VP &, void *); + + void ZOffset(DGUS_VP &, void *); + void ZOffsetStep(DGUS_VP &, void *); + void ZOffsetSetStep(DGUS_VP &, void *); + + void MoveToPoint(DGUS_VP &, void *); + + void Probe(DGUS_VP &, void *); + void DisableABL(DGUS_VP &, void *); + + void FilamentSelect(DGUS_VP &, void *); + void FilamentLength(DGUS_VP &, void *); + void FilamentMove(DGUS_VP &, void *); + + void Home(DGUS_VP &, void *); + void Move(DGUS_VP &, void *); + void MoveStep(DGUS_VP &, void *); + void MoveSetStep(DGUS_VP &, void *); + + void GcodeClear(DGUS_VP &, void *); + void GcodeExecute(DGUS_VP &, void *); + + void ResetEEPROM(DGUS_VP &, void *); + + void SettingsExtra(DGUS_VP &, void *); + + void PIDSelect(DGUS_VP &, void *); + void PIDSetTemp(DGUS_VP &, void *); + void PIDRun(DGUS_VP &, void *); + + #if ENABLED(POWER_LOSS_RECOVERY) + void PowerLossAbort(DGUS_VP &, void *); + void PowerLossResume(DGUS_VP &, void *); + #endif + + void WaitAbort(DGUS_VP &, void *); + void WaitContinue(DGUS_VP &, void *); + + void FanSpeed(DGUS_VP &, void *); + + void Volume(DGUS_VP &, void *); + + void Brightness(DGUS_VP &, void *); + + void StringToExtra(DGUS_VP &, void *); + + 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 = Swap16(*(uint16_t*)data_ptr); + *(T*)vp.extra = (T)data; + break; + } + case 4: { + const uint32_t data = dgus_display.SwapBytes(*(uint32_t*)data_ptr); + *(T*)vp.extra = (T)data; + break; + } + } + } + +} diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.cpp new file mode 100644 index 000000000000..b014703a0b63 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.cpp @@ -0,0 +1,522 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUSScreenHandler.h" + +#include "DGUSDisplay.h" +#include "definition/DGUS_ScreenAddrList.h" +#include "definition/DGUS_ScreenSetup.h" + +#include "../../../../gcode/queue.h" + +#if ENABLED(SDSUPPORT) + ExtUI::FileList DGUSScreenHandler::filelist; + uint16_t DGUSScreenHandler::filelist_offset = 0; + int16_t DGUSScreenHandler::filelist_selected = -1; +#endif + +DGUS_Data::StepSize DGUSScreenHandler::offset_steps = DGUS_Data::StepSize::MMP1; +DGUS_Data::StepSize DGUSScreenHandler::move_steps = DGUS_Data::StepSize::MM10; + +uint16_t DGUSScreenHandler::probing_icons[] = { 0, 0 }; + +DGUS_Data::Extruder DGUSScreenHandler::filament_extruder = DGUS_Data::Extruder::CURRENT; +uint16_t DGUSScreenHandler::filament_length = DGUS_DEFAULT_FILAMENT_LEN; + +char DGUSScreenHandler::gcode[] = ""; + +DGUS_Data::Heater DGUSScreenHandler::pid_heater = DGUS_Data::Heater::H0; +uint16_t DGUSScreenHandler::pid_temp = DGUS_PLA_TEMP_HOTEND; +uint8_t DGUSScreenHandler::pid_cycles = 5; + +bool DGUSScreenHandler::settings_ready = false; +bool DGUSScreenHandler::booted = false; + +DGUS_Screen DGUSScreenHandler::current_screen = DGUS_Screen::BOOT; +DGUS_Screen DGUSScreenHandler::new_screen = DGUS_Screen::BOOT; +bool DGUSScreenHandler::full_update = false; + +DGUS_Screen DGUSScreenHandler::wait_return_screen = DGUS_Screen::HOME; +bool DGUSScreenHandler::wait_continue = false; + +millis_t DGUSScreenHandler::status_expire = 0; +millis_t DGUSScreenHandler::eeprom_save = 0; + +const char DGUS_MSG_HOMING_REQUIRED[] PROGMEM = "Homing required", + DGUS_MSG_BUSY[] PROGMEM = "Busy", + DGUS_MSG_UNDEF[] PROGMEM = "-", + DGUS_MSG_HOMING[] PROGMEM = "Homing..."; + +const char DGUS_CMD_HOME[] PROGMEM = "G28", + DGUS_CMD_EEPROM_SAVE[] PROGMEM = "M500"; + +void DGUSScreenHandler::Init() { + dgus_display.Init(); + + MoveToScreen(DGUS_Screen::BOOT); +} + +void DGUSScreenHandler::Ready() { + dgus_display.PlaySound(1); +} + +void DGUSScreenHandler::Loop() { + if (!settings_ready || current_screen == DGUS_Screen::KILL) { + return; + } + + const millis_t ms = ExtUI::safe_millis(); + static millis_t next_event_ms = 0; + + if (new_screen != DGUS_Screen::BOOT) { + const DGUS_Screen screen = new_screen; + new_screen = DGUS_Screen::BOOT; + + if (current_screen == screen) { + TriggerFullUpdate(); + } + else { + MoveToScreen(screen); + } + return; + } + + if (!booted && ELAPSED(ms, 3000)) { + booted = true; + + if (current_screen == DGUS_Screen::BOOT) { + MoveToScreen(DGUS_Screen::HOME); + } + return; + } + + if (ELAPSED(ms, next_event_ms) || full_update) { + next_event_ms = ms + DGUS_UPDATE_INTERVAL_MS; + + if (!SendScreenVPData(current_screen, full_update)) { + DEBUG_ECHOLNPGM("SendScreenVPData failed"); + } + return; + } + + if (current_screen == DGUS_Screen::WAIT + && ((wait_continue && !wait_for_user) + || (!wait_continue && IsPrinterIdle()))) { + MoveToScreen(wait_return_screen, true); + return; + } + + if (current_screen == DGUS_Screen::LEVELING_PROBING + && IsPrinterIdle()) { + dgus_display.PlaySound(3); + + SetStatusMessagePGM(ExtUI::getMeshValid() ? + PSTR("Probing successful") + : PSTR("Probing failed")); + + MoveToScreen(DGUS_Screen::LEVELING_AUTOMATIC); + return; + } + + if (status_expire > 0 && ELAPSED(ms, status_expire)) { + SetStatusMessagePGM(NUL_STR, 0); + return; + } + + if (eeprom_save > 0 && ELAPSED(ms, eeprom_save) && IsPrinterIdle()) { + eeprom_save = 0; + + queue.enqueue_now_P(DGUS_CMD_EEPROM_SAVE); + return; + } + + dgus_display.Loop(); +} + +void DGUSScreenHandler::PrinterKilled(PGM_P error, PGM_P component) { + SetMessageLinePGM(error, 1); + SetMessageLinePGM(component, 2); + SetMessageLinePGM(NUL_STR, 3); + SetMessageLinePGM(GET_TEXT(MSG_PLEASE_RESET), 4); + + dgus_display.PlaySound(3, 1, 200); + + MoveToScreen(DGUS_Screen::KILL, true); +} + +void DGUSScreenHandler::UserConfirmRequired(const char * const msg) { + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLine(msg, 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + + dgus_display.PlaySound(3); + + dgus_screen_handler.ShowWaitScreen(current_screen, true); +} + +void DGUSScreenHandler::SettingsReset() { + dgus_display.SetVolume(DGUS_DEFAULT_VOLUME); + dgus_display.SetBrightness(DGUS_DEFAULT_BRIGHTNESS); + + if (!settings_ready) { + settings_ready = true; + + Ready(); + } + + SetStatusMessagePGM(PSTR("EEPROM reset")); +} + +void DGUSScreenHandler::StoreSettings(char *buff) { + eeprom_data_t data; + + static_assert(sizeof(data) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size."); + + data.initialized = true; + data.volume = dgus_display.GetVolume(); + data.brightness = dgus_display.GetBrightness(); + data.abl = (ExtUI::getLevelingActive() && ExtUI::getMeshValid()); + + memcpy(buff, &data, sizeof(data)); +} + +void DGUSScreenHandler::LoadSettings(const char *buff) { + eeprom_data_t data; + + static_assert(sizeof(data) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size."); + + memcpy(&data, buff, sizeof(data)); + + dgus_display.SetVolume(data.initialized ? data.volume : DGUS_DEFAULT_VOLUME); + dgus_display.SetBrightness(data.initialized ? data.brightness : DGUS_DEFAULT_BRIGHTNESS); + + if (data.initialized && data.abl && ExtUI::getMeshValid()) { + ExtUI::setLevelingActive(true); + } +} + +void DGUSScreenHandler::ConfigurationStoreWritten(bool success) { + if (!success) { + SetStatusMessagePGM(PSTR("EEPROM write failed")); + } +} + +void DGUSScreenHandler::ConfigurationStoreRead(bool success) { + if (!success) { + SetStatusMessagePGM(PSTR("EEPROM read failed")); + } + else if (!settings_ready) { + settings_ready = true; + + Ready(); + } +} + +void DGUSScreenHandler::PlayTone(const uint16_t frequency, const uint16_t duration) { + UNUSED(duration); + + if (frequency >= 1 && frequency <= 64) { + dgus_display.PlaySound((uint8_t)frequency); + } +} + +void DGUSScreenHandler::MeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + if (current_screen != DGUS_Screen::LEVELING_PROBING) { + if (current_screen == DGUS_Screen::LEVELING_AUTOMATIC) { + TriggerFullUpdate(); + } + + return; + } + + uint8_t point = ypos * GRID_MAX_POINTS_X + xpos; + probing_icons[point < 16 ? 0 : 1] |= (1U << (point % 16)); + + if (xpos >= GRID_MAX_POINTS_X - 1 + && ypos >= GRID_MAX_POINTS_Y - 1 + && !ExtUI::getMeshValid()) { + probing_icons[0] = 0; + probing_icons[1] = 0; + } + + TriggerFullUpdate(); +} + +void DGUSScreenHandler::PrintTimerStarted() { + TriggerScreenChange(DGUS_Screen::PRINT_STATUS); +} + +void DGUSScreenHandler::PrintTimerPaused() { + dgus_display.PlaySound(3); + + TriggerFullUpdate(); +} + +void DGUSScreenHandler::PrintTimerStopped() { + if (current_screen != DGUS_Screen::PRINT_STATUS + && current_screen != DGUS_Screen::PRINT_ADJUST) { + return; + } + + dgus_display.PlaySound(3); + + TriggerScreenChange(DGUS_Screen::PRINT_FINISHED); +} + +void DGUSScreenHandler::FilamentRunout(const ExtUI::extruder_t extruder) { + char buffer[20]; + snprintf_P(buffer, sizeof(buffer), PSTR("Filament runout E%d"), extruder); + + SetStatusMessage(buffer); + + dgus_display.PlaySound(3); +} + +#if ENABLED(SDSUPPORT) + + void DGUSScreenHandler::SDCardInserted() { + if (current_screen == DGUS_Screen::HOME) { + TriggerScreenChange(DGUS_Screen::PRINT); + } + } + + void DGUSScreenHandler::SDCardRemoved() { + if (current_screen == DGUS_Screen::PRINT) { + TriggerScreenChange(DGUS_Screen::HOME); + } + } + + void DGUSScreenHandler::SDCardError() { + SetStatusMessagePGM(GET_TEXT(MSG_MEDIA_READ_ERROR)); + + if (current_screen == DGUS_Screen::PRINT) { + TriggerScreenChange(DGUS_Screen::HOME); + } + } + +#endif // SDSUPPORT + +#if ENABLED(POWER_LOSS_RECOVERY) + + void DGUSScreenHandler::PowerLossResume() { + TriggerScreenChange(DGUS_Screen::POWERLOSS); + } + +#endif // POWER_LOSS_RECOVERY + +#if HAS_PID_HEATING + + void DGUSScreenHandler::PidTuning(const ExtUI::result_t rst) { + switch (rst) { + case ExtUI::PID_DONE: + SetStatusMessagePGM(PSTR("PID tuning successful")); + break; + case ExtUI::PID_BAD_EXTRUDER_NUM: + SetStatusMessagePGM(PSTR("Unknown extruder")); + break; + case ExtUI::PID_TEMP_TOO_HIGH: + SetStatusMessagePGM(PSTR("Temperature too high")); + break; + case ExtUI::PID_TUNING_TIMEOUT: + SetStatusMessagePGM(PSTR("Timed out")); + break; + } + + dgus_display.PlaySound(3); + } + +#endif // HAS_PID_HEATING + +void DGUSScreenHandler::SetMessageLine(const char* msg, uint8_t line) { + switch (line) { + default: return; + case 1: + dgus_display.WriteString((uint16_t)DGUS_Addr::MESSAGE_Line1, msg, DGUS_LINE_LEN, true, true); + break; + case 2: + dgus_display.WriteString((uint16_t)DGUS_Addr::MESSAGE_Line2, msg, DGUS_LINE_LEN, true, true); + break; + case 3: + dgus_display.WriteString((uint16_t)DGUS_Addr::MESSAGE_Line3, msg, DGUS_LINE_LEN, true, true); + break; + case 4: + dgus_display.WriteString((uint16_t)DGUS_Addr::MESSAGE_Line4, msg, DGUS_LINE_LEN, true, true); + break; + } +} + +void DGUSScreenHandler::SetMessageLinePGM(PGM_P msg, uint8_t line) { + switch (line) { + default: return; + case 1: + dgus_display.WriteStringPGM((uint16_t)DGUS_Addr::MESSAGE_Line1, msg, DGUS_LINE_LEN, true, true); + break; + case 2: + dgus_display.WriteStringPGM((uint16_t)DGUS_Addr::MESSAGE_Line2, msg, DGUS_LINE_LEN, true, true); + break; + case 3: + dgus_display.WriteStringPGM((uint16_t)DGUS_Addr::MESSAGE_Line3, msg, DGUS_LINE_LEN, true, true); + break; + case 4: + dgus_display.WriteStringPGM((uint16_t)DGUS_Addr::MESSAGE_Line4, msg, DGUS_LINE_LEN, true, true); + break; + } +} + +void DGUSScreenHandler::SetStatusMessage(const char* msg, const millis_t duration) { + dgus_display.WriteString((uint16_t)DGUS_Addr::MESSAGE_Status, msg, DGUS_STATUS_LEN, false, true); + + status_expire = (duration > 0 ? ExtUI::safe_millis() + duration : 0); +} + +void DGUSScreenHandler::SetStatusMessagePGM(PGM_P msg, const millis_t duration) { + dgus_display.WriteStringPGM((uint16_t)DGUS_Addr::MESSAGE_Status, msg, DGUS_STATUS_LEN, false, true); + + status_expire = (duration > 0 ? ExtUI::safe_millis() + duration : 0); +} + +void DGUSScreenHandler::ShowWaitScreen(DGUS_Screen return_screen, bool has_continue) { + if (return_screen != DGUS_Screen::WAIT) { + wait_return_screen = return_screen; + } + wait_continue = has_continue; + + TriggerScreenChange(DGUS_Screen::WAIT); +} + +DGUS_Screen DGUSScreenHandler::GetCurrentScreen() { + return current_screen; +} + +void DGUSScreenHandler::TriggerScreenChange(DGUS_Screen screen) { + new_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_Screen 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_Screen 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_Screen screen, bool abort_wait) { + if (current_screen == DGUS_Screen::KILL) { + return; + } + + if (current_screen == DGUS_Screen::WAIT) { + if (screen != DGUS_Screen::WAIT) { + wait_return_screen = screen; + } + + if (!abort_wait) return; + + if (wait_continue && wait_for_user) { + ExtUI::setUserConfirmed(); + } + } + + if (!CallScreenSetup(screen)) return; + + if (!SendScreenVPData(screen, true)) { + DEBUG_ECHOLNPGM("SendScreenVPData failed"); + return; + } + + current_screen = screen; + dgus_display.SwitchScreen(current_screen); +} + +bool DGUSScreenHandler::SendScreenVPData(DGUS_Screen 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)) 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_display.GetFreeTxBuffer()) { + if (ELAPSED(ExtUI::safe_millis(), try_until)) return false; // Stop trying after 1 second + + dgus_display.FlushTx(); // Flush the TX buffer + delay(50); + } + + vp.tx_handler(vp); + } +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.h new file mode 100644 index 000000000000..12426d1816e1 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSScreenHandler.h @@ -0,0 +1,146 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include "config/DGUS_Addr.h" +#include "config/DGUS_Data.h" +#include "config/DGUS_Screen.h" +#include "config/DGUS_Constants.h" + +#include "../../ui_api.h" +#include "../../../../inc/MarlinConfigPre.h" + +class DGUSScreenHandler { +public: + DGUSScreenHandler() = default; + + static void Init(); + static void Ready(); + static void Loop(); + + static void PrinterKilled(PGM_P error, PGM_P component); + static void UserConfirmRequired(const char * const msg); + 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 MeshUpdate(const int8_t xpos, const int8_t ypos, const float zval); + static void PrintTimerStarted(); + static void PrintTimerPaused(); + static void PrintTimerStopped(); + static void FilamentRunout(const ExtUI::extruder_t extruder); + + #if ENABLED(SDSUPPORT) + /// 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(); + #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 SetMessageLine(const char* msg, uint8_t line); + static void SetMessageLinePGM(PGM_P msg, uint8_t line); + + static void SetStatusMessage(const char* msg, const millis_t duration = DGUS_STATUS_EXPIRATION_MS); + static void SetStatusMessagePGM(PGM_P msg, const millis_t duration = DGUS_STATUS_EXPIRATION_MS); + + static void ShowWaitScreen(DGUS_Screen return_screen, bool has_continue = false); + + static DGUS_Screen GetCurrentScreen(); + static void TriggerScreenChange(DGUS_Screen screen); + static void TriggerFullUpdate(); + + static void TriggerEEPROMSave(); + + static bool IsPrinterIdle(); + + #if ENABLED(SDSUPPORT) + static ExtUI::FileList filelist; + static uint16_t filelist_offset; + static int16_t filelist_selected; + #endif + + static DGUS_Data::StepSize offset_steps; + static DGUS_Data::StepSize move_steps; + + static uint16_t probing_icons[2]; + + static DGUS_Data::Extruder filament_extruder; + static uint16_t filament_length; + + static char gcode[DGUS_GCODE_LEN + 1]; + + static DGUS_Data::Heater pid_heater; + static uint16_t pid_temp; + static uint8_t pid_cycles; + + static bool wait_continue; + +private: + static const DGUS_Addr* FindScreenAddrList(DGUS_Screen screen); + static bool CallScreenSetup(DGUS_Screen screen); + + static void MoveToScreen(DGUS_Screen screen, bool abort_wait = false); + static bool SendScreenVPData(DGUS_Screen screen, bool complete_update); + + static bool settings_ready; + static bool booted; + + static DGUS_Screen current_screen; + static DGUS_Screen new_screen; + static bool full_update; + + static DGUS_Screen wait_return_screen; + + static millis_t status_expire; + static millis_t eeprom_save; + + typedef struct { + bool initialized; + uint8_t volume; + uint8_t brightness; + bool abl; + } eeprom_data_t; +}; + +extern DGUSScreenHandler dgus_screen_handler; + +extern const char DGUS_MSG_HOMING_REQUIRED[], + DGUS_MSG_BUSY[], + DGUS_MSG_UNDEF[], + DGUS_MSG_HOMING[]; + +extern const char DGUS_CMD_HOME[], + DGUS_CMD_EEPROM_SAVE[]; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.cpp new file mode 100644 index 000000000000..d3400433430f --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.cpp @@ -0,0 +1,184 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUSSetupHandler.h" + +#include "DGUSDisplay.h" +#include "DGUSScreenHandler.h" + +#include "../../../../gcode/queue.h" + +#if ENABLED(SDSUPPORT) + bool DGUSSetupHandler::Print() { + dgus_screen_handler.filelist.refresh(); + + while (!dgus_screen_handler.filelist.isAtRootDir()) { + dgus_screen_handler.filelist.upDir(); + } + + dgus_screen_handler.filelist_offset = 0; + dgus_screen_handler.filelist_selected = -1; + + return true; + } +#endif + +bool DGUSSetupHandler::PrintStatus() { + if (printingIsActive() || printingIsPaused()) { + return true; + } + + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::PRINT_FINISHED); + return false; +} + +bool DGUSSetupHandler::PrintAdjust() { + if (printingIsActive() || printingIsPaused()) { + return true; + } + + dgus_screen_handler.TriggerScreenChange(DGUS_Screen::PRINT_FINISHED); + return false; +} + +bool DGUSSetupHandler::LevelingMenu() { + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return false; + } + + if (ExtUI::isPositionKnown()) { + if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 10.0f) { + queue.enqueue_now_P(PSTR("G0Z10")); + } + + return true; + } + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(DGUS_MSG_HOMING, 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(DGUS_Screen::LEVELING_MENU); + + queue.enqueue_now_P(DGUS_CMD_HOME); + + return false; +} + +bool DGUSSetupHandler::LevelingManual() { + if (ExtUI::isPositionKnown()) { + return true; + } + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return false; + } + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(DGUS_MSG_HOMING, 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(DGUS_Screen::LEVELING_MANUAL); + + queue.enqueue_now_P(DGUS_CMD_HOME); + + return false; +} + +bool DGUSSetupHandler::LevelingOffset() { + dgus_screen_handler.offset_steps = DGUS_Data::StepSize::MMP1; + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return false; + } + + if (ExtUI::isPositionKnown()) { + if (ExtUI::getAxisPosition_mm(ExtUI::Z) < 4.0f) { + queue.enqueue_now_P(PSTR("G0Z4")); + } + + char buffer[20]; + snprintf_P(buffer, sizeof(buffer), PSTR("G0X%dY%d"), DGUS_LEVEL_CENTER_X, DGUS_LEVEL_CENTER_Y); + + queue.enqueue_one_now(buffer); + queue.enqueue_now_P(PSTR("G0Z0")); + + return true; + } + + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 1); + dgus_screen_handler.SetMessageLinePGM(DGUS_MSG_HOMING, 2); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 3); + dgus_screen_handler.SetMessageLinePGM(NUL_STR, 4); + dgus_screen_handler.ShowWaitScreen(DGUS_Screen::LEVELING_OFFSET); + + queue.enqueue_now_P(DGUS_CMD_HOME); + + return false; +} + +bool DGUSSetupHandler::LevelingProbing() { + dgus_screen_handler.probing_icons[0] = 0; + dgus_screen_handler.probing_icons[1] = 0; + + return true; +} + +bool DGUSSetupHandler::Filament() { + dgus_screen_handler.filament_extruder = DGUS_Data::Extruder::CURRENT; + dgus_screen_handler.filament_length = DGUS_DEFAULT_FILAMENT_LEN; + + return true; +} + +bool DGUSSetupHandler::Move() { + dgus_screen_handler.move_steps = DGUS_Data::StepSize::MM10; + + if (!dgus_screen_handler.IsPrinterIdle()) { + dgus_screen_handler.SetStatusMessagePGM(DGUS_MSG_BUSY); + return false; + } + + return true; +} + +bool DGUSSetupHandler::Gcode() { + ZERO(dgus_screen_handler.gcode); + + return true; +} + +bool DGUSSetupHandler::PID() { + dgus_screen_handler.pid_heater = DGUS_Data::Heater::H0; + dgus_screen_handler.pid_temp = DGUS_PLA_TEMP_HOTEND; + + return true; +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.h new file mode 100644 index 000000000000..2d9d0b551f53 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSSetupHandler.h @@ -0,0 +1,41 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +namespace DGUSSetupHandler { + + #if ENABLED(SDSUPPORT) + bool Print(); + #endif + bool PrintStatus(); + bool PrintAdjust(); + bool LevelingMenu(); + bool LevelingOffset(); + bool LevelingManual(); + bool LevelingProbing(); + bool Filament(); + bool Move(); + bool Gcode(); + bool PID(); + +} diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.cpp new file mode 100644 index 000000000000..45d169911368 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.cpp @@ -0,0 +1,632 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUSTxHandler.h" + +#include "DGUSScreenHandler.h" +#include "config/DGUS_Data.h" + +#include "../../ui_api.h" +#include "../../../../module/stepper.h" +#include "../../../../module/printcounter.h" +#if ENABLED(ADVANCED_PAUSE_FEATURE) + #include "../../../../feature/pause.h" +#endif + +#if ENABLED(SDSUPPORT) + void DGUSTxHandler::SetFileControlState(int file, bool state) { + DGUS_Control control; + + switch (file) { + default: return; + case 0: + control = DGUS_Control::FILE0; + break; + case 1: + control = DGUS_Control::FILE1; + break; + case 2: + control = DGUS_Control::FILE2; + break; + case 3: + control = DGUS_Control::FILE3; + break; + case 4: + control = DGUS_Control::FILE4; + break; + } + + if (state) { + dgus_display.EnableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + control); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + control); + } + } + + void DGUSTxHandler::FileType(DGUS_VP &vp) { + // Batch send + uint16_t data[DGUS_FILE_COUNT]; + + for (int i = 0; i < DGUS_FILE_COUNT; i++) { + if (!dgus_screen_handler.filelist.seek(dgus_screen_handler.filelist_offset + i)) { + data[i] = Swap16((uint16_t)DGUS_Data::SDType::NONE); + + SetFileControlState(i, false); + continue; + } + + data[i] = dgus_screen_handler.filelist.isDir() ? + Swap16((uint16_t)DGUS_Data::SDType::DIRECTORY) + : Swap16((uint16_t)DGUS_Data::SDType::FILE); + + SetFileControlState(i, true); + } + + dgus_display.Write((uint16_t)vp.addr, data, sizeof(*data) * DGUS_FILE_COUNT); + } + + void DGUSTxHandler::FileName(DGUS_VP &vp) { + uint8_t offset; + + switch (vp.addr) { + default: return; + case DGUS_Addr::SD_FileName0: + offset = 0; + break; + case DGUS_Addr::SD_FileName1: + offset = 1; + break; + case DGUS_Addr::SD_FileName2: + offset = 2; + break; + case DGUS_Addr::SD_FileName3: + offset = 3; + break; + case DGUS_Addr::SD_FileName4: + offset = 4; + break; + } + + if (dgus_screen_handler.filelist.seek(dgus_screen_handler.filelist_offset + offset)) { + dgus_display.WriteString((uint16_t)vp.addr, dgus_screen_handler.filelist.filename(), vp.size); + } + else { + dgus_display.WriteStringPGM((uint16_t)vp.addr, NUL_STR, vp.size); + } + } + + void DGUSTxHandler::ScrollIcons(DGUS_VP &vp) { + uint16_t icons = 0; + + if (!dgus_screen_handler.filelist.isAtRootDir()) { + icons |= (uint16_t)DGUS_Data::ScrollIcon::GO_BACK; + + dgus_display.EnableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::GO_BACK); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::GO_BACK); + } + + if (dgus_screen_handler.filelist_offset > 0) { + icons |= (uint16_t)DGUS_Data::ScrollIcon::UP; + + dgus_display.EnableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::SCROLL_UP); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::SCROLL_UP); + } + + if (dgus_screen_handler.filelist_offset + DGUS_FILE_COUNT < dgus_screen_handler.filelist.count()) { + icons |= (uint16_t)DGUS_Data::ScrollIcon::DOWN; + + dgus_display.EnableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::SCROLL_DOWN); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::SCROLL_DOWN); + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); + } + + void DGUSTxHandler::SelectedFileName(DGUS_VP &vp) { + if (dgus_screen_handler.filelist_selected < 0 + || !dgus_screen_handler.filelist.seek(dgus_screen_handler.filelist_selected)) { + dgus_display.WriteStringPGM((uint16_t)vp.addr, NUL_STR, vp.size); + return; + } + + dgus_display.WriteString((uint16_t)vp.addr, dgus_screen_handler.filelist.filename(), vp.size); + } +#endif // SDSUPPORT + +void DGUSTxHandler::PositionZ(DGUS_VP &vp) { + float position = ExtUI::isAxisPositionKnown(ExtUI::Z) ? + planner.get_axis_position_mm(Z_AXIS) + : 0; + + const int16_t data = dgus_display.ToFixedPoint(position); + dgus_display.Write((uint16_t)vp.addr, Swap16(data)); +} + +void DGUSTxHandler::Ellapsed(DGUS_VP &vp) { + char buffer[21]; + duration_t(print_job_timer.duration()).toString(buffer); + + dgus_display.WriteString((uint16_t)vp.addr, buffer, vp.size); +} + +void DGUSTxHandler::Percent(DGUS_VP &vp) { + uint16_t progress; + + switch (vp.addr) { + default: return; + case DGUS_Addr::STATUS_Percent: + progress = constrain(ExtUI::getProgress_percent(), 0, 100); + break; + case DGUS_Addr::STATUS_Percent_Complete: + progress = 100; + break; + } + + dgus_display.Write((uint16_t)DGUS_Addr::STATUS_Percent, Swap16(progress)); +} + +void DGUSTxHandler::StatusIcons(DGUS_VP &vp) { + uint16_t icons = 0; + + if (printingIsActive()) { + icons |= (uint16_t)DGUS_Data::StatusIcon::PAUSE; + + dgus_display.EnableControl(DGUS_Screen::PRINT_STATUS, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::PAUSE); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT_STATUS, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::PAUSE); + } + + if (printingIsPaused()) { + icons |= (uint16_t)DGUS_Data::StatusIcon::RESUME; + + dgus_display.EnableControl(DGUS_Screen::PRINT_STATUS, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::RESUME); + } + else { + dgus_display.DisableControl(DGUS_Screen::PRINT_STATUS, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::RESUME); + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); +} + +void DGUSTxHandler::Flowrate(DGUS_VP &vp) { + int16_t flowrate; + + switch (vp.addr) { + default: return; + case DGUS_Addr::ADJUST_Flowrate_CUR: + #if EXTRUDERS > 1 + flowrate = ExtUI::getFlowPercentage(ExtUI::getActiveTool()); + #else + flowrate = ExtUI::getFlowPercentage(ExtUI::E0); + #endif + break; + #if EXTRUDERS > 1 + case DGUS_Addr::ADJUST_Flowrate_E0: + flowrate = ExtUI::getFlowPercentage(ExtUI::E0); + break; + case DGUS_Addr::ADJUST_Flowrate_E1: + flowrate = ExtUI::getFlowPercentage(ExtUI::E1); + break; + #endif + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(flowrate)); +} + +void DGUSTxHandler::TempMax(DGUS_VP &vp) { + uint16_t temp; + + switch (vp.addr) { + default: return; + case DGUS_Addr::TEMP_Max_Bed: + temp = BED_MAXTEMP - 10; + break; + case DGUS_Addr::TEMP_Max_H0: + temp = HEATER_0_MAXTEMP - 15; + break; + #if HOTENDS > 1 + case DGUS_Addr::TEMP_Max_H1: + temp = HEATER_1_MAXTEMP - 15; + break; + #endif + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(temp)); +} + +void DGUSTxHandler::StepperStatus(DGUS_VP &vp) { + if (X_ENABLE_READ() == X_ENABLE_ON + && Y_ENABLE_READ() == Y_ENABLE_ON + && Z_ENABLE_READ() == Z_ENABLE_ON) { + dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::ENABLED)); + } + else { + dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::DISABLED)); + } +} + +void DGUSTxHandler::StepIcons(DGUS_VP &vp) { + if (!vp.extra) return; + uint16_t icons = 0; + DGUS_Data::StepSize size = *(DGUS_Data::StepSize*)vp.extra; + + switch (size) { + case DGUS_Data::StepSize::MM10: + icons |= (uint16_t)DGUS_Data::StepIcon::MM10; + break; + case DGUS_Data::StepSize::MM1: + icons |= (uint16_t)DGUS_Data::StepIcon::MM1; + break; + case DGUS_Data::StepSize::MMP1: + icons |= (uint16_t)DGUS_Data::StepIcon::MMP1; + break; + case DGUS_Data::StepSize::MMP01: + icons |= (uint16_t)DGUS_Data::StepIcon::MMP01; + break; + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); +} + +void DGUSTxHandler::ABLDisableIcon(DGUS_VP &vp) { + uint16_t data; + + if (ExtUI::getLevelingActive()) { + data = (uint16_t)DGUS_Data::Status::ENABLED; + + dgus_display.EnableControl(DGUS_Screen::LEVELING_AUTOMATIC, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::DISABLE); + } + else { + data = (uint16_t)DGUS_Data::Status::DISABLED; + + dgus_display.DisableControl(DGUS_Screen::LEVELING_AUTOMATIC, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::DISABLE); + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(data)); +} + +void DGUSTxHandler::ABLGrid(DGUS_VP &vp) { + // Batch send + int16_t data[DGUS_LEVEL_GRID_SIZE]; + xy_uint8_t point; + int16_t fixed; + + for (int i = 0; i < DGUS_LEVEL_GRID_SIZE; i++) { + point.x = i % GRID_MAX_POINTS_X; + point.y = i / GRID_MAX_POINTS_X; + fixed = dgus_display.ToFixedPoint(ExtUI::getMeshPoint(point)); + data[i] = Swap16(fixed); + } + + dgus_display.Write((uint16_t)vp.addr, data, sizeof(*data) * DGUS_LEVEL_GRID_SIZE); +} + +void DGUSTxHandler::FilamentIcons(DGUS_VP &vp) { + uint16_t icons = 0; + + switch (dgus_screen_handler.filament_extruder) { + default: return; + case DGUS_Data::Extruder::CURRENT: + #if EXTRUDERS > 1 + switch (ExtUI::getActiveTool()) { + default: break; + case ExtUI::E0: + icons |= (uint16_t)DGUS_Data::ExtruderIcon::E0; + break; + case ExtUI::E1: + icons |= (uint16_t)DGUS_Data::ExtruderIcon::E1; + break; + } + break; + #endif + case DGUS_Data::Extruder::E0: + icons |= (uint16_t)DGUS_Data::ExtruderIcon::E0; + break; + case DGUS_Data::Extruder::E1: + icons |= (uint16_t)DGUS_Data::ExtruderIcon::E1; + break; + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); +} + +void DGUSTxHandler::BLTouch(DGUS_VP &vp) { + #if ENABLED(BLTOUCH) + dgus_display.EnableControl(DGUS_Screen::SETTINGS_MENU2, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::EXTRA2); + + dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::ENABLED)); + #else + dgus_display.DisableControl(DGUS_Screen::SETTINGS_MENU2, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::EXTRA2); + + dgus_display.Write((uint16_t)vp.addr, Swap16((uint16_t)DGUS_Data::Status::DISABLED)); + #endif +} + +void DGUSTxHandler::PIDIcons(DGUS_VP &vp) { + uint16_t icons = 0; + + switch (dgus_screen_handler.pid_heater) { + default: return; + case DGUS_Data::Heater::BED: + icons |= (uint16_t)DGUS_Data::HeaterIcon::BED; + break; + case DGUS_Data::Heater::H0: + icons |= (uint16_t)DGUS_Data::HeaterIcon::H0; + break; + case DGUS_Data::Heater::H1: + icons |= (uint16_t)DGUS_Data::HeaterIcon::H1; + break; + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); +} + +void DGUSTxHandler::PIDKp(DGUS_VP &vp) { + float value; + + switch (dgus_screen_handler.pid_heater) { + default: return; + #if ENABLED(PIDTEMPBED) + case DGUS_Data::Heater::BED: + value = ExtUI::getBedPIDValues_Kp(); + break; + #endif + #if ENABLED(PIDTEMP) + case DGUS_Data::Heater::H0: + value = ExtUI::getPIDValues_Kp(ExtUI::E0); + break; + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + value = ExtUI::getPIDValues_Kp(ExtUI::E1); + break; + #endif + #endif + } + + const int32_t data = dgus_display.ToFixedPoint(value); + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(data)); +} + +void DGUSTxHandler::PIDKi(DGUS_VP &vp) { + float value; + + switch (dgus_screen_handler.pid_heater) { + default: return; + #if ENABLED(PIDTEMPBED) + case DGUS_Data::Heater::BED: + value = ExtUI::getBedPIDValues_Ki(); + break; + #endif + #if ENABLED(PIDTEMP) + case DGUS_Data::Heater::H0: + value = ExtUI::getPIDValues_Ki(ExtUI::E0); + break; + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + value = ExtUI::getPIDValues_Ki(ExtUI::E1); + break; + #endif + #endif + } + + const int32_t data = dgus_display.ToFixedPoint(value); + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(data)); +} + +void DGUSTxHandler::PIDKd(DGUS_VP &vp) { + float value; + + switch (dgus_screen_handler.pid_heater) { + default: return; + #if ENABLED(PIDTEMPBED) + case DGUS_Data::Heater::BED: + value = ExtUI::getBedPIDValues_Kd(); + break; + #endif + #if ENABLED(PIDTEMP) + case DGUS_Data::Heater::H0: + value = ExtUI::getPIDValues_Kd(ExtUI::E0); + break; + #if HOTENDS > 1 + case DGUS_Data::Heater::H1: + value = ExtUI::getPIDValues_Kd(ExtUI::E1); + break; + #endif + #endif + } + + const int32_t data = dgus_display.ToFixedPoint(value); + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(data)); +} + +void DGUSTxHandler::BuildVolume(DGUS_VP &vp) { + char buffer[vp.size]; + snprintf_P(buffer, vp.size, PSTR("%dx%dx%d"), X_BED_SIZE, Y_BED_SIZE, (Z_MAX_POS - Z_MIN_POS)); + + dgus_display.WriteString((uint16_t)vp.addr, buffer, vp.size); +} + +void DGUSTxHandler::TotalPrints(DGUS_VP &vp) { + #if ENABLED(PRINTCOUNTER) + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(print_job_timer.getStats().totalPrints)); + #else + UNUSED(vp); + #endif +} + +void DGUSTxHandler::FinishedPrints(DGUS_VP &vp) { + #if ENABLED(PRINTCOUNTER) + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(print_job_timer.getStats().finishedPrints)); + #else + UNUSED(vp); + #endif +} + +void DGUSTxHandler::PrintTime(DGUS_VP &vp) { + #if ENABLED(PRINTCOUNTER) + char buffer[21]; + ExtUI::getTotalPrintTime_str(buffer); + + dgus_display.WriteString((uint16_t)vp.addr, buffer, vp.size); + #else + dgus_display.WriteStringPGM((uint16_t)vp.addr, DGUS_MSG_UNDEF, vp.size); + #endif +} + +void DGUSTxHandler::LongestPrint(DGUS_VP &vp) { + #if ENABLED(PRINTCOUNTER) + char buffer[21]; + ExtUI::getLongestPrint_str(buffer); + + dgus_display.WriteString((uint16_t)vp.addr, buffer, vp.size); + #else + dgus_display.WriteStringPGM((uint16_t)vp.addr, DGUS_MSG_UNDEF, vp.size); + #endif +} + +void DGUSTxHandler::FilamentUsed(DGUS_VP &vp) { + #if ENABLED(PRINTCOUNTER) + char buffer[21]; + ExtUI::getFilamentUsed_str(buffer); + + dgus_display.WriteString((uint16_t)vp.addr, buffer, vp.size); + #else + dgus_display.WriteStringPGM((uint16_t)vp.addr, DGUS_MSG_UNDEF, vp.size); + #endif +} + +void DGUSTxHandler::WaitIcons(DGUS_VP &vp) { + uint16_t icons = 0; + + if (printingIsPaused() + #if ENABLED(ADVANCED_PAUSE_FEATURE) + && did_pause_print + #endif + ) { + icons |= (uint16_t)DGUS_Data::WaitIcon::ABORT; + + dgus_display.EnableControl(DGUS_Screen::WAIT, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::ABORT); + } + else { + dgus_display.DisableControl(DGUS_Screen::WAIT, + DGUSDisplay::POPUP_WINDOW, + DGUS_Control::ABORT); + } + + if (dgus_screen_handler.wait_continue) { + icons |= (uint16_t)DGUS_Data::WaitIcon::CONTINUE; + + dgus_display.EnableControl(DGUS_Screen::WAIT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::CONTINUE); + } + else { + dgus_display.DisableControl(DGUS_Screen::WAIT, + DGUSDisplay::RETURN_KEY_CODE, + DGUS_Control::CONTINUE); + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(icons)); +} + +void DGUSTxHandler::FanSpeed(DGUS_VP &vp) { + uint16_t fan_speed; + + switch (vp.addr) { + default: return; + case DGUS_Addr::FAN0_Speed: fan_speed = ExtUI::getTargetFan_percent(ExtUI::FAN0); break; + } + + dgus_display.Write((uint16_t)vp.addr, Swap16(fan_speed)); +} + +void DGUSTxHandler::Volume(DGUS_VP &vp) { + const uint16_t volume = dgus_display.GetVolume(); + + dgus_display.Write((uint16_t)vp.addr, Swap16(volume)); +} + +void DGUSTxHandler::Brightness(DGUS_VP &vp) { + const uint16_t brightness = dgus_display.GetBrightness(); + + dgus_display.Write((uint16_t)vp.addr, Swap16(brightness)); +} + +void DGUSTxHandler::ExtraToString(DGUS_VP &vp) { + if (!vp.size || !vp.extra) return; + + dgus_display.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_display.WriteStringPGM((uint16_t)vp.addr, vp.extra, vp.size, true, false, false); +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.h new file mode 100644 index 000000000000..2abccd5b2913 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/DGUSTxHandler.h @@ -0,0 +1,127 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once + +#include "DGUSDisplay.h" +#include "definition/DGUS_VP.h" + +namespace DGUSTxHandler { + + #if ENABLED(SDSUPPORT) + void SetFileControlState(int, bool); + void FileType(DGUS_VP &); + void FileName(DGUS_VP &); + void ScrollIcons(DGUS_VP &); + void SelectedFileName(DGUS_VP &); + #endif + + void PositionZ(DGUS_VP &); + void Ellapsed(DGUS_VP &); + void Percent(DGUS_VP &); + void StatusIcons(DGUS_VP &); + + void Flowrate(DGUS_VP &); + + void TempMax(DGUS_VP &); + + void StepperStatus(DGUS_VP &); + + void StepIcons(DGUS_VP &); + + void ABLDisableIcon(DGUS_VP &); + void ABLGrid(DGUS_VP &); + + void FilamentIcons(DGUS_VP &); + + void BLTouch(DGUS_VP &); + + void PIDIcons(DGUS_VP &); + void PIDKp(DGUS_VP &); + void PIDKi(DGUS_VP &); + void PIDKd(DGUS_VP &); + + void BuildVolume(DGUS_VP &); + void TotalPrints(DGUS_VP &); + void FinishedPrints(DGUS_VP &); + void PrintTime(DGUS_VP &); + void LongestPrint(DGUS_VP &); + void FilamentUsed(DGUS_VP &); + + void WaitIcons(DGUS_VP &); + + void FanSpeed(DGUS_VP &); + + void Volume(DGUS_VP &); + + void Brightness(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_display.Write((uint16_t)vp.addr, data); + break; + } + case 2: { + const uint16_t data = (uint16_t)(*(T*)vp.extra); + dgus_display.Write((uint16_t)vp.addr, Swap16(data)); + break; + } + case 4: { + const uint32_t data = (uint32_t)(*(T*)vp.extra); + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(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_display.ToFixedPoint(*(T*)vp.extra); + dgus_display.Write((uint16_t)vp.addr, data); + break; + } + case 2: { + const uint16_t data = dgus_display.ToFixedPoint(*(T*)vp.extra); + dgus_display.Write((uint16_t)vp.addr, Swap16(data)); + break; + } + case 4: { + const uint32_t data = dgus_display.ToFixedPoint(*(T*)vp.extra); + dgus_display.Write((uint16_t)vp.addr, dgus_display.SwapBytes(data)); + break; + } + } + } + +} diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Addr.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Addr.h new file mode 100644 index 000000000000..14b4676aa8bb --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Addr.h @@ -0,0 +1,172 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +constexpr uint8_t DGUS_LINE_LEN = 32; +constexpr uint8_t DGUS_STATUS_LEN = 32; +constexpr uint8_t DGUS_FILE_COUNT = 5; +constexpr uint8_t DGUS_FILENAME_LEN = 32; +constexpr uint8_t DGUS_ELLAPSED_LEN = 15; +constexpr uint8_t DGUS_LEVEL_GRID_SIZE = 25; +constexpr uint8_t DGUS_MACHINE_LEN = 24; +constexpr uint8_t DGUS_BUILDVOLUME_LEN = 24; +constexpr uint8_t DGUS_VERSION_LEN = 16; +constexpr uint8_t DGUS_PRINTTIME_LEN = 24; +constexpr uint8_t DGUS_LONGESTPRINT_LEN = 24; +constexpr uint8_t DGUS_FILAMENTUSED_LEN = 24; +constexpr uint8_t DGUS_GCODE_LEN = 32; + +enum class DGUS_Addr : uint16_t { + MESSAGE_Line1 = 0x1100, // 0x1100 - 0x111F + MESSAGE_Line2 = 0x1120, // 0x1120 - 0x113F + MESSAGE_Line3 = 0x1140, // 0x1140 - 0x115F + MESSAGE_Line4 = 0x1160, // 0x1160 - 0x117F + + // READ-ONLY VARIABLES + + SCREENCHANGE = 0x2000, // Screen change request. Data contains target screen in low byte. + SCREENCHANGE_SD = 0x2001, // Only change if SD card present. + SCREENCHANGE_Idle = 0x2002, // Only change if not printing. + SCREENCHANGE_Printing = 0x2003, // Only change if printing. + SD_SelectFile = 0x2004, // Data: file index (0-4) + SD_Scroll = 0x2005, // Data: DGUS_Data::Scroll + SD_Print = 0x2006, + STATUS_Abort = 0x2007, // Popup / Data: DGUS_Data::Popup + STATUS_Pause = 0x2008, // Popup / Data: DGUS_Data::Popup + STATUS_Resume = 0x2009, // Popup / Data: DGUS_Data::Popup + ADJUST_SetFeedrate = 0x200A, // Type: Integer (16 bits signed) + ADJUST_SetFlowrate_CUR = 0x200B, // Type: Integer (16 bits signed) + #if EXTRUDERS > 1 + ADJUST_SetFlowrate_E0 = 0x200C, // Type: Integer (16 bits signed) + ADJUST_SetFlowrate_E1 = 0x200D, // Type: Integer (16 bits signed) + #endif + ADJUST_SetBabystep = 0x200E, // Type: Fixed point, 2 decimals (16 bits signed) + ADJUST_Babystep = 0x200F, // Data: DGUS_Data::Adjust + TEMP_Preset = 0x2010, // Popup / Data: DGUS_Data::TempPreset + TEMP_SetTarget_Bed = 0x2011, // Type: Integer (16 bits signed) + TEMP_SetTarget_H0 = 0x2012, // Type: Integer (16 bits signed) + #if HOTENDS > 1 + TEMP_SetTarget_H1 = 0x2013, // Type: Integer (16 bits signed) + #endif + TEMP_Cool = 0x2014, // Data: DGUS_Data::Heater + STEPPER_Control = 0x2015, // Popup / Data: DGUS_Data::Control + LEVEL_OFFSET_Set = 0x2016, // Type: Fixed point, 2 decimals (16 bits signed) + LEVEL_OFFSET_Step = 0x2017, // Data: DGUS_Data::Adjust + LEVEL_OFFSET_SetStep = 0x2018, // Data: DGUS_Data::StepSize + LEVEL_MANUAL_Point = 0x2019, // Data: point index (1-5) + LEVEL_AUTO_Probe = 0x201A, + LEVEL_AUTO_Disable = 0x201B, + FILAMENT_Select = 0x201C, // Data: DGUS_Data::Extruder + FILAMENT_SetLength = 0x201D, // Type: Integer (16 bits unsigned) + FILAMENT_Move = 0x201E, // Data: DGUS_Data::FilamentMove + MOVE_Home = 0x201F, // Data: DGUS_Data::Axis + MOVE_SetX = 0x2020, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_SetY = 0x2021, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_SetZ = 0x2022, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_Step = 0x2023, // Data: DGUS_Data::MoveDirection + MOVE_SetStep = 0x2024, // Data: DGUS_Data::StepSize + GCODE_Clear = 0x2025, + GCODE_Execute = 0x2026, + EEPROM_Reset = 0x2027, // Popup / Data: DGUS_Data::Popup + SETTINGS2_Extra = 0x2028, // Data: DGUS_Data::Extra + PID_Select = 0x2029, // Data: DGUS_Data::Heater + PID_SetTemp = 0x202A, // Type: Integer (16 bits unsigned) + PID_Run = 0x202B, + POWERLOSS_Abort = 0x202C, // Popup / Data: DGUS_Data::Popup + POWERLOSS_Resume = 0x202D, // Popup / Data: DGUS_Data::Popup + WAIT_Abort = 0x202E, // Popup / Data: DGUS_Data::Popup + WAIT_Continue = 0x202F, + + // WRITE-ONLY VARIABLES + + MESSAGE_Status = 0x3000, // 0x3000 - 0x301F + SD_Type = 0x3020, // 0x3020 - 0x3024 / Data: DGUS_Data::SDType + SD_FileName0 = 0x3025, // 0x3025 - 0x3044 + SD_FileName1 = 0x3045, // 0x3045 - 0x3064 + SD_FileName2 = 0x3065, // 0x3065 - 0x3084 + SD_FileName3 = 0x3085, // 0x3085 - 0x30A4 + SD_FileName4 = 0x30A5, // 0x30A5 - 0x30C4 + SD_ScrollIcons = 0x30C5, // Bits: DGUS_Data::ScrollIcon + SD_SelectedFileName = 0x30C6, // 0x30C6 - 0x30E5 + STATUS_PositionZ = 0x30E6, // Type: Fixed point, 1 decimal (16 bits signed) + STATUS_Ellapsed = 0x30E7, // 0x30E7 - 0x30F5 + STATUS_Percent = 0x30F6, // Type: Integer (16 bits unsigned) + STATUS_Icons = 0x30F7, // Bits: DGUS_Data::StatusIcon + ADJUST_Feedrate = 0x30F8, // Type: Integer (16 bits signed) + ADJUST_Flowrate_CUR = 0x30F9, // Type: Integer (16 bits signed) + #if EXTRUDERS > 1 + ADJUST_Flowrate_E0 = 0x30FA, // Type: Integer (16 bits signed) + ADJUST_Flowrate_E1 = 0x30FB, // Type: Integer (16 bits signed) + #endif + TEMP_Current_Bed = 0x30FC, // Type: Integer (16 bits signed) + TEMP_Target_Bed = 0x30FD, // Type: Integer (16 bits signed) + TEMP_Max_Bed = 0x30FE, // Type: Integer (16 bits unsigned) + TEMP_Current_H0 = 0x30FF, // Type: Integer (16 bits signed) + TEMP_Target_H0 = 0x3100, // Type: Integer (16 bits signed) + TEMP_Max_H0 = 0x3101, // Type: Integer (16 bits unsigned) + #if HOTENDS > 1 + TEMP_Current_H1 = 0x3102, // Type: Integer (16 bits signed) + TEMP_Target_H1 = 0x3103, // Type: Integer (16 bits signed) + TEMP_Max_H1 = 0x3104, // Type: Integer (16 bits unsigned) + #endif + STEPPER_Status = 0x3105, // Data: DGUS_Data::Status + LEVEL_OFFSET_Current = 0x3106, // Type: Fixed point, 2 decimals (16 bits signed) + LEVEL_OFFSET_StepIcons = 0x3107, // Bits: DGUS_Data::StepIcon + LEVEL_AUTO_DisableIcon = 0x3108, // Data: DGUS_Data::Status + LEVEL_AUTO_Grid = 0x3109, // 0x3109 - 0x3121 / Type: Fixed point, 3 decimals (16 bits signed) + LEVEL_PROBING_Icons1 = 0x3122, // Type: Integer (16 bits unsigned) / Each bit represents a grid point + LEVEL_PROBING_Icons2 = 0x3123, // Type: Integer (16 bits unsigned) / Each bit represents a grid point + FILAMENT_ExtruderIcons = 0x3124, // Data: DGUS_Data::ExtruderIcon + FILAMENT_Length = 0x3125, // Type: Integer (16 bits unsigned) + MOVE_CurrentX = 0x3126, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_CurrentY = 0x3127, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_CurrentZ = 0x3128, // Type: Fixed point, 1 decimal (16 bits signed) + MOVE_StepIcons = 0x3129, // Bits: DGUS_Data::StepIcon + SETTINGS2_BLTouch = 0x312A, // Data: DGUS_Data::Status + PID_HeaterIcons = 0x312B, // Data: DGUS_Data::HeaterIcon + PID_Temp = 0x312C, // Type: Integer (16 bits unsigned) + PID_Kp = 0x312D, // Type: Fixed point, 2 decimals (32 bits signed) + PID_Ki = 0x312F, // Type: Fixed point, 2 decimals (32 bits signed) + PID_Kd = 0x3131, // Type: Fixed point, 2 decimals (32 bits signed) + INFOS_Machine = 0x3133, // 0x3133 - 0x314A + INFOS_BuildVolume = 0x314B, // 0x314B - 0x3162 + INFOS_Version = 0x3163, // 0x3163 - 0x3172 + INFOS_TotalPrints = 0x3173, // Type: Integer (16 bits unsigned) + INFOS_FinishedPrints = 0x3174, // Type: Integer (16 bits unsigned) + INFOS_PrintTime = 0x3175, // 0x3175 - 0x318C + INFOS_LongestPrint = 0x318D, // 0x318D - 0x31A4 + INFOS_FilamentUsed = 0x31A5, // 0x31A5 - 0x31BC + WAIT_Icons = 0x31BD, // Bits: DGUS_Data::WaitIcon + + // READ-WRITE VARIABLES + + FAN0_Speed = 0x4000, // Type: Integer (16 bits unsigned) / Data: fan speed as percent (0-100) + GCODE_Data = 0x4001, // 0x4001 - 0x4020 + PID_Cycles = 0x4021, // Type: Integer (16 bits unsigned) + VOLUME_Level = 0x4022, // Type: Integer (16 bits unsigned) / Data: volume as percent (0-100) + BRIGHTNESS_Level = 0x4023, // Type: Integer (16 bits unsigned) / Data: brightness as percent (0-100) + + // SPECIAL CASES + + STATUS_Percent_Complete = 0x5000, // Same as STATUS_Percent, but always 100% + +}; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Constants.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Constants.h new file mode 100644 index 000000000000..b4e83ce394c0 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Constants.h @@ -0,0 +1,96 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../../../../../inc/MarlinConfigPre.h" + +#include "DGUS_Addr.h" + +static_assert((DGUS_LEVEL_GRID_SIZE == GRID_MAX_POINTS_X * GRID_MAX_POINTS_Y), "DGUS_LEVEL_GRID_SIZE incompatible with current mesh."); + +#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 DGUS_PRINT_BABYSTEP + #define DGUS_PRINT_BABYSTEP 0.01f +#endif + +#ifndef DGUS_PLA_TEMP_HOTEND + #define DGUS_PLA_TEMP_HOTEND 200 +#endif + +#ifndef DGUS_PLA_TEMP_BED + #define DGUS_PLA_TEMP_BED 60 +#endif + +#ifndef DGUS_ABS_TEMP_HOTEND + #define DGUS_ABS_TEMP_HOTEND 240 +#endif + +#ifndef DGUS_ABS_TEMP_BED + #define DGUS_ABS_TEMP_BED 80 +#endif + +#ifndef DGUS_PETG_TEMP_HOTEND + #define DGUS_PETG_TEMP_HOTEND 240 +#endif + +#ifndef DGUS_PETG_TEMP_BED + #define DGUS_PETG_TEMP_BED 60 +#endif + +#ifndef DGUS_DEFAULT_FILAMENT_LEN + #define DGUS_DEFAULT_FILAMENT_LEN 10 +#endif + +#ifndef LEVEL_CORNERS_Z_HOP + #define LEVEL_CORNERS_Z_HOP 4.0 +#endif + +#ifndef LEVEL_CORNERS_HEIGHT + #define LEVEL_CORNERS_HEIGHT 0.0 +#endif + +static_assert(LEVEL_CORNERS_Z_HOP >= 0, "LEVEL_CORNERS_Z_HOP must be >= 0. Please update your configuration."); + +#ifndef DGUS_LEVEL_CENTER_X + #define DGUS_LEVEL_CENTER_X ((X_BED_SIZE) / 2) +#endif + +#ifndef DGUS_LEVEL_CENTER_Y + #define DGUS_LEVEL_CENTER_Y ((Y_BED_SIZE) / 2) +#endif + +#if ENABLED(BLTOUCH) + #ifndef DGUS_RESET_BLTOUCH + #define DGUS_RESET_BLTOUCH "M999\nM280P0S160" + #endif +#endif diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Control.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Control.h new file mode 100644 index 000000000000..7d16723280f6 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Control.h @@ -0,0 +1,50 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +enum class DGUS_Control : uint8_t { + + // PRINT + FILE0 = 1, // RETURN_KEY_CODE + FILE1 = 2, // RETURN_KEY_CODE + FILE2 = 3, // RETURN_KEY_CODE + FILE3 = 4, // RETURN_KEY_CODE + FILE4 = 5, // RETURN_KEY_CODE + GO_BACK = 6, // RETURN_KEY_CODE + SCROLL_UP = 7, // RETURN_KEY_CODE + SCROLL_DOWN = 8, // RETURN_KEY_CODE + + // PRINT_STATUS + PAUSE = 1, // POPUP_WINDOW + RESUME = 2, // POPUP_WINDOW + + // LEVELING_AUTOMATIC + DISABLE = 5, // RETURN_KEY_CODE + + // SETTINGS_MENU2 + EXTRA2 = 6, // RETURN_KEY_CODE + + // WAIT + ABORT = 1, // POPUP_WINDOW + CONTINUE = 2 // RETURN_KEY_CODE + +}; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Data.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Data.h new file mode 100644 index 000000000000..6d6577375b45 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Data.h @@ -0,0 +1,148 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include + +namespace DGUS_Data { + + // RX constants + + enum class Scroll : uint8_t { + GO_BACK = 0, + UP = 1, + DOWN = 2 + }; + + enum class Popup : uint8_t { + CONFIRMED = 1 + }; + + enum class Adjust : uint8_t { + INCREMENT = 0, + DECREMENT = 1 + }; + + enum class TempPreset : uint8_t { + PLA = 1, + ABS = 2, + PETG = 3 + }; + + enum class Extruder : int8_t { + CURRENT = -1, + E0 = 0, + E1 = 1 + }; + + enum class Heater : int8_t { + ALL = -2, + BED = -1, + H0 = 0, + H1 = 1 + }; + + enum class Control : uint8_t { + ENABLE = 1, + DISABLE = 2 + }; + + enum class StepSize : uint8_t { + MM10 = 0, // 10mm + MM1 = 1, // 1mm + MMP1 = 2, // 0.1mm + MMP01 = 3 // 0.01mm + }; + + enum class FilamentMove : uint8_t { + RETRACT = 0, + EXTRUDE = 1 + }; + + enum class Axis : uint8_t { + X_Y_Z = 0, + X_Y = 1, + Z = 2 + }; + + enum class MoveDirection : uint8_t { + XP = 0, // X+ + XM = 1, // X- + YP = 2, // Y+ + YM = 3, // Y- + ZP = 4, // Z+ + ZM = 5 // Z- + }; + + enum class Extra : uint8_t { + BUTTON1 = 0, + BUTTON2 = 1 + }; + + // TX constants + + enum class SDType : uint16_t { + NONE = 0, + FILE = 1, + DIRECTORY = 2 + }; + + enum class ScrollIcon : uint16_t { + GO_BACK = 1U << 0, + UP = 1U << 1, + DOWN = 1U << 2 + }; + + enum class StatusIcon : uint16_t { + PAUSE = 1U << 0, + RESUME = 1U << 1 + }; + + enum class Status : uint16_t { + DISABLED = 0, + ENABLED = 1 + }; + + enum class StepIcon : uint16_t { + MM10 = 1U << 0, // 10mm + MM1 = 1U << 1, // 1mm + MMP1 = 1U << 2, // 0.1mm + MMP01 = 1U << 3 // 0.01mm + }; + + enum class ExtruderIcon : uint16_t { + E0 = 1U << 0, + E1 = 1U << 1 + }; + + enum class HeaterIcon : uint16_t { + BED = 1U << 0, + H0 = 1U << 1, + H1 = 1U << 2 + }; + + enum class WaitIcon : uint16_t { + ABORT = 1U << 0, + CONTINUE = 1U << 1 + }; + +}; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Screen.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Screen.h new file mode 100644 index 000000000000..f3c28924669c --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/config/DGUS_Screen.h @@ -0,0 +1,51 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +enum class DGUS_Screen : uint8_t { + BOOT = 0, + HOME = 1, + PRINT = 2, + PRINT_STATUS = 3, + PRINT_ADJUST = 4, + PRINT_FINISHED = 5, + TEMP_MENU = 6, + TEMP_MANUAL = 7, + FAN = 8, + SETTINGS_MENU = 9, + LEVELING_MENU = 10, + LEVELING_OFFSET = 11, + LEVELING_MANUAL = 12, + LEVELING_AUTOMATIC = 13, + LEVELING_PROBING = 14, + FILAMENT = 15, + MOVE = 16, + GCODE = 17, + SETTINGS_MENU2 = 18, + PID = 19, + VOLUME = 20, + BRIGHTNESS = 21, + INFOS = 22, + POWERLOSS = 248, + WAIT = 249, + KILL = 250 +}; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp new file mode 100644 index 000000000000..897d353525ec --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp @@ -0,0 +1,240 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUS_ScreenAddrList.h" + +#include "../../../ui_api.h" + +constexpr DGUS_Addr LIST_HOME[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + (DGUS_Addr)0 +}; + +#if ENABLED(SDSUPPORT) + constexpr DGUS_Addr LIST_PRINT[] PROGMEM = { + DGUS_Addr::SD_Type, + DGUS_Addr::SD_FileName0, + DGUS_Addr::SD_FileName1, + DGUS_Addr::SD_FileName2, + DGUS_Addr::SD_FileName3, + DGUS_Addr::SD_FileName4, + DGUS_Addr::SD_ScrollIcons, + DGUS_Addr::SD_SelectedFileName, + (DGUS_Addr)0 + }; +#endif + +constexpr DGUS_Addr LIST_PRINT_STATUS[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + DGUS_Addr::STATUS_PositionZ, + DGUS_Addr::STATUS_Ellapsed, + DGUS_Addr::STATUS_Percent, + DGUS_Addr::STATUS_Icons, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_PRINT_ADJUST[] PROGMEM = { + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Target_Bed, + DGUS_Addr::FAN0_Speed, + DGUS_Addr::ADJUST_Feedrate, + DGUS_Addr::ADJUST_Flowrate_CUR, + DGUS_Addr::LEVEL_OFFSET_Current, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_PRINT_FINISHED[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + DGUS_Addr::STATUS_PositionZ, + DGUS_Addr::STATUS_Ellapsed, + DGUS_Addr::STATUS_Percent_Complete, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_TEMP_MENU[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_TEMP_MANUAL[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Max_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + DGUS_Addr::TEMP_Max_Bed, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_FAN[] PROGMEM = { + DGUS_Addr::FAN0_Speed, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_SETTINGS_MENU[] PROGMEM = { + DGUS_Addr::STEPPER_Status, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_LEVELING_OFFSET[] PROGMEM = { + DGUS_Addr::LEVEL_OFFSET_Current, + DGUS_Addr::LEVEL_OFFSET_StepIcons, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_LEVELING_MANUAL[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_LEVELING_AUTOMATIC[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::TEMP_Current_Bed, + DGUS_Addr::TEMP_Target_Bed, + DGUS_Addr::LEVEL_AUTO_DisableIcon, + DGUS_Addr::LEVEL_AUTO_Grid, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_LEVELING_PROBING[] PROGMEM = { + DGUS_Addr::LEVEL_PROBING_Icons1, + DGUS_Addr::LEVEL_PROBING_Icons2, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_FILAMENT[] PROGMEM = { + DGUS_Addr::TEMP_Current_H0, + DGUS_Addr::TEMP_Target_H0, + DGUS_Addr::FILAMENT_ExtruderIcons, + DGUS_Addr::FILAMENT_Length, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_MOVE[] PROGMEM = { + DGUS_Addr::MOVE_CurrentX, + DGUS_Addr::MOVE_CurrentY, + DGUS_Addr::MOVE_CurrentZ, + DGUS_Addr::MOVE_StepIcons, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_GCODE[] PROGMEM = { + DGUS_Addr::GCODE_Data, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_SETTINGS_MENU2[] PROGMEM = { + DGUS_Addr::SETTINGS2_BLTouch, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_PID[] PROGMEM = { + DGUS_Addr::PID_HeaterIcons, + DGUS_Addr::PID_Temp, + DGUS_Addr::PID_Cycles, + DGUS_Addr::PID_Kp, + DGUS_Addr::PID_Ki, + DGUS_Addr::PID_Kd, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_VOLUME[] PROGMEM = { + DGUS_Addr::VOLUME_Level, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_BRIGHTNESS[] PROGMEM = { + DGUS_Addr::BRIGHTNESS_Level, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_INFOS[] PROGMEM = { + DGUS_Addr::INFOS_Machine, + DGUS_Addr::INFOS_BuildVolume, + DGUS_Addr::INFOS_Version, + DGUS_Addr::INFOS_TotalPrints, + DGUS_Addr::INFOS_FinishedPrints, + DGUS_Addr::INFOS_PrintTime, + DGUS_Addr::INFOS_LongestPrint, + DGUS_Addr::INFOS_FilamentUsed, + (DGUS_Addr)0 +}; + +constexpr DGUS_Addr LIST_WAIT[] PROGMEM = { + DGUS_Addr::WAIT_Icons, + (DGUS_Addr)0 +}; + +#define MAP_HELPER(SCREEN, LIST) \ + { .screen = SCREEN, \ + .addr_list = LIST } + +const struct DGUS_ScreenAddrList screen_addr_list_map[] PROGMEM = { + MAP_HELPER(DGUS_Screen::HOME, LIST_HOME), + #if ENABLED(SDSUPPORT) + MAP_HELPER(DGUS_Screen::PRINT, LIST_PRINT), + #endif + MAP_HELPER(DGUS_Screen::PRINT_STATUS, LIST_PRINT_STATUS), + MAP_HELPER(DGUS_Screen::PRINT_ADJUST, LIST_PRINT_ADJUST), + MAP_HELPER(DGUS_Screen::PRINT_FINISHED, LIST_PRINT_FINISHED), + MAP_HELPER(DGUS_Screen::TEMP_MENU, LIST_TEMP_MENU), + MAP_HELPER(DGUS_Screen::TEMP_MANUAL, LIST_TEMP_MANUAL), + MAP_HELPER(DGUS_Screen::FAN, LIST_FAN), + MAP_HELPER(DGUS_Screen::SETTINGS_MENU, LIST_SETTINGS_MENU), + MAP_HELPER(DGUS_Screen::LEVELING_OFFSET, LIST_LEVELING_OFFSET), + MAP_HELPER(DGUS_Screen::LEVELING_MANUAL, LIST_LEVELING_MANUAL), + MAP_HELPER(DGUS_Screen::LEVELING_AUTOMATIC, LIST_LEVELING_AUTOMATIC), + MAP_HELPER(DGUS_Screen::LEVELING_PROBING, LIST_LEVELING_PROBING), + MAP_HELPER(DGUS_Screen::FILAMENT, LIST_FILAMENT), + MAP_HELPER(DGUS_Screen::MOVE, LIST_MOVE), + MAP_HELPER(DGUS_Screen::GCODE, LIST_GCODE), + MAP_HELPER(DGUS_Screen::SETTINGS_MENU2, LIST_SETTINGS_MENU2), + MAP_HELPER(DGUS_Screen::PID, LIST_PID), + MAP_HELPER(DGUS_Screen::VOLUME, LIST_VOLUME), + MAP_HELPER(DGUS_Screen::BRIGHTNESS, LIST_BRIGHTNESS), + MAP_HELPER(DGUS_Screen::INFOS, LIST_INFOS), + MAP_HELPER(DGUS_Screen::WAIT, LIST_WAIT), + + MAP_HELPER((DGUS_Screen)0, nullptr) +}; + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.h new file mode 100644 index 000000000000..190b594af014 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenAddrList.h @@ -0,0 +1,32 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../config/DGUS_Screen.h" +#include "../config/DGUS_Addr.h" + +struct DGUS_ScreenAddrList { + DGUS_Screen screen; + const DGUS_Addr *addr_list; +}; + +extern const struct DGUS_ScreenAddrList screen_addr_list_map[]; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.cpp new file mode 100644 index 000000000000..66b5b4936c69 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.cpp @@ -0,0 +1,55 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#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 = { + #if ENABLED(SDSUPPORT) + SETUP_HELPER(DGUS_Screen::PRINT, &DGUSSetupHandler::Print), + #endif + SETUP_HELPER(DGUS_Screen::PRINT_STATUS, &DGUSSetupHandler::PrintStatus), + SETUP_HELPER(DGUS_Screen::PRINT_ADJUST, &DGUSSetupHandler::PrintAdjust), + SETUP_HELPER(DGUS_Screen::LEVELING_MENU, &DGUSSetupHandler::LevelingMenu), + SETUP_HELPER(DGUS_Screen::LEVELING_OFFSET, &DGUSSetupHandler::LevelingOffset), + SETUP_HELPER(DGUS_Screen::LEVELING_MANUAL, &DGUSSetupHandler::LevelingManual), + SETUP_HELPER(DGUS_Screen::LEVELING_PROBING, &DGUSSetupHandler::LevelingProbing), + SETUP_HELPER(DGUS_Screen::FILAMENT, &DGUSSetupHandler::Filament), + SETUP_HELPER(DGUS_Screen::MOVE, &DGUSSetupHandler::Move), + SETUP_HELPER(DGUS_Screen::GCODE, &DGUSSetupHandler::Gcode), + SETUP_HELPER(DGUS_Screen::PID, &DGUSSetupHandler::PID), + + SETUP_HELPER((DGUS_Screen)0, nullptr) +}; + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.h new file mode 100644 index 000000000000..adf285698862 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_ScreenSetup.h @@ -0,0 +1,31 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../config/DGUS_Screen.h" + +struct DGUS_ScreenSetup { + DGUS_Screen screen; + bool (*setup_fn)(void); +}; + +extern const struct DGUS_ScreenSetup screen_setup_list[]; diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VP.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VP.h new file mode 100644 index 000000000000..d78a171baafd --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VP.h @@ -0,0 +1,40 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "../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) + +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/lib/dgus_reloaded/definition/DGUS_VPList.cpp b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.cpp new file mode 100644 index 000000000000..4a86483c4130 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.cpp @@ -0,0 +1,367 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "../../../../../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "DGUS_VPList.h" + +#include "../config/DGUS_Addr.h" +#include "../DGUSScreenHandler.h" +#include "../DGUSRxHandler.h" +#include "../DGUSTxHandler.h" + +#include "../../../ui_api.h" +#include "../../../../../module/probe.h" +#include "../../../../../module/motion.h" +#include "../../../../../module/temperature.h" + +const char DGUS_MACHINENAME[] PROGMEM = MACHINE_NAME; +const char DGUS_MARLINVERSION[] PROGMEM = SHORT_BUILD_VERSION; + +#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_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) + +const struct DGUS_VP vp_list[] PROGMEM = { + + // READ-ONLY VARIABLES + + VP_HELPER_RX(DGUS_Addr::SCREENCHANGE, &DGUSRxHandler::ScreenChange), + VP_HELPER_RX(DGUS_Addr::SCREENCHANGE_SD, &DGUSRxHandler::ScreenChange), + VP_HELPER_RX(DGUS_Addr::SCREENCHANGE_Idle, &DGUSRxHandler::ScreenChange), + VP_HELPER_RX(DGUS_Addr::SCREENCHANGE_Printing, &DGUSRxHandler::ScreenChange), + + #if ENABLED(SDSUPPORT) + VP_HELPER_RX(DGUS_Addr::SD_SelectFile, &DGUSRxHandler::SelectFile), + VP_HELPER_RX(DGUS_Addr::SD_Scroll, &DGUSRxHandler::Scroll), + VP_HELPER_RX_NODATA(DGUS_Addr::SD_Print, &DGUSRxHandler::PrintFile), + #endif + + VP_HELPER_RX(DGUS_Addr::STATUS_Abort, &DGUSRxHandler::PrintAbort), + VP_HELPER_RX(DGUS_Addr::STATUS_Pause, &DGUSRxHandler::PrintPause), + VP_HELPER_RX(DGUS_Addr::STATUS_Resume, &DGUSRxHandler::PrintResume), + + VP_HELPER_RX(DGUS_Addr::ADJUST_SetFeedrate, &DGUSRxHandler::Feedrate), + VP_HELPER_RX(DGUS_Addr::ADJUST_SetFlowrate_CUR, &DGUSRxHandler::Flowrate), + #if EXTRUDERS > 1 + VP_HELPER_RX(DGUS_Addr::ADJUST_SetFlowrate_E0, &DGUSRxHandler::Flowrate), + VP_HELPER_RX(DGUS_Addr::ADJUST_SetFlowrate_E1, &DGUSRxHandler::Flowrate), + #endif + VP_HELPER_RX(DGUS_Addr::ADJUST_SetBabystep, &DGUSRxHandler::BabystepSet), + VP_HELPER_RX(DGUS_Addr::ADJUST_Babystep, &DGUSRxHandler::Babystep), + + VP_HELPER_RX(DGUS_Addr::TEMP_Preset, &DGUSRxHandler::TempPreset), + VP_HELPER_RX(DGUS_Addr::TEMP_SetTarget_Bed, &DGUSRxHandler::TempTarget), + VP_HELPER_RX(DGUS_Addr::TEMP_SetTarget_H0, &DGUSRxHandler::TempTarget), + #if HOTENDS > 1 + VP_HELPER_RX(DGUS_Addr::TEMP_SetTarget_H1, &DGUSRxHandler::TempTarget), + #endif + VP_HELPER_RX(DGUS_Addr::TEMP_Cool, &DGUSRxHandler::TempCool), + + VP_HELPER_RX(DGUS_Addr::STEPPER_Control, &DGUSRxHandler::Steppers), + + VP_HELPER_RX(DGUS_Addr::LEVEL_OFFSET_Set, &DGUSRxHandler::ZOffset), + VP_HELPER_RX(DGUS_Addr::LEVEL_OFFSET_Step, &DGUSRxHandler::ZOffsetStep), + VP_HELPER_RX(DGUS_Addr::LEVEL_OFFSET_SetStep, &DGUSRxHandler::ZOffsetSetStep), + + VP_HELPER_RX(DGUS_Addr::LEVEL_MANUAL_Point, &DGUSRxHandler::MoveToPoint), + + VP_HELPER_RX_NODATA(DGUS_Addr::LEVEL_AUTO_Probe, &DGUSRxHandler::Probe), + VP_HELPER_RX_NODATA(DGUS_Addr::LEVEL_AUTO_Disable, + &DGUSRxHandler::DisableABL), + + VP_HELPER_RX(DGUS_Addr::FILAMENT_Select, &DGUSRxHandler::FilamentSelect), + VP_HELPER_RX(DGUS_Addr::FILAMENT_SetLength, &DGUSRxHandler::FilamentLength), + VP_HELPER_RX(DGUS_Addr::FILAMENT_Move, &DGUSRxHandler::FilamentMove), + + VP_HELPER_RX(DGUS_Addr::MOVE_Home, &DGUSRxHandler::Home), + VP_HELPER_RX(DGUS_Addr::MOVE_SetX, &DGUSRxHandler::Move), + VP_HELPER_RX(DGUS_Addr::MOVE_SetY, &DGUSRxHandler::Move), + VP_HELPER_RX(DGUS_Addr::MOVE_SetZ, &DGUSRxHandler::Move), + VP_HELPER_RX(DGUS_Addr::MOVE_Step, &DGUSRxHandler::MoveStep), + VP_HELPER_RX(DGUS_Addr::MOVE_SetStep, &DGUSRxHandler::MoveSetStep), + + VP_HELPER_RX_NODATA(DGUS_Addr::GCODE_Clear, &DGUSRxHandler::GcodeClear), + VP_HELPER_RX_NODATA(DGUS_Addr::GCODE_Execute, &DGUSRxHandler::GcodeExecute), + + VP_HELPER_RX(DGUS_Addr::EEPROM_Reset, &DGUSRxHandler::ResetEEPROM), + + VP_HELPER_RX(DGUS_Addr::SETTINGS2_Extra, &DGUSRxHandler::SettingsExtra), + + VP_HELPER_RX(DGUS_Addr::PID_Select, &DGUSRxHandler::PIDSelect), + VP_HELPER_RX(DGUS_Addr::PID_SetTemp, &DGUSRxHandler::PIDSetTemp), + VP_HELPER_RX_NODATA(DGUS_Addr::PID_Run, &DGUSRxHandler::PIDRun), + + #if ENABLED(POWER_LOSS_RECOVERY) + VP_HELPER_RX(DGUS_Addr::POWERLOSS_Abort, &DGUSRxHandler::PowerLossAbort), + VP_HELPER_RX(DGUS_Addr::POWERLOSS_Resume, &DGUSRxHandler::PowerLossResume), + #endif + + VP_HELPER_RX(DGUS_Addr::WAIT_Abort, &DGUSRxHandler::WaitAbort), + VP_HELPER_RX_NODATA(DGUS_Addr::WAIT_Continue, &DGUSRxHandler::WaitContinue), + + // WRITE-ONLY VARIABLES + + #if ENABLED(SDSUPPORT) + VP_HELPER_TX(DGUS_Addr::SD_Type, &DGUSTxHandler::FileType), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_FileName0, + DGUS_FILENAME_LEN, + &DGUSTxHandler::FileName), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_FileName1, + DGUS_FILENAME_LEN, + &DGUSTxHandler::FileName), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_FileName2, + DGUS_FILENAME_LEN, + &DGUSTxHandler::FileName), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_FileName3, + DGUS_FILENAME_LEN, + &DGUSTxHandler::FileName), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_FileName4, + DGUS_FILENAME_LEN, + &DGUSTxHandler::FileName), + VP_HELPER_TX(DGUS_Addr::SD_ScrollIcons, &DGUSTxHandler::ScrollIcons), + VP_HELPER_TX_SIZE(DGUS_Addr::SD_SelectedFileName, + DGUS_FILENAME_LEN, + &DGUSTxHandler::SelectedFileName), + #endif + + VP_HELPER_TX_AUTO(DGUS_Addr::STATUS_PositionZ, + nullptr, + &DGUSTxHandler::PositionZ), + VP_HELPER(DGUS_Addr::STATUS_Ellapsed, + DGUS_ELLAPSED_LEN, + VPFLAG_AUTOUPLOAD, + nullptr, + nullptr, + &DGUSTxHandler::Ellapsed), + VP_HELPER_TX_AUTO(DGUS_Addr::STATUS_Percent, + nullptr, + &DGUSTxHandler::Percent), + VP_HELPER_TX(DGUS_Addr::STATUS_Icons, &DGUSTxHandler::StatusIcons), + + VP_HELPER_TX_AUTO(DGUS_Addr::ADJUST_Feedrate, + &feedrate_percentage, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX_AUTO(DGUS_Addr::ADJUST_Flowrate_CUR, + nullptr, + &DGUSTxHandler::Flowrate), + #if EXTRUDERS > 1 + VP_HELPER_TX_AUTO(DGUS_Addr::ADJUST_Flowrate_E0, + nullptr, + &DGUSTxHandler::Flowrate), + VP_HELPER_TX_AUTO(DGUS_Addr::ADJUST_Flowrate_E1, + nullptr, + &DGUSTxHandler::Flowrate), + #endif + + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Current_Bed, + &thermalManager.temp_bed.celsius, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Target_Bed, + &thermalManager.temp_bed.target, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX(DGUS_Addr::TEMP_Max_Bed, &DGUSTxHandler::TempMax), + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Current_H0, + &thermalManager.temp_hotend[ExtUI::heater_t::H0].celsius, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Target_H0, + &thermalManager.temp_hotend[ExtUI::heater_t::H0].target, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX(DGUS_Addr::TEMP_Max_H0, &DGUSTxHandler::TempMax), + #if HOTENDS > 1 + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Current_H1, + &thermalManager.temp_hotend[ExtUI::heater_t::H1].celsius, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX_AUTO(DGUS_Addr::TEMP_Target_H1, + &thermalManager.temp_hotend[ExtUI::heater_t::H1].target, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX(DGUS_Addr::TEMP_Max_H1, &DGUSTxHandler::TempMax), + #endif + + VP_HELPER_TX_AUTO(DGUS_Addr::STEPPER_Status, + nullptr, + &DGUSTxHandler::StepperStatus), + + VP_HELPER_TX_AUTO(DGUS_Addr::LEVEL_OFFSET_Current, + &probe.offset.z, + (&DGUSTxHandler::ExtraToFixedPoint)), + VP_HELPER_TX_EXTRA(DGUS_Addr::LEVEL_OFFSET_StepIcons, + &DGUSScreenHandler::offset_steps, + &DGUSTxHandler::StepIcons), + + VP_HELPER_TX_AUTO(DGUS_Addr::LEVEL_AUTO_DisableIcon, + nullptr, + &DGUSTxHandler::ABLDisableIcon), + VP_HELPER_TX(DGUS_Addr::LEVEL_AUTO_Grid, &DGUSTxHandler::ABLGrid), + + VP_HELPER_TX_EXTRA(DGUS_Addr::LEVEL_PROBING_Icons1, + &DGUSScreenHandler::probing_icons[0], + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_TX_EXTRA(DGUS_Addr::LEVEL_PROBING_Icons2, + &DGUSScreenHandler::probing_icons[1], + &DGUSTxHandler::ExtraToInteger), + + VP_HELPER_TX(DGUS_Addr::FILAMENT_ExtruderIcons, &DGUSTxHandler::FilamentIcons), + VP_HELPER_TX_EXTRA(DGUS_Addr::FILAMENT_Length, + &DGUSScreenHandler::filament_length, + &DGUSTxHandler::ExtraToInteger), + + VP_HELPER_TX_AUTO(DGUS_Addr::MOVE_CurrentX, + ¤t_position.x, + (&DGUSTxHandler::ExtraToFixedPoint)), + VP_HELPER_TX_AUTO(DGUS_Addr::MOVE_CurrentY, + ¤t_position.y, + (&DGUSTxHandler::ExtraToFixedPoint)), + VP_HELPER_TX_AUTO(DGUS_Addr::MOVE_CurrentZ, + ¤t_position.z, + (&DGUSTxHandler::ExtraToFixedPoint)), + VP_HELPER_TX_EXTRA(DGUS_Addr::MOVE_StepIcons, + &DGUSScreenHandler::move_steps, + &DGUSTxHandler::StepIcons), + + VP_HELPER_TX(DGUS_Addr::SETTINGS2_BLTouch, &DGUSTxHandler::BLTouch), + + VP_HELPER_TX(DGUS_Addr::PID_HeaterIcons, &DGUSTxHandler::PIDIcons), + VP_HELPER_TX_EXTRA(DGUS_Addr::PID_Temp, + &DGUSScreenHandler::pid_temp, + &DGUSTxHandler::ExtraToInteger), + VP_HELPER_DWORD(DGUS_Addr::PID_Kp, + VPFLAG_AUTOUPLOAD, + nullptr, + nullptr, + &DGUSTxHandler::PIDKp), + VP_HELPER_DWORD(DGUS_Addr::PID_Ki, + VPFLAG_AUTOUPLOAD, + nullptr, + nullptr, + &DGUSTxHandler::PIDKi), + VP_HELPER_DWORD(DGUS_Addr::PID_Kd, + VPFLAG_AUTOUPLOAD, + nullptr, + nullptr, + &DGUSTxHandler::PIDKd), + + VP_HELPER(DGUS_Addr::INFOS_Machine, + DGUS_MACHINE_LEN, + VPFLAG_NONE, + (void*)DGUS_MACHINENAME, + nullptr, + &DGUSTxHandler::ExtraPGMToString), + VP_HELPER_TX_SIZE(DGUS_Addr::INFOS_BuildVolume, + DGUS_BUILDVOLUME_LEN, + &DGUSTxHandler::BuildVolume), + VP_HELPER(DGUS_Addr::INFOS_Version, + DGUS_VERSION_LEN, + VPFLAG_NONE, + (void*)DGUS_MARLINVERSION, + nullptr, + &DGUSTxHandler::ExtraPGMToString), + VP_HELPER_TX(DGUS_Addr::INFOS_TotalPrints, &DGUSTxHandler::TotalPrints), + VP_HELPER_TX(DGUS_Addr::INFOS_FinishedPrints, &DGUSTxHandler::FinishedPrints), + VP_HELPER_TX_SIZE(DGUS_Addr::INFOS_PrintTime, + DGUS_PRINTTIME_LEN, + &DGUSTxHandler::PrintTime), + VP_HELPER_TX_SIZE(DGUS_Addr::INFOS_LongestPrint, + DGUS_LONGESTPRINT_LEN, + &DGUSTxHandler::LongestPrint), + VP_HELPER_TX_SIZE(DGUS_Addr::INFOS_FilamentUsed, + DGUS_FILAMENTUSED_LEN, + &DGUSTxHandler::FilamentUsed), + + VP_HELPER_TX(DGUS_Addr::WAIT_Icons, &DGUSTxHandler::WaitIcons), + + // READ-WRITE VARIABLES + + VP_HELPER(DGUS_Addr::FAN0_Speed, + 2, + VPFLAG_AUTOUPLOAD, + nullptr, + &DGUSRxHandler::FanSpeed, + &DGUSTxHandler::FanSpeed), + + VP_HELPER(DGUS_Addr::GCODE_Data, + DGUS_GCODE_LEN, + VPFLAG_RXSTRING, + (void*)DGUSScreenHandler::gcode, + &DGUSRxHandler::StringToExtra, + &DGUSTxHandler::ExtraToString), + + VP_HELPER(DGUS_Addr::PID_Cycles, + 2, + VPFLAG_NONE, + &DGUSScreenHandler::pid_cycles, + &DGUSRxHandler::IntegerToExtra, + &DGUSTxHandler::ExtraToInteger), + + VP_HELPER(DGUS_Addr::VOLUME_Level, + 2, + VPFLAG_NONE, + nullptr, + &DGUSRxHandler::Volume, + &DGUSTxHandler::Volume), + + VP_HELPER(DGUS_Addr::BRIGHTNESS_Level, + 2, + VPFLAG_NONE, + nullptr, + &DGUSRxHandler::Brightness, + &DGUSTxHandler::Brightness), + + // SPECIAL CASES + + VP_HELPER_TX(DGUS_Addr::STATUS_Percent_Complete, &DGUSTxHandler::Percent), + + VP_HELPER((DGUS_Addr)0, 0, VPFLAG_NONE, nullptr, nullptr, nullptr) + +}; + +#endif // DGUS_LCD_UI_RELOADED diff --git a/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.h b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.h new file mode 100644 index 000000000000..12e3c1274e34 --- /dev/null +++ b/Marlin/src/lcd/extui/lib/dgus_reloaded/definition/DGUS_VPList.h @@ -0,0 +1,26 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#include "DGUS_VP.h" + +extern const struct DGUS_VP vp_list[]; diff --git a/Marlin/src/lcd/extui_dgus_lcd.cpp b/Marlin/src/lcd/extui_dgus_classic.cpp similarity index 98% rename from Marlin/src/lcd/extui_dgus_lcd.cpp rename to Marlin/src/lcd/extui_dgus_classic.cpp index 855d09033e85..e487a01d4cd8 100644 --- a/Marlin/src/lcd/extui_dgus_lcd.cpp +++ b/Marlin/src/lcd/extui_dgus_classic.cpp @@ -21,14 +21,14 @@ */ /** - * extui_dgus_lcd.cpp + * extui_dgus_classic.cpp * * DGUS implementation for Marlin by coldtobi, Feb-May 2019 */ #include "../inc/MarlinConfigPre.h" -#if HAS_DGUS_LCD +#if ENABLED(DGUS_LCD_UI_CLASSIC) #include "extui/ui_api.h" #include "extui/lib/dgus/DGUSDisplay.h" @@ -153,4 +153,4 @@ namespace ExtUI { #endif } -#endif // HAS_DGUS_LCD +#endif // DGUS_LCD_UI_CLASSIC diff --git a/Marlin/src/lcd/extui_dgus_reloaded.cpp b/Marlin/src/lcd/extui_dgus_reloaded.cpp new file mode 100644 index 000000000000..bfb02bf98710 --- /dev/null +++ b/Marlin/src/lcd/extui_dgus_reloaded.cpp @@ -0,0 +1,144 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * extui_dgus_lcd.cpp + * + * DGUS implementation for Marlin by coldtobi, Feb-May 2019 + */ + +#include "../inc/MarlinConfigPre.h" + +#if ENABLED(DGUS_LCD_UI_RELOADED) + +#include "extui/ui_api.h" + +#include "extui/lib/dgus_reloaded/DGUSScreenHandler.h" + +namespace ExtUI { + + void onStartup() { + dgus_screen_handler.Init(); + } + + void onIdle() { + static bool processing = false; + + // Prevent recursion + if (!processing) { + processing = true; + dgus_screen_handler.Loop(); + processing = false; + } + } + + void onPrinterKilled(PGM_P error, PGM_P component) { + dgus_screen_handler.PrinterKilled(error, component); + } + + void onMediaInserted() { + #if ENABLED(SDSUPPORT) + dgus_screen_handler.SDCardInserted(); + #endif + } + + void onMediaError() { + #if ENABLED(SDSUPPORT) + dgus_screen_handler.SDCardError(); + #endif + } + + void onMediaRemoved() { + #if ENABLED(SDSUPPORT) + dgus_screen_handler.SDCardRemoved(); + #endif + } + + void onPlayTone(const uint16_t frequency, const uint16_t duration) { + dgus_screen_handler.PlayTone(frequency, duration); + } + + void onPrintTimerStarted() { + dgus_screen_handler.PrintTimerStarted(); + } + + void onPrintTimerPaused() { + dgus_screen_handler.PrintTimerPaused(); + } + + void onPrintTimerStopped() { + dgus_screen_handler.PrintTimerStopped(); + } + + void onFilamentRunout(const extruder_t extruder) { + dgus_screen_handler.FilamentRunout(extruder); + } + + void onUserConfirmRequired(const char * const msg) { + dgus_screen_handler.UserConfirmRequired(msg); + } + + void onStatusChanged(const char * const msg) { + dgus_screen_handler.SetStatusMessage(msg); + } + + void onFactoryReset() { + dgus_screen_handler.SettingsReset(); + } + + void onStoreSettings(char *buff) { + dgus_screen_handler.StoreSettings(buff); + } + + void onLoadSettings(const char *buff) { + dgus_screen_handler.LoadSettings(buff); + } + + void onConfigurationStoreWritten(bool success) { + dgus_screen_handler.ConfigurationStoreWritten(success); + } + + void onConfigurationStoreRead(bool success) { + dgus_screen_handler.ConfigurationStoreRead(success); + } + + void onMeshUpdate(const int8_t xpos, const int8_t ypos, const float zval) { + dgus_screen_handler.MeshUpdate(xpos, ypos, zval); + } + + #if ENABLED(POWER_LOSS_RECOVERY) + void onPowerLossResume() { + // Called on resume from power-loss + dgus_screen_handler.PowerLossResume(); + } + #endif + + #if HAS_PID_HEATING + void onPidTuning(const result_t rst) { + // Called for temperature PID tuning result + dgus_screen_handler.PidTuning(rst); + } + #endif + +} + +#endif // DGUS_LCD_UI_RELOADED diff --git a/README.md b/README.md index 5ec9452ddb26..cdfb5ca807c8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,18 @@ Additional documentation can be found at the [Marlin Home Page](http://marlinfw.org/). Please let us know if Marlin misbehaves in any way. Volunteers are standing by! +## Modifications + +The scope of modifications is limited to the integration of a new extensible UI library for DGUS touchscreens. + +Core functionnality is, by design, left untouched from the upstream. + +The touchscreen firmware compatible with this fork is available in [this repository](https://github.com/Desuuuu/DGUS-reloaded). + +Example configurations are available in [this repository](https://github.com/Desuuuu/DGUS-reloaded-config). + +Precompiled binaries might be available on the [Releases page](https://github.com/Desuuuu/Marlin/releases) using these example configurations. + ## Marlin 2.0 Marlin 2.0 takes this popular RepRap firmware to the next level by adding support for much faster 32-bit and ARM-based boards while improving support for 8-bit AVR boards. Read about Marlin's decision to use a "Hardware Abstraction Layer" below.