Browse Source

Ender-3 V2 CrealityUI Enhanced (#21942, #22728, #22733)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
vanilla_fb_2.0.x
Miguel Risco-Castillo 3 years ago
committed by Scott Lahteine
parent
commit
6cf2cf7bd4
  1. 5
      Marlin/Configuration.h
  2. 13
      Marlin/src/MarlinCore.cpp
  3. 13
      Marlin/src/feature/pause.cpp
  4. 2
      Marlin/src/feature/powerloss.cpp
  5. 2
      Marlin/src/feature/powerloss.h
  6. 3
      Marlin/src/feature/runout.cpp
  7. 17
      Marlin/src/gcode/bedlevel/abl/G29.cpp
  8. 3
      Marlin/src/gcode/bedlevel/mbl/G29.cpp
  9. 3
      Marlin/src/gcode/bedlevel/ubl/M421.cpp
  10. 11
      Marlin/src/gcode/calibrate/G28.cpp
  11. 6
      Marlin/src/gcode/control/M997.cpp
  12. 7
      Marlin/src/gcode/feature/powerloss/M1000.cpp
  13. 4
      Marlin/src/gcode/lcd/M0_M1.cpp
  14. 28
      Marlin/src/gcode/lcd/M73.cpp
  15. 3
      Marlin/src/gcode/sd/M1001.cpp
  16. 23
      Marlin/src/gcode/stats/M75-M78.cpp
  17. 3
      Marlin/src/gcode/temp/M303.cpp
  18. 5
      Marlin/src/inc/Conditionals_LCD.h
  19. 4
      Marlin/src/inc/Conditionals_post.h
  20. 18
      Marlin/src/inc/SanityCheck.h
  21. 0
      Marlin/src/lcd/e3v2/README.md
  22. 12
      Marlin/src/lcd/e3v2/creality/rotary_encoder.h
  23. 3657
      Marlin/src/lcd/e3v2/enhanced/dwin.cpp
  24. 265
      Marlin/src/lcd/e3v2/enhanced/dwin.h
  25. 570
      Marlin/src/lcd/e3v2/enhanced/dwin_lcd.cpp
  26. 285
      Marlin/src/lcd/e3v2/enhanced/dwin_lcd.h
  27. 452
      Marlin/src/lcd/e3v2/enhanced/dwinui.cpp
  28. 624
      Marlin/src/lcd/e3v2/enhanced/dwinui.h
  29. 69
      Marlin/src/lcd/e3v2/enhanced/lockscreen.cpp
  30. 35
      Marlin/src/lcd/e3v2/enhanced/lockscreen.h
  31. 261
      Marlin/src/lcd/e3v2/enhanced/rotary_encoder.cpp
  32. 93
      Marlin/src/lcd/e3v2/enhanced/rotary_encoder.h
  33. 3
      Marlin/src/lcd/e3v2/jyersui/dwin_lcd.h
  34. 17
      Marlin/src/lcd/language/language_en.h
  35. 5
      Marlin/src/lcd/marlinui.cpp
  36. 21
      Marlin/src/lcd/marlinui.h
  37. 2
      Marlin/src/lcd/tft/ui_common.h
  38. 4
      Marlin/src/module/probe.cpp
  39. 40
      Marlin/src/module/settings.cpp
  40. 29
      Marlin/src/module/temperature.cpp
  41. 2
      Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h
  42. 4
      Marlin/src/sd/cardreader.cpp
  43. 5
      buildroot/tests/STM32F103RET6_creality
  44. 1
      ini/features.ini
  45. 2
      platformio.ini

5
Marlin/Configuration.h

@ -2756,6 +2756,11 @@
//
//#define DWIN_CREALITY_LCD
//
// Ender-3 v2 OEM display, enhanced.
//
//#define DWIN_CREALITY_LCD_ENHANCED
//
// Ender-3 v2 OEM display with enhancements by Jacob Myers
//

13
Marlin/src/MarlinCore.cpp

@ -77,6 +77,9 @@
#if ENABLED(DWIN_CREALITY_LCD)
#include "lcd/e3v2/creality/dwin.h"
#include "lcd/e3v2/creality/rotary_encoder.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "lcd/e3v2/enhanced/dwin.h"
#include "lcd/e3v2/enhanced/rotary_encoder.h"
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#include "lcd/e3v2/jyersui/dwin.h"
#include "lcd/e3v2/jyersui/rotary_encoder.h"
@ -849,7 +852,7 @@ void idle(bool no_stepper_sleep/*=false*/) {
TERN_(USE_BEEPER, buzzer.tick());
// Handle UI input / draw events
TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update());
// Run i2c Position Encoders
#if ENABLED(I2C_POSITION_ENCODERS)
@ -904,7 +907,7 @@ void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr
// Echo the LCD message to serial for extra context
if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLNPGM_P(lcd_error); }
#if HAS_DISPLAY
#if EITHER(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED)
ui.kill_screen(lcd_error ?: GET_TEXT(MSG_KILLED), lcd_component ?: NUL_STR);
#else
UNUSED(lcd_error); UNUSED(lcd_component);
@ -1315,7 +1318,7 @@ void setup() {
// UI must be initialized before EEPROM
// (because EEPROM code calls the UI).
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
SETUP_RUN(DWIN_Startup());
#else
SETUP_RUN(ui.init());
@ -1590,7 +1593,7 @@ void setup() {
SERIAL_ECHO_TERNARY(err, "BL24CXX Check ", "failed", "succeeded", "!\n");
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
Encoder_Configuration();
HMI_Init();
HMI_SetLanguageCache();
@ -1598,7 +1601,7 @@ void setup() {
DWIN_StatusChanged_P(GET_TEXT(WELCOME_MSG));
#endif
#if HAS_SERVICE_INTERVALS && DISABLED(DWIN_CREALITY_LCD)
#if HAS_SERVICE_INTERVALS && !HAS_DWIN_E3V2_BASIC
ui.reset_status(true); // Show service messages or keep current status
#endif

13
Marlin/src/feature/pause.cpp

@ -53,6 +53,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#endif
#include "../lcd/marlinui.h"
@ -242,6 +244,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_FILAMENT_CHANGE_PURGE)));
TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_FILAMENT_CHANGE_PURGE), CONTINUE_STR));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_Popup_Confirm(ICON_BLTouch, GET_TEXT(MSG_FILAMENT_CHANGE_PURGE), CONTINUE_STR));
wait_for_user = true; // A click or M108 breaks the purge_length loop
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
@ -265,7 +268,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
// Show "Purge More" / "Resume" menu and wait for reply
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = false;
#if HAS_LCD_MENU
#if EITHER(HAS_LCD_MENU, DWIN_CREALITY_LCD_ENHANCED)
ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR
#else
pause_menu_response = PAUSE_RESPONSE_WAIT_FOR;
@ -525,6 +528,8 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged_P(GET_TEXT(MSG_REHEATING)));
TERN_(DWIN_CREALITY_LCD_ENHANCED, ui.set_status_P(GET_TEXT(MSG_REHEATING)));
// Re-enable the heaters if they timed out
HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e);
@ -538,8 +543,13 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT);
HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout);
TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_REHEATDONE), CONTINUE_STR));
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_REHEATDONE)));
TERN_(DWIN_CREALITY_LCD_ENHANCED, ui.set_status_P(GET_TEXT(MSG_REHEATDONE)));
wait_for_user = true;
nozzle_timed_out = false;
@ -675,6 +685,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
TERN_(HAS_STATUS_MESSAGE, ui.reset_status());
TERN_(HAS_LCD_MENU, ui.return_to_status());
TERN_(DWIN_CREALITY_LCD_ENHANCED, HMI_ReturnScreen());
}
#endif // ADVANCED_PAUSE_FEATURE

2
Marlin/src/feature/powerloss.cpp

@ -40,7 +40,7 @@ uint8_t PrintJobRecovery::queue_index_r;
uint32_t PrintJobRecovery::cmd_sdpos, // = 0
PrintJobRecovery::sdpos[BUFSIZE];
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
bool PrintJobRecovery::dwin_flag; // = false
#endif

2
Marlin/src/feature/powerloss.h

@ -145,7 +145,7 @@ class PrintJobRecovery {
static uint32_t cmd_sdpos, //!< SD position of the next command
sdpos[BUFSIZE]; //!< SD positions of queued commands
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
static bool dwin_flag;
#endif

3
Marlin/src/feature/runout.cpp

@ -68,6 +68,8 @@ bool FilamentMonitorBase::enabled = true,
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#endif
void event_filament_runout(const uint8_t extruder) {
@ -86,6 +88,7 @@ void event_filament_runout(const uint8_t extruder) {
#endif
TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getTool(extruder)));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_FilamentRunout(extruder));
#if ANY(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS, MULTI_FILAMENT_SENSOR)
const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, extruder);

17
Marlin/src/gcode/bedlevel/abl/G29.cpp

@ -58,10 +58,10 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#elif ENABLED(DWIN_CREALITY_LCD)
#include "../../../lcd/e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
#if HAS_MULTI_HOTEND
@ -403,10 +403,9 @@ G29_TYPE GcodeSuite::G29() {
#if ENABLED(AUTO_BED_LEVELING_3POINT)
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> 3-point Leveling");
points[0].z = points[1].z = points[2].z = 0; // Probe at 3 arbitrary points
#endif
#if BOTH(AUTO_BED_LEVELING_BILINEAR, EXTENSIBLE_UI)
ExtUI::onMeshLevelingStart();
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
TERN_(EXTENSIBLE_UI, ExtUI::onMeshLevelingStart());
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshLevelingStart());
#endif
if (!faux) {
@ -886,9 +885,7 @@ G29_TYPE GcodeSuite::G29() {
process_subcommands_now_P(PSTR(Z_PROBE_END_SCRIPT));
#endif
#if ENABLED(DWIN_CREALITY_LCD)
DWIN_CompletedLeveling();
#endif
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_CompletedLeveling());
report_current_position();

3
Marlin/src/gcode/bedlevel/mbl/G29.cpp

@ -40,6 +40,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
@ -191,6 +193,7 @@ void GcodeSuite::G29() {
if (parser.seenval('Z')) {
mbl.z_values[ix][iy] = parser.value_linear_units();
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, mbl.z_values[ix][iy]));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshUpdate(ix, iy, mbl.z_values[ix][iy]));
}
else
return echo_not_entered('Z');

3
Marlin/src/gcode/bedlevel/ubl/M421.cpp

@ -33,6 +33,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
@ -67,6 +69,7 @@ void GcodeSuite::M421() {
float &zval = ubl.z_values[ij.x][ij.y]; // Altering this Mesh Point
zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); // N=NAN, Z=NEWVAL, or Q=ADDVAL
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); // Ping ExtUI in case it's showing the mesh
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_MeshUpdate(ij.x, ij.y, zval));
}
}

11
Marlin/src/gcode/calibrate/G28.cpp

@ -46,12 +46,13 @@
#endif
#include "../../lcd/marlinui.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../../lcd/e3v2/creality/dwin.h"
#endif
#if ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD)
#include "../../lcd/e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
#if HAS_L64XX // set L6470 absolute position registers to counts
@ -238,7 +239,7 @@ void GcodeSuite::G28() {
return;
}
TERN_(DWIN_CREALITY_LCD, DWIN_StartHoming());
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_StartHoming());
TERN_(EXTENSIBLE_UI, ExtUI::onHomingStart());
planner.synchronize(); // Wait for planner moves to finish!
@ -522,7 +523,7 @@ void GcodeSuite::G28() {
ui.refresh();
TERN_(DWIN_CREALITY_LCD, DWIN_CompletedHoming());
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_CompletedHoming());
TERN_(EXTENSIBLE_UI, ExtUI::onHomingComplete());
report_current_position();

6
Marlin/src/gcode/control/M997.cpp

@ -24,11 +24,17 @@
#if ENABLED(PLATFORM_M997_SUPPORT)
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
* M997: Perform in-application firmware update
*/
void GcodeSuite::M997() {
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_RebootScreen());
flashFirmware(parser.intval('S'));
}

7
Marlin/src/gcode/feature/powerloss/M1000.cpp

@ -27,9 +27,14 @@
#include "../../gcode.h"
#include "../../../feature/powerloss.h"
#include "../../../module/motion.h"
#include "../../../lcd/marlinui.h"
#if ENABLED(EXTENSIBLE_UI)
#include "../../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD)
#include "../../../lcd/e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../lcd/e3v2/enhanced/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#include "../../../lcd/e3v2/jyersui/dwin.h" // Temporary fix until it can be better implemented
#endif
@ -64,7 +69,7 @@ void GcodeSuite::M1000() {
if (parser.seen_test('S')) {
#if HAS_LCD_MENU
ui.goto_screen(menu_job_recovery);
#elif ENABLED(DWIN_CREALITY_LCD)
#elif HAS_DWIN_E3V2_BASIC
recovery.dwin_flag = true;
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) // Temporary fix until it can be better implemented
CrealityDWIN.Popup_Handler(Resume);

4
Marlin/src/gcode/lcd/M0_M1.cpp

@ -35,6 +35,8 @@
#include "../../lcd/marlinui.h"
#elif ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
#if ENABLED(HOST_PROMPT_SUPPORT)
@ -68,6 +70,8 @@ void GcodeSuite::M0_M1() {
ExtUI::onUserConfirmRequired(parser.string_arg); // Can this take an SRAM string??
else
ExtUI::onUserConfirmRequired_P(GET_TEXT(MSG_USERWAIT));
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
DWIN_Popup_Confirm(ICON_BLTouch, parser.string_arg ?: GET_TEXT(MSG_STOPPED), GET_TEXT(MSG_USERWAIT));
#else
if (parser.string_arg) {

28
Marlin/src/gcode/lcd/M73.cpp

@ -28,6 +28,10 @@
#include "../../lcd/marlinui.h"
#include "../../sd/cardreader.h"
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
* M73: Set percentage complete (for display on LCD)
*
@ -35,13 +39,23 @@
* M73 P25 ; Set progress to 25%
*/
void GcodeSuite::M73() {
if (parser.seenval('P'))
ui.set_progress((PROGRESS_SCALE) > 1
? parser.value_float() * (PROGRESS_SCALE)
: parser.value_byte()
);
#if ENABLED(USE_M73_REMAINING_TIME)
if (parser.seenval('R')) ui.set_remaining_time(60 * parser.value_ulong());
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
DWIN_Progress_Update();
#else
if (parser.seenval('P'))
ui.set_progress((PROGRESS_SCALE) > 1
? parser.value_float() * (PROGRESS_SCALE)
: parser.value_byte()
);
#if ENABLED(USE_M73_REMAINING_TIME)
if (parser.seenval('R')) ui.set_remaining_time(60 * parser.value_ulong());
#endif
#endif
}

3
Marlin/src/gcode/sd/M1001.cpp

@ -48,6 +48,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
#if ENABLED(HOST_ACTION_COMMANDS)
@ -106,6 +108,7 @@ void GcodeSuite::M1001() {
#endif
TERN_(EXTENSIBLE_UI, ExtUI::onPrintFinished());
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_Print_Finished());
// Re-select the last printed file in the UI
TERN_(SD_REPRINT_LAST_SELECTED_FILE, ui.reselect_last_file());

23
Marlin/src/gcode/stats/M75-M78.cpp

@ -29,11 +29,19 @@
#include "../../MarlinCore.h" // for startOrResumeJob
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
* M75: Start print timer
*/
void GcodeSuite::M75() {
startOrResumeJob();
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
DWIN_Print_Header(parser.string_arg && parser.string_arg[0] ? parser.string_arg : GET_TEXT(MSG_HOST_START_PRINT));
DWIN_Print_Started(false);
#endif
}
/**
@ -49,29 +57,30 @@ void GcodeSuite::M76() {
*/
void GcodeSuite::M77() {
print_job_timer.stop();
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_Print_Finished());
}
#if ENABLED(PRINTCOUNTER)
/**
/**
* M78: Show print statistics
*/
void GcodeSuite::M78() {
if (parser.intval('S') == 78) { // "M78 S78" will reset the statistics
void GcodeSuite::M78() {
if (parser.intval('S') == 78) { // "M78 S78" will reset the statistics
print_job_timer.initStats();
ui.reset_status();
return;
return;
}
#if HAS_SERVICE_INTERVALS
if (parser.seenval('R')) {
if (parser.seenval('R')) {
print_job_timer.resetServiceInterval(parser.value_int());
ui.reset_status();
return;
return;
}
#endif
print_job_timer.showStats();
}
}
#endif // PRINTCOUNTER

3
Marlin/src/gcode/temp/M303.cpp

@ -30,6 +30,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
@ -71,6 +73,7 @@ void GcodeSuite::M303() {
default:
SERIAL_ECHOLNPGM(STR_PID_BAD_HEATER_ID);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_BAD_EXTRUDER_NUM));
return;
}

5
Marlin/src/inc/Conditionals_LCD.h

@ -493,7 +493,10 @@
#endif
// Aliases for LCD features
#if ANY(DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_JYERSUI)
#if EITHER(DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_ENHANCED)
#define HAS_DWIN_E3V2_BASIC 1
#endif
#if EITHER(HAS_DWIN_E3V2_BASIC, DWIN_CREALITY_LCD_JYERSUI)
#define HAS_DWIN_E3V2 1
#endif

4
Marlin/src/inc/Conditionals_post.h

@ -421,7 +421,7 @@
#endif
#endif
#if ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#if EITHER(DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI)
#define HAS_LCD_BRIGHTNESS 1
#endif
@ -2953,7 +2953,7 @@
* Advanced Pause - Filament Change
*/
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI) || BOTH(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT)
#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI) || BOTH(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT)
#define M600_PURGE_MORE_RESUMABLE 1
#endif
#ifndef FILAMENT_CHANGE_SLOW_LOAD_LENGTH

18
Marlin/src/inc/SanityCheck.h

@ -808,7 +808,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "PROGRESS_MSG_EXPIRE must be greater than or equal to 0."
#endif
#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && NONE(HAS_MARLINUI_U8GLIB, HAS_GRAPHICAL_TFT, HAS_MARLINUI_HD44780, EXTENSIBLE_UI, HAS_DWIN_E3V2, IS_DWIN_MARLINUI)
#error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_*, or EXTENSIBLE_UI."
#error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR, Character LCD, Graphical LCD, TFT, DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_*, OR EXTENSIBLE_UI."
#endif
#if ENABLED(USE_M73_REMAINING_TIME) && DISABLED(LCD_SET_PROGRESS_MANUALLY)
@ -1748,7 +1748,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
* LCD_BED_LEVELING requirements
*/
#if ENABLED(LCD_BED_LEVELING)
#if NONE(HAS_LCD_MENU, DWIN_CREALITY_LCD)
#if NONE(HAS_LCD_MENU, DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_ENHANCED)
#error "LCD_BED_LEVELING is not supported by the selected LCD controller."
#elif !(ENABLED(MESH_BED_LEVELING) || HAS_ABL_NOT_UBL)
#error "LCD_BED_LEVELING requires MESH_BED_LEVELING or AUTO_BED_LEVELING."
@ -2655,7 +2655,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
+ COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \
+ COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY, DGUS_LCD_UI_MKS, DGUS_LCD_UI_RELOADED) \
+ COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY) \
+ COUNT_ENABLED(DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) \
+ COUNT_ENABLED(DWIN_CREALITY_LCD, DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) \
+ COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) \
+ COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \
+ COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \
@ -2763,6 +2763,18 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
#error "DWIN_CREALITY_LCD does not support LCD_BED_LEVELING with PROBE_MANUALLY."
#endif
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#if DISABLED(SDSUPPORT)
#error "DWIN_CREALITY_LCD_ENHANCED requires SDSUPPORT to be enabled."
#elif ENABLED(PID_EDIT_MENU)
#error "DWIN_CREALITY_LCD_ENHANCED does not support PID_EDIT_MENU."
#elif ENABLED(PID_AUTOTUNE_MENU)
#error "DWIN_CREALITY_LCD_ENHANCED does not support PID_AUTOTUNE_MENU."
#elif ENABLED(LEVEL_BED_CORNERS)
#error "DWIN_CREALITY_LCD_ENHANCED does not support LEVEL_BED_CORNERS."
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
#error "DWIN_CREALITY_LCD_ENHANCED does not support LCD_BED_LEVELING with PROBE_MANUALLY."
#endif
#endif
/**

0
Marlin/src/lcd/e3v2/creality/README.md → Marlin/src/lcd/e3v2/README.md

12
Marlin/src/lcd/e3v2/creality/rotary_encoder.h

@ -22,12 +22,12 @@
#pragma once
/*****************************************************************************
* @file lcd/e3v2/creality/rotary_encoder.h
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief Rotary encoder functions
****************************************************************************/
* @file lcd/e3v2/creality/rotary_encoder.h
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief Rotary encoder functions
****************************************************************************/
#include "../../../inc/MarlinConfig.h"

3657
Marlin/src/lcd/e3v2/enhanced/dwin.cpp

File diff suppressed because it is too large

265
Marlin/src/lcd/e3v2/enhanced/dwin.h

@ -0,0 +1,265 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../../inc/MarlinConfigPre.h"
#include "dwinui.h"
#include "rotary_encoder.h"
#include "../../../libs/BL24CXX.h"
#if ANY(HAS_HOTEND, HAS_HEATED_BED, HAS_FAN) && PREHEAT_COUNT
#define HAS_PREHEAT 1
#if PREHEAT_COUNT < 2
#error "Creality DWIN requires two material preheat presets."
#endif
#endif
#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) && DISABLED(PROBE_MANUALLY)
#define HAS_ONESTEP_LEVELING 1
#endif
#if !HAS_BED_PROBE && ENABLED(BABYSTEPPING)
#define JUST_BABYSTEP 1
#endif
#if ANY(BABYSTEPPING, HAS_BED_PROBE, HAS_WORKSPACE_OFFSET)
#define HAS_ZOFFSET_ITEM 1
#endif
static constexpr size_t eeprom_data_size = 64;
enum processID : uint8_t {
// Process ID
MainMenu,
Menu,
SetInt,
SetPInt,
SetIntNoDraw,
SetFloat,
SetPFloat,
SelectFile,
PrintProcess,
PrintDone,
Info,
// Popup Windows
Homing,
Leveling,
PauseOrStop,
FilamentPurge,
WaitResponse,
Locked,
NothingToDo,
};
enum pidresult_t : uint8_t {
PID_BAD_EXTRUDER_NUM,
PID_TEMP_TOO_HIGH,
PID_TUNING_TIMEOUT,
PID_EXTR_START,
PID_BED_START,
PID_DONE
};
// Picture ID
#define Start_Process 0
#define Language_English 1
#define Language_Chinese 2
#define DWIN_CHINESE 123
#define DWIN_ENGLISH 0
typedef struct {
int8_t Color[3]; // Color components
int8_t Preheat = 0; // Material Select 0: PLA, 1: ABS, 2: Custom
AxisEnum axis = X_AXIS; // Axis Select
int32_t MaxValue = 0; // Auxiliar max integer/scaled float value
int32_t MinValue = 0; // Auxiliar min integer/scaled float value
int8_t dp = 0; // Auxiliar decimal places
int32_t Value = 0; // Auxiliar integer / scaled float value
int16_t *P_Int = nullptr; // Auxiliar pointer to 16 bit integer variable
float *P_Float = nullptr; // Auxiliar pointer to float variable
void (*Apply)() = nullptr; // Auxiliar apply function
void (*LiveUpdate)() = nullptr; // Auxiliar live update function
} HMI_value_t;
typedef struct {
uint16_t Background_Color = Def_Background_Color;
uint16_t Cursor_color = Def_Cursor_color;
uint16_t TitleBg_color = Def_TitleBg_color;
uint16_t TitleTxt_color = Def_TitleTxt_color;
uint16_t Text_Color = Def_Text_Color;
uint16_t Selected_Color = Def_Selected_Color;
uint16_t SplitLine_Color = Def_SplitLine_Color;
uint16_t Highlight_Color = Def_Highlight_Color;
uint16_t StatusBg_Color = Def_StatusBg_Color;
uint16_t StatusTxt_Color = Def_StatusTxt_Color;
uint16_t PopupBg_color = Def_PopupBg_color;
uint16_t PopupTxt_Color = Def_PopupTxt_Color;
uint16_t AlertBg_Color = Def_AlertBg_Color;
uint16_t AlertTxt_Color = Def_AlertTxt_Color;
uint16_t PercentTxt_Color = Def_PercentTxt_Color;
uint16_t Barfill_Color = Def_Barfill_Color;
uint16_t Indicator_Color = Def_Indicator_Color;
uint16_t Coordinate_Color = Def_Coordinate_Color;
TERN_(HAS_HOTEND, int16_t HotendPidT = PREHEAT_1_TEMP_HOTEND);
TERN_(HAS_HOTEND, int16_t PidCycles = 10);
#ifdef PREHEAT_1_TEMP_BED
int16_t BedPidT = PREHEAT_1_TEMP_BED;
#endif
TERN_(PREVENT_COLD_EXTRUSION, int16_t ExtMinT = EXTRUDE_MINTEMP);
} HMI_data_t;
typedef struct {
uint8_t language;
bool pause_flag:1; // printing is paused
bool pause_action:1; // flag a pause action
bool print_finish:1; // print was finished
bool select_flag:1; // Popup button selected
bool home_flag:1; // homing in course
bool heat_flag:1; // 0: heating done 1: during heating
bool lock_flag:1; // 0: lock called from AdvSet 1: lock called from Tune
} HMI_flag_t;
extern HMI_value_t HMI_value;
extern HMI_flag_t HMI_flag;
extern HMI_data_t HMI_data;
extern uint8_t checkkey;
extern millis_t dwin_heat_time;
// Popup windows
void DWIN_Popup_Confirm(uint8_t icon, const char * const msg1, const char * const msg2);
#if HAS_HOTEND || HAS_HEATED_BED
void DWIN_Popup_Temperature(const bool toohigh);
#endif
TERN_(HAS_HOTEND, void Popup_Window_ETempTooLow());
void Popup_Window_Resume();
// SD Card
void HMI_SDCardInit();
void HMI_SDCardUpdate();
// Main Process
//void Icon_print();
//void Icon_control();
//void Icon_leveling(bool value);
// Other
void Goto_PrintProcess();
void Goto_Main_Menu();
void update_variable();
void Draw_Select_Highlight(const bool sel);
void Draw_Status_Area(const bool with_update); // Status Area
void Draw_Main_Area(); // Redraw main area;
void DWIN_Redraw_screen(); // Redraw all screen elements
void HMI_StartFrame(const bool with_update); // Prepare the menu view
void HMI_MainMenu(); // Main process screen
void HMI_SelectFile(); // File page
void HMI_Printing(); // Print page
void HMI_ReturnScreen(); // Return to previous screen before popups
void ApplyExtMinT();
void HMI_SetLanguageCache(); // Set the languaje image cache
//void HMI_Leveling(); // Level the page
//void HMI_LevBedCorners(); // Tramming menu
//void HMI_Info(); // Information menu
void HMI_Init();
void HMI_Popup();
void HMI_SaveProcessID(const uint8_t id);
void HMI_AudioFeedback(const bool success=true);
void DWIN_Startup();
void DWIN_Update();
void EachMomentUpdate();
void DWIN_HandleScreen();
void DWIN_DrawStatusLine(const uint16_t color, const uint16_t bgcolor, const char *text);
void DWIN_StatusChanged(const char * const text);
void DWIN_StatusChanged_P(PGM_P const text);
void DWIN_StartHoming();
void DWIN_CompletedHoming();
#if HAS_MESH
void DWIN_MeshUpdate(const int8_t xpos, const int8_t ypos, const float zval);
#endif
void DWIN_MeshLevelingStart();
void DWIN_CompletedLeveling();
void DWIN_PidTuning(pidresult_t result);
void DWIN_Print_Started(const bool sd = false);
void DWIN_Print_Finished();
#if HAS_FILAMENT_SENSOR
void DWIN_FilamentRunout(const uint8_t extruder);
#endif
void DWIN_Progress_Update();
void DWIN_Print_Header(const char *text);
void DWIN_SetColorDefaults();
void DWIN_StoreSettings(char *buff);
void DWIN_LoadSettings(const char *buff);
void DWIN_SetDataDefaults();
void DWIN_RebootScreen();
#if ENABLED(ADVANCED_PAUSE_FEATURE)
void Draw_Popup_FilamentPurge();
void DWIN_Popup_FilamentPurge();
void HMI_FilamentPurge();
#endif
// Utility and extensions
void HMI_LockScreen();
void DWIN_LockScreen(const bool flag = true);
// HMI user control functions
void HMI_Menu();
void HMI_SetInt();
void HMI_SetPInt();
void HMI_SetIntNoDraw();
void HMI_SetFloat();
void HMI_SetPFloat();
// Menu drawing functions
void Draw_Control_Menu();
void Draw_AdvancedSettings_Menu();
void Draw_Prepare_Menu();
void Draw_Move_Menu();
void Draw_LevBedCorners_Menu();
TERN_(HAS_HOME_OFFSET, void Draw_HomeOffset_Menu());
TERN_(HAS_BED_PROBE, void Draw_ProbeSet_Menu());
TERN_(HAS_FILAMENT_SENSOR, void Draw_FilSet_Menu());
void Draw_SelectColors_Menu();
void Draw_GetColor_Menu();
void Draw_Tune_Menu();
void Draw_Motion_Menu();
TERN_(ADVANCED_PAUSE_FEATURE, void Draw_FilamentMan_Menu());
TERN_(MESH_BED_LEVELING, void Draw_ManualMesh_Menu());
#if HAS_HOTEND
void Draw_Preheat1_Menu();
void Draw_Preheat2_Menu();
void Draw_Preheat3_Menu();
#endif
void Draw_Temperature_Menu();
void Draw_MaxSpeed_Menu();
void Draw_MaxAccel_Menu();
TERN_(HAS_CLASSIC_JERK, void Draw_MaxJerk_Menu());
void Draw_Steps_Menu();
TERN_(HAS_HOTEND, void Draw_HotendPID_Menu());
TERN_(HAS_HEATED_BED, void Draw_BedPID_Menu());
#if EITHER(HAS_BED_PROBE, BABYSTEPPING)
void Draw_ZOffsetWiz_Menu();
#endif

570
Marlin/src/lcd/e3v2/enhanced/dwin_lcd.cpp

@ -0,0 +1,570 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/********************************************************************************
* @file lcd/e3v2/enhanced/dwin_lcd.cpp
* @author LEO / Creality3D - Enhanced by Miguel A. Risco-Castillo
* @date 2021/09/08
* @version 2.2.1
* @brief DWIN screen control functions
********************************************************************************/
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../inc/MarlinConfig.h"
#include "dwin_lcd.h"
#include <string.h> // for memset
//#define DEBUG_OUT 1
#include "../../../core/debug_out.h"
// Make sure DWIN_SendBuf is large enough to hold the largest string plus draw command and tail.
// Assume the narrowest (6 pixel) font and 2-byte gb2312-encoded characters.
uint8_t DWIN_SendBuf[11 + DWIN_DataLength] = { 0xAA };
uint8_t DWIN_BufTail[4] = { 0xCC, 0x33, 0xC3, 0x3C };
uint8_t databuf[26] = { 0 };
uint8_t receivedType;
int recnum = 0;
inline void DWIN_Byte(size_t &i, const uint16_t bval) {
DWIN_SendBuf[++i] = bval;
}
inline void DWIN_Word(size_t &i, const uint16_t wval) {
DWIN_SendBuf[++i] = wval >> 8;
DWIN_SendBuf[++i] = wval & 0xFF;
}
inline void DWIN_Long(size_t &i, const uint32_t lval) {
DWIN_SendBuf[++i] = (lval >> 24) & 0xFF;
DWIN_SendBuf[++i] = (lval >> 16) & 0xFF;
DWIN_SendBuf[++i] = (lval >> 8) & 0xFF;
DWIN_SendBuf[++i] = lval & 0xFF;
}
inline void DWIN_String(size_t &i, const char * const string, uint16_t rlimit = 0xFFFF) {
if (!string) return;
const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(strlen(string), rlimit));
if (len == 0) return;
memcpy(&DWIN_SendBuf[i+1], string, len);
i += len;
}
inline void DWIN_String(size_t &i, const __FlashStringHelper * string, uint16_t rlimit = 0xFFFF) {
if (!string) return;
const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(rlimit, strlen_P((PGM_P)string))); // cast it to PGM_P, which is basically const char *, and measure it using the _P version of strlen.
if (len == 0) return;
memcpy(&DWIN_SendBuf[i+1], string, len);
i += len;
}
// Send the data in the buffer and the packet end
inline void DWIN_Send(size_t &i) {
++i;
LOOP_L_N(n, i) { LCD_SERIAL.write(DWIN_SendBuf[n]); delayMicroseconds(1); }
LOOP_L_N(n, 4) { LCD_SERIAL.write(DWIN_BufTail[n]); delayMicroseconds(1); }
}
/*-------------------------------------- System variable function --------------------------------------*/
// Handshake (1: Success, 0: Fail)
bool DWIN_Handshake(void) {
#ifndef LCD_BAUDRATE
#define LCD_BAUDRATE 115200
#endif
LCD_SERIAL.begin(LCD_BAUDRATE);
const millis_t serial_connect_timeout = millis() + 1000UL;
while (!LCD_SERIAL.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
size_t i = 0;
DWIN_Byte(i, 0x00);
DWIN_Send(i);
while (LCD_SERIAL.available() > 0 && recnum < (signed)sizeof(databuf)) {
databuf[recnum] = LCD_SERIAL.read();
// ignore the invalid data
if (databuf[0] != FHONE) { // prevent the program from running.
if (recnum > 0) {
recnum = 0;
ZERO(databuf);
}
continue;
}
delay(10);
recnum++;
}
return ( recnum >= 3
&& databuf[0] == FHONE
&& databuf[1] == '\0'
&& databuf[2] == 'O'
&& databuf[3] == 'K' );
}
// Set screen display direction
// dir: 0=0°, 1=90°, 2=180°, 3=270°
void DWIN_Frame_SetDir(uint8_t dir) {
size_t i = 0;
DWIN_Byte(i, 0x34);
DWIN_Byte(i, 0x5A);
DWIN_Byte(i, 0xA5);
DWIN_Byte(i, dir);
DWIN_Send(i);
}
// Update display
void DWIN_UpdateLCD(void) {
size_t i = 0;
DWIN_Byte(i, 0x3D);
DWIN_Send(i);
}
/*---------------------------------------- Drawing functions ----------------------------------------*/
// Clear screen
// color: Clear screen color
void DWIN_Frame_Clear(const uint16_t color) {
size_t i = 0;
DWIN_Byte(i, 0x01);
DWIN_Word(i, color);
DWIN_Send(i);
}
// Draw a point
// color: point color
// width: point width 0x01-0x0F
// height: point height 0x01-0x0F
// x,y: upper left point
void DWIN_Draw_Point(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y) {
size_t i = 0;
DWIN_Byte(i, 0x02);
DWIN_Word(i, color);
DWIN_Byte(i, width);
DWIN_Byte(i, height);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Send(i);
}
// Draw a line
// color: Line segment color
// xStart/yStart: Start point
// xEnd/yEnd: End point
void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x03);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
// Draw a rectangle
// mode: 0=frame, 1=fill, 2=XOR fill
// color: Rectangle color
// xStart/yStart: upper left point
// xEnd/yEnd: lower right point
void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color,
uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x05);
DWIN_Byte(i, mode);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
// Move a screen area
// mode: 0, circle shift; 1, translation
// dir: 0=left, 1=right, 2=up, 3=down
// dis: Distance
// color: Fill color
// xStart/yStart: upper left point
// xEnd/yEnd: bottom right point
void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis,
uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x09);
DWIN_Byte(i, (mode << 7) | dir);
DWIN_Word(i, dis);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
/*---------------------------------------- Text related functions ----------------------------------------*/
// Draw a string
// widthAdjust: true=self-adjust character width; false=no adjustment
// bShow: true=display background color; false=don't display background color
// size: Font size
// color: Character color
// bColor: Background color
// x/y: Upper-left coordinate of the string
// *string: The string
// rlimit: For draw less chars than string length use rlimit
void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const char * const string, uint16_t rlimit) {
size_t i = 0;
DWIN_Byte(i, 0x11);
// Bit 7: widthAdjust
// Bit 6: bShow
// Bit 5-4: Unused (0)
// Bit 3-0: size
DWIN_Byte(i, (widthAdjust * 0x80) | (bShow * 0x40) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_String(i, string, rlimit);
DWIN_Send(i);
}
// Draw a positive integer
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of digits
// x/y: Upper-left coordinate
// value: Integer value
void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) {
size_t i = 0;
DWIN_Byte(i, 0x14);
// Bit 7: bshow
// Bit 6: 1 = signed; 0 = unsigned number;
// Bit 5: zeroFill
// Bit 4: zeroMode
// Bit 3-0: size
DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Byte(i, iNum);
DWIN_Byte(i, 0); // fNum
DWIN_Word(i, x);
DWIN_Word(i, y);
#if 0
for (char count = 0; count < 8; count++) {
DWIN_Byte(i, value);
value >>= 8;
if (!(value & 0xFF)) break;
}
#else
// Write a big-endian 64 bit integer
const size_t p = i + 1;
for (char count = 8; count--;) { // 7..0
++i;
DWIN_SendBuf[p + count] = value;
value >>= 8;
}
#endif
DWIN_Send(i);
}
// Draw a positive floating point number
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of whole digits
// fNum: Number of decimal digits
// x/y: Upper-left point
// value: Scaled positive float value
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) {
size_t i = 0;
DWIN_Byte(i, 0x14);
DWIN_Byte(i, (bShow * 0x80) | (zeroFill * 0x20) | (zeroMode * 0x10) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Byte(i, iNum);
DWIN_Byte(i, fNum);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Long(i, value);
DWIN_Send(i);
}
// value: positive float value
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
const long val = round(value * POW(10, fNum));
DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, val);
}
/*---------------------------------------- Picture related functions ----------------------------------------*/
// Display QR code
// The size of the QR code is (46*QR_Pixel)*(46*QR_Pixel) dot matrix
// QR_Pixel: The pixel size occupied by each point of the QR code: 0x01-0x0F (1-16)
// (Nx, Ny): The coordinates of the upper left corner displayed by the QR code
// str: multi-bit data
void DWIN_Draw_QR(uint8_t QR_Pixel, uint16_t x, uint16_t y, char *string) {
size_t i = 0;
DWIN_Byte(i, 0x21);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Byte(i, QR_Pixel);
DWIN_String(i, string);
DWIN_Send(i);
}
// Draw JPG and cached in #0 virtual display area
// id: Picture ID
void DWIN_JPG_ShowAndCache(const uint8_t id) {
size_t i = 0;
DWIN_Word(i, 0x2200);
DWIN_Byte(i, id);
DWIN_Send(i);
}
// Draw an Icon
// IBD: The icon background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// libID: Icon library ID
// picID: Icon ID
// x/y: Upper-left point
void DWIN_ICON_Show(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint8_t libID, uint8_t picID, uint16_t x, uint16_t y) {
NOMORE(x, DWIN_WIDTH - 1);
NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl
size_t i = 0;
DWIN_Byte(i, 0x23);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Byte(i, IBD%2<<7 | BIR%2<<6 | BFI%2<<5 | libID);
DWIN_Byte(i, picID);
DWIN_Send(i);
}
// Draw an Icon from SRAM
// IBD: The icon background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// x/y: Upper-left point
// addr: SRAM address
void DWIN_ICON_Show(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint16_t x, uint16_t y, uint16_t addr) {
NOMORE(x, DWIN_WIDTH - 1);
NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl
size_t i = 0;
DWIN_Byte(i, 0x24);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Byte(i, IBD%2<<7 | BIR%2<<6 | BFI%2<<5 | 0x00);
DWIN_Word(i, addr);
DWIN_Send(i);
}
// Unzip the JPG picture to a virtual display area
// n: Cache index
// id: Picture ID
void DWIN_JPG_CacheToN(uint8_t n, uint8_t id) {
size_t i = 0;
DWIN_Byte(i, 0x25);
DWIN_Byte(i, n);
DWIN_Byte(i, id);
DWIN_Send(i);
}
// Copy area from current virtual display area to current screen
// xStart/yStart: Upper-left of virtual area
// xEnd/yEnd: Lower-right of virtual area
// x/y: Screen paste point
void DWIN_Frame_AreaCopy(uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) {
size_t i = 0;
DWIN_Byte(i, 0x26);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Send(i);
}
// Copy area from virtual display area to current screen
// IBD: background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// cacheID: virtual area number
// xStart/yStart: Upper-left of virtual area
// xEnd/yEnd: Lower-right of virtual area
// x/y: Screen paste point
void DWIN_Frame_AreaCopy(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint8_t cacheID, uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) {
size_t i = 0;
DWIN_Byte(i, 0x27);
DWIN_Byte(i, IBD%2<<7 | BIR%2<<6 | BFI%2<<5 | cacheID);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Send(i);
}
// Animate a series of icons
// animID: Animation ID; 0x00-0x0F
// animate: true on; false off;
// libID: Icon library ID
// picIDs: Icon starting ID
// picIDe: Icon ending ID
// x/y: Upper-left point
// interval: Display time interval, unit 10mS
void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs, uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval) {
NOMORE(x, DWIN_WIDTH - 1);
NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl
size_t i = 0;
DWIN_Byte(i, 0x28);
DWIN_Word(i, x);
DWIN_Word(i, y);
// Bit 7: animation on or off
// Bit 6: start from begin or end
// Bit 5-4: unused (0)
// Bit 3-0: animID
DWIN_Byte(i, (animate * 0x80) | 0x40 | animID);
DWIN_Byte(i, libID);
DWIN_Byte(i, picIDs);
DWIN_Byte(i, picIDe);
DWIN_Byte(i, interval);
DWIN_Send(i);
}
// Animation Control
// state: 16 bits, each bit is the state of an animation id
void DWIN_ICON_AnimationControl(uint16_t state) {
size_t i = 0;
DWIN_Byte(i, 0x29);
DWIN_Word(i, state);
DWIN_Send(i);
}
// Set LCD Brightness 0x00-0xFF
void DWIN_LCD_Brightness(const uint8_t brightness) {
size_t i = 0;
DWIN_Byte(i, 0x30);
DWIN_Byte(i, brightness);
DWIN_Send(i);
}
// Write buffer data to the SRAM or Flash
// mem: 0x5A=32KB SRAM, 0xA5=16KB Flash
// addr: start address
// length: Bytes to write
// data: address of the buffer with data
void DWIN_WriteToMem(uint8_t mem, uint16_t addr, uint16_t length, uint8_t *data) {
const uint8_t max_size = 128;
uint16_t pending = length;
uint16_t to_send;
uint16_t indx;
uint8_t block = 0;
while (pending > 0) {
indx = block * max_size;
to_send = _MIN(pending, max_size);
size_t i = 0;
DWIN_Byte(i, 0x31);
DWIN_Byte(i, mem);
DWIN_Word(i, addr + indx); // start address of the data block
++i;
LOOP_L_N(j, i) { LCD_SERIAL.write(DWIN_SendBuf[j]); delayMicroseconds(1); } // Buf header
for (uint16_t j = indx; j <= indx + to_send - 1; j++) LCD_SERIAL.write(*(data + j)); delayMicroseconds(1); // write block of data
LOOP_L_N(j, 4) { LCD_SERIAL.write(DWIN_BufTail[j]); delayMicroseconds(1); }
block++;
pending -= to_send;
}
}
// Write the contents of the 32KB SRAM data memory into the designated image memory space.
// picID: Picture memory space location, 0x00-0x0F, each space is 32Kbytes
void DWIN_SRAMToPic(uint8_t picID) {
size_t i = 0;
DWIN_Byte(i, 0x33);
DWIN_Byte(i, 0x5A);
DWIN_Byte(i, 0xA5);
DWIN_Byte(i, picID);
DWIN_Send(i);
}
//--------------------------Test area -------------------------
// void DWIN_ReadSRAM(uint16_t addr, uint8_t length, const char * const data) {
// size_t i = 0;
// DWIN_Byte(i, 0x32);
// DWIN_Byte(i, 0x5A); // 0x5A Read from SRAM - 0xA5 Read from Flash
// DWIN_Word(i, addr); // 0x0000 to 0x7FFF
// const size_t len = _MIN(0xF0, length);
// DWIN_Byte(i, len);
// DWIN_Send(i);
// }
/*---------------------------------------- Memory functions ----------------------------------------*/
// The LCD has an additional 32KB SRAM and 16KB Flash
// Data can be written to the sram and save to one of the jpeg page files
// Write Data Memory
// command 0x31
// Type: Write memory selection; 0x5A=SRAM; 0xA5=Flash
// Address: Write data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash
// Data: data
//
// Flash writing returns 0xA5 0x4F 0x4B
// Read Data Memory
// command 0x32
// Type: Read memory selection; 0x5A=SRAM; 0xA5=Flash
// Address: Read data memory address; 0x000-0x7FFF for SRAM; 0x000-0x3FFF for Flash
// Length: leangth of data to read; 0x01-0xF0
//
// Response:
// Type, Address, Length, Data
// Write Picture Memory
// Write the contents of the 32KB SRAM data memory into the designated image memory space
// Issued: 0x5A, 0xA5, PIC_ID
// Response: 0xA5 0x4F 0x4B
//
// command 0x33
// 0x5A, 0xA5
// PicId: Picture Memory location, 0x00-0x0F
//
// Flash writing returns 0xA5 0x4F 0x4B
#endif // DWIN_CREALITY_LCD_ENHANCED

285
Marlin/src/lcd/e3v2/enhanced/dwin_lcd.h

@ -0,0 +1,285 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/********************************************************************************
* @file lcd/e3v2/enhanced/dwin_lcd.h
* @author LEO / Creality3D - Enhanced by Miguel A. Risco-Castillo
* @date 2021/08/09
* @version 2.2.1
* @brief DWIN screen control functions
********************************************************************************/
#pragma once
#include <stdint.h>
#define RECEIVED_NO_DATA 0x00
#define RECEIVED_SHAKE_HAND_ACK 0x01
#define FHONE 0xAA
#define DWIN_SCROLL_UP 2
#define DWIN_SCROLL_DOWN 3
#define DWIN_WIDTH 272
#define DWIN_HEIGHT 480
#define DWIN_DataLength (DWIN_WIDTH / 6 * 2)
/*-------------------------------------- System variable function --------------------------------------*/
// Handshake (1: Success, 0: Fail)
bool DWIN_Handshake(void);
// Set the backlight luminance
// luminance: (0x00-0xFF)
void DWIN_Backlight_SetLuminance(const uint8_t luminance);
// Set screen display direction
// dir: 0=0°, 1=90°, 2=180°, 3=270°
void DWIN_Frame_SetDir(uint8_t dir);
// Update display
void DWIN_UpdateLCD(void);
/*---------------------------------------- Drawing functions ----------------------------------------*/
// Clear screen
// color: Clear screen color
void DWIN_Frame_Clear(const uint16_t color);
// Draw a point
// color: point color
// width: point width 0x01-0x0F
// height: point height 0x01-0x0F
// x,y: upper left point
void DWIN_Draw_Point(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y);
// Draw a line
// color: Line segment color
// xStart/yStart: Start point
// xEnd/yEnd: End point
void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
// Draw a Horizontal line
// color: Line segment color
// xStart/yStart: Start point
// xLength: Line Length
inline void DWIN_Draw_HLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xLength) {
DWIN_Draw_Line(color, xStart, yStart, xStart + xLength - 1, yStart);
}
// Draw a Vertical line
// color: Line segment color
// xStart/yStart: Start point
// yLength: Line Length
inline void DWIN_Draw_VLine(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t yLength) {
DWIN_Draw_Line(color, xStart, yStart, xStart, yStart + yLength - 1);
}
// Draw a rectangle
// mode: 0=frame, 1=fill, 2=XOR fill
// color: Rectangle color
// xStart/yStart: upper left point
// xEnd/yEnd: lower right point
void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
// Draw a box
// mode: 0=frame, 1=fill, 2=XOR fill
// color: Rectangle color
// xStart/yStart: upper left point
// xSize/ySize: box size
inline void DWIN_Draw_Box(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xSize, uint16_t ySize) {
DWIN_Draw_Rectangle(mode, color, xStart, yStart, xStart + xSize - 1, yStart + ySize - 1);
}
// Move a screen area
// mode: 0, circle shift; 1, translation
// dir: 0=left, 1=right, 2=up, 3=down
// dis: Distance
// color: Fill color
// xStart/yStart: upper left point
// xEnd/yEnd: bottom right point
void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis,
uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
/*---------------------------------------- Text related functions ----------------------------------------*/
// Draw a string
// widthAdjust: true=self-adjust character width; false=no adjustment
// bShow: true=display background color; false=don't display background color
// size: Font size
// color: Character color
// bColor: Background color
// x/y: Upper-left coordinate of the string
// *string: The string
// rlimit: For draw less chars than string length use rlimit
void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const char * const string, uint16_t rlimit = 0xFFFF);
inline void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const char * const string, uint16_t rlimit = 0xFFFF) {
DWIN_Draw_String(0, bShow, size, color, bColor, x, y, string, rlimit);
}
class __FlashStringHelper;
inline void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(widthAdjust, bShow, size, color, bColor, x, y, (char *)title);
}
inline void DWIN_Draw_String(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(0, bShow, size, color, bColor, x, y, (char *)title);
}
// Draw a positive integer
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of digits
// x/y: Upper-left coordinate
// value: Integer value
void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value);
// Draw a positive floating point number
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of whole digits
// fNum: Number of decimal digits
// x/y: Upper-left point
// value: Scaled positive float value
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value);
// value: positive float value
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value);
/*---------------------------------------- Picture related functions ----------------------------------------*/
// Display QR code
// The size of the QR code is (46*QR_Pixel)*(46*QR_Pixel) dot matrix
// QR_Pixel: The pixel size occupied by each point of the QR code: 0x01-0x0F (1-16)
// (Nx, Ny): The coordinates of the upper left corner displayed by the QR code
// str: multi-bit data
void DWIN_Draw_QR(uint8_t QR_Pixel, uint16_t x, uint16_t y, char *string);
inline void DWIN_Draw_QR(uint8_t QR_Pixel, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_QR(QR_Pixel, x, y, (char *)title);
}
// Draw JPG and cached in #0 virtual display area
// id: Picture ID
void DWIN_JPG_ShowAndCache(const uint8_t id);
// Draw an Icon
// IBD: The icon background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// libID: Icon library ID
// picID: Icon ID
// x/y: Upper-left point
void DWIN_ICON_Show(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint8_t libID, uint8_t picID, uint16_t x, uint16_t y);
// Draw an Icon with transparent background
// libID: Icon library ID
// picID: Icon ID
// x/y: Upper-left point
inline void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y) {
DWIN_ICON_Show(0, 0, 1, libID, picID, x, y);
}
// Draw an Icon from SRAM
// IBD: The icon background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// x/y: Upper-left point
// addr: SRAM address
void DWIN_ICON_Show(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint16_t x, uint16_t y, uint16_t addr);
// Unzip the JPG picture to a virtual display area
// n: Cache index
// id: Picture ID
void DWIN_JPG_CacheToN(uint8_t n, uint8_t id);
// Unzip the JPG picture to virtual display area #1
// id: Picture ID
inline void DWIN_JPG_CacheTo1(uint8_t id) { DWIN_JPG_CacheToN(1, id); }
// Copy area from current virtual display area to current screen
// xStart/yStart: Upper-left of virtual area
// xEnd/yEnd: Lower-right of virtual area
// x/y: Screen paste point
void DWIN_Frame_AreaCopy(uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y);
// Copy area from virtual display area to current screen
// IBD: background display: 0=Background filtering is not displayed, 1=Background display \\When setting the background filtering not to display, the background must be pure black
// BIR: Background image restoration: 0=Background image is not restored, 1=Automatically use virtual display area image for background restoration
// BFI: Background filtering strength: 0=normal, 1=enhanced, (only valid when the icon background display=0)
// cacheID: virtual area number
// xStart/yStart: Upper-left of virtual area
// xEnd/yEnd: Lower-right of virtual area
// x/y: Screen paste point
void DWIN_Frame_AreaCopy(uint8_t IBD, uint8_t BIR, uint8_t BFI, uint8_t cacheID, uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y);
// Copy area from virtual display area to current screen with transparent background
// cacheID: virtual area number
// xStart/yStart: Upper-left of virtual area
// xEnd/yEnd: Lower-right of virtual area
// x/y: Screen paste point
inline void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) {
DWIN_Frame_AreaCopy(0, 0, 1, cacheID, xStart, yStart, xEnd, yEnd, x, y);
}
// Animate a series of icons
// animID: Animation ID up to 16
// animate: animation on or off
// libID: Icon library ID
// picIDs: Icon starting ID
// picIDe: Icon ending ID
// x/y: Upper-left point
// interval: Display time interval, unit 10mS
void DWIN_ICON_Animation(uint8_t animID, bool animate, uint8_t libID, uint8_t picIDs,
uint8_t picIDe, uint16_t x, uint16_t y, uint16_t interval);
// Animation Control
// state: 16 bits, each bit is the state of an animation id
void DWIN_ICON_AnimationControl(uint16_t state);
// Set LCD Brightness 0x00-0x0F
void DWIN_LCD_Brightness(const uint8_t brightness);
// Write buffer data to the SRAM or Flash
// mem: 0x5A=32KB SRAM, 0xA5=16KB Flash
// addr: start address
// length: Bytes to write
// data: address of the buffer with data
void DWIN_WriteToMem(uint8_t mem, uint16_t addr, uint16_t length, uint8_t *data);
// Write the contents of the 32KB SRAM data memory into the designated image memory space.
// picID: Picture memory space location, 0x00-0x0F, each space is 32Kbytes
void DWIN_SRAMToPic(uint8_t picID);

452
Marlin/src/lcd/e3v2/enhanced/dwinui.cpp

@ -0,0 +1,452 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.3
* Date: 2021/08/09
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../inc/MarlinConfig.h"
#include "../../../core/macros.h"
#include "dwin_lcd.h"
#include "dwinui.h"
//#define DEBUG_OUT 1
#include "../../../core/debug_out.h"
uint8_t MenuItemTotal = 0;
uint8_t MenuItemCount = 0;
MenuItemClass** MenuItems = nullptr;
MenuClass *CurrentMenu = nullptr;
MenuClass *PreviousMenu = nullptr;
xy_int_t DWINUI::cursor = { 0 };
uint16_t DWINUI::pencolor = Color_White;
uint16_t DWINUI::textcolor = Def_Text_Color;
uint16_t DWINUI::backcolor = Def_Background_Color;
uint8_t DWINUI::font = font8x16;
void (*DWINUI::onCursorErase)(uint8_t line)=nullptr;
void (*DWINUI::onCursorDraw)(uint8_t line)=nullptr;
void (*DWINUI::onTitleDraw)(TitleClass* title)=nullptr;
void (*DWINUI::onMenuDraw)(MenuClass* menu)=nullptr;
void DWINUI::Init(void) {
DEBUG_ECHOPGM("\r\nDWIN handshake ");
delay(750); // Delay here or init later in the boot process
const bool success = DWIN_Handshake();
if (success) DEBUG_ECHOLNPGM("ok."); else DEBUG_ECHOLNPGM("error.");
DWIN_Frame_SetDir(1);
TERN(SHOW_BOOTSCREEN,,DWIN_Frame_Clear(Color_Bg_Black));
DWIN_UpdateLCD();
cursor.x = 0;
cursor.y = 0;
pencolor = Color_White;
textcolor = Def_Text_Color;
backcolor = Def_Background_Color;
font = font8x16;
}
// Set text/number font
void DWINUI::SetFont(uint8_t cfont) {
font = cfont;
}
// Get font character width
uint8_t DWINUI::Get_font_width(uint8_t cfont) {
switch (cfont) {
case font6x12 : return 6;
case font8x16 : return 8;
case font10x20: return 10;
case font12x24: return 12;
case font14x28: return 14;
case font16x32: return 16;
case font20x40: return 20;
case font24x48: return 24;
case font28x56: return 28;
case font32x64: return 32;
default: return 0;
}
}
// Get font character heigh
uint8_t DWINUI::Get_font_height(uint8_t cfont) {
switch (cfont) {
case font6x12 : return 12;
case font8x16 : return 16;
case font10x20: return 20;
case font12x24: return 24;
case font14x28: return 28;
case font16x32: return 32;
case font20x40: return 40;
case font24x48: return 48;
case font28x56: return 56;
case font32x64: return 64;
default: return 0;
}
}
// Get screen x coodinates from text column
uint16_t DWINUI::ColToX(uint8_t col) {
return col * Get_font_width(font);
}
// Get screen y coodinates from text row
uint16_t DWINUI::RowToY(uint8_t row) {
return row * Get_font_height(font);
}
// Set text/number color
void DWINUI::SetColors(uint16_t fgcolor, uint16_t bgcolor) {
textcolor = fgcolor;
backcolor = bgcolor;
}
void DWINUI::SetTextColor(uint16_t fgcolor) {
textcolor = fgcolor;
}
void DWINUI::SetBackgroundColor(uint16_t bgcolor) {
backcolor = bgcolor;
}
// Moves cursor to point
// x: abscissa of the display
// y: ordinate of the display
// point: xy coordinate
void DWINUI::MoveTo(int16_t x, int16_t y) {
cursor.x = x;
cursor.y = y;
}
void DWINUI::MoveTo(xy_int_t point) {
cursor = point;
}
// Moves cursor relative to the actual position
// x: abscissa of the display
// y: ordinate of the display
// point: xy coordinate
void DWINUI::MoveBy(int16_t x, int16_t y) {
cursor.x += x;
cursor.y += y;
}
void DWINUI::MoveBy(xy_int_t point) {
cursor += point;
}
// Draw a Centered string using DWIN_WIDTH
void DWINUI::Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string) {
const int8_t x = _MAX(0U, DWIN_WIDTH - strlen_P(string) * Get_font_width(size)) / 2 - 1;
DWIN_Draw_String(bShow, size, color, bColor, x, y, string);
}
// Draw a char at cursor position
void DWINUI::Draw_Char(const char c) {
const char string[2] = { c, 0};
DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, 1);
MoveBy(Get_font_width(font), 0);
}
// Draw a string at cursor position
// color: Character color
// *string: The string
// rlimit: For draw less chars than string length use rlimit
void DWINUI::Draw_String(const char * const string, uint16_t rlimit) {
DWIN_Draw_String(false, font, textcolor, backcolor, cursor.x, cursor.y, string, rlimit);
MoveBy(strlen(string) * Get_font_width(font), 0);
}
void DWINUI::Draw_String(uint16_t color, const char * const string, uint16_t rlimit) {
DWIN_Draw_String(false, font, color, backcolor, cursor.x, cursor.y, string, rlimit);
MoveBy(strlen(string) * Get_font_width(font), 0);
}
// Draw a signed floating point number
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// bColor: Background color
// iNum: Number of whole digits
// fNum: Number of decimal digits
// x/y: Upper-left point
// value: Float value
void DWINUI::Draw_Signed_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
if (value < 0) {
DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, -value);
DWIN_Draw_String(bShow, size, color, bColor, x - 6, y, F("-"));
}
else {
DWIN_Draw_String(bShow, size, color, bColor, x - 6, y, F(" "));
DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value);
}
}
// Draw a circle
// color: circle color
// x: the abscissa of the center of the circle
// y: ordinate of the center of the circle
// r: circle radius
void DWINUI::Draw_Circle(uint16_t color, uint16_t x, uint16_t y, uint8_t r) {
int a = 0, b = 0;
while (a <= b) {
b = SQRT(sq(r) - sq(a));
if (a == 0) b--;
DWIN_Draw_Point(color, 1, 1, x + a, y + b); // Draw some sector 1
DWIN_Draw_Point(color, 1, 1, x + b, y + a); // Draw some sector 2
DWIN_Draw_Point(color, 1, 1, x + b, y - a); // Draw some sector 3
DWIN_Draw_Point(color, 1, 1, x + a, y - b); // Draw some sector 4
DWIN_Draw_Point(color, 1, 1, x - a, y - b); // Draw some sector 5
DWIN_Draw_Point(color, 1, 1, x - b, y - a); // Draw some sector 6
DWIN_Draw_Point(color, 1, 1, x - b, y + a); // Draw some sector 7
DWIN_Draw_Point(color, 1, 1, x - a, y + b); // Draw some sector 8
a++;
}
}
// Draw a circle filled with color
// bcolor: fill color
// x: the abscissa of the center of the circle
// y: ordinate of the center of the circle
// r: circle radius
void DWINUI::Draw_FillCircle(uint16_t bcolor, uint16_t x,uint16_t y,uint8_t r) {
int a = 0, b = 0;
while (a <= b) {
b = SQRT(sq(r) - sq(a)); // b=sqrt(r*r-a*a);
if (a == 0) b--;
DWIN_Draw_Line(bcolor, x-b,y-a,x+b,y-a);
DWIN_Draw_Line(bcolor, x-a,y-b,x+a,y-b);
DWIN_Draw_Line(bcolor, x-b,y+a,x+b,y+a);
DWIN_Draw_Line(bcolor, x-a,y+b,x+a,y+b);
a++;
}
}
// Color Interpolator
// val : Interpolator minv..maxv
// minv : Minimum value
// maxv : Maximun value
// color1 : Start color
// color2 : End color
uint16_t DWINUI::ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2) {
uint8_t B,G,R;
float n;
n = (float)(val-minv)/(maxv-minv);
R = (1-n)*GetRColor(color1) + n*GetRColor(color2);
G = (1-n)*GetGColor(color1) + n*GetGColor(color2);
B = (1-n)*GetBColor(color1) + n*GetBColor(color2);
return RGB(R,G,B);
}
// Color Interpolator through Red->Yellow->Green->Blue
// val : Interpolator minv..maxv
// minv : Minimum value
// maxv : Maximun value
uint16_t DWINUI::RainbowInt(int16_t val, int16_t minv, int16_t maxv) {
uint8_t B,G,R;
const uint8_t maxB = 28;
const uint8_t maxR = 28;
const uint8_t maxG = 38;
const int16_t limv = _MAX(abs(minv), abs(maxv));
float n;
if (minv>=0) {
n = (float)(val-minv)/(maxv-minv);
} else {
n = (float)val/limv;
}
n = _MIN(1, n);
n = _MAX(-1, n);
if (n < 0) {
R = 0;
G = (1+n)*maxG;
B = (-n)*maxB;
} else if (n < 0.5) {
R = maxR*n*2;
G = maxG;
B = 0;
} else {
R = maxR;
G = maxG*(1-n);
B = 0;
}
return RGB(R,G,B);
}
// Draw a checkbox
// Color: frame color
// bColor: Background color
// x/y: Upper-left point
// mode : 0 : unchecked, 1 : checked
void DWINUI::Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool checked=false) {
DWIN_Draw_String(false, true, font8x16, color, bcolor, x + 4, y, checked ? F("x") : F(" "));
DWIN_Draw_Rectangle(0, color, x + 2, y + 2, x + 17, y + 17);
}
// Clear Menu by filling the menu area with background color
void DWINUI::ClearMenuArea() {
DWIN_Draw_Rectangle(1, backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1);
}
void DWINUI::MenuItemsClear() {
if (MenuItems == nullptr) return;
for (uint8_t i = 0; i < MenuItemCount; i++) delete MenuItems[i];
delete[] MenuItems;
MenuItems = nullptr;
MenuItemCount = 0;
MenuItemTotal = 0;
}
void DWINUI::MenuItemsPrepare(uint8_t totalitems) {
MenuItemsClear();
MenuItemTotal = totalitems;
MenuItems = new MenuItemClass*[totalitems];
}
MenuItemClass* DWINUI::MenuItemsAdd(MenuItemClass* menuitem) {
if (MenuItemCount < MenuItemTotal) {
MenuItems[MenuItemCount] = menuitem;
menuitem->pos = MenuItemCount++;
return menuitem;
}
else {
delete menuitem;
return nullptr;
}
}
/* Title Class ==============================================================*/
TitleClass Title;
void TitleClass::Draw() {
if (DWINUI::onTitleDraw != nullptr) (*DWINUI::onTitleDraw)(this);
}
void TitleClass::SetCaption(const char * const title) {
frameid = 0;
if ( caption == title ) return;
const uint8_t len = _MIN(sizeof(caption) - 1, strlen(title));
memcpy(&caption[0], title, len);
caption[len] = '\0';
}
void TitleClass::ShowCaption(const char * const title) {
SetCaption(title);
Draw();
}
void TitleClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
caption[0] = '\0';
frameid = id;
frame = { x1, y1, x2, y2 };
}
void TitleClass::SetFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
SetFrame(1, x, y, x + w - 1, y + h - 1);
}
void TitleClass::FrameCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
SetFrame(id, x1, y1, x2, y2);
Draw();
}
void TitleClass::FrameCopy(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
FrameCopy(1, x, y, x + w - 1, y + h - 1);
}
/* Menu Class ===============================================================*/
MenuClass::MenuClass() {
selected = 0;
topline = 0;
}
void MenuClass::Draw() {
MenuTitle.Draw();
if (DWINUI::onMenuDraw != nullptr) (*DWINUI::onMenuDraw)(this);
for (uint8_t i = 0; i < MenuItemCount; i++)
MenuItems[i]->Draw(i - topline);
if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
DWIN_UpdateLCD();
}
void MenuClass::onScroll(bool dir) {
int8_t sel = selected;
if (dir) sel++; else sel--;
LIMIT(sel, 0, MenuItemCount - 1);
if (sel != selected) {
if (DWINUI::onCursorErase != nullptr) DWINUI::onCursorErase(line());
if ((sel - topline) == TROWS) {
DWIN_Frame_AreaMove(1, DWIN_SCROLL_UP, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
topline++;
MenuItems[sel]->Draw(TROWS - 1);
}
if ((sel < topline)) {
DWIN_Frame_AreaMove(1, DWIN_SCROLL_DOWN, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
topline--;
MenuItems[sel]->Draw(0);
}
selected = sel;
if (DWINUI::onCursorDraw != nullptr) DWINUI::onCursorDraw(line());
DWIN_UpdateLCD();
}
}
void MenuClass::onClick() {
if (MenuItems[selected]->onClick != nullptr) (*MenuItems[selected]->onClick)();
}
MenuItemClass *MenuClass::SelectedItem() {
return MenuItems[selected];
}
/* MenuItem Class ===========================================================*/
MenuItemClass::MenuItemClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
icon = cicon;
onClick = onclick;
onDraw = ondraw;
const uint8_t len = _MIN(sizeof(caption) - 1, strlen(text));
memcpy(&caption[0], text, len);
caption[len] = '\0';
}
MenuItemClass::MenuItemClass(uint8_t cicon, uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
icon = cicon;
onClick = onclick;
onDraw = ondraw;
caption[0] = '\0';
frameid = id;
frame = { x1, y1, x2, y2 };
}
void MenuItemClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
caption[0] = '\0';
frameid = id;
frame = { x1, y1, x2, y2 };
}
void MenuItemClass::Draw(int8_t line) {
if (line < 0 || line >= TROWS) return;
if (onDraw != nullptr) (*onDraw)(this, line);
};
MenuItemPtrClass::MenuItemPtrClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val) : MenuItemClass(cicon, text, ondraw, onclick) {
value = val;
};
#endif // DWIN_CREALITY_LCD_ENHANCED

624
Marlin/src/lcd/e3v2/enhanced/dwinui.h

@ -0,0 +1,624 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.3
* Date: 2021/08/09
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../../core/types.h"
#include "dwin_lcd.h"
// ICON ID
#define ICON 7 // Icon set file 7.ICO
#define ICON_LOGO 0
#define ICON_Print_0 1
#define ICON_Print_1 2
#define ICON_Prepare_0 3
#define ICON_Prepare_1 4
#define ICON_Control_0 5
#define ICON_Control_1 6
#define ICON_Leveling_0 7
#define ICON_Leveling_1 8
#define ICON_HotendTemp 9
#define ICON_BedTemp 10
#define ICON_Speed 11
#define ICON_Zoffset 12
#define ICON_Back 13
#define ICON_File 14
#define ICON_PrintTime 15
#define ICON_RemainTime 16
#define ICON_Setup_0 17
#define ICON_Setup_1 18
#define ICON_Pause_0 19
#define ICON_Pause_1 20
#define ICON_Continue_0 21
#define ICON_Continue_1 22
#define ICON_Stop_0 23
#define ICON_Stop_1 24
#define ICON_Bar 25
#define ICON_More 26
#define ICON_Axis 27
#define ICON_CloseMotor 28
#define ICON_Homing 29
#define ICON_SetHome 30
#define ICON_PLAPreheat 31
#define ICON_ABSPreheat 32
#define ICON_Cool 33
#define ICON_Language 34
#define ICON_MoveX 35
#define ICON_MoveY 36
#define ICON_MoveZ 37
#define ICON_Extruder 38
#define ICON_Temperature 40
#define ICON_Motion 41
#define ICON_WriteEEPROM 42
#define ICON_ReadEEPROM 43
#define ICON_ResumeEEPROM 44
#define ICON_Info 45
#define ICON_SetEndTemp 46
#define ICON_SetBedTemp 47
#define ICON_FanSpeed 48
#define ICON_SetPLAPreheat 49
#define ICON_SetABSPreheat 50
#define ICON_MaxSpeed 51
#define ICON_MaxAccelerated 52
#define ICON_MaxJerk 53
#define ICON_Step 54
#define ICON_PrintSize 55
#define ICON_Version 56
#define ICON_Contact 57
#define ICON_StockConfiguration 58
#define ICON_MaxSpeedX 59
#define ICON_MaxSpeedY 60
#define ICON_MaxSpeedZ 61
#define ICON_MaxSpeedE 62
#define ICON_MaxAccX 63
#define ICON_MaxAccY 64
#define ICON_MaxAccZ 65
#define ICON_MaxAccE 66
#define ICON_MaxSpeedJerkX 67
#define ICON_MaxSpeedJerkY 68
#define ICON_MaxSpeedJerkZ 69
#define ICON_MaxSpeedJerkE 70
#define ICON_StepX 71
#define ICON_StepY 72
#define ICON_StepZ 73
#define ICON_StepE 74
#define ICON_Setspeed 75
#define ICON_SetZOffset 76
#define ICON_Rectangle 77
#define ICON_BLTouch 78
#define ICON_TempTooLow 79
#define ICON_AutoLeveling 80
#define ICON_TempTooHigh 81
#define ICON_NoTips_C 82
#define ICON_NoTips_E 83
#define ICON_Continue_C 84
#define ICON_Continue_E 85
#define ICON_Cancel_C 86
#define ICON_Cancel_E 87
#define ICON_Confirm_C 88
#define ICON_Confirm_E 89
#define ICON_Info_0 90
#define ICON_Info_1 91
// Extra Icons
#define ICON_AdvSet ICON_Language
#define ICON_Brightness ICON_Motion
#define ICON_Cancel ICON_StockConfiguration
#define ICON_CustomPreheat ICON_SetEndTemp
#define ICON_Error ICON_TempTooHigh
#define ICON_ExtrudeMinT ICON_HotendTemp
#define ICON_FilLoad ICON_WriteEEPROM
#define ICON_FilMan ICON_ResumeEEPROM
#define ICON_FilSet ICON_ResumeEEPROM
#define ICON_FilUnload ICON_ReadEEPROM
#define ICON_Flow ICON_StepE
#define ICON_HomeOffset ICON_AdvSet
#define ICON_HomeOffsetX ICON_StepX
#define ICON_HomeOffsetY ICON_StepY
#define ICON_HomeOffsetZ ICON_StepZ
#define ICON_LevBed ICON_SetEndTemp
#define ICON_Lock ICON_Cool
#define ICON_ManualMesh ICON_HotendTemp
#define ICON_MeshNext ICON_Axis
#define ICON_MeshSave ICON_WriteEEPROM
#define ICON_MoveZ0 ICON_HotendTemp
#define ICON_Park ICON_Motion
#define ICON_PIDbed ICON_SetBedTemp
#define ICON_PIDcycles ICON_ResumeEEPROM
#define ICON_PIDNozzle ICON_SetEndTemp
#define ICON_PIDValue ICON_Contact
#define ICON_ProbeOffsetX ICON_StepX
#define ICON_ProbeOffsetY ICON_StepY
#define ICON_ProbeOffsetZ ICON_StepZ
#define ICON_ProbeSet ICON_SetEndTemp
#define ICON_ProbeTest ICON_SetEndTemp
#define ICON_Pwrlossr ICON_Motion
#define ICON_Reboot ICON_ResumeEEPROM
#define ICON_Runout ICON_MaxAccE
#define ICON_Scolor ICON_MaxSpeed
#define ICON_SetCustomPreheat ICON_SetEndTemp
#define ICON_Sound ICON_Cool
/**
* 3-.0The font size, 0x00-0x09, corresponds to the font size below:
* 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28
* 0x05=16*32 0x06=20*40 0x07=24*48 0x08=28*56 0x09=32*64
*/
#define font6x12 0x00
#define font8x16 0x01
#define font10x20 0x02
#define font12x24 0x03
#define font14x28 0x04
#define font16x32 0x05
#define font20x40 0x06
#define font24x48 0x07
#define font28x56 0x08
#define font32x64 0x09
// Extended and default UI Colors
#define RGB(R,G,B) (R << 11) | (G << 5) | (B) // R,B: 0..31; G: 0..63
#define GetRColor(color) ((color >> 11) & 0x1F)
#define GetGColor(color) ((color >> 5) & 0x3F)
#define GetBColor(color) ((color >> 0) & 0x1F)
#define Color_White 0xFFFF
#define Color_Bg_Window 0x31E8 // Popup background color
#define Color_Bg_Blue 0x1125 // Dark blue background color
#define Color_Bg_Black 0x0841 // Black background color
#define Color_Bg_Red 0xF00F // Red background color
#define Popup_Text_Color 0xD6BA // Popup font background color
#define Line_Color 0x3A6A // Split line color
#define Rectangle_Color 0xEE2F // Blue square cursor color
#define Percent_Color 0xFE29 // Percentage color
#define BarFill_Color 0x10E4 // Fill color of progress bar
#define Select_Color 0x33BB // Selected color
#define Color_Black 0
#define Color_Red RGB(31,0,0)
#define Color_Yellow RGB(31,63,0)
#define Color_Green RGB(0,63,0)
#define Color_Aqua RGB(0,63,31)
#define Color_Blue RGB(0,0,31)
// Default UI Colors
#define Def_Background_Color Color_Bg_Black
#define Def_Cursor_color Rectangle_Color
#define Def_TitleBg_color Color_Bg_Blue
#define Def_TitleTxt_color Color_White
#define Def_Text_Color Color_White
#define Def_Selected_Color Select_Color
#define Def_SplitLine_Color Line_Color
#define Def_Highlight_Color Color_White
#define Def_StatusBg_Color RGB(0,20,20)
#define Def_StatusTxt_Color Color_Yellow
#define Def_PopupBg_color Color_Bg_Window
#define Def_PopupTxt_Color Popup_Text_Color
#define Def_AlertBg_Color Color_Bg_Red
#define Def_AlertTxt_Color Color_Yellow
#define Def_PercentTxt_Color Percent_Color
#define Def_Barfill_Color BarFill_Color
#define Def_Indicator_Color Color_White
#define Def_Coordinate_Color Color_White
//UI elements defines and constants
#define DWIN_FONT_MENU font8x16
#define DWIN_FONT_STAT font10x20
#define DWIN_FONT_HEAD font10x20
#define DWIN_FONT_ALERT font10x20
#define STATUS_Y 354
#define LCD_WIDTH (DWIN_WIDTH / 8)
constexpr uint16_t TITLE_HEIGHT = 30, // Title bar height
MLINE = 53, // Menu line height
TROWS = (STATUS_Y - TITLE_HEIGHT) / MLINE, // Total rows
MROWS = TROWS - 1, // Other-than-Back
ICOX = 26, // Menu item icon X position
LBLX = 60, // Menu item label X position
VALX = 210, // Menu item value X position
MENU_CHR_W = 8, MENU_CHR_H = 16, // Menu font 8x16
STAT_CHR_W = 10;
// Menuitem Y position
#define MYPOS(L) (TITLE_HEIGHT + MLINE * (L))
// Menuitem caption Offset
#define CAPOFF ((MLINE - MENU_CHR_H) / 2)
// Menuitem caption Y position
#define MBASE(L) (MYPOS(L) + CAPOFF)
// Create and add a MenuItem object to the menu array
#define ADDMENUITEM(V...) DWINUI::MenuItemsAdd(new MenuItemClass(V))
#define ADDMENUITEM_P(V...) DWINUI::MenuItemsAdd(new MenuItemPtrClass(V))
typedef struct { uint16_t left, top, right, bottom; } rect_t;
typedef struct { uint16_t x, y, w, h; } frame_rect_t;
class TitleClass {
public:
char caption[32] = "";
uint8_t frameid = 0;
rect_t frame = {0};
void Draw();
void SetCaption(const char * const title);
inline void SetCaption(const __FlashStringHelper * title) { SetCaption((char *)title); }
void ShowCaption(const char * const title);
inline void ShowCaption(const __FlashStringHelper * title) { ShowCaption((char *)title); }
void SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void SetFrame(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void FrameCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void FrameCopy(uint16_t x, uint16_t y, uint16_t h, uint16_t v);
};
extern TitleClass Title;
class MenuItemClass {
protected:
public:
uint8_t pos = 0;
uint8_t icon = 0;
char caption[32] = "";
uint8_t frameid = 0;
rect_t frame = {0};
void (*onDraw)(MenuItemClass* menuitem, int8_t line) = nullptr;
void (*onClick)() = nullptr;
MenuItemClass() {};
MenuItemClass(uint8_t cicon, const char * const text=nullptr, void (*ondraw)(MenuItemClass* menuitem, int8_t line)=nullptr, void (*onclick)()=nullptr);
MenuItemClass(uint8_t cicon, const __FlashStringHelper * text = nullptr, void (*ondraw)(MenuItemClass* menuitem, int8_t line)=nullptr, void (*onclick)()=nullptr) : MenuItemClass(cicon, (char*)text, ondraw, onclick){}
MenuItemClass(uint8_t cicon, uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void (*ondraw)(MenuItemClass* menuitem, int8_t line)=nullptr, void (*onclick)()=nullptr);
void SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
virtual ~MenuItemClass(){};
virtual void Draw(int8_t line);
};
class MenuItemPtrClass: public MenuItemClass {
public:
void *value = nullptr;
using MenuItemClass::MenuItemClass;
MenuItemPtrClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val);
MenuItemPtrClass(uint8_t cicon, const __FlashStringHelper * text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val) : MenuItemPtrClass(cicon, (char*)text, ondraw, onclick, val){}
};
class MenuClass {
public:
int8_t topline = 0;
int8_t selected = 0;
TitleClass MenuTitle;
MenuClass();
virtual ~MenuClass(){};
inline int8_t line() { return selected - topline; };
inline int8_t line(uint8_t pos) {return pos - topline; };
void Draw();
void onScroll(bool dir);
void onClick();
MenuItemClass* SelectedItem();
};
extern MenuClass *CurrentMenu;
namespace DWINUI {
extern xy_int_t cursor;
extern uint16_t pencolor;
extern uint16_t textcolor;
extern uint16_t backcolor;
extern uint8_t font;
extern void (*onCursorErase)(uint8_t line);
extern void (*onCursorDraw)(uint8_t line);
extern void (*onTitleDraw)(TitleClass* title);
extern void (*onMenuDraw)(MenuClass* menu);
// DWIN LCD Initialization
void Init(void);
// Set text/number font
void SetFont(uint8_t cfont);
// Get font character width
uint8_t Get_font_width(uint8_t cfont);
// Get font character heigh
uint8_t Get_font_height(uint8_t cfont);
// Get screen x coodinates from text column
uint16_t ColToX(uint8_t col);
// Get screen y coodinates from text row
uint16_t RowToY(uint8_t row);
// Set text/number color
void SetColors(uint16_t fgcolor, uint16_t bgcolor);
void SetTextColor(uint16_t fgcolor);
void SetBackgroundColor(uint16_t bgcolor);
// Moves cursor to point
// x: abscissa of the display
// y: ordinate of the display
// point: xy coordinate
void MoveTo(int16_t x, int16_t y);
void MoveTo(xy_int_t point);
// Moves cursor relative to the actual position
// x: abscissa of the display
// y: ordinate of the display
// point: xy coordinate
void MoveBy(int16_t x, int16_t y);
void MoveBy(xy_int_t point);
// Draw a line from the cursor to xy position
// color: Line segment color
// x/y: End point
inline void LineTo(uint16_t color, uint16_t x, uint16_t y) {
DWIN_Draw_Line(color, cursor.x, cursor.y, x, y);
}
inline void LineTo(uint16_t x, uint16_t y) {
DWIN_Draw_Line(pencolor, cursor.x, cursor.y, x, y);
}
// Draw an Icon with transparent background from the library ICON
// icon: Icon ID
// x/y: Upper-left point
inline void Draw_Icon(uint8_t icon, uint16_t x, uint16_t y) {
DWIN_ICON_Show(ICON, icon, x, y);
}
// Draw a positive integer
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of digits
// x/y: Upper-left coordinate
// value: Integer value
inline void Draw_Int(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) {
DWIN_Draw_IntValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, x, y, value);
}
inline void Draw_Int(uint8_t iNum, long value) {
DWIN_Draw_IntValue(false, true, 0, font, textcolor, backcolor, iNum, cursor.x, cursor.y, value);
MoveBy(iNum * Get_font_width(font), 0);
}
inline void Draw_Int(uint8_t iNum, uint16_t x, uint16_t y, long value) {
DWIN_Draw_IntValue(false, true, 0, font, textcolor, backcolor, iNum, x, y, value);
}
inline void Draw_Int(uint16_t color, uint8_t iNum, uint16_t x, uint16_t y, long value) {
DWIN_Draw_IntValue(false, true, 0, font, color, backcolor, iNum, x, y, value);
}
inline void Draw_Int(uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) {
DWIN_Draw_IntValue(true, true, 0, font, color, bColor, iNum, x, y, value);
}
inline void Draw_Int(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, long value) {
DWIN_Draw_IntValue(true, true, 0, size, color, bColor, iNum, x, y, value);
}
// Draw a floating point number
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// color: Character color
// bColor: Background color
// iNum: Number of whole digits
// fNum: Number of decimal digits
// x/y: Upper-left point
// value: Float value
inline void Draw_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
DWIN_Draw_FloatValue(bShow, zeroFill, zeroMode, size, color, bColor, iNum, fNum, x, y, value);
}
inline void Draw_Float(uint8_t iNum, uint8_t fNum, float value) {
DWIN_Draw_FloatValue(false, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value);
MoveBy((iNum + fNum + 1) * Get_font_width(font), 0);
}
inline void Draw_Float(uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
DWIN_Draw_FloatValue(false, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value);
}
inline void Draw_Float(uint16_t color, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
DWIN_Draw_FloatValue(false, true, 0, font, color, backcolor, iNum, fNum, x, y, value);
}
inline void Draw_Float(uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
DWIN_Draw_FloatValue(true, true, 0, font, color, bColor, iNum, fNum, x, y, value);
}
inline void Draw_Float(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
DWIN_Draw_FloatValue(true, true, 0, size, color, bColor, iNum, fNum, x, y, value);
}
// Draw a signed floating point number
// bShow: true=display background color; false=don't display background color
// zeroFill: true=zero fill; false=no zero fill
// zeroMode: 1=leading 0 displayed as 0; 0=leading 0 displayed as a space
// size: Font size
// bColor: Background color
// iNum: Number of whole digits
// fNum: Number of decimal digits
// x/y: Upper-left point
// value: Float value
void Draw_Signed_Float(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value);
inline void Draw_Signed_Float(uint8_t iNum, uint8_t fNum, float value) {
Draw_Signed_Float(false, true, 0, font, textcolor, backcolor, iNum, fNum, cursor.x, cursor.y, value);
MoveBy((iNum + fNum + 1) * Get_font_width(font), 0);
}
inline void Draw_Signed_Float(uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
Draw_Signed_Float(false, true, 0, font, textcolor, backcolor, iNum, fNum, x, y, value);
}
inline void Draw_Signed_Float(uint8_t size, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
Draw_Signed_Float(false, true, 0, size, textcolor, backcolor, iNum, fNum, x, y, value);
}
inline void Draw_Signed_Float(uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
Draw_Signed_Float(true, true, 0, font, color, bColor, iNum, fNum, x, y, value);
}
inline void Draw_Signed_Float(uint8_t size, uint16_t color, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, float value) {
Draw_Signed_Float(true, true, 0, size, color, bColor, iNum, fNum, x, y, value);
}
// Draw a char at cursor position
void Draw_Char(const char c);
// Draw a string at cursor position
// color: Character color
// *string: The string
// rlimit: For draw less chars than string length use rlimit
void Draw_String(const char * const string, uint16_t rlimit = 0xFFFF);
void Draw_String(uint16_t color, const char * const string, uint16_t rlimit = 0xFFFF);
// Draw a string
// size: Font size
// color: Character color
// bColor: Background color
// x/y: Upper-left coordinate of the string
// *string: The string
inline void Draw_String(uint16_t x, uint16_t y, const char * const string) {
DWIN_Draw_String(false, font, textcolor, backcolor, x, y, string);
}
inline void Draw_String(uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(false, font, textcolor, backcolor, x, y, (char *)title);
}
inline void Draw_String(uint16_t color, uint16_t x, uint16_t y, const char * const string) {
DWIN_Draw_String(false, font, color, backcolor, x, y, string);
}
inline void Draw_String(uint16_t color, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(false, font, color, backcolor, x, y, (char *)title);
}
inline void Draw_String(uint16_t color, uint16_t bgcolor, uint16_t x, uint16_t y, const char * const string) {
DWIN_Draw_String(true, font, color, bgcolor, x, y, string);
}
inline void Draw_String(uint16_t color, uint16_t bgcolor, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(true, font, color, bgcolor, x, y, (char *)title);
}
inline void Draw_String(uint8_t size, uint16_t color, uint16_t bgcolor, uint16_t x, uint16_t y, const char * const string) {
DWIN_Draw_String(true, size, color, bgcolor, x, y, string);
}
inline void Draw_String(uint8_t size, uint16_t color, uint16_t bgcolor, uint16_t x, uint16_t y, const __FlashStringHelper *title) {
DWIN_Draw_String(true, size, color, bgcolor, x, y, (char *)title);
}
// Draw a centered string using DWIN_WIDTH
// bShow: true=display background color; false=don't display background color
// size: Font size
// color: Character color
// bColor: Background color
// y: Upper coordinate of the string
// *string: The string
void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const char * const string);
inline void Draw_CenteredString(bool bShow, uint8_t size, uint16_t color, uint16_t bColor, uint16_t y, const __FlashStringHelper *title) {
Draw_CenteredString(bShow, size, color, bColor, y, (char *)title);
}
inline void Draw_CenteredString(uint16_t color, uint16_t bcolor, uint16_t y, const char * const string) {
Draw_CenteredString(true, font, color, bcolor, y, string);
}
inline void Draw_CenteredString(uint8_t size, uint16_t color, uint16_t y, const char * const string) {
Draw_CenteredString(false, size, color, backcolor, y, string);
}
inline void Draw_CenteredString(uint8_t size, uint16_t color, uint16_t y, const __FlashStringHelper *title) {
Draw_CenteredString(false, size, color, backcolor, y, (char *)title);
}
inline void Draw_CenteredString(uint16_t color, uint16_t y, const char * const string) {
Draw_CenteredString(false, font, color, backcolor, y, string);
}
inline void Draw_CenteredString(uint16_t color, uint16_t y, const __FlashStringHelper *title) {
Draw_CenteredString(false, font, color, backcolor, y, (char *)title);
}
inline void Draw_CenteredString(uint16_t y, const char * const string) {
Draw_CenteredString(false, font, textcolor, backcolor, y, string);
}
inline void Draw_CenteredString(uint16_t y, const __FlashStringHelper *title) {
Draw_CenteredString(false, font, textcolor, backcolor, y, (char *)title);
}
// Draw a circle
// Color: circle color
// x: the abscissa of the center of the circle
// y: ordinate of the center of the circle
// r: circle radius
void Draw_Circle(uint16_t color, uint16_t x,uint16_t y,uint8_t r);
inline void Draw_Circle(uint16_t color, uint8_t r) {
Draw_Circle(color, cursor.x, cursor.y, r);
}
// Draw a checkbox
// Color: frame color
// bColor: Background color
// x/y: Upper-left point
// checked : 0 : unchecked, 1 : checked
void Draw_Checkbox(uint16_t color, uint16_t bcolor, uint16_t x, uint16_t y, bool checked);
inline void Draw_Checkbox(uint16_t x, uint16_t y, bool checked=false) {
Draw_Checkbox(textcolor, backcolor, x, y, checked);
}
// Color Interpolator
// val : Interpolator minv..maxv
// minv : Minimum value
// maxv : Maximun value
// color1 : Start color
// color2 : End color
uint16_t ColorInt(int16_t val, int16_t minv, int16_t maxv, uint16_t color1, uint16_t color2);
// -------------------------- Extra -------------------------------//
// Draw a circle filled with color
// bcolor: fill color
// x: the abscissa of the center of the circle
// y: ordinate of the center of the circle
// r: circle radius
void Draw_FillCircle(uint16_t bcolor, uint16_t x,uint16_t y,uint8_t r);
inline void Draw_FillCircle(uint16_t bcolor, uint8_t r) {
Draw_FillCircle(bcolor, cursor.x, cursor.y, r);
}
// Color Interpolator through Red->Yellow->Green->Blue
// val : Interpolator minv..maxv
// minv : Minimum value
// maxv : Maximun value
uint16_t RainbowInt(int16_t val, int16_t minv, int16_t maxv);
// Write buffer data to the SRAM
// addr: SRAM start address 0x0000-0x7FFF
// length: Bytes to write
// data: address of the buffer with data
inline void WriteToSRAM(uint16_t addr, uint16_t length, uint8_t *data) {
DWIN_WriteToMem(0x5A, addr, length, data);
}
// Write buffer data to the Flash
// addr: Flash start address 0x0000-0x3FFF
// length: Bytes to write
// data: address of the buffer with data
inline void WriteToFlash(uint16_t addr, uint16_t length, uint8_t *data) {
DWIN_WriteToMem(0xA5, addr, length, data);
}
// Clear Menu by filling the area with background color
// Area (0, TITLE_HEIGHT, DWIN_WIDTH, STATUS_Y - 1)
void ClearMenuArea();
// Clear MenuItems array and free MenuItems elements
void MenuItemsClear();
// Prepare MenuItems array
void MenuItemsPrepare(uint8_t totalitems);
// Add elements to the MenuItems array
MenuItemClass* MenuItemsAdd(MenuItemClass* menuitem);
};

69
Marlin/src/lcd/e3v2/enhanced/lockscreen.cpp

@ -0,0 +1,69 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../../core/types.h"
#include "dwin_lcd.h"
#include "dwinui.h"
#include "dwin.h"
#include "lockscreen.h"
LockScreenClass LockScreen;
void LockScreenClass::Init() {
Lock_Pos = 0;
unlocked = false;
Draw();
}
void LockScreenClass::Draw() {
Title.SetCaption(PSTR("Lock Screen"));
DWINUI::ClearMenuArea();
DWINUI::Draw_Icon(ICON_LOGO, 71, 120); // CREALITY logo
DWINUI::Draw_CenteredString(Color_White, 180, F("Printer is Locked,"));
DWINUI::Draw_CenteredString(Color_White, 200, F("Scroll to unlock."));
DWINUI::Draw_CenteredString(Color_White, 240, F("-> | <-"));
DWIN_Draw_Box(1, HMI_data.Barfill_Color, 0, 260, DWIN_WIDTH, 20);
DWIN_Draw_VLine(Color_Yellow, Lock_Pos * DWIN_WIDTH / 255, 260, 20);
DWIN_UpdateLCD();
}
void LockScreenClass::onEncoderState(ENCODER_DiffState encoder_diffState) {
if (encoder_diffState == ENCODER_DIFF_CW) {
Lock_Pos += 8;
}
else if (encoder_diffState == ENCODER_DIFF_CCW) {
Lock_Pos -= 8;
}
else if (encoder_diffState == ENCODER_DIFF_ENTER) {
unlocked = (Lock_Pos == 128);
}
DWIN_Draw_Box(1, HMI_data.Barfill_Color, 0, 260, DWIN_WIDTH, 20);
DWIN_Draw_VLine(Color_Yellow, Lock_Pos * DWIN_WIDTH / 255, 260, 20);
DWIN_UpdateLCD();
}
bool LockScreenClass::isUnlocked() { return unlocked; }
#endif // DWIN_CREALITY_LCD_ENHANCED

35
Marlin/src/lcd/e3v2/enhanced/lockscreen.h

@ -0,0 +1,35 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../../core/types.h"
class LockScreenClass {
private:
uint8_t Lock_Pos = 0;
bool unlocked = false;
public:
void Init();
void onEncoderState(ENCODER_DiffState encoder_diffState);
void Draw();
bool isUnlocked();
};
extern LockScreenClass LockScreen;

261
Marlin/src/lcd/e3v2/enhanced/rotary_encoder.cpp

@ -0,0 +1,261 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/*****************************************************************************
* @file lcd/e3v2/enhanced/rotary_encoder.cpp
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief Rotary encoder functions
*****************************************************************************/
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "rotary_encoder.h"
#include "../../buttons.h"
#include "../../../MarlinCore.h"
#include "../../../HAL/shared/Delay.h"
#if HAS_BUZZER
#include "../../../libs/buzzer.h"
#endif
#include <stdlib.h>
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#if ENABLED(SOUND_MENU_ITEM)
#include "../../marlinui.h"
#endif
ENCODER_Rate EncoderRate;
// Buzzer
void Encoder_tick() {
#if PIN_EXISTS(BEEPER)
if (TERN1(SOUND_MENU_ITEM, ui.buzzer_enabled)) {
WRITE(BEEPER_PIN, HIGH);
delay(10);
WRITE(BEEPER_PIN, LOW);
}
#endif
}
// Encoder initialization
void Encoder_Configuration() {
#if BUTTON_EXISTS(EN1)
SET_INPUT_PULLUP(BTN_EN1);
#endif
#if BUTTON_EXISTS(EN2)
SET_INPUT_PULLUP(BTN_EN2);
#endif
#if BUTTON_EXISTS(ENC)
SET_INPUT_PULLUP(BTN_ENC);
#endif
#if PIN_EXISTS(BEEPER)
SET_OUTPUT(BEEPER_PIN);
#endif
}
// Analyze encoder value and return state
ENCODER_DiffState Encoder_ReceiveAnalyze() {
const millis_t now = millis();
static uint8_t lastEncoderBits;
uint8_t newbutton = 0;
static signed char temp_diff = 0;
ENCODER_DiffState temp_diffState = ENCODER_DIFF_NO;
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
if (BUTTON_PRESSED(ENC)) {
static millis_t next_click_update_ms;
if (ELAPSED(now, next_click_update_ms)) {
next_click_update_ms = millis() + 300;
Encoder_tick();
#if PIN_EXISTS(LCD_LED)
//LED_Action();
#endif
const bool was_waiting = wait_for_user;
wait_for_user = false;
return was_waiting ? ENCODER_DIFF_NO : ENCODER_DIFF_ENTER;
}
else return ENCODER_DIFF_NO;
}
if (newbutton != lastEncoderBits) {
switch (newbutton) {
case ENCODER_PHASE_0:
if (lastEncoderBits == ENCODER_PHASE_3) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_1) temp_diff--;
break;
case ENCODER_PHASE_1:
if (lastEncoderBits == ENCODER_PHASE_0) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_2) temp_diff--;
break;
case ENCODER_PHASE_2:
if (lastEncoderBits == ENCODER_PHASE_1) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_3) temp_diff--;
break;
case ENCODER_PHASE_3:
if (lastEncoderBits == ENCODER_PHASE_2) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_0) temp_diff--;
break;
}
lastEncoderBits = newbutton;
}
if (ABS(temp_diff) >= ENCODER_PULSES_PER_STEP) {
if (temp_diff > 0) temp_diffState = ENCODER_DIFF_CW;
else temp_diffState = ENCODER_DIFF_CCW;
#if ENABLED(ENCODER_RATE_MULTIPLIER)
millis_t ms = millis();
int32_t encoderMultiplier = 1;
// if must encoder rati multiplier
if (EncoderRate.enabled) {
const float abs_diff = ABS(temp_diff),
encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP);
if (EncoderRate.lastEncoderTime) {
// Note that the rate is always calculated between two passes through the
// loop and that the abs of the temp_diff value is tracked.
const float encoderStepRate = encoderMovementSteps / float(ms - EncoderRate.lastEncoderTime) * 1000;
if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100;
else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10;
else if (encoderStepRate >= ENCODER_5X_STEPS_PER_SEC) encoderMultiplier = 5;
}
EncoderRate.lastEncoderTime = ms;
}
#else
constexpr int32_t encoderMultiplier = 1;
#endif
// EncoderRate.encoderMoveValue += (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP);
EncoderRate.encoderMoveValue = (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP);
if (EncoderRate.encoderMoveValue < 0) EncoderRate.encoderMoveValue = -EncoderRate.encoderMoveValue;
temp_diff = 0;
}
return temp_diffState;
}
#if PIN_EXISTS(LCD_LED)
// Take the low 24 valid bits 24Bit: G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 B7 B6 B5 B4 B3 B2 B1 B0
uint16_t LED_DataArray[LED_NUM];
// LED light operation
void LED_Action() {
LED_Control(RGB_SCALE_WARM_WHITE,0x0F);
delay(30);
LED_Control(RGB_SCALE_WARM_WHITE,0x00);
}
// LED initialization
void LED_Configuration() {
SET_OUTPUT(LCD_LED_PIN);
}
// LED write data
void LED_WriteData() {
uint8_t tempCounter_LED, tempCounter_Bit;
for (tempCounter_LED = 0; tempCounter_LED < LED_NUM; tempCounter_LED++) {
for (tempCounter_Bit = 0; tempCounter_Bit < 24; tempCounter_Bit++) {
if (LED_DataArray[tempCounter_LED] & (0x800000 >> tempCounter_Bit)) {
LED_DATA_HIGH;
DELAY_NS(300);
LED_DATA_LOW;
DELAY_NS(200);
}
else {
LED_DATA_HIGH;
LED_DATA_LOW;
DELAY_NS(200);
}
}
}
}
// LED control
// RGB_Scale: RGB color ratio
// luminance: brightness (0~0xFF)
void LED_Control(const uint8_t RGB_Scale, const uint8_t luminance) {
for (uint8_t i = 0; i < LED_NUM; i++) {
LED_DataArray[i] = 0;
switch (RGB_Scale) {
case RGB_SCALE_R10_G7_B5: LED_DataArray[i] = (luminance * 10/10) << 8 | (luminance * 7/10) << 16 | luminance * 5/10; break;
case RGB_SCALE_R10_G7_B4: LED_DataArray[i] = (luminance * 10/10) << 8 | (luminance * 7/10) << 16 | luminance * 4/10; break;
case RGB_SCALE_R10_G8_B7: LED_DataArray[i] = (luminance * 10/10) << 8 | (luminance * 8/10) << 16 | luminance * 7/10; break;
}
}
LED_WriteData();
}
// LED gradient control
// RGB_Scale: RGB color ratio
// luminance: brightness (0~0xFF)
// change_Time: gradient time (ms)
void LED_GraduallyControl(const uint8_t RGB_Scale, const uint8_t luminance, const uint16_t change_Interval) {
struct { uint8_t g, r, b; } led_data[LED_NUM];
for (uint8_t i = 0; i < LED_NUM; i++) {
switch (RGB_Scale) {
case RGB_SCALE_R10_G7_B5:
led_data[i] = { luminance * 7/10, luminance * 10/10, luminance * 5/10 };
break;
case RGB_SCALE_R10_G7_B4:
led_data[i] = { luminance * 7/10, luminance * 10/10, luminance * 4/10 };
break;
case RGB_SCALE_R10_G8_B7:
led_data[i] = { luminance * 8/10, luminance * 10/10, luminance * 7/10 };
break;
}
}
struct { bool g, r, b; } led_flag = { false, false, false };
for (uint8_t i = 0; i < LED_NUM; i++) {
while (1) {
const uint8_t g = uint8_t(LED_DataArray[i] >> 16),
r = uint8_t(LED_DataArray[i] >> 8),
b = uint8_t(LED_DataArray[i]);
if (g == led_data[i].g) led_flag.g = true;
else LED_DataArray[i] += (g > led_data[i].g) ? -0x010000 : 0x010000;
if (r == led_data[i].r) led_flag.r = true;
else LED_DataArray[i] += (r > led_data[i].r) ? -0x000100 : 0x000100;
if (b == led_data[i].b) led_flag.b = true;
else LED_DataArray[i] += (b > led_data[i].b) ? -0x000001 : 0x000001;
LED_WriteData();
if (led_flag.r && led_flag.g && led_flag.b) break;
delay(change_Interval);
}
}
}
#endif // LCD_LED
#endif // DWIN_CREALITY_LCD_ENHANCED

93
Marlin/src/lcd/e3v2/enhanced/rotary_encoder.h

@ -0,0 +1,93 @@
/**
* DWIN UI Enhanced implementation
* Author: Miguel A. Risco-Castillo
* Version: 3.6.1
* Date: 2021/08/29
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/*****************************************************************************
* @file lcd/e3v2/enhanced/rotary_encoder.h
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief Rotary encoder functions
****************************************************************************/
#include "../../../inc/MarlinConfig.h"
/*********************** Encoder Set ***********************/
typedef struct {
bool enabled = false;
int encoderMoveValue = 0;
millis_t lastEncoderTime = 0;
} ENCODER_Rate;
extern ENCODER_Rate EncoderRate;
typedef enum {
ENCODER_DIFF_NO = 0, // no state
ENCODER_DIFF_CW = 1, // clockwise rotation
ENCODER_DIFF_CCW = 2, // counterclockwise rotation
ENCODER_DIFF_ENTER = 3 // click
} ENCODER_DiffState;
// Encoder initialization
void Encoder_Configuration();
// Analyze encoder value and return state
ENCODER_DiffState Encoder_ReceiveAnalyze();
/*********************** Encoder LED ***********************/
#if PIN_EXISTS(LCD_LED)
#define LED_NUM 4
#define LED_DATA_HIGH WRITE(LCD_LED_PIN, 1)
#define LED_DATA_LOW WRITE(LCD_LED_PIN, 0)
#define RGB_SCALE_R10_G7_B5 1
#define RGB_SCALE_R10_G7_B4 2
#define RGB_SCALE_R10_G8_B7 3
#define RGB_SCALE_NEUTRAL_WHITE RGB_SCALE_R10_G7_B5
#define RGB_SCALE_WARM_WHITE RGB_SCALE_R10_G7_B4
#define RGB_SCALE_COOL_WHITE RGB_SCALE_R10_G8_B7
extern unsigned int LED_DataArray[LED_NUM];
// LED light operation
void LED_Action();
// LED initialization
void LED_Configuration();
// LED write data
void LED_WriteData();
// LED control
// RGB_Scale: RGB color ratio
// luminance: brightness (0~0xFF)
void LED_Control(const uint8_t RGB_Scale, const uint8_t luminance);
// LED gradient control
// RGB_Scale: RGB color ratio
// luminance: brightness (0~0xFF)
// change_Time: gradient time (ms)
void LED_GraduallyControl(const uint8_t RGB_Scale, const uint8_t luminance, const uint16_t change_Interval);
#endif // LCD_LED

3
Marlin/src/lcd/e3v2/jyersui/dwin_lcd.h

@ -44,9 +44,6 @@
// Handshake (1: Success, 0: Fail)
bool DWIN_Handshake(void);
// Common DWIN startup
void DWIN_Startup(void);
// Set the backlight luminance
// luminance: (0x00-0xFF)
void DWIN_Backlight_SetLuminance(const uint8_t luminance);

17
Marlin/src/lcd/language/language_en.h

@ -78,6 +78,14 @@ namespace Language_en {
PROGMEM Language_Str MSG_AUTO_HOME_I = _UxGT("Home ") LCD_STR_I;
PROGMEM Language_Str MSG_AUTO_HOME_J = _UxGT("Home ") LCD_STR_J;
PROGMEM Language_Str MSG_AUTO_HOME_K = _UxGT("Home ") LCD_STR_K;
PROGMEM Language_Str MSG_FILAMENT_SET = _UxGT("Filament Settings");
PROGMEM Language_Str MSG_FILAMENT_MAN = _UxGT("Filament Management");
PROGMEM Language_Str MSG_LEVBED_FL = _UxGT("Front Left");
PROGMEM Language_Str MSG_LEVBED_FR = _UxGT("Front Right");
PROGMEM Language_Str MSG_LEVBED_C = _UxGT("Center");
PROGMEM Language_Str MSG_LEVBED_BL = _UxGT("Back Left");
PROGMEM Language_Str MSG_LEVBED_BR = _UxGT("Back Right");
PROGMEM Language_Str MSG_MANUAL_MESH = _UxGT("Manual Mesh");
PROGMEM Language_Str MSG_AUTO_Z_ALIGN = _UxGT("Auto Z-Align");
PROGMEM Language_Str MSG_ITERATION = _UxGT("G34 Iteration: %i");
PROGMEM Language_Str MSG_DECREASING_ACCURACY = _UxGT("Accuracy Decreasing!");
@ -289,6 +297,11 @@ namespace Language_en {
PROGMEM Language_Str MSG_MOVE_01IN = _UxGT("Move 0.1in");
PROGMEM Language_Str MSG_MOVE_1IN = _UxGT("Move 1.0in");
PROGMEM Language_Str MSG_SPEED = _UxGT("Speed");
PROGMEM Language_Str MSG_MAXSPEED = _UxGT("Max Speed (mm/s)");
PROGMEM Language_Str MSG_MAXSPEED_X = _UxGT("Max ") LCD_STR_A _UxGT(" Speed");
PROGMEM Language_Str MSG_MAXSPEED_Y = _UxGT("Max ") LCD_STR_B _UxGT(" Speed");
PROGMEM Language_Str MSG_MAXSPEED_Z = _UxGT("Max ") LCD_STR_C _UxGT(" Speed");
PROGMEM Language_Str MSG_MAXSPEED_E = _UxGT("Max ") LCD_STR_E _UxGT(" Speed");
PROGMEM Language_Str MSG_BED_Z = _UxGT("Bed Z");
PROGMEM Language_Str MSG_NOZZLE = _UxGT("Nozzle");
PROGMEM Language_Str MSG_NOZZLE_N = _UxGT("Nozzle ~");
@ -321,7 +334,7 @@ namespace Language_en {
PROGMEM Language_Str MSG_LCD_OFF = _UxGT("Off");
PROGMEM Language_Str MSG_PID_AUTOTUNE = _UxGT("PID Autotune");
PROGMEM Language_Str MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *");
PROGMEM Language_Str MSG_PID_CYCLE = _UxGT("PID Cycle");
PROGMEM Language_Str MSG_PID_CYCLE = _UxGT("PID Cycles");
PROGMEM Language_Str MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done");
PROGMEM Language_Str MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed. Bad extruder.");
PROGMEM Language_Str MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed. Temperature too high.");
@ -504,6 +517,7 @@ namespace Language_en {
PROGMEM Language_Str MSG_MANUAL_DEPLOY = _UxGT("Deploy Z-Probe");
PROGMEM Language_Str MSG_MANUAL_STOW = _UxGT("Stow Z-Probe");
PROGMEM Language_Str MSG_HOME_FIRST = _UxGT("Home %s%s%s First");
PROGMEM Language_Str MSG_ZPROBE_SETTINGS = _UxGT("Probe Settings");
PROGMEM Language_Str MSG_ZPROBE_OFFSETS = _UxGT("Probe Offsets");
PROGMEM Language_Str MSG_ZPROBE_XOFFSET = _UxGT("Probe X Offset");
PROGMEM Language_Str MSG_ZPROBE_YOFFSET = _UxGT("Probe Y Offset");
@ -611,6 +625,7 @@ namespace Language_en {
PROGMEM Language_Str MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: ");
PROGMEM Language_Str MSG_RUNOUT_SENSOR = _UxGT("Runout Sensor");
PROGMEM Language_Str MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout Dist mm");
PROGMEM Language_Str MSG_RUNOUT_ENABLE = _UxGT("Enable Runout");
PROGMEM Language_Str MSG_KILL_HOMING_FAILED = _UxGT("Homing Failed");
PROGMEM Language_Str MSG_LCD_PROBING_FAILED = _UxGT("Probing Failed");

5
Marlin/src/lcd/marlinui.cpp

@ -48,6 +48,8 @@ MarlinUI ui;
#if ENABLED(DWIN_CREALITY_LCD)
#include "e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "e3v2/enhanced/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#include "e3v2/jyersui/dwin.h"
#endif
@ -101,6 +103,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
backlight = !!value;
if (backlight) brightness = constrain(value, MIN_LCD_BRIGHTNESS, MAX_LCD_BRIGHTNESS);
// Set brightness on enabled LCD here
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_LCD_Brightness(brightness));
TERN_(DWIN_CREALITY_LCD_JYERSUI, DWIN_Backlight_SetLuminance(backlight ? brightness : 0));
}
#endif
@ -1474,7 +1477,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
#endif
TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(status_message));
TERN_(DWIN_CREALITY_LCD, DWIN_StatusChanged(status_message));
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_StatusChanged(status_message));
TERN_(DWIN_CREALITY_LCD_JYERSUI, CrealityDWIN.Update_Status(status_message));
}

21
Marlin/src/lcd/marlinui.h

@ -55,11 +55,17 @@
#include "../module/printcounter.h"
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE) && ANY(HAS_LCD_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI)
#if ENABLED(ADVANCED_PAUSE_FEATURE) && ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#include "../feature/pause.h"
#include "../module/motion.h" // for active_extruder
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#include "e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "e3v2/enhanced/dwin.h"
#endif
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80U)
#if HAS_WIRED_LCD
@ -257,7 +263,7 @@ public:
FORCE_INLINE static void refresh_brightness() { set_brightness(brightness); }
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
static void refresh();
#else
FORCE_INLINE static void refresh() {
@ -315,7 +321,7 @@ public:
#if HAS_STATUS_MESSAGE
#if HAS_WIRED_LCD
#if EITHER(HAS_WIRED_LCD, DWIN_CREALITY_LCD_ENHANCED)
#if ENABLED(STATUS_MESSAGE_SCROLLING)
#define MAX_MESSAGE_LENGTH _MAX(LONG_FILENAME_LENGTH, MAX_LANG_CHARSIZE * 2 * (LCD_WIDTH))
#else
@ -351,6 +357,12 @@ public:
static inline void reset_alert_level() {}
#endif
#if EITHER(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED)
static void kill_screen(PGM_P const lcd_error, PGM_P const lcd_component);
#else
static inline void kill_screen(PGM_P const, PGM_P const) {}
#endif
#if HAS_DISPLAY
static void init();
@ -457,7 +469,6 @@ public:
static bool did_first_redraw;
#endif
static void kill_screen(PGM_P const lcd_error, PGM_P const lcd_component);
static void draw_kill_screen();
#else // No LCD
@ -585,7 +596,7 @@ public:
static inline bool use_click() { return false; }
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE) && ANY(HAS_LCD_MENU, EXTENSIBLE_UI, DWIN_CREALITY_LCD_JYERSUI)
#if ENABLED(ADVANCED_PAUSE_FEATURE) && ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
static void pause_show_message(const PauseMessage message, const PauseMode mode=PAUSE_MODE_SAME, const uint8_t extruder=active_extruder);
#else
static inline void _pause_show_message() {}

2
Marlin/src/lcd/tft/ui_common.h

@ -23,7 +23,7 @@
#include "../../inc/MarlinConfigPre.h"
#if !HAS_LCD_MENU
#if ENABLED(NO_LCD_MENUS)
#error "Seriously? High resolution TFT screen without menu?"
#endif

4
Marlin/src/module/probe.cpp

@ -79,6 +79,8 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
@ -295,7 +297,7 @@ FORCE_INLINE void probe_specific_action(const bool deploy) {
TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Stow Probe"), CONTINUE_STR));
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Stow Probe")));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_Popup_Confirm(ICON_BLTouch, PSTR("Stow Probe"), CONTINUE_STR));
wait_for_user_response();
ui.reset_status();

40
Marlin/src/module/settings.cpp

@ -71,9 +71,9 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#endif
#if ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#include "../lcd/e3v2/jyersui/dwin.h"
#endif
@ -441,14 +441,15 @@ typedef struct SettingsDataStruct {
// EXTENSIBLE_UI
//
#if ENABLED(EXTENSIBLE_UI)
// This is a significant hardware change; don't reserve space when not present
uint8_t extui_data[ExtUI::eeprom_data_size];
#endif
//
// DWIN_CREALITY_LCD_JYERSUI
// Ender-3 V2 DWIN
//
#if ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
uint8_t dwin_data[eeprom_data_size];
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
uint8_t dwin_settings[CrealityDWIN.eeprom_data_size];
#endif
@ -1358,9 +1359,16 @@ void MarlinSettings::postprocess() {
#endif
//
// Creality UI Settings
// Creality DWIN User Data
//
#if ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
{
char dwin_data[eeprom_data_size] = { 0 };
DWIN_StoreSettings(dwin_data);
_FIELD_TEST(dwin_data);
EEPROM_WRITE(dwin_data);
}
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
{
char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 };
CrealityDWIN.Save_Settings(dwin_settings);
@ -1488,6 +1496,8 @@ void MarlinSettings::postprocess() {
stored_ver[1] = '\0';
}
DEBUG_ECHO_MSG("EEPROM version mismatch (EEPROM=", stored_ver, " Marlin=" EEPROM_VERSION ")");
TERN_(DWIN_CREALITY_LCD_ENHANCED, ui.set_status(GET_TEXT(MSG_ERR_EEPROM_VERSION)));
IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_version());
eeprom_error = true;
}
@ -2249,9 +2259,16 @@ void MarlinSettings::postprocess() {
#endif
//
// Creality UI Settings
// Creality DWIN User Data
//
#if ENABLED(DWIN_CREALITY_LCD_JYERSUI)
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
{
const char dwin_data[eeprom_data_size] = { 0 };
_FIELD_TEST(dwin_data);
EEPROM_READ(dwin_data);
if (!validating) DWIN_LoadSettings(dwin_data);
}
#elif ENABLED(DWIN_CREALITY_LCD_JYERSUI)
{
const char dwin_settings[CrealityDWIN.eeprom_data_size] = { 0 };
_FIELD_TEST(dwin_settings);
@ -2340,6 +2357,7 @@ void MarlinSettings::postprocess() {
else if (working_crc != stored_crc) {
eeprom_error = true;
DEBUG_ERROR_MSG("EEPROM CRC mismatch - (stored) ", stored_crc, " != ", working_crc, " (calculated)!");
TERN_(DWIN_CREALITY_LCD_ENHANCED, ui.set_status(GET_TEXT(MSG_ERR_EEPROM_CRC)));
IF_DISABLED(EEPROM_AUTO_INIT, ui.eeprom_alert_crc());
}
else if (!validating) {
@ -2656,7 +2674,7 @@ void MarlinSettings::reset() {
#endif
TERN_(EXTENSIBLE_UI, ExtUI::onFactoryReset());
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_SetDataDefaults());
TERN_(DWIN_CREALITY_LCD_JYERSUI, CrealityDWIN.Reset_Settings());
//

29
Marlin/src/module/temperature.cpp

@ -47,6 +47,8 @@
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#endif
#if ENABLED(EXTENSIBLE_UI)
@ -603,10 +605,12 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(HAS_AUTO_FAN, next_auto_fan_check_ms = next_temp_ms + 2500UL);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_STARTED));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START));
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
return;
}
@ -627,6 +631,7 @@ volatile bool Temperature::raw_temps_ready = false;
// PID Tuning loop
wait_for_heatup = true; // Can be interrupted with M108
TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT), "Wait for heat up..."));
while (wait_for_heatup) {
const millis_t ms = millis();
@ -687,6 +692,7 @@ volatile bool Temperature::raw_temps_ready = false;
}
}
SHV((bias + d) >> 1);
TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PID_CYCLE), cycles, ncycles));
cycles++;
minT = target;
}
@ -699,6 +705,7 @@ volatile bool Temperature::raw_temps_ready = false;
if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
break;
}
@ -734,6 +741,7 @@ volatile bool Temperature::raw_temps_ready = false;
#endif
if ((ms - _MIN(t1, t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) {
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_TUNING_TIMEOUT));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
break;
@ -787,6 +795,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_DONE));
goto EXIT_M303;
}
@ -795,7 +804,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(HAL_IDLETASK, HAL_idletask());
// Run UI update
TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
TERN(HAS_DWIN_E3V2_BASIC, DWIN_Update(), ui.update());
}
wait_for_heatup = false;
@ -804,6 +813,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE));
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_PidTuning(PID_DONE));
EXIT_M303:
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = true);
@ -1014,14 +1024,14 @@ void Temperature::_temp_error(const heater_id_t heater_id, PGM_P const serial_ms
}
void Temperature::max_temp_error(const heater_id_t heater_id) {
#if ENABLED(DWIN_CREALITY_LCD) && (HAS_HOTEND || HAS_HEATED_BED)
#if HAS_DWIN_E3V2_BASIC && (HAS_HOTEND || HAS_HEATED_BED)
DWIN_Popup_Temperature(1);
#endif
_temp_error(heater_id, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP));
}
void Temperature::min_temp_error(const heater_id_t heater_id) {
#if ENABLED(DWIN_CREALITY_LCD) && (HAS_HOTEND || HAS_HEATED_BED)
#if HAS_DWIN_E3V2_BASIC && (HAS_HOTEND || HAS_HEATED_BED)
DWIN_Popup_Temperature(0);
#endif
_temp_error(heater_id, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP));
@ -1329,7 +1339,7 @@ void Temperature::manage_heater() {
if (watch_hotend[e].check(degHotend(e))) // Increased enough?
start_watching_hotend(e); // If temp reached, turn off elapsed check
else {
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0));
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
_temp_error((heater_id_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD));
}
}
@ -1372,7 +1382,7 @@ void Temperature::manage_heater() {
if (watch_bed.check(degBed())) // Increased enough?
start_watching_bed(); // If temp reached, turn off elapsed check
else {
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0));
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
_temp_error(H_BED, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD));
}
}
@ -2586,7 +2596,7 @@ void Temperature::init() {
state = TRRunaway;
case TRRunaway:
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0));
TERN_(HAS_DWIN_E3V2_BASIC, DWIN_Popup_Temperature(0));
_temp_error(heater_id, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY));
}
}
@ -3600,7 +3610,7 @@ void Temperature::isr() {
#if HAS_MULTI_HOTEND
PSTR("E%c " S_FMT), '1' + e
#else
PSTR("E " S_FMT)
PSTR("E1 " S_FMT)
#endif
, heating ? GET_TEXT(MSG_HEATING) : GET_TEXT(MSG_COOLING)
);
@ -3720,13 +3730,12 @@ void Temperature::isr() {
if (wait_for_heatup) {
wait_for_heatup = false;
#if ENABLED(DWIN_CREALITY_LCD)
#if HAS_DWIN_E3V2_BASIC
HMI_flag.heat_flag = 0;
duration_t elapsed = print_job_timer.duration(); // print timer
dwin_heat_time = elapsed.value;
#else
ui.reset_status();
#endif
ui.reset_status();
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onHeatingDone());
return true;
}

2
Marlin/src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h

@ -148,7 +148,7 @@
* All pins are labeled as printed on DWIN PCB. Connect TX-TX, A-A and so on.
*/
#error "DWIN_CREALITY_LCD requires a custom cable, see diagram above this line. Comment out this line to continue."
#error "Ender-3 V2 display requires a custom cable, see diagram above this line. Comment out this line to continue."
#define BEEPER_PIN EXP1_9
#define BTN_EN1 EXP1_3

4
Marlin/src/sd/cardreader.cpp

@ -33,6 +33,8 @@
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/e3v2/creality/dwin.h"
#elif ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../lcd/e3v2/enhanced/dwin.h"
#endif
#include "../module/planner.h" // for synchronize
@ -564,7 +566,7 @@ void CardReader::startOrResumeFilePrinting() {
//
void CardReader::endFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0);
TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting);
TERN_(HAS_DWIN_E3V2_BASIC, HMI_flag.print_finish = flag.sdprinting);
flag.abort_sd_printing = false;
if (isFileOpen()) file.close();
TERN_(SD_RESORT, if (re_sort) presort());

5
buildroot/tests/STM32F103RET6_creality

@ -13,6 +13,11 @@ use_example_configs "Creality/Ender-3 V2/CrealityUI"
opt_enable MARLIN_DEV_MODE BUFFER_MONITORING
exec_test $1 $2 "Ender 3 v2 with CrealityUI" "$3"
use_example_configs "Creality/Ender-3 V2/CrealityUI"
opt_disable DWIN_CREALITY_LCD
opt_enable DWIN_CREALITY_LCD_ENHANCED
exec_test $1 $2 "Ender 3 v2 with Enhanced UI" "$3"
use_example_configs "Creality/Ender-3 V2/CrealityUI"
opt_disable DWIN_CREALITY_LCD
opt_enable DWIN_CREALITY_LCD_JYERSUI

1
ini/features.ini

@ -45,6 +45,7 @@ I2C_EEPROM = src_filter=+<src/HAL/shared/eeprom_if_i
SOFT_I2C_EEPROM = SlowSoftI2CMaster, SlowSoftWire=https://github.com/felias-fogg/SlowSoftWire/archive/master.zip
SPI_EEPROM = src_filter=+<src/HAL/shared/eeprom_if_spi.cpp>
DWIN_CREALITY_LCD = src_filter=+<src/lcd/e3v2/creality>
DWIN_CREALITY_LCD_ENHANCED = src_filter=+<src/lcd/e3v2/enhanced>
DWIN_CREALITY_LCD_JYERSUI = src_filter=+<src/lcd/e3v2/jyersui>
DWIN_MARLINUI_.+ = src_filter=+<src/lcd/e3v2/marlinui>
HAS_GRAPHICAL_TFT = src_filter=+<src/lcd/tft>

2
platformio.ini

@ -50,7 +50,7 @@ lib_deps =
default_src_filter = +<src/*> -<src/config> -<src/HAL> +<src/HAL/shared>
-<src/lcd/HD44780> -<src/lcd/TFTGLCD> -<src/lcd/dogm> -<src/lcd/tft> -<src/lcd/tft_io>
-<src/HAL/STM32/tft> -<src/HAL/STM32F1/tft>
-<src/lcd/e3v2/creality> -<src/lcd/e3v2/jyersui> -<src/lcd/e3v2/marlinui>
-<src/lcd/e3v2/creality> -<src/lcd/e3v2/enhanced> -<src/lcd/e3v2/jyersui> -<src/lcd/e3v2/marlinui>
-<src/lcd/menu>
-<src/lcd/menu/game/game.cpp> -<src/lcd/menu/game/brickout.cpp> -<src/lcd/menu/game/invaders.cpp>
-<src/lcd/menu/game/maze.cpp> -<src/lcd/menu/game/snake.cpp>

Loading…
Cancel
Save