aboutsummaryrefslogtreecommitdiff
path: root/Marlin/src/lcd/extui/lib/mks_ui
diff options
context:
space:
mode:
Diffstat (limited to 'Marlin/src/lcd/extui/lib/mks_ui')
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp303
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h108
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp83
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h43
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp65
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_about.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp155
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp96
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp90
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp179
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h35
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.cpp184
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.h37
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp225
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h39
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp205
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.h37
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp574
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h91
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp82
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp72
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp46
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h37
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp266
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h38
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp117
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h34
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp216
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h35
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp126
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp93
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_home.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp104
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp99
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp289
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp208
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_language.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp104
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h35
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp84
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp82
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp135
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp146
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp119
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_more.cpp119
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_more.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp98
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp211
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h34
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp772
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp230
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp51
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h32
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp85
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp297
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h36
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp552
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h64
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp290
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h53
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp220
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h40
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp134
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_set.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp115
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp156
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h34
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp154
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp113
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.cpp117
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.h34
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.cpp101
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.h35
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp1510
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h551
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp166
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h38
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp177
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h76
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp141
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h36
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp68
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h51
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp105
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp63
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp655
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h33
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp622
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h168
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp250
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h36
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h751
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h268
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h265
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h384
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h518
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h274
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h515
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp584
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h69
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp2920
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h865
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp526
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h145
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp2231
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h201
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp726
-rw-r--r--Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h74
129 files changed, 26213 insertions, 0 deletions
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp
new file mode 100644
index 0000000..8685bf1
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.cpp
@@ -0,0 +1,303 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../../inc/MarlinConfig.h"
+#include "SPIFlashStorage.h"
+
+extern W25QXXFlash W25QXX;
+
+uint8_t SPIFlashStorage::m_pageData[SPI_FLASH_PageSize];
+uint32_t SPIFlashStorage::m_currentPage;
+uint16_t SPIFlashStorage::m_pageDataUsed;
+uint32_t SPIFlashStorage::m_startAddress;
+
+#if HAS_SPI_FLASH_COMPRESSION
+
+ uint8_t SPIFlashStorage::m_compressedData[SPI_FLASH_PageSize];
+ uint16_t SPIFlashStorage::m_compressedDataUsed;
+
+ template <typename T>
+ static uint32_t rle_compress(T *output, uint32_t outputLength, T *input, uint32_t inputLength, uint32_t& inputProcessed) {
+ uint32_t count = 0, out = 0, index, i;
+ T pixel;
+ //32767 for uint16_t
+ //127 for uint16_t
+ //calculated at compile time
+ constexpr T max = (0xFFFFFFFF >> (8 * (4 - sizeof(T)))) / 2;
+
+ inputProcessed = 0;
+ while (count < inputLength && out < outputLength) {
+ index = count;
+ pixel = input[index++];
+ while (index < inputLength && index - count < max && input[index] == pixel)
+ index++;
+ if (index - count == 1) {
+ /*
+ * Failed to "replicate" the current pixel. See how many to copy.
+ * Avoid a replicate run of only 2-pixels after a literal run. There
+ * is no gain in this, and there is a risK of loss if the run after
+ * the two identical pixels is another literal run. So search for
+ * 3 identical pixels.
+ */
+ while (index < inputLength && index - count < max && (input[index] != input[index - 1] || (index > 1 && input[index] != input[index - 2])))
+ index++;
+ /*
+ * Check why this run stopped. If it found two identical pixels, reset
+ * the index so we can add a run. Do this twice: the previous run
+ * tried to detect a replicate run of at least 3 pixels. So we may be
+ * able to back up two pixels if such a replicate run was found.
+ */
+ while (index < inputLength && input[index] == input[index - 1])
+ index--;
+ // If the output buffer could overflow, stop at the remaining bytes
+ NOMORE(index, count + outputLength - out - 1);
+ output[out++] = (uint16_t)(count - index);
+ for (i = count; i < index; i++)
+ output[out++] = input[i];
+ }
+ else {
+ // Need at least more 2 spaces
+ if (out > outputLength - 2) break;
+ output[out++] = (uint16_t)(index - count);
+ output[out++] = pixel;
+ }
+ count = index;
+ }
+ inputProcessed = count;
+
+ // Padding
+ if (out == outputLength - 1) output[out++] = 0;
+
+ return out;
+ }
+
+ template <typename UT, typename T>
+ static uint32_t rle_uncompress(UT *output, uint32_t outputLength, UT *input, uint32_t inputLength, uint32_t &outputFilled) {
+ T count;
+ UT i;
+ uint32_t processedBytes = 0;
+ outputFilled = 0;
+
+ while (outputLength > 0 && inputLength > 0) {
+ processedBytes++;
+ count = static_cast<T>(*input++);
+ inputLength--;
+ if (count > 0) { // Replicate run
+ for (i = 0; i < count && outputLength > i; i++)
+ output[i] = *input;
+ outputFilled += i;
+ // If copy incomplete, change the input buffer to start with remaining data in the next call
+ if (i < count) {
+ // Change to process the difference in the next call
+ *(input - 1) = static_cast<UT>(count - i);
+ return processedBytes - 1;
+ }
+ input++;
+ inputLength--;
+ processedBytes++;
+ }
+ else if (count < 0) { // literal run
+ count = static_cast<T>(-count);
+ // Copy, validating if the output have enough space
+ for (i = 0; i < count && outputLength > i; i++)
+ output[i] = input[i];
+ outputFilled += i;
+ // If copy incomplete, change the input buffer to start with remaining data in the next call
+ if (i < count) {
+ input[i - 1] = static_cast<UT>((count - i) * -1);
+ // Back one
+ return processedBytes + i - 1;
+ }
+ input += count;
+ inputLength -= count;
+ processedBytes += count;
+ }
+ output += count;
+ outputLength -= count;
+ }
+
+ return processedBytes;
+ }
+
+#endif // HAS_SPI_FLASH_COMPRESSION
+
+void SPIFlashStorage::beginWrite(uint32_t startAddress) {
+ m_pageDataUsed = 0;
+ m_currentPage = 0;
+ m_startAddress = startAddress;
+ #if HAS_SPI_FLASH_COMPRESSION
+ // Restart the compressed buffer, keep the pointers of the uncompressed buffer
+ m_compressedDataUsed = 0;
+ #endif
+}
+
+
+void SPIFlashStorage::endWrite() {
+ // Flush remaining data
+ #if HAS_SPI_FLASH_COMPRESSION
+ if (m_compressedDataUsed > 0) {
+ flushPage();
+ savePage(m_compressedData);
+ }
+ #else
+ if (m_pageDataUsed > 0) flushPage();
+ #endif
+}
+
+void SPIFlashStorage::savePage(uint8_t* buffer) {
+ W25QXX.SPI_FLASH_BufferWrite(buffer, m_startAddress + (SPI_FLASH_PageSize * m_currentPage), SPI_FLASH_PageSize);
+}
+
+void SPIFlashStorage::loadPage(uint8_t* buffer) {
+ W25QXX.SPI_FLASH_BufferRead(buffer, m_startAddress + (SPI_FLASH_PageSize * m_currentPage), SPI_FLASH_PageSize);
+}
+
+void SPIFlashStorage::flushPage() {
+ #if HAS_SPI_FLASH_COMPRESSION
+ // Work com with compressed in memory
+ uint32_t inputProcessed;
+ uint32_t compressedSize = rle_compress<uint16_t>((uint16_t *)(m_compressedData + m_compressedDataUsed), compressedDataFree() / 2, (uint16_t *)m_pageData, m_pageDataUsed / 2, inputProcessed) * 2;
+ inputProcessed *= 2;
+ m_compressedDataUsed += compressedSize;
+
+ // Space remaining in the compressed buffer?
+ if (compressedDataFree() > 0) {
+ // Free the uncompressed buffer
+ m_pageDataUsed = 0;
+ return;
+ }
+
+ // Part of the m_pageData was compressed, so ajust the pointers, freeing what was processed, shift the buffer
+ // TODO: To avoid this copy, use a circular buffer
+ memmove(m_pageData, m_pageData + inputProcessed, m_pageDataUsed - inputProcessed);
+ m_pageDataUsed -= inputProcessed;
+
+ // No? So flush page with compressed data!!
+ uint8_t *buffer = m_compressedData;
+ #else
+ uint8_t *buffer = m_pageData;
+ #endif
+
+ savePage(buffer);
+
+ #if HAS_SPI_FLASH_COMPRESSION
+ // Restart the compressed buffer, keep the pointers of the uncompressed buffer
+ m_compressedDataUsed = 0;
+ #else
+ m_pageDataUsed = 0;
+ #endif
+ m_currentPage++;
+}
+
+void SPIFlashStorage::readPage() {
+ #if HAS_SPI_FLASH_COMPRESSION
+ if (compressedDataFree() == 0) {
+ loadPage(m_compressedData);
+ m_currentPage++;
+ m_compressedDataUsed = 0;
+ }
+
+ // Need to uncompress data
+ if (pageDataFree() == 0) {
+ m_pageDataUsed = 0;
+ uint32_t outpuProcessed = 0;
+ uint32_t inputProcessed = rle_uncompress<uint16_t, int16_t>((uint16_t *)(m_pageData + m_pageDataUsed), pageDataFree() / 2, (uint16_t *)(m_compressedData + m_compressedDataUsed), compressedDataFree() / 2, outpuProcessed);
+ inputProcessed *= 2;
+ outpuProcessed *= 2;
+ if (outpuProcessed < pageDataFree()) {
+ m_pageDataUsed = SPI_FLASH_PageSize - outpuProcessed;
+ // TODO: To avoid this copy, use a circular buffer
+ memmove(m_pageData + m_pageDataUsed, m_pageData, outpuProcessed);
+ }
+
+ m_compressedDataUsed += inputProcessed;
+ }
+ #else
+ loadPage(m_pageData);
+ m_pageDataUsed = 0;
+ m_currentPage++;
+ #endif
+}
+
+uint16_t SPIFlashStorage::inData(uint8_t* data, uint16_t size) {
+ // Don't write more than we can
+ NOMORE(size, pageDataFree());
+ memcpy(m_pageData + m_pageDataUsed, data, size);
+ m_pageDataUsed += size;
+ return size;
+}
+
+void SPIFlashStorage::writeData(uint8_t* data, uint16_t size) {
+ // Flush a page if needed
+ if (pageDataFree() == 0) flushPage();
+
+ while (size > 0) {
+ uint16_t written = inData(data, size);
+ size -= written;
+ // Need to write more? Flush page and continue!
+ if (size > 0) {
+ flushPage();
+ data += written;
+ }
+ }
+}
+
+void SPIFlashStorage::beginRead(uint32_t startAddress) {
+ m_startAddress = startAddress;
+ m_currentPage = 0;
+ // Nothing in memory now
+ m_pageDataUsed = SPI_FLASH_PageSize;
+ #if HAS_SPI_FLASH_COMPRESSION
+ m_compressedDataUsed = sizeof(m_compressedData);
+ #endif
+}
+
+uint16_t SPIFlashStorage::outData(uint8_t* data, uint16_t size) {
+ // Don't read more than we have
+ NOMORE(size, pageDataFree());
+ memcpy(data, m_pageData + m_pageDataUsed, size);
+ m_pageDataUsed += size;
+ return size;
+}
+
+void SPIFlashStorage::readData(uint8_t* data, uint16_t size) {
+ // Read a page if needed
+ if (pageDataFree() == 0) readPage();
+
+ while (size > 0) {
+ uint16_t read = outData(data, size);
+ size -= read;
+ // Need to write more? Flush page and continue!
+ if (size > 0) {
+ readPage();
+ data += read;
+ }
+ }
+}
+
+SPIFlashStorage SPIFlash;
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h
new file mode 100644
index 0000000..98c8067
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/SPIFlashStorage.h
@@ -0,0 +1,108 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "../../../../libs/W25Qxx.h"
+
+#define HAS_SPI_FLASH_COMPRESSION 1
+
+/**
+ * This class manages and optimizes SPI Flash data storage,
+ * keeping an internal buffer to write and save full SPI flash
+ * pages as needed.
+ *
+ * Since the data is always in the buffer, the class is also
+ * able to support fast on-the-fly RLE compression/decompression.
+ *
+ * In testing with the current LVGL_UI it compacts 2.9MB of icons
+ * (which have lots of runs) down to 370kB!!! As a result the UI
+ * refresh rate becomes faster and now all LVGL UI can fit into a
+ * tiny 2MB SPI Flash, such as the Chitu Board.
+ *
+ * == Usage ==
+ *
+ * Writing:
+ *
+ * The class keeps an internal buffer that caches data until it
+ * fits into a full SPI Flash page. Each time the buffer fills up
+ * the page is saved to SPI Flash. Sequential writes are optimal.
+ *
+ * SPIFlashStorage.beginWrite(myStartAddress);
+ * while (there is data to write)
+ * SPIFlashStorage.addData(myBuffer, bufferSize);
+ * SPIFlashStorage.endWrite(); // Flush remaining buffer data
+ *
+ * Reading:
+ *
+ * When reading, it loads a full page from SPI Flash at once and
+ * keeps it in a private SRAM buffer. Data is loaded as needed to
+ * fullfill requests. Sequential reads are optimal.
+ *
+ * SPIFlashStorage.beginRead(myStartAddress);
+ * while (there is data to read)
+ * SPIFlashStorage.readData(myBuffer, bufferSize);
+ *
+ * Compression:
+ *
+ * The biggest advantage of this class is the RLE compression.
+ * With compression activated a second buffer holds the compressed
+ * data, so when writing data, as this buffer becomes full it is
+ * flushed to SPI Flash.
+ *
+ * The same goes for reading: A compressed page is read from SPI
+ * flash, and the data is uncompressed as needed to provide the
+ * requested amount of data.
+ */
+class SPIFlashStorage {
+public:
+ // Write operation
+ static void beginWrite(uint32_t startAddress);
+ static void endWrite();
+ static void writeData(uint8_t* data, uint16_t size);
+
+ // Read operation
+ static void beginRead(uint32_t startAddress);
+ static void readData(uint8_t* data, uint16_t size);
+
+ static uint32_t getCurrentPage() { return m_currentPage; }
+
+private:
+ static void flushPage();
+ static void savePage(uint8_t* buffer);
+ static void loadPage(uint8_t* buffer);
+ static void readPage();
+ static uint16_t inData(uint8_t* data, uint16_t size);
+ static uint16_t outData(uint8_t* data, uint16_t size);
+
+ static uint8_t m_pageData[SPI_FLASH_PageSize];
+ static uint32_t m_currentPage;
+ static uint16_t m_pageDataUsed;
+ static inline uint16_t pageDataFree() { return SPI_FLASH_PageSize - m_pageDataUsed; }
+ static uint32_t m_startAddress;
+ #if HAS_SPI_FLASH_COMPRESSION
+ static uint8_t m_compressedData[SPI_FLASH_PageSize];
+ static uint16_t m_compressedDataUsed;
+ static inline uint16_t compressedDataFree() { return SPI_FLASH_PageSize - m_compressedDataUsed; }
+ #endif
+};
+
+extern SPIFlashStorage SPIFlash;
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp
new file mode 100644
index 0000000..242944b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.cpp
@@ -0,0 +1,83 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "SPI_TFT.h"
+#include "pic_manager.h"
+#include "tft_lvgl_configuration.h"
+
+#include "../../../../inc/MarlinConfig.h"
+
+#include <SPI.h>
+
+#include "draw_ui.h"
+
+TFT SPI_TFT;
+
+// use SPI1 for the spi tft.
+void TFT::spi_init(uint8_t spiRate) {
+ tftio.Init();
+}
+
+void TFT::SetPoint(uint16_t x, uint16_t y, uint16_t point) {
+ if ((x > 480) || (y > 320)) return;
+
+ setWindow(x, y, 1, 1);
+ tftio.WriteMultiple(point, (uint16_t)1);
+}
+
+void TFT::setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height) {
+ tftio.set_window(x, y, (x + with - 1), (y + height - 1));
+}
+
+void TFT::LCD_init() {
+ tftio.InitTFT();
+ #if PIN_EXISTS(TFT_BACKLIGHT)
+ OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
+ #endif
+ delay(100);
+ LCD_clear(0x0000);
+ LCD_Draw_Logo();
+ #if PIN_EXISTS(TFT_BACKLIGHT)
+ OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
+ #endif
+}
+
+void TFT::LCD_clear(uint16_t color) {
+ setWindow(0, 0, (TFT_WIDTH), (TFT_HEIGHT));
+ tftio.WriteMultiple(color, (uint32_t)(TFT_WIDTH) * (TFT_HEIGHT));
+}
+
+void TFT::LCD_Draw_Logo() {
+ #if HAS_LOGO_IN_FLASH
+ setWindow(0, 0, TFT_WIDTH, TFT_HEIGHT);
+ for (uint16_t i = 0; i < (TFT_HEIGHT); i ++) {
+ Pic_Logo_Read((uint8_t *)"", (uint8_t *)bmp_public_buf, (TFT_WIDTH) * 2);
+ tftio.WriteSequence((uint16_t *)bmp_public_buf, TFT_WIDTH);
+ }
+ #endif
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h
new file mode 100644
index 0000000..f3be3dc
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/SPI_TFT.h
@@ -0,0 +1,43 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../tft_io/tft_io.h"
+
+class TFT {
+public:
+ TFT_IO tftio;
+ void spi_init(uint8_t spiRate);
+ void SetPoint(uint16_t x, uint16_t y, uint16_t point);
+ void setWindow(uint16_t x, uint16_t y, uint16_t with, uint16_t height);
+ void LCD_init();
+ void LCD_clear(uint16_t color);
+ void LCD_Draw_Logo();
+};
+
+extern TFT SPI_TFT;
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp
new file mode 100644
index 0000000..4634c5a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.cpp
@@ -0,0 +1,65 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *fw_type, *board;
+
+enum { ID_A_RETURN = 1 };
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_A_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_about(void) {
+ scr = lv_screen_create(ABOUT_UI);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_A_RETURN);
+
+ fw_type = lv_label_create(scr, "Firmware: Marlin " SHORT_BUILD_VERSION);
+ lv_obj_align(fw_type, nullptr, LV_ALIGN_CENTER, 0, -20);
+
+ board = lv_label_create(scr, "Board: " BOARD_INFO_NAME);
+ lv_obj_align(board, nullptr, LV_ALIGN_CENTER, 0, -60);
+}
+
+void lv_clear_about() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h
new file mode 100644
index 0000000..9eae2b0
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_about.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_about(void);
+extern void lv_clear_about();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp
new file mode 100644
index 0000000..9e5dd4f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.cpp
@@ -0,0 +1,155 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+#include "../../../../MarlinCore.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_ACCE_RETURN = 1,
+ ID_ACCE_PRINT,
+ ID_ACCE_RETRA,
+ ID_ACCE_TRAVEL,
+ ID_ACCE_X,
+ ID_ACCE_Y,
+ ID_ACCE_Z,
+ ID_ACCE_E0,
+ ID_ACCE_E1,
+ ID_ACCE_UP,
+ ID_ACCE_DOWN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_ACCE_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_clear_acceleration_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_ACCE_PRINT:
+ value = PrintAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_RETRA:
+ value = RetractAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_TRAVEL:
+ value = TravelAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_X:
+ value = XAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_Y:
+ value = YAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_Z:
+ value = ZAcceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_E0:
+ value = E0Acceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_E1:
+ value = E1Acceleration;
+ lv_clear_acceleration_settings();
+ lv_draw_number_key();
+ break;
+ case ID_ACCE_UP:
+ uiCfg.para_ui_page = 0;
+ lv_clear_acceleration_settings();
+ lv_draw_acceleration_settings();
+ break;
+ case ID_ACCE_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_clear_acceleration_settings();
+ lv_draw_acceleration_settings();
+ break;
+ }
+}
+
+void lv_draw_acceleration_settings(void) {
+ scr = lv_screen_create(ACCELERATION_UI, machine_menu.AccelerationConfTitle);
+ char str_1[16];
+ if (uiCfg.para_ui_page != 1) {
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.acceleration, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.PrintAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_ACCE_PRINT, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.retract_acceleration, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.RetractAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_ACCE_RETRA, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.travel_acceleration, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.TravelAcceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_ACCE_TRAVEL, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]);
+ lv_screen_menu_item_1_edit(scr, machine_menu.X_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_ACCE_X, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_ACCE_DOWN);
+ }
+ else {
+ sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
+ lv_screen_menu_item_1_edit(scr, machine_menu.Y_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_ACCE_Y, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]);
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_ACCE_Z, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]);
+ lv_screen_menu_item_1_edit(scr, machine_menu.E0_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_ACCE_E0, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]);
+ lv_screen_menu_item_1_edit(scr, machine_menu.E1_Acceleration, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_ACCE_E1, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_ACCE_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_ACCE_RETURN);
+}
+
+void lv_clear_acceleration_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h
new file mode 100644
index 0000000..6ab4971
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_acceleration_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_acceleration_settings(void);
+extern void lv_clear_acceleration_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp
new file mode 100644
index 0000000..973fa10
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.cpp
@@ -0,0 +1,96 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_ADVANCE_RETURN = 1,
+ ID_PAUSE_POS,
+ ID_WIFI_PARA,
+ ID_FILAMENT_SETTINGS,
+ ID_ENCODER_SETTINGS
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_ADVANCE_RETURN:
+ lv_clear_advance_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_PAUSE_POS:
+ lv_clear_advance_settings();
+ lv_draw_pause_position();
+ break;
+ case ID_FILAMENT_SETTINGS:
+ lv_clear_advance_settings();
+ lv_draw_filament_settings();
+ break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case ID_WIFI_PARA:
+ lv_clear_advance_settings();
+ lv_draw_wifi_settings();
+ break;
+ #endif
+ #if HAS_ROTARY_ENCODER
+ case ID_ENCODER_SETTINGS:
+ lv_clear_advance_settings();
+ lv_draw_encoder_settings();
+ break;
+ #endif
+ }
+}
+
+void lv_draw_advance_settings(void) {
+ scr = lv_screen_create(ADVANCED_UI, machine_menu.AdvancedConfTitle);
+
+ int index = 0;
+ lv_screen_menu_item(scr, machine_menu.PausePosition, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_PAUSE_POS, index++);
+ lv_screen_menu_item(scr, machine_menu.FilamentConf, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_FILAMENT_SETTINGS, index++);
+ #if ENABLED(MKS_WIFI_MODULE)
+ lv_screen_menu_item(scr, machine_menu.WifiSettings, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_WIFI_PARA, index++);
+ #endif
+ #if HAS_ROTARY_ENCODER
+ lv_screen_menu_item(scr, machine_menu.EncoderSettings, PARA_UI_POS_X, PARA_UI_POS_Y * (index + 1), event_handler, ID_ENCODER_SETTINGS, index);
+ index++;
+ #endif
+
+ lv_screen_menu_item_return(scr, event_handler, ID_ADVANCE_RETURN);
+}
+
+void lv_clear_advance_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h
new file mode 100644
index 0000000..84e4a4d
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_advance_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_advance_settings(void);
+extern void lv_clear_advance_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp
new file mode 100644
index 0000000..0f2a527
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.cpp
@@ -0,0 +1,90 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, HAS_BED_PROBE)
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/probe.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_OFFSET_RETURN = 1,
+ ID_OFFSET_X,
+ ID_OFFSET_Y,
+ ID_OFFSET_Z
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_OFFSET_RETURN:
+ lv_clear_auto_level_offset_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_OFFSET_X:
+ value = x_offset;
+ lv_clear_auto_level_offset_settings();
+ lv_draw_number_key();
+ break;
+ case ID_OFFSET_Y:
+ value = y_offset;
+ lv_clear_auto_level_offset_settings();
+ lv_draw_number_key();
+ break;
+ case ID_OFFSET_Z:
+ value = z_offset;
+ lv_clear_auto_level_offset_settings();
+ lv_draw_number_key();
+ break;
+ }
+}
+
+void lv_draw_auto_level_offset_settings(void) {
+ char str_1[16];
+ scr = lv_screen_create(NOZZLE_PROBE_OFFSET_UI, machine_menu.OffsetConfTitle);
+
+ sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET,dtostrf(probe.offset.x, 1, 3, str_1) , 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Xoffset, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_OFFSET_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET,dtostrf(probe.offset.y, 1, 3, str_1) , 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Yoffset, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_OFFSET_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), TERN(HAS_PROBE_XY_OFFSET,dtostrf(probe.offset.z, 1, 3, str_1) , 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Zoffset, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_OFFSET_Z, 2, public_buf_l);
+
+ lv_screen_menu_item_return(scr, event_handler, ID_OFFSET_RETURN);
+}
+
+void lv_clear_auto_level_offset_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && HAS_BED_PROBE
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h
new file mode 100644
index 0000000..688cd20
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_auto_level_offset_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_auto_level_offset_settings(void);
+extern void lv_clear_auto_level_offset_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp
new file mode 100644
index 0000000..a94d1c1
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.cpp
@@ -0,0 +1,179 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/queue.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS)
+ #include "../../../../module/settings.h"
+#endif
+
+#if HAS_BED_PROBE
+ #include "../../../../module/probe.h"
+#endif
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+static lv_obj_t *labelV, *buttonV, *zOffsetText;
+
+enum {
+ ID_BABY_STEP_X_P = 1,
+ ID_BABY_STEP_X_N,
+ ID_BABY_STEP_Y_P,
+ ID_BABY_STEP_Y_N,
+ ID_BABY_STEP_Z_P,
+ ID_BABY_STEP_Z_N,
+ ID_BABY_STEP_DIST,
+ ID_BABY_STEP_RETURN
+};
+
+static float babystep_dist=0.01;
+static uint8_t has_adjust_z = 0;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ char baby_buf[30] = { 0 };
+ char str_1[16];
+ switch (obj->mks_obj_id) {
+ case ID_BABY_STEP_X_P:
+ sprintf_P(baby_buf, PSTR("M290 X%s"), dtostrf(babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_X_N:
+ sprintf_P(baby_buf, PSTR("M290 X%s"), dtostrf(-babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_Y_P:
+ sprintf_P(baby_buf, PSTR("M290 Y%s"), dtostrf(babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_Y_N:
+ sprintf_P(baby_buf, PSTR("M290 Y%s"), dtostrf(-babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_Z_P:
+ sprintf_P(baby_buf, PSTR("M290 Z%s"), dtostrf(babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_Z_N:
+ sprintf_P(baby_buf, PSTR("M290 Z%s"), dtostrf(-babystep_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BABY_STEP_DIST:
+ if (abs((int)(100 * babystep_dist)) == 1)
+ babystep_dist = 0.05;
+ else if (abs((int)(100 * babystep_dist)) == 5)
+ babystep_dist = 0.1;
+ else
+ babystep_dist = 0.01;
+ disp_baby_step_dist();
+ break;
+ case ID_BABY_STEP_RETURN:
+ if (has_adjust_z == 1) {
+ TERN_(EEPROM_SETTINGS, (void)settings.save());
+ has_adjust_z = 0;
+ }
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_baby_stepping(void) {
+ scr = lv_screen_create(BABY_STEP_UI);
+ lv_big_button_create(scr, "F:/bmp_xAdd.bin", move_menu.x_add, INTERVAL_V, titleHeight, event_handler, ID_BABY_STEP_X_P);
+ lv_big_button_create(scr, "F:/bmp_xDec.bin", move_menu.x_dec, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BABY_STEP_X_N);
+ lv_big_button_create(scr, "F:/bmp_yAdd.bin", move_menu.y_add, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_BABY_STEP_Y_P);
+ lv_big_button_create(scr, "F:/bmp_yDec.bin", move_menu.y_dec, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BABY_STEP_Y_N);
+ lv_big_button_create(scr, "F:/bmp_zAdd.bin", move_menu.z_add, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_BABY_STEP_Z_P);
+ lv_big_button_create(scr, "F:/bmp_zDec.bin", move_menu.z_dec, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BABY_STEP_Z_N);
+ buttonV = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_BABY_STEP_DIST);
+ labelV = lv_label_create_empty(buttonV);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonV);
+ }
+ #endif
+
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BABY_STEP_RETURN);
+
+ disp_baby_step_dist();
+
+ zOffsetText = lv_label_create(scr, 290, TITLE_YPOS, nullptr);
+ disp_z_offset_value();
+}
+
+void disp_baby_step_dist() {
+ if ((int)(100 * babystep_dist) == 1)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_01.bin");
+ else if ((int)(100 * babystep_dist) == 5)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_05.bin");
+ else if ((int)(100 * babystep_dist) == 10)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_1.bin");
+
+ if (gCfgItems.multiple_language) {
+ if ((int)(100 * babystep_dist) == 1) {
+ lv_label_set_text(labelV, move_menu.step_001mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(100 * babystep_dist) == 5) {
+ lv_label_set_text(labelV, move_menu.step_005mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(100 * babystep_dist) == 10) {
+ lv_label_set_text(labelV, move_menu.step_01mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_z_offset_value() {
+ char buf[20];
+ #if HAS_BED_PROBE
+ char str_1[16];
+ #endif
+ sprintf_P(buf, PSTR("offset Z: %s mm"), TERN(HAS_BED_PROBE, dtostrf(probe.offset.z, 1, 3, str_1), "0"));
+ lv_label_set_text(zOffsetText, buf);
+}
+
+void lv_clear_baby_stepping() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h
new file mode 100644
index 0000000..5886a20
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_baby_stepping.h
@@ -0,0 +1,35 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_baby_stepping(void);
+extern void lv_clear_baby_stepping();
+extern void disp_baby_step_dist();
+extern void disp_z_offset_value();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.cpp
new file mode 100644
index 0000000..7fec704
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.cpp
@@ -0,0 +1,184 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../../MarlinCore.h"
+#include "draw_ui.h"
+
+#include "../../../../module/temperature.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../gcode/gcode.h"
+
+#include "../../../../module/probe.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr, *labelV, *buttonV, *zOffsetText;
+static lv_obj_t *labelExt1, *labelBed;
+
+static uint8_t has_adjust_z = 0;
+static float step_dist=0.01;
+
+enum {
+ ID_BLTOUCH_INIT = 1,
+ ID_BLTOUCH_ZOFFSETPOS,
+ ID_BLTOUCH_ZOFFSETNEG,
+ ID_BLTOUCH_SAVE,
+ ID_BLTOUCH_TEST,
+ ID_BLTOUCH_STEPS,
+ ID_BLTOUCH_RETURN
+ };
+
+
+static void event_handler(lv_obj_t * obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ char baby_buf[30] = { 0 };
+ char str_1[40];
+ switch (obj->mks_obj_id) {
+ case ID_BLTOUCH_INIT:
+ bltouch_do_init();
+ break;
+ case ID_BLTOUCH_ZOFFSETPOS:
+ sprintf_P(baby_buf, PSTR("M290 Z%s"), dtostrf(step_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BLTOUCH_ZOFFSETNEG:
+ sprintf_P(baby_buf, PSTR("M290 Z%s"), dtostrf(-step_dist, 1, 3, str_1));
+ gcode.process_subcommands_now_P(PSTR(baby_buf));
+ has_adjust_z = 1;
+ break;
+ case ID_BLTOUCH_SAVE:
+ if (queue.length <= (BUFSIZE - 2)) queue.enqueue_now_P(PSTR("M500\nG28 X Y"));
+
+ break;
+ case ID_BLTOUCH_TEST:
+ sprintf_P(str_1, PSTR("G28\nG1 Z10 F2400\nG1 X%d Y%d\nG1 Z0"), X_MAX_POS / 2, Y_MAX_POS / 2);
+ if (!queue.length) queue.enqueue_now_P(PSTR(str_1));
+ break;
+ case ID_BLTOUCH_STEPS:
+ if (abs((int)(100 * step_dist)) == 1)
+ step_dist = 0.05;
+ else if (abs((int)(100 * step_dist)) == 5)
+ step_dist = 0.1;
+ else
+ step_dist = 0.01;
+ disp_step_dist();
+ break;
+ case ID_BLTOUCH_RETURN:
+ TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstop._enabled = true);
+ lv_clear_bltouch_settings();
+ lv_draw_return_ui();
+ break;
+
+ }
+}
+
+void lv_draw_bltouch_settings(void) {
+ scr = lv_screen_create(BLTOUCH_UI, machine_menu.BLTouchLevelingConfTitle);
+ // Create image buttons
+ lv_big_button_create(scr, "F:/bmp_Add.bin" , machine_menu.BLTouchOffsetpos, INTERVAL_V, titleHeight, event_handler, ID_BLTOUCH_ZOFFSETPOS);
+ lv_obj_t *buttonExt1 = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonExt1 , "F:/bmp_ext1_state.bin");
+ lv_obj_set_pos(buttonExt1 , 171, 50);
+
+ lv_obj_t *buttonBedstate = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonBedstate, "F:/bmp_bed_state.bin");
+ lv_obj_set_pos(buttonBedstate, 266, 50);
+ labelExt1 = lv_label_create(scr, 161, 115, nullptr);
+ labelBed = lv_label_create(scr, 256, 115, nullptr);
+
+ lv_obj_align(labelExt1, buttonExt1 , LV_ALIGN_IN_BOTTOM_MID, 2, 20);
+ lv_obj_align(labelBed , buttonBedstate, LV_ALIGN_IN_BOTTOM_MID, 2, 20);
+
+ zOffsetText = lv_label_create(scr , 170, 140, nullptr);
+ lv_big_button_create(scr, "F:/bmp_Dec.bin" , machine_menu.BLTouchOffsetneg, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_BLTOUCH_ZOFFSETNEG);
+
+ buttonV = lv_imgbtn_create(scr , nullptr , INTERVAL_V , BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BLTOUCH_STEPS);
+ labelV = lv_label_create_empty(buttonV);
+
+ lv_big_button_create(scr, "F:/bmp_in.bin" , machine_menu.BLTouchTest , BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BLTOUCH_TEST);
+ lv_big_button_create(scr, "F:/bmp_set.bin" , machine_menu.BLTouchSave , BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BLTOUCH_SAVE);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back , BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_BLTOUCH_RETURN);
+
+ disp_step_dist();
+ disp_bltouch_z_offset_value();
+}
+
+void disp_step_dist() {
+ if ((int)(100 * step_dist) == 1)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_01.bin");
+ else if ((int)(100 * step_dist) == 5)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_05.bin");
+ else if ((int)(100 * step_dist) == 10)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_baby_move0_1.bin");
+
+ if (gCfgItems.multiple_language) {
+ if ((int)(100 * step_dist) == 1) {
+ lv_label_set_text(labelV, move_menu.step_001mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(100 * step_dist) == 5) {
+ lv_label_set_text(labelV, move_menu.step_005mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(100 * step_dist) == 10) {
+ lv_label_set_text(labelV, move_menu.step_01mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_bltouch_z_offset_value() {
+ char buf[20];
+ char str_1[16];
+ sprintf_P(buf, PSTR("Z Offset : %s mm"), dtostrf(probe.offset.z, 1, 2, str_1) );
+ lv_label_set_text(zOffsetText, buf);
+
+ sprintf(public_buf_l, printing_menu.temp1, (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target);
+ lv_label_set_text(labelExt1, public_buf_l);
+
+ #if HAS_HEATED_BED
+ sprintf(public_buf_l, printing_menu.bed_temp, (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target);
+ lv_label_set_text(labelBed, public_buf_l);
+ #endif
+
+}
+
+void bltouch_do_init() {
+ char str_1[50];
+ TERN_(HAS_BED_PROBE, probe.offset.z = 0);
+ TERN_(HAS_SOFTWARE_ENDSTOPS, soft_endstop._enabled = false);
+ queue.clear();
+ sprintf_P(str_1, PSTR("G28\nG1 Z10 F2400\nG1 X%d Y%d\nG1 Z0"), X_MAX_POS / 2, Y_MAX_POS / 2);
+ queue.enqueue_now_P(PSTR(str_1));
+}
+
+void lv_clear_bltouch_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.h
new file mode 100644
index 0000000..5f33359
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_bltouch_settings.h
@@ -0,0 +1,37 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_bltouch_settings(void);
+extern void lv_clear_bltouch_settings();
+extern void disp_step_dist();
+extern void bltouch_do_init();
+extern void disp_bltouch_z_offset_value();
+
+//extern void disp_temp_ready_print();
+#ifdef __cplusplus
+} /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp
new file mode 100644
index 0000000..bb3be74
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.cpp
@@ -0,0 +1,225 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *labelStep, *buttonStep, *buttonMov, *buttonExt;
+static lv_obj_t *labelMov, *labelExt;
+static lv_obj_t *printSpeedText;
+
+enum {
+ ID_C_ADD = 1,
+ ID_C_DEC,
+ ID_C_MOVE,
+ ID_C_EXT,
+ ID_C_STEP,
+ ID_C_RETURN
+};
+
+static bool editingFlowrate;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_C_ADD:
+ if (!editingFlowrate) {
+ if (feedrate_percentage < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed)
+ feedrate_percentage += uiCfg.stepPrintSpeed;
+ else
+ feedrate_percentage = MAX_EXT_SPEED_PERCENT;
+ }
+ else {
+ if (planner.flow_percentage[0] < MAX_EXT_SPEED_PERCENT - uiCfg.stepPrintSpeed)
+ planner.flow_percentage[0] += uiCfg.stepPrintSpeed;
+ else
+ planner.flow_percentage[0] = MAX_EXT_SPEED_PERCENT;
+ planner.refresh_e_factor(0);
+ #if HAS_MULTI_EXTRUDER
+ planner.flow_percentage[1] = planner.flow_percentage[0];
+ planner.refresh_e_factor(1);
+ #endif
+ }
+ disp_print_speed();
+ break;
+ case ID_C_DEC:
+ if (!editingFlowrate) {
+ if (feedrate_percentage > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed)
+ feedrate_percentage -= uiCfg.stepPrintSpeed;
+ else
+ feedrate_percentage = MIN_EXT_SPEED_PERCENT;
+ }
+ else {
+ if (planner.flow_percentage[0] > MIN_EXT_SPEED_PERCENT + uiCfg.stepPrintSpeed)
+ planner.flow_percentage[0] -= uiCfg.stepPrintSpeed;
+ else
+ planner.flow_percentage[0] = MIN_EXT_SPEED_PERCENT;
+ planner.refresh_e_factor(0);
+ #if HAS_MULTI_EXTRUDER
+ planner.flow_percentage[1] = planner.flow_percentage[0];
+ planner.refresh_e_factor(1);
+ #endif
+ }
+ disp_print_speed();
+ break;
+ case ID_C_MOVE:
+ editingFlowrate = false;
+ disp_speed_type();
+ disp_print_speed();
+ break;
+ case ID_C_EXT:
+ editingFlowrate = true;
+ disp_speed_type();
+ disp_print_speed();
+ break;
+ case ID_C_STEP:
+ if (uiCfg.stepPrintSpeed == 1)
+ uiCfg.stepPrintSpeed = 5;
+ else if (uiCfg.stepPrintSpeed == 5)
+ uiCfg.stepPrintSpeed = 10;
+ else
+ uiCfg.stepPrintSpeed = 1;
+ disp_speed_step();
+ break;
+ case ID_C_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_change_speed(void) {
+ scr = lv_screen_create(CHANGE_SPEED_UI);
+ // Create an Image button
+ lv_big_button_create(scr, "F:/bmp_Add.bin", speed_menu.add, INTERVAL_V, titleHeight, event_handler, ID_C_ADD);
+ lv_big_button_create(scr, "F:/bmp_Dec.bin", speed_menu.dec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_C_DEC);
+ buttonMov = lv_imgbtn_create(scr, nullptr, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_C_MOVE);
+ buttonExt = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_C_EXT);
+ buttonStep = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_C_STEP);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonMov);
+ lv_group_add_obj(g, buttonExt);
+ lv_group_add_obj(g, buttonStep);
+ }
+ #endif
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_C_RETURN);
+
+ // Create labels on the image buttons
+ labelMov = lv_label_create_empty(buttonMov);
+ labelExt = lv_label_create_empty(buttonExt);
+ labelStep = lv_label_create_empty(buttonStep);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonMov);
+ lv_group_add_obj(g, buttonExt);
+ lv_group_add_obj(g, buttonStep);
+ }
+ #endif
+
+ disp_speed_type();
+ disp_speed_step();
+
+ printSpeedText = lv_label_create_empty(scr);
+ lv_obj_set_style(printSpeedText, &tft_style_label_rel);
+ disp_print_speed();
+}
+
+void disp_speed_step() {
+ if (uiCfg.stepPrintSpeed == 1)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step1_percent.bin");
+ else if (uiCfg.stepPrintSpeed == 5)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step5_percent.bin");
+ else if (uiCfg.stepPrintSpeed == 10)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step10_percent.bin");
+
+ if (gCfgItems.multiple_language) {
+ if (uiCfg.stepPrintSpeed == 1) {
+ lv_label_set_text(labelStep, speed_menu.step_1percent);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.stepPrintSpeed == 5) {
+ lv_label_set_text(labelStep, speed_menu.step_5percent);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.stepPrintSpeed == 10) {
+ lv_label_set_text(labelStep, speed_menu.step_10percent);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_print_speed() {
+ char buf[30] = { 0 };
+
+ public_buf_l[0] = '\0';
+
+ int16_t val;
+ const char *lbl;
+ if (editingFlowrate) {
+ lbl = speed_menu.extrude_speed;
+ val = planner.flow_percentage[0];
+ }
+ else {
+ lbl = speed_menu.move_speed;
+ val = feedrate_percentage;
+ }
+ strcpy(public_buf_l, lbl);
+ strcat_P(public_buf_l, PSTR(": "));
+ sprintf_P(buf, PSTR("%d%%"), val);
+ strcat(public_buf_l, buf);
+ lv_label_set_text(printSpeedText, public_buf_l);
+ lv_obj_align(printSpeedText, nullptr, LV_ALIGN_CENTER, 0, -65);
+}
+
+void disp_speed_type() {
+ lv_imgbtn_set_src_both(buttonMov, editingFlowrate ? "F:/bmp_mov_changeSpeed.bin" : "F:/bmp_mov_sel.bin");
+ lv_imgbtn_set_src_both(buttonExt, editingFlowrate ? "F:/bmp_extruct_sel.bin" : "F:/bmp_speed_extruct.bin");
+ lv_obj_refresh_ext_draw_pad(buttonExt);
+ lv_obj_refresh_ext_draw_pad(buttonMov);
+
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelMov, speed_menu.move);
+ lv_obj_align(labelMov, buttonMov, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(labelExt, speed_menu.extrude);
+ lv_obj_align(labelExt, buttonExt, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+}
+
+void lv_clear_change_speed() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h
new file mode 100644
index 0000000..8fa4c80
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_change_speed.h
@@ -0,0 +1,39 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#define MIN_EXT_SPEED_PERCENT 10
+#define MAX_EXT_SPEED_PERCENT 999
+
+extern void lv_draw_change_speed(void);
+extern void lv_clear_change_speed();
+extern void disp_speed_step();
+extern void disp_print_speed();
+extern void disp_speed_type();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp
new file mode 100644
index 0000000..38c3ebf
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.cpp
@@ -0,0 +1,205 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, MKS_WIFI_MODULE)
+
+#include "lv_conf.h"
+#include "draw_ui.h"
+
+#include "../../../../MarlinCore.h"
+#include "../../../../module/temperature.h"
+
+#include "QR_Encode.h"
+
+extern lv_group_t * g;
+static lv_obj_t * scr;
+static lv_obj_t *button_bind_or_not = NULL, *label_bind_or_not = NULL;
+static lv_obj_t *buttonReleaseBind = NULL, *label_ReleaseBind = NULL;
+static lv_obj_t * text_id;
+
+static uint8_t unbinding_flag = 0;
+static uint8_t id_mark = 0;
+
+#define ID_CLOUD_BIND_RETURN 1
+#define ID_CLOUD_BIND_OR_NOT 2
+#define ID_CLOUD_RELEASE_BIND 3
+
+static void event_handler(lv_obj_t * obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_CLOUD_BIND_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ case ID_CLOUD_RELEASE_BIND:
+ if (cloud_para.state == 0x12) {
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TYPE_UNBIND);
+ }
+ break;
+ }
+}
+
+void lv_draw_cloud_bind(void) {
+ lv_obj_t *buttonBack = NULL, *label_Back = NULL;
+ scr = lv_screen_create(BIND_UI);
+
+ button_bind_or_not = lv_btn_create(scr, NULL);
+ lv_obj_set_pos(button_bind_or_not, TFT_WIDTH - 130, TFT_HEIGHT - 80 * 3);
+ lv_obj_set_size(button_bind_or_not, PARA_UI_VALUE_BTN_X_SIZE + 15, PARA_UI_VALUE_BTN_Y_SIZE + 15);
+ lv_obj_set_event_cb_mks(button_bind_or_not, event_handler, ID_CLOUD_BIND_OR_NOT, NULL, 0);
+ lv_btn_set_style(button_bind_or_not, LV_BTN_STYLE_REL, &style_para_value);
+ lv_btn_set_style(button_bind_or_not, LV_BTN_STYLE_PR, &style_para_value);
+ label_bind_or_not = lv_label_create_empty(button_bind_or_not);
+
+ buttonReleaseBind = lv_btn_create(scr, NULL);
+ lv_obj_set_pos(buttonReleaseBind, TFT_WIDTH - 130, TFT_HEIGHT - 80 * 2);
+ lv_obj_set_size(buttonReleaseBind, PARA_UI_VALUE_BTN_X_SIZE + 15, PARA_UI_VALUE_BTN_Y_SIZE + 15);
+ lv_obj_set_event_cb_mks(buttonReleaseBind, event_handler, ID_CLOUD_RELEASE_BIND, NULL, 0);
+ label_ReleaseBind = lv_label_create_empty(buttonReleaseBind);
+ lv_label_set_text(label_ReleaseBind, cloud_menu.unbind);
+ lv_obj_align(label_ReleaseBind, buttonReleaseBind, LV_ALIGN_CENTER, 0, 0);
+
+ buttonBack = lv_btn_create(scr, NULL);
+ lv_obj_set_pos(buttonBack, TFT_WIDTH - 130, TFT_HEIGHT - 80);
+ lv_obj_set_size(buttonBack, PARA_UI_VALUE_BTN_X_SIZE + 15, PARA_UI_VALUE_BTN_Y_SIZE + 15);
+ lv_obj_set_event_cb_mks(buttonBack, event_handler, ID_CLOUD_BIND_RETURN, NULL, 0);
+ lv_btn_set_style(buttonBack, LV_BTN_STYLE_REL, &style_para_back);
+ lv_btn_set_style(buttonBack, LV_BTN_STYLE_PR, &style_para_back);
+ label_Back = lv_label_create_empty(buttonBack);
+ lv_label_set_text(label_Back, common_menu.text_back);
+ lv_obj_align(label_Back, buttonBack, LV_ALIGN_CENTER, 0, 0);
+
+ #if BUTTONS_EXIST(EN1, EN2, ENC)
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonReleaseBind);
+ lv_group_add_obj(g, buttonBack);
+ }
+ #endif
+
+ text_id = lv_label_create_empty(scr);
+ lv_obj_set_pos(text_id, 50, 60 + 200 + 20);
+ lv_obj_set_style(text_id, &tft_style_label_rel);
+ lv_label_set_text(text_id, (char *)cloud_para.id);
+
+ id_mark = 0;
+
+ disp_bind_state();
+}
+
+void disp_bind_state() {
+ if (cloud_para.state != 0x12)
+ unbinding_flag = 0;
+
+ if (unbinding_flag) {
+ lv_label_set_text(label_bind_or_not, cloud_menu.unbinding);
+ lv_obj_align(label_bind_or_not, button_bind_or_not, LV_ALIGN_CENTER, 0, 0);
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_REL, &style_para_value);
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_PR, &style_para_value);
+ }
+ else {
+ if (cloud_para.state == 0x10) {
+ lv_label_set_text(label_bind_or_not, cloud_menu.disconnected);
+ lv_obj_align(label_bind_or_not, button_bind_or_not, LV_ALIGN_CENTER, 0, 0);
+ }
+ else if (cloud_para.state == 0x11) {
+ lv_label_set_text(label_bind_or_not, cloud_menu.unbinded);
+ lv_obj_align(label_bind_or_not, button_bind_or_not, LV_ALIGN_CENTER, 0, 0);
+ }
+ else if (cloud_para.state == 0x12) {
+ lv_label_set_text(label_bind_or_not, cloud_menu.binded);
+ lv_obj_align(label_bind_or_not, button_bind_or_not, LV_ALIGN_CENTER, 0, 0);
+ }
+ else {
+ lv_label_set_text(label_bind_or_not, cloud_menu.disable);
+ lv_obj_align(label_bind_or_not, button_bind_or_not, LV_ALIGN_CENTER, 0, 0);
+ }
+ }
+
+ if (cloud_para.state == 0x12 && !unbinding_flag) {
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_REL, &style_para_back);
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_PR, &style_para_back);
+ }
+ else {
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_REL, &style_para_value);
+ lv_btn_set_style(buttonReleaseBind, LV_BTN_STYLE_PR, &style_para_value);
+ }
+}
+
+static char last_cloud_state = 0;
+void refresh_bind_ui() {
+ if ((last_cloud_state != cloud_para.state) || unbinding_flag) {
+ disp_bind_state();
+ last_cloud_state = cloud_para.state;
+ }
+ if (cloud_para.id[0]) {
+ if (!id_mark) {
+ display_qrcode((uint8_t *)cloud_para.id);
+ lv_label_set_text(text_id, (char *)cloud_para.id);
+ }
+ }
+ else
+ id_mark = 0;
+}
+
+void display_qrcode(uint8_t *qrcode_data) {
+ uint8_t i, j;
+ uint16_t x, y, p;
+
+ if (!id_mark) {
+ EncodeData((char *)qrcode_data);
+ id_mark = 1;
+ }
+
+ lv_fill_rect(10, QRCODE_Y, 300, QRCODE_Y + 300, LV_COLOR_WHITE);
+
+ if (m_nSymbleSize * 2 > QRCODE_WIDTH) return;
+
+ for (i = 0; i < 40; i++)
+ if ((m_nSymbleSize * i * 2) > QRCODE_WIDTH) break;
+
+ p = (i - 1) * 2;
+
+ x = QRCODE_X + 70;
+ y = QRCODE_Y + 70;
+
+ for (i = 0; i < m_nSymbleSize; i++)
+ for (j = 0; j < m_nSymbleSize; j++)
+ if (m_byModuleData[i][j] == 1)
+ lv_fill_rect(x + p * i, y + p * j, x + p * (i + 1) - 1, y + p * (j + 1) - 1, LV_COLOR_BACKGROUND);
+}
+
+void cloud_unbind() {
+ package_to_wifi(WIFI_CLOUD_UNBIND, (uint8_t *)0, 0);
+ unbinding_flag = 1;
+}
+
+void lv_clear_cloud_bind() {
+ #if BUTTONS_EXIST(EN1, EN2, ENC)
+ if (gCfgItems.encoder_enable)
+ lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.h
new file mode 100644
index 0000000..f0f354a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_cloud_bind.h
@@ -0,0 +1,37 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_cloud_bind(void);
+extern void lv_clear_cloud_bind();
+extern void disp_bind_state();
+extern void refresh_bind_ui();
+extern void display_qrcode(uint8_t *qrcode_data);
+extern void cloud_unbind();
+
+#ifdef __cplusplus
+} /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp
new file mode 100644
index 0000000..4b0eebe
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.cpp
@@ -0,0 +1,574 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * draw_dialog.cpp
+ */
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../sd/cardreader.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../module/temperature.h"
+#include "../../../../module/planner.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS)
+ #include "../../../../module/settings.h"
+#endif
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+#if ENABLED(PARK_HEAD_ON_PAUSE)
+ #include "../../../../feature/pause.h"
+#endif
+
+#if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ #include "../../../tft_io/touch_calibration.h"
+ #include "draw_touch_calibration.h"
+#endif
+
+extern lv_group_t *g;
+static lv_obj_t *scr, *tempText1, *filament_bar;
+
+extern uint8_t sel_id;
+extern bool once_flag, gcode_preview_over;
+extern int upload_result;
+extern uint32_t upload_time;
+extern uint32_t upload_size;
+extern bool temps_update_flag;
+
+static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ if (DIALOG_IS(TYPE_PRINT_FILE)) {
+ #if HAS_GCODE_PREVIEW
+ preview_gcode_prehandle(list_file.file_name[sel_id]);
+ #endif
+ reset_print_time();
+ start_print_time();
+
+ uiCfg.print_state = WORKING;
+ lv_clear_dialog();
+ lv_draw_printing();
+
+ #if ENABLED(SDSUPPORT)
+ if (!gcode_preview_over) {
+ //char *cur_name;
+ //cur_name = strrchr(list_file.file_name[sel_id], '/');
+
+ //SdFile file, *curDir;
+ card.endFilePrint();
+ //const char * const fname = card.diveToFile(true, curDir, cur_name);
+ //if (!fname) return;
+ //if (file.open(curDir, fname, O_READ)) {
+ //gCfgItems.curFilesize = file.fileSize();
+ //file.close();
+ //update_spi_flash();
+ //}
+ card.openFileRead(list_file.file_name[sel_id]);
+ if (card.isFileOpen()) {
+ gCfgItems.curFilesize = card.getFileSize();
+ update_spi_flash();
+ feedrate_percentage = 100;
+ planner.flow_percentage[0] = 100;
+ planner.e_factor[0] = planner.flow_percentage[0] * 0.01f;
+ #if HAS_MULTI_EXTRUDER
+ planner.flow_percentage[1] = 100;
+ planner.e_factor[1] = planner.flow_percentage[1] * 0.01f;
+ #endif
+ card.startFileprint();
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ recovery.prepare();
+ #endif
+ once_flag = false;
+ }
+ }
+ #endif
+ }
+ else if (DIALOG_IS(TYPE_STOP)) {
+ wait_for_heatup = false;
+ stop_print_time();
+ lv_clear_dialog();
+ lv_draw_ready_print();
+
+ #if ENABLED(SDSUPPORT)
+ uiCfg.print_state = IDLE;
+ card.flag.abort_sd_printing = true;
+ #endif
+ }
+ else if (DIALOG_IS(TYPE_FINISH_PRINT)) {
+ lv_clear_cur_ui();
+ lv_draw_ready_print();
+ }
+ #if ENABLED(ADVANCED_PAUSE_FEATURE)
+ else if (DIALOG_IS(PAUSE_MESSAGE_WAITING, PAUSE_MESSAGE_INSERT, PAUSE_MESSAGE_HEAT))
+ wait_for_user = false;
+ else if (DIALOG_IS(PAUSE_MESSAGE_OPTION))
+ pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE;
+ else if (DIALOG_IS(PAUSE_MESSAGE_RESUME)) {
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ #endif
+ else if (DIALOG_IS(STORE_EEPROM_TIPS)) {
+ TERN_(EEPROM_SETTINGS, (void)settings.save());
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ else if (DIALOG_IS(READ_EEPROM_TIPS)) {
+ TERN_(EEPROM_SETTINGS, (void)settings.load());
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ else if (DIALOG_IS(REVERT_EEPROM_TIPS)) {
+ TERN_(EEPROM_SETTINGS, (void)settings.reset());
+ lv_clear_cur_ui();
+ #if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ const bool do_draw_cal = touch_calibration.need_calibration();
+ if (do_draw_cal) {
+ disp_state_stack._disp_index--; // We are asynchronous from the dialog, so let's remove the dialog from the stack
+ lv_draw_touch_calibration_screen();
+ }
+ #else
+ constexpr bool do_draw_cal = false;
+ #endif
+ if (!do_draw_cal) lv_draw_return_ui();
+ }
+ else if (DIALOG_IS(WIFI_CONFIG_TIPS)) {
+ uiCfg.configWifi = 1;
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_HEAT_LOAD_COMPLETED))
+ uiCfg.filament_heat_completed_load = 1;
+ else if (DIALOG_IS(TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED))
+ uiCfg.filament_heat_completed_unload = 1;
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_COMPLETED, TYPE_FILAMENT_UNLOAD_COMPLETED)) {
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ #if ENABLED(MKS_WIFI_MODULE)
+ else if (DIALOG_IS(TYPE_UNBIND)) {
+ cloud_unbind();
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ #endif
+ else {
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+}
+
+static void btn_cancel_event_cb(lv_obj_t *btn, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ if (DIALOG_IS(PAUSE_MESSAGE_OPTION)) {
+ TERN_(ADVANCED_PAUSE_FEATURE, pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_HEAT, TYPE_FILAMENT_UNLOAD_HEAT, TYPE_FILAMENT_HEAT_LOAD_COMPLETED, TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED)) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target= uiCfg.desireSprayerTempBak;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOADING, TYPE_FILAMENT_UNLOADING)) {
+ queue.enqueue_one_P(PSTR("M410"));
+ uiCfg.filament_rate = 0;
+ uiCfg.filament_loading_completed = 0;
+ uiCfg.filament_unloading_completed = 0;
+ uiCfg.filament_loading_time_flg = 0;
+ uiCfg.filament_loading_time_cnt = 0;
+ uiCfg.filament_unloading_time_flg = 0;
+ uiCfg.filament_unloading_time_cnt = 0;
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = uiCfg.desireSprayerTempBak;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+ else {
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ }
+}
+
+void lv_draw_dialog(uint8_t type) {
+ lv_obj_t *btnOk = nullptr, *btnCancel = nullptr;
+ uiCfg.dialogType = type;
+ scr = lv_screen_create(DIALOG_UI);
+
+ lv_obj_t *labelDialog = lv_label_create(scr, "");
+
+ if (DIALOG_IS(TYPE_FINISH_PRINT, PAUSE_MESSAGE_RESUME)) {
+ btnOk = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_ok_event_cb);
+ lv_obj_t *labelOk = lv_label_create_empty(btnOk); // Add a label to the button
+ lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_WAITING, PAUSE_MESSAGE_INSERT, PAUSE_MESSAGE_HEAT)) {
+ btnOk = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_ok_event_cb);
+ lv_obj_t *labelOk = lv_label_create_empty(btnOk); // Add a label to the button
+ lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_PAUSING, PAUSE_MESSAGE_CHANGING, PAUSE_MESSAGE_UNLOAD, PAUSE_MESSAGE_LOAD, PAUSE_MESSAGE_PURGE, PAUSE_MESSAGE_RESUME, PAUSE_MESSAGE_HEATING)) {
+ // nothing to do
+ }
+ else if (DIALOG_IS(WIFI_ENABLE_TIPS)) {
+ btnCancel = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel);
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+ }
+ else if (DIALOG_IS(TRANSFER_NO_DEVICE)) {
+ btnCancel = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel);
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+ }
+ #if ENABLED(MKS_WIFI_MODULE)
+ else if (DIALOG_IS(TYPE_UPLOAD_FILE)) {
+ if (upload_result == 2) {
+ btnCancel = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel);
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+ }
+ else if (upload_result == 3) {
+ btnOk = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_ok_event_cb);
+ lv_obj_t *labelOk = lv_label_create_empty(btnOk);
+ lv_label_set_text(labelOk, print_file_dialog_menu.confirm);
+ }
+ }
+ else if (DIALOG_IS(TYPE_UPDATE_ESP_FIRMARE)) {
+ // nothing to do
+ }
+ #endif
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_HEAT, TYPE_FILAMENT_UNLOAD_HEAT)) {
+ btnCancel = lv_button_btn_create(scr, BTN_OK_X+90, BTN_OK_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel);
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+
+ tempText1 = lv_label_create_empty(scr);
+ filament_sprayer_temp();
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_COMPLETED, TYPE_FILAMENT_UNLOAD_COMPLETED)) {
+ btnOk = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_ok_event_cb);
+ lv_obj_t *labelOk = lv_label_create_empty(btnOk);
+ lv_label_set_text(labelOk, print_file_dialog_menu.confirm);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOADING, TYPE_FILAMENT_UNLOADING)) {
+ btnCancel = lv_button_btn_create(scr, BTN_OK_X + 90, BTN_OK_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel);
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+
+ filament_bar = lv_bar_create(scr, nullptr);
+ lv_obj_set_pos(filament_bar, (TFT_WIDTH-400)/2, ((TFT_HEIGHT - titleHeight)-40)/2);
+ lv_obj_set_size(filament_bar, 400, 25);
+ lv_bar_set_style(filament_bar, LV_BAR_STYLE_INDIC, &lv_bar_style_indic);
+ lv_bar_set_anim_time(filament_bar, 1000);
+ lv_bar_set_value(filament_bar, 0, LV_ANIM_ON);
+ }
+ else if(DIALOG_IS(TYPE_MACHINE_PAUSING_TIPS)) {
+ //nothing to do
+ }
+ else {
+ btnOk = lv_button_btn_create(scr, BTN_OK_X, BTN_OK_Y, 100, 50, btn_ok_event_cb);
+ lv_obj_t *labelOk = lv_label_create_empty(btnOk); // Add a label to the button
+
+ btnCancel = lv_button_btn_create(scr, BTN_CANCEL_X, BTN_CANCEL_Y, 100, 50, btn_cancel_event_cb);
+ lv_obj_t *labelCancel = lv_label_create_empty(btnCancel); // Add a label to the button
+
+ if (DIALOG_IS(PAUSE_MESSAGE_OPTION)) {
+ lv_label_set_text(labelOk, pause_msg_menu.purgeMore); // Set the labels text
+ lv_label_set_text(labelCancel, pause_msg_menu.continuePrint);
+ }
+ else {
+ lv_label_set_text(labelOk, print_file_dialog_menu.confirm); // Set the labels text
+ lv_label_set_text(labelCancel, print_file_dialog_menu.cancel);
+ }
+ }
+ if (DIALOG_IS(TYPE_PRINT_FILE)) {
+ lv_label_set_text(labelDialog, print_file_dialog_menu.print_file);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+
+ lv_obj_t *labelFile = lv_label_create(scr, list_file.long_name[sel_id]);
+ lv_obj_align(labelFile, nullptr, LV_ALIGN_CENTER, 0, -60);
+ }
+ else if (DIALOG_IS(TYPE_STOP)) {
+ lv_label_set_text(labelDialog, print_file_dialog_menu.cancel_print);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FINISH_PRINT)) {
+ lv_label_set_text(labelDialog, print_file_dialog_menu.print_finish);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_PAUSING)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.pausing);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_CHANGING)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.changing);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_UNLOAD)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.unload);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_WAITING)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.waiting);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_INSERT)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.insert);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_LOAD)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.load);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_PURGE)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.purge);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_RESUME)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.resume);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_HEAT)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.heat);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_HEATING)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.heating);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(PAUSE_MESSAGE_OPTION)) {
+ lv_label_set_text(labelDialog, pause_msg_menu.option);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(STORE_EEPROM_TIPS)) {
+ lv_label_set_text(labelDialog, eeprom_menu.storeTips);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(READ_EEPROM_TIPS)) {
+ lv_label_set_text(labelDialog, eeprom_menu.readTips);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(REVERT_EEPROM_TIPS)) {
+ lv_label_set_text(labelDialog, eeprom_menu.revertTips);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(WIFI_CONFIG_TIPS)) {
+ lv_label_set_text(labelDialog, machine_menu.wifiConfigTips);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(WIFI_ENABLE_TIPS)) {
+ lv_label_set_text(labelDialog, print_file_dialog_menu.wifi_enable_tips);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TRANSFER_NO_DEVICE)) {
+ lv_label_set_text(labelDialog, DIALOG_UPDATE_NO_DEVICE_EN);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ #if ENABLED(MKS_WIFI_MODULE)
+ else if (DIALOG_IS(TYPE_UPLOAD_FILE)) {
+ if (upload_result == 1) {
+ lv_label_set_text(labelDialog, DIALOG_UPLOAD_ING_EN);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (upload_result == 2) {
+ lv_label_set_text(labelDialog, DIALOG_UPLOAD_ERROR_EN);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (upload_result == 3) {
+ char buf[200];
+ int _index = 0;
+
+ strcpy(buf, DIALOG_UPLOAD_FINISH_EN);
+ _index = strlen(buf);
+ buf[_index] = '\n';
+ _index++;
+ strcat(buf, DIALOG_UPLOAD_SIZE_EN);
+
+ _index = strlen(buf);
+ buf[_index] = ':';
+ _index++;
+ sprintf(&buf[_index], " %d KBytes\n", (int)(upload_size / 1024));
+
+ strcat(buf, DIALOG_UPLOAD_TIME_EN);
+ _index = strlen(buf);
+ buf[_index] = ':';
+ _index++;
+ sprintf(&buf[_index], " %d s\n", (int)upload_time);
+
+ strcat(buf, DIALOG_UPLOAD_SPEED_EN);
+ _index = strlen(buf);
+ buf[_index] = ':';
+ _index++;
+ sprintf(&buf[_index], " %d KBytes/s\n", (int)(upload_size / upload_time / 1024));
+
+ lv_label_set_text(labelDialog, buf);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ }
+ else if (DIALOG_IS(TYPE_UPDATE_ESP_FIRMARE)) {
+ lv_label_set_text(labelDialog, DIALOG_UPDATE_WIFI_FIRMWARE_EN);
+ lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -20);
+ }
+ #endif // MKS_WIFI_MODULE
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_HEAT)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_heat);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_HEAT_LOAD_COMPLETED)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_heat_confirm);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_UNLOAD_HEAT)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_heat);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_heat_confirm);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOAD_COMPLETED)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_load_completed);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_UNLOAD_COMPLETED)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_unload_completed);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -20);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_LOADING)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_loading);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -70);
+ }
+ else if (DIALOG_IS(TYPE_FILAMENT_UNLOADING)) {
+ lv_label_set_text(labelDialog, filament_menu.filament_dialog_unloading);
+ lv_obj_align(labelDialog, nullptr, LV_ALIGN_CENTER, 0, -70);
+ }
+ #if ENABLED(MKS_WIFI_MODULE)
+ else if (DIALOG_IS(TYPE_UNBIND)) {
+ lv_label_set_text(labelDialog, common_menu.unbind_printer_tips);
+ lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, -70);
+ }
+ #endif
+ else if(DIALOG_IS(TYPE_MACHINE_PAUSING_TIPS)) {
+ lv_label_set_text(labelDialog, print_file_dialog_menu.machinePausingTips);
+ lv_obj_align(labelDialog, NULL, LV_ALIGN_CENTER, 0, 0);
+ }
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ if (btnOk) lv_group_add_obj(g, btnOk);
+ if (btnCancel) lv_group_add_obj(g, btnCancel);
+ }
+ #endif
+}
+
+void filament_sprayer_temp() {
+ char buf[20] = {0};
+ sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target);
+
+ strcpy(public_buf_l, uiCfg.curSprayerChoose < 1 ? extrude_menu.ext1 : extrude_menu.ext2);
+ strcat_P(public_buf_l, PSTR(": "));
+ strcat(public_buf_l, buf);
+ lv_label_set_text(tempText1, public_buf_l);
+ lv_obj_align(tempText1, nullptr, LV_ALIGN_CENTER, 0, -50);
+}
+
+void filament_dialog_handle() {
+ if (temps_update_flag && (DIALOG_IS(TYPE_FILAMENT_LOAD_HEAT, TYPE_FILAMENT_UNLOAD_HEAT))) {
+ filament_sprayer_temp();
+ temps_update_flag = false;
+ }
+ if (uiCfg.filament_heat_completed_load == 1) {
+ uiCfg.filament_heat_completed_load = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOADING);
+ planner.synchronize();
+ uiCfg.filament_loading_time_flg = 1;
+ uiCfg.filament_loading_time_cnt = 0;
+ sprintf_P(public_buf_m, PSTR("T%d\nG91\nG1 E%d F%d\nG90"), uiCfg.curSprayerChoose, gCfgItems.filamentchange_load_length, gCfgItems.filamentchange_load_speed);
+ queue.inject(public_buf_m);
+ }
+ if (uiCfg.filament_heat_completed_unload == 1) {
+ uiCfg.filament_heat_completed_unload = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOADING);
+ planner.synchronize();
+ uiCfg.filament_unloading_time_flg = 1;
+ uiCfg.filament_unloading_time_cnt = 0;
+ sprintf_P(public_buf_m, PSTR("T%d\nG91\nG1 E-%d F%d\nG90"), uiCfg.curSprayerChoose, gCfgItems.filamentchange_unload_length, gCfgItems.filamentchange_unload_speed);
+ queue.inject(public_buf_m);
+ }
+
+ if (((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius - gCfgItems.filament_limit_temper)) <= 1)
+ || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius > gCfgItems.filament_limit_temper))
+ && (uiCfg.filament_load_heat_flg == 1)
+ ) {
+ uiCfg.filament_load_heat_flg = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED);
+ }
+
+ if (uiCfg.filament_loading_completed == 1) {
+ uiCfg.filament_rate = 0;
+ uiCfg.filament_loading_completed = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOAD_COMPLETED);
+ }
+ if (((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius - gCfgItems.filament_limit_temper)) <= 1)
+ || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius > gCfgItems.filament_limit_temper))
+ && (uiCfg.filament_unload_heat_flg == 1)
+ ) {
+ uiCfg.filament_unload_heat_flg = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED);
+ }
+
+ if (uiCfg.filament_unloading_completed == 1) {
+ uiCfg.filament_rate = 0;
+ uiCfg.filament_unloading_completed = 0;
+ lv_clear_dialog();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED);
+ }
+
+ if (DIALOG_IS(TYPE_FILAMENT_LOADING, TYPE_FILAMENT_UNLOADING))
+ lv_filament_setbar();
+}
+
+void lv_filament_setbar() {
+ lv_bar_set_value(filament_bar, uiCfg.filament_rate, LV_ANIM_ON);
+}
+
+void lv_clear_dialog() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h
new file mode 100644
index 0000000..69b8491
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_dialog.h
@@ -0,0 +1,91 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+enum {
+ DIALOG_TYPE_STOP = 0,
+ DIALOG_TYPE_PRINT_FILE,
+ DIALOG_TYPE_REPRINT_NO_FILE,
+
+ DIALOG_TYPE_M80_FAIL,
+ DIALOG_TYPE_MESSAGE_ERR1,
+
+ DIALOG_TYPE_UPDATE_ESP_FIRMARE,
+ DIALOG_TYPE_UPDATE_ESP_DATA,
+ DIALOG_TYPE_UPLOAD_FILE,
+ DIALOG_TYPE_UNBIND,
+
+ DIALOG_TYPE_FILAMENT_LOAD_HEAT,
+ DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED,
+ DIALOG_TYPE_FILAMENT_LOADING,
+ DIALOG_TYPE_FILAMENT_LOAD_COMPLETED,
+ DIALOG_TYPE_FILAMENT_UNLOAD_HEAT,
+ DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED,
+ DIALOG_TYPE_FILAMENT_UNLOADING,
+ DIALOG_TYPE_FILAMENT_UNLOAD_COMPLETED,
+
+ DIALOG_TYPE_FILE_LOADING,
+
+ DIALOG_TYPE_FILAMENT_NO_PRESS,
+ DIALOG_TYPE_FINISH_PRINT,
+
+ DIALOG_WIFI_ENABLE_TIPS,
+
+ DIALOG_PAUSE_MESSAGE_PAUSING,
+ DIALOG_PAUSE_MESSAGE_CHANGING,
+ DIALOG_PAUSE_MESSAGE_UNLOAD,
+ DIALOG_PAUSE_MESSAGE_WAITING,
+ DIALOG_PAUSE_MESSAGE_INSERT,
+ DIALOG_PAUSE_MESSAGE_LOAD,
+ DIALOG_PAUSE_MESSAGE_PURGE,
+ DIALOG_PAUSE_MESSAGE_RESUME,
+ DIALOG_PAUSE_MESSAGE_HEAT,
+ DIALOG_PAUSE_MESSAGE_HEATING,
+ DIALOG_PAUSE_MESSAGE_OPTION,
+
+ DIALOG_STORE_EEPROM_TIPS,
+ DIALOG_READ_EEPROM_TIPS,
+ DIALOG_REVERT_EEPROM_TIPS,
+
+ DIALOG_WIFI_CONFIG_TIPS,
+ DIALOG_TRANSFER_NO_DEVICE,
+ DIALOG_TYPE_MACHINE_PAUSING_TIPS
+};
+
+#define BTN_OK_X 100
+#define BTN_OK_Y 180
+#define BTN_CANCEL_X 280
+#define BTN_CANCEL_Y 180
+
+extern void lv_draw_dialog(uint8_t type);
+extern void lv_clear_dialog();
+extern void filament_sprayer_temp();
+extern void filament_dialog_handle();
+extern void lv_filament_setbar();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp
new file mode 100644
index 0000000..446b942
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.cpp
@@ -0,0 +1,82 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_EEPROM_RETURN = 1,
+ ID_EEPROM_STORE,
+ ID_EEPROM_STORE_ARROW,
+ ID_EEPROM_READ,
+ ID_EEPROM_READ_ARROW,
+ ID_EEPROM_REVERT,
+ ID_EEPROM_REVERT_ARROW
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_EEPROM_RETURN:
+ lv_clear_eeprom_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_EEPROM_STORE:
+ lv_clear_eeprom_settings();
+ lv_draw_dialog(DIALOG_STORE_EEPROM_TIPS);
+ break;
+ #if 0
+ case ID_EEPROM_READ:
+ lv_clear_eeprom_settings();
+ lv_draw_dialog(DIALOG_READ_EEPROM_TIPS);
+ break;
+ #endif
+ case ID_EEPROM_REVERT:
+ lv_clear_eeprom_settings();
+ lv_draw_dialog(DIALOG_REVERT_EEPROM_TIPS);
+ break;
+ }
+}
+
+void lv_draw_eeprom_settings(void) {
+ scr = lv_screen_create(EEPROM_SETTINGS_UI);
+ lv_screen_menu_item(scr, eeprom_menu.revert, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_EEPROM_REVERT, 0);
+ lv_screen_menu_item(scr, eeprom_menu.store, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_EEPROM_STORE, 1);
+ lv_screen_menu_item_return(scr, event_handler, ID_EEPROM_RETURN);
+}
+
+void lv_clear_eeprom_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h
new file mode 100644
index 0000000..6d5ecf0
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_eeprom_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_eeprom_settings(void);
+extern void lv_clear_eeprom_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp
new file mode 100644
index 0000000..ab48924
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.cpp
@@ -0,0 +1,72 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+#if BUTTONS_EXIST(EN1, EN2)
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *buttonEncoderState = nullptr;
+
+enum {
+ ID_ENCODER_RETURN = 1,
+ ID_ENCODER_STATE
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_ENCODER_RETURN:
+ lv_clear_encoder_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_ENCODER_STATE:
+ gCfgItems.encoder_enable ^= true;
+ lv_screen_menu_item_onoff_update(buttonEncoderState, gCfgItems.encoder_enable);
+ update_spi_flash();
+ break;
+ }
+}
+
+void lv_draw_encoder_settings(void) {
+ scr = lv_screen_create(ENCODER_SETTINGS_UI, machine_menu.EncoderConfTitle);
+ buttonEncoderState = lv_screen_menu_item_onoff(scr, machine_menu.EncoderConfText, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_ENCODER_STATE, 0, gCfgItems.encoder_enable);
+ lv_screen_menu_item_return(scr, event_handler, ID_ENCODER_RETURN);
+}
+
+void lv_clear_encoder_settings() {
+ #if HAS_ROTARY_ENCODER
+ lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // BUTTONS_EXIST(EN1, EN2)
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h
new file mode 100644
index 0000000..62892a6
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_encoder_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_encoder_settings(void);
+extern void lv_clear_encoder_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp
new file mode 100644
index 0000000..bdae725
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.cpp
@@ -0,0 +1,46 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "tft_lvgl_configuration.h"
+
+#include "SPI_TFT.h"
+#include "mks_hardware_test.h"
+#include "../../../../inc/MarlinConfig.h"
+
+static lv_obj_t *scr;
+
+void lv_draw_error_message(PGM_P const msg) {
+ SPI_TFT.LCD_clear(0x0000);
+ if (msg) disp_string((TFT_WIDTH - strlen(msg) * 16) / 2, 100, msg, 0xFFFF, 0x0000);
+ disp_string((TFT_WIDTH - strlen("PRINTER HALTED") * 16) / 2, 140, "PRINTER HALTED", 0xFFFF, 0x0000);
+ disp_string((TFT_WIDTH - strlen("Please Reset") * 16) / 2, 180, "Please Reset", 0xFFFF, 0x0000);
+}
+
+void lv_clear_error_message() { lv_obj_del(scr); }
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h
new file mode 100644
index 0000000..35e3bd6
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_error_message.h
@@ -0,0 +1,37 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#ifndef PGM_P
+ #define PGM_P const char *
+#endif
+
+extern void lv_draw_error_message(PGM_P const msg);
+extern void lv_clear_error_message();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp
new file mode 100644
index 0000000..d3574d2
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.cpp
@@ -0,0 +1,266 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../inc/MarlinConfig.h"
+#include "../../../../module/planner.h"
+
+static lv_obj_t *scr;
+extern lv_group_t *g;
+static lv_obj_t *buttonType, *buttonStep, *buttonSpeed;
+static lv_obj_t *labelType;
+static lv_obj_t *labelStep;
+static lv_obj_t *labelSpeed;
+static lv_obj_t *tempText;
+static lv_obj_t *ExtruText;
+
+enum {
+ ID_E_ADD = 1,
+ ID_E_DEC,
+ ID_E_TYPE,
+ ID_E_STEP,
+ ID_E_SPEED,
+ ID_E_RETURN
+};
+
+static int32_t extrudeAmount;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_E_ADD:
+ if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= EXTRUDE_MINTEMP) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P((char *)public_buf_l, PSTR("G1 E%d F%d"), uiCfg.extruStep, 60 * uiCfg.extruSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ extrudeAmount += uiCfg.extruStep;
+ disp_extru_amount();
+ }
+ break;
+ case ID_E_DEC:
+ if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= EXTRUDE_MINTEMP) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P((char *)public_buf_l, PSTR("G1 E%d F%d"), 0 - uiCfg.extruStep, 60 * uiCfg.extruSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ extrudeAmount -= uiCfg.extruStep;
+ disp_extru_amount();
+ }
+ break;
+ case ID_E_TYPE:
+ if (ENABLED(HAS_MULTI_EXTRUDER)) {
+ if (uiCfg.curSprayerChoose == 0) {
+ uiCfg.curSprayerChoose = 1;
+ queue.inject_P(PSTR("T1"));
+ }
+ else {
+ uiCfg.curSprayerChoose = 0;
+ queue.inject_P(PSTR("T0"));
+ }
+ }
+ else
+ uiCfg.curSprayerChoose = 0;
+
+ extrudeAmount = 0;
+ disp_hotend_temp();
+ disp_ext_type();
+ disp_extru_amount();
+ break;
+ case ID_E_STEP:
+ switch (abs(uiCfg.extruStep)) {
+ case 1: uiCfg.extruStep = 5; break;
+ case 5: uiCfg.extruStep = 10; break;
+ case 10: uiCfg.extruStep = 1; break;
+ default: break;
+ }
+ disp_ext_step();
+ break;
+ case ID_E_SPEED:
+ switch (uiCfg.extruSpeed) {
+ case 1: uiCfg.extruSpeed = 10; break;
+ case 10: uiCfg.extruSpeed = 20; break;
+ case 20: uiCfg.extruSpeed = 1; break;
+ default: break;
+ }
+ disp_ext_speed();
+ break;
+ case ID_E_RETURN:
+ feedrate_mm_s = (float)uiCfg.moveSpeed_bak;
+ if(uiCfg.print_state == PAUSED)
+ planner.set_e_position_mm((destination.e = current_position.e = uiCfg.current_e_position_bak));
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_extrusion(void) {
+ scr = lv_screen_create(EXTRUSION_UI);
+ // Create image buttons
+ lv_obj_t *buttonAdd = lv_big_button_create(scr, "F:/bmp_in.bin", extrude_menu.in, INTERVAL_V, titleHeight, event_handler, ID_E_ADD);
+ lv_obj_clear_protect(buttonAdd, LV_PROTECT_FOLLOW);
+ lv_big_button_create(scr, "F:/bmp_out.bin", extrude_menu.out, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_E_DEC);
+
+ buttonType = lv_imgbtn_create(scr, nullptr, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_E_TYPE);
+ buttonStep = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_E_STEP);
+ buttonSpeed = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_E_SPEED);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonType);
+ lv_group_add_obj(g, buttonStep);
+ lv_group_add_obj(g, buttonSpeed);
+ }
+ #endif
+
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_E_RETURN);
+
+ // Create labels on the image buttons
+ labelType = lv_label_create_empty(buttonType);
+ labelStep = lv_label_create_empty(buttonStep);
+ labelSpeed = lv_label_create_empty(buttonSpeed);
+
+ disp_ext_type();
+ disp_ext_step();
+ disp_ext_speed();
+
+ tempText = lv_label_create_empty(scr);
+ lv_obj_set_style(tempText, &tft_style_label_rel);
+ disp_hotend_temp();
+
+ ExtruText = lv_label_create_empty(scr);
+ lv_obj_set_style(ExtruText, &tft_style_label_rel);
+ disp_extru_amount();
+}
+
+void disp_ext_type() {
+ if (uiCfg.curSprayerChoose == 1) {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru2.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, extrude_menu.ext2);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+ else {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru1.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, extrude_menu.ext1);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_ext_speed() {
+ if (uiCfg.extruSpeed == 20)
+ lv_imgbtn_set_src_both(buttonSpeed, "F:/bmp_speed_high.bin");
+ else if (uiCfg.extruSpeed == 1)
+ lv_imgbtn_set_src_both(buttonSpeed, "F:/bmp_speed_slow.bin");
+ else
+ lv_imgbtn_set_src_both(buttonSpeed, "F:/bmp_speed_normal.bin");
+
+ if (gCfgItems.multiple_language) {
+ if (uiCfg.extruSpeed == 20) {
+ lv_label_set_text(labelSpeed, extrude_menu.high);
+ lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.extruSpeed == 1) {
+ lv_label_set_text(labelSpeed, extrude_menu.low);
+ lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else {
+ lv_label_set_text(labelSpeed, extrude_menu.normal);
+ lv_obj_align(labelSpeed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_hotend_temp() {
+ char buf[20] = {0};
+ #if ENABLED(SINGLENOZZLE)
+ sprintf(buf, extrude_menu.temp_value, (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target);
+ #else
+ sprintf(buf, extrude_menu.temp_value, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target);
+ #endif
+ strcpy(public_buf_l, extrude_menu.temper_text);
+ strcat(public_buf_l, buf);
+ lv_label_set_text(tempText, public_buf_l);
+ lv_obj_align(tempText, nullptr, LV_ALIGN_CENTER, 0, -50);
+}
+
+void disp_extru_amount() {
+ char buf1[10] = {0};
+
+ public_buf_l[0] = '\0';
+
+ if (extrudeAmount < 999 && extrudeAmount > -99)
+ sprintf(buf1, extrude_menu.count_value_mm, extrudeAmount);
+ else if (extrudeAmount < 9999 && extrudeAmount > -999)
+ sprintf(buf1, extrude_menu.count_value_cm, extrudeAmount / 10);
+ else
+ sprintf(buf1, extrude_menu.count_value_m, extrudeAmount / 1000);
+ strcat(public_buf_l, uiCfg.curSprayerChoose < 1 ? extrude_menu.ext1 : extrude_menu.ext2);
+ strcat(public_buf_l, buf1);
+
+ lv_label_set_text(ExtruText, public_buf_l);
+ lv_obj_align(ExtruText, nullptr, LV_ALIGN_CENTER, 0, -75);
+}
+
+void disp_ext_step() {
+ if (uiCfg.extruStep == 1)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step1_mm.bin");
+ else if (uiCfg.extruStep == 5)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step5_mm.bin");
+ else if (uiCfg.extruStep == 10)
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step10_mm.bin");
+
+ if (gCfgItems.multiple_language) {
+ if (uiCfg.extruStep == 1) {
+ lv_label_set_text(labelStep, extrude_menu.step_1mm);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.extruStep == 5) {
+ lv_label_set_text(labelStep, extrude_menu.step_5mm);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.extruStep == 10) {
+ lv_label_set_text(labelStep, extrude_menu.step_10mm);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void lv_clear_extrusion() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h
new file mode 100644
index 0000000..6178a8e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_extrusion.h
@@ -0,0 +1,38 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_extrusion(void);
+extern void lv_clear_extrusion();
+extern void disp_ext_type();
+extern void disp_ext_step();
+extern void disp_ext_speed();
+extern void disp_hotend_temp();
+extern void disp_extru_amount();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp
new file mode 100644
index 0000000..ae2f432
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.cpp
@@ -0,0 +1,117 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *fanText;
+
+enum {
+ ID_F_ADD = 1,
+ ID_F_DEC,
+ ID_F_HIGH,
+ ID_F_MID,
+ ID_F_OFF,
+ ID_F_RETURN
+};
+
+static uint8_t fanSpeed;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+
+ switch (obj->mks_obj_id) {
+ case ID_F_ADD:
+ if (fanSpeed < 254) fanSpeed++;
+ break;
+ case ID_F_DEC:
+ if (fanSpeed > 0) fanSpeed--;
+ break;
+ case ID_F_HIGH:
+ fanSpeed = 255;
+ break;
+ case ID_F_MID:
+ fanSpeed = 127;
+ break;
+ case ID_F_OFF:
+ gcode.process_subcommands_now_P(PSTR("M107"));
+ return;
+ case ID_F_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ return;
+ }
+ sprintf_P(public_buf_l, PSTR("M106 S%d"), fanSpeed);
+ gcode.process_subcommands_now(public_buf_l);
+}
+
+void lv_draw_fan(void) {
+ lv_obj_t *buttonAdd;
+
+ #if HAS_FAN
+ fanSpeed = thermalManager.fan_speed[0];
+ #endif
+
+ scr = lv_screen_create(FAN_UI);
+ // Create an Image button
+ buttonAdd = lv_big_button_create(scr, "F:/bmp_Add.bin", fan_menu.add, INTERVAL_V, titleHeight, event_handler, ID_F_ADD);
+ lv_obj_clear_protect(buttonAdd, LV_PROTECT_FOLLOW);
+ lv_big_button_create(scr, "F:/bmp_Dec.bin", fan_menu.dec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_F_DEC);
+ lv_big_button_create(scr, "F:/bmp_speed255.bin", fan_menu.full, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_F_HIGH);
+ lv_big_button_create(scr, "F:/bmp_speed127.bin", fan_menu.half, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_F_MID);
+ lv_big_button_create(scr, "F:/bmp_speed0.bin", fan_menu.off, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_F_OFF);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_F_RETURN);
+
+ fanText = lv_label_create_empty(scr);
+ lv_obj_set_style(fanText, &tft_style_label_rel);
+ disp_fan_value();
+}
+
+void disp_fan_value() {
+ char buf1[10] = {0};
+ public_buf_l[0] = '\0';
+ strcat(public_buf_l, fan_menu.state);
+ strcat_P(public_buf_l, PSTR(": "));
+ sprintf_P(buf1, PSTR("%3d"), thermalManager.fan_speed[0]);
+ strcat(public_buf_l, buf1);
+ lv_label_set_text(fanText, public_buf_l);
+ lv_obj_align(fanText, nullptr, LV_ALIGN_CENTER, 0, -65);
+}
+
+void lv_clear_fan() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h
new file mode 100644
index 0000000..5a3323e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_fan.h
@@ -0,0 +1,34 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_fan(void);
+extern void lv_clear_fan();
+extern void disp_fan_value();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp
new file mode 100644
index 0000000..d5bdb3f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.cpp
@@ -0,0 +1,216 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../module/motion.h"
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *buttonType;
+static lv_obj_t *labelType;
+static lv_obj_t *tempText1;
+
+enum {
+ ID_FILAMNT_IN = 1,
+ ID_FILAMNT_OUT,
+ ID_FILAMNT_TYPE,
+ ID_FILAMNT_RETURN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_FILAMNT_IN:
+ uiCfg.filament_load_heat_flg = 1;
+ #if ENABLED(SINGLENOZZLE)
+ if ((abs(thermalManager.temp_hotend[0].target - thermalManager.temp_hotend[0].celsius) <= 1)
+ || (gCfgItems.filament_limit_temper <= thermalManager.temp_hotend[0].celsius)) {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED);
+ }
+ else {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOAD_HEAT);
+ if (thermalManager.temp_hotend[0].target < gCfgItems.filament_limit_temper) {
+ thermalManager.temp_hotend[0].target = gCfgItems.filament_limit_temper;
+ thermalManager.start_watching_hotend(0);
+ }
+ }
+ #else
+ if ((abs(thermalManager.temp_hotend[uiCfg.curSprayerChoose].target - thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius) <= 1)
+ || (gCfgItems.filament_limit_temper <= thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius)) {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_LOAD_COMPLETED);
+ }
+ else {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_LOAD_HEAT);
+ if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].target < gCfgItems.filament_limit_temper) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = gCfgItems.filament_limit_temper;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ }
+ }
+ #endif
+ break;
+ case ID_FILAMNT_OUT:
+ uiCfg.filament_unload_heat_flg=1;
+ #if ENABLED(SINGLENOZZLE)
+ if ((thermalManager.temp_hotend[0].target > 0)
+ && ((abs((int)((int)thermalManager.temp_hotend[0].target - thermalManager.temp_hotend[0].celsius)) <= 1)
+ || ((int)thermalManager.temp_hotend[0].celsius >= gCfgItems.filament_limit_temper))
+ ) {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED);
+ }
+ else {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOAD_HEAT);
+ if (thermalManager.temp_hotend[0].target < gCfgItems.filament_limit_temper) {
+ thermalManager.temp_hotend[0].target = gCfgItems.filament_limit_temper;
+ thermalManager.start_watching_hotend(0);
+ }
+ filament_sprayer_temp();
+ }
+ #else
+ if ((thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > 0)
+ && ((abs((int)((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target - thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius)) <= 1)
+ || ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius >= gCfgItems.filament_limit_temper))
+ ) {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_HEAT_UNLOAD_COMPLETED);
+ }
+ else {
+ lv_clear_filament_change();
+ lv_draw_dialog(DIALOG_TYPE_FILAMENT_UNLOAD_HEAT);
+ if (thermalManager.temp_hotend[uiCfg.curSprayerChoose].target < gCfgItems.filament_limit_temper) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = gCfgItems.filament_limit_temper;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ }
+ filament_sprayer_temp();
+ }
+ #endif
+ break;
+ case ID_FILAMNT_TYPE:
+ #if HAS_MULTI_EXTRUDER
+ uiCfg.curSprayerChoose = !uiCfg.curSprayerChoose;
+ #endif
+ disp_filament_type();
+ break;
+ case ID_FILAMNT_RETURN:
+ #if HAS_MULTI_EXTRUDER
+ if (uiCfg.print_state != IDLE && uiCfg.print_state != REPRINTED)
+ gcode.process_subcommands_now_P(uiCfg.curSprayerChoose_bak == 1 ? PSTR("T1") : PSTR("T0"));
+ #endif
+ feedrate_mm_s = (float)uiCfg.moveSpeed_bak;
+ if (uiCfg.print_state == PAUSED)
+ planner.set_e_position_mm((destination.e = current_position.e = uiCfg.current_e_position_bak));
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = uiCfg.desireSprayerTempBak;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+
+ //Reset filament flag
+ uiCfg.filament_heat_completed_load = 0;
+ uiCfg.filament_heat_completed_unload = 0;
+ uiCfg.filament_load_heat_flg = 0;
+ uiCfg.filament_unload_heat_flg = 0;
+ uiCfg.filament_loading_completed = 0;
+ uiCfg.filament_unloading_completed = 0;
+
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_filament_change(void) {
+ scr = lv_screen_create(FILAMENTCHANGE_UI);
+ // Create an Image button
+ lv_obj_t *buttonIn = lv_big_button_create(scr, "F:/bmp_in.bin", filament_menu.in, INTERVAL_V, titleHeight, event_handler, ID_FILAMNT_IN);
+ lv_obj_clear_protect(buttonIn, LV_PROTECT_FOLLOW);
+ lv_big_button_create(scr, "F:/bmp_out.bin", filament_menu.out, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_FILAMNT_OUT);
+
+ buttonType = lv_imgbtn_create(scr, nullptr, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_FILAMNT_TYPE);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonType);
+ }
+ #endif
+
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_FILAMNT_RETURN);
+
+ // Create labels on the image buttons
+ labelType = lv_label_create_empty(buttonType);
+
+ disp_filament_type();
+
+ tempText1 = lv_label_create_empty(scr);
+ lv_obj_set_style(tempText1, &tft_style_label_rel);
+ disp_filament_temp();
+}
+
+void disp_filament_type() {
+ if (uiCfg.curSprayerChoose == 1) {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru2.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.ext2);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+ else {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru1.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.ext1);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_filament_temp() {
+ char buf[20] = {0};
+
+ public_buf_l[0] = '\0';
+
+ strcat(public_buf_l, uiCfg.curSprayerChoose < 1 ? preheat_menu.ext1 : preheat_menu.ext2);
+ sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target);
+
+ strcat_P(public_buf_l, PSTR(": "));
+ strcat(public_buf_l, buf);
+ lv_label_set_text(tempText1, public_buf_l);
+ lv_obj_align(tempText1, nullptr, LV_ALIGN_CENTER, 0, -50);
+}
+
+void lv_clear_filament_change() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h
new file mode 100644
index 0000000..18efe58
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_change.h
@@ -0,0 +1,35 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_filament_change(void);
+extern void lv_clear_filament_change();
+extern void disp_filament_type();
+extern void disp_filament_temp();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp
new file mode 100644
index 0000000..ab87fed
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.cpp
@@ -0,0 +1,126 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_FILAMENT_SET_RETURN = 1,
+ ID_FILAMENT_SET_IN_LENGTH,
+ ID_FILAMENT_SET_IN_SPEED,
+ ID_FILAMENT_SET_OUT_LENGTH,
+ ID_FILAMENT_SET_OUT_SPEED,
+ ID_FILAMENT_SET_TEMP,
+ ID_FILAMENT_SET_DOWN,
+ ID_FILAMENT_SET_UP
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_FILAMENT_SET_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_clear_filament_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_FILAMENT_SET_IN_LENGTH:
+ value = load_length;
+ lv_clear_filament_settings();
+ lv_draw_number_key();
+ break;
+ case ID_FILAMENT_SET_IN_SPEED:
+ value = load_speed;
+ lv_clear_filament_settings();
+ lv_draw_number_key();
+ break;
+ case ID_FILAMENT_SET_OUT_LENGTH:
+ value = unload_length;
+ lv_clear_filament_settings();
+ lv_draw_number_key();
+ break;
+ case ID_FILAMENT_SET_OUT_SPEED:
+ value = unload_speed;
+ lv_clear_filament_settings();
+ lv_draw_number_key();
+ break;
+ case ID_FILAMENT_SET_TEMP:
+ value = filament_temp;
+ lv_clear_filament_settings();
+ lv_draw_number_key();
+ break;
+ case ID_FILAMENT_SET_UP:
+ uiCfg.para_ui_page = 0;
+ lv_clear_filament_settings();
+ lv_draw_filament_settings();
+ break;
+ case ID_FILAMENT_SET_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_clear_filament_settings();
+ lv_draw_filament_settings();
+ break;
+ }
+}
+
+void lv_draw_filament_settings(void) {
+ scr = lv_screen_create(FILAMENT_SETTINGS_UI, machine_menu.FilamentConfTitle);
+
+ if (uiCfg.para_ui_page != 1) {
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_length);
+ lv_screen_menu_item_1_edit(scr, machine_menu.InLength, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FILAMENT_SET_IN_LENGTH, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_load_speed);
+ lv_screen_menu_item_1_edit(scr, machine_menu.InSpeed, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_FILAMENT_SET_IN_SPEED, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_length);
+ lv_screen_menu_item_1_edit(scr, machine_menu.OutLength, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_FILAMENT_SET_OUT_LENGTH, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filamentchange_unload_speed);
+ lv_screen_menu_item_1_edit(scr, machine_menu.OutSpeed, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_FILAMENT_SET_OUT_SPEED, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_FILAMENT_SET_DOWN);
+ }
+ else {
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.filament_limit_temper);
+ lv_screen_menu_item_1_edit(scr, machine_menu.FilamentTemperature, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FILAMENT_SET_TEMP, 0, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_FILAMENT_SET_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_FILAMENT_SET_RETURN);
+}
+
+void lv_clear_filament_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h
new file mode 100644
index 0000000..a5ae542
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_filament_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_filament_settings(void);
+extern void lv_clear_filament_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp
new file mode 100644
index 0000000..1b0a07b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.cpp
@@ -0,0 +1,93 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ready_print.h"
+#include "draw_set.h"
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/queue.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_H_ALL = 1,
+ ID_H_X,
+ ID_H_Y,
+ ID_H_Z,
+ ID_H_RETURN,
+ ID_H_OFF_ALL,
+ ID_H_OFF_XY
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_H_ALL:
+ queue.inject_P(PSTR("G28"));
+ break;
+ case ID_H_X:
+ queue.inject_P(PSTR("G28 X0"));
+ break;
+ case ID_H_Y:
+ queue.inject_P(PSTR("G28 Y0"));
+ break;
+ case ID_H_Z:
+ queue.inject_P(PSTR("G28 Z0"));
+ break;
+ case ID_H_OFF_ALL:
+ queue.inject_P(PSTR("M84"));
+ break;
+ case ID_H_OFF_XY:
+ queue.inject_P(PSTR("M84 X Y"));
+ break;
+ case ID_H_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_home(void) {
+ scr = lv_screen_create(ZERO_UI);
+ lv_big_button_create(scr, "F:/bmp_zeroAll.bin", home_menu.home_all, INTERVAL_V, titleHeight, event_handler, ID_H_ALL);
+ lv_big_button_create(scr, "F:/bmp_zeroX.bin", home_menu.home_x, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_H_X);
+ lv_big_button_create(scr, "F:/bmp_zeroY.bin", home_menu.home_y, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_H_Y);
+ lv_big_button_create(scr, "F:/bmp_zeroZ.bin", home_menu.home_z, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_H_Z);
+ lv_big_button_create(scr, "F:/bmp_function1.bin", set_menu.motoroff, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_H_OFF_ALL);
+ lv_big_button_create(scr, "F:/bmp_function1.bin", set_menu.motoroffXY, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_H_OFF_XY);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_H_RETURN);
+}
+
+void lv_clear_home() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h
new file mode 100644
index 0000000..a8f11d9
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_home.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_home(void);
+extern void lv_clear_home();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp
new file mode 100644
index 0000000..71a0657
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.cpp
@@ -0,0 +1,104 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfig.h"
+
+#if HAS_TFT_LVGL_UI && USE_SENSORLESS
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../module/probe.h"
+#include "../../../../module/stepper/indirection.h"
+#include "../../../../feature/tmc_util.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_SENSITIVITY_RETURN = 1,
+ ID_SENSITIVITY_X,
+ ID_SENSITIVITY_Y,
+ ID_SENSITIVITY_Z,
+ ID_SENSITIVITY_Z2
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_SENSITIVITY_RETURN:
+ lv_clear_homing_sensitivity_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_SENSITIVITY_X:
+ value = x_sensitivity;
+ lv_clear_homing_sensitivity_settings();
+ lv_draw_number_key();
+ break;
+ case ID_SENSITIVITY_Y:
+ value = y_sensitivity;
+ lv_clear_homing_sensitivity_settings();
+ lv_draw_number_key();
+ break;
+ case ID_SENSITIVITY_Z:
+ value = z_sensitivity;
+ lv_clear_homing_sensitivity_settings();
+ lv_draw_number_key();
+ break;
+ #if Z2_SENSORLESS
+ case ID_SENSITIVITY_Z2:
+ value = z2_sensitivity;
+ lv_clear_homing_sensitivity_settings();
+ lv_draw_number_key();
+ break;
+ #endif
+ }
+}
+
+void lv_draw_homing_sensitivity_settings(void) {
+ scr = lv_screen_create(HOMING_SENSITIVITY_UI, machine_menu.HomingSensitivityConfTitle);
+
+ sprintf_P(public_buf_l, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.X_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_SENSITIVITY_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Y_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_SENSITIVITY_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_SENSITIVITY_Z, 2, public_buf_l);
+
+ #if Z2_SENSORLESS
+ sprintf_P(public_buf_l, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z2_Sensitivity, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_SENSITIVITY_Z2, 3, public_buf_l);
+ #endif
+
+ lv_screen_menu_item_return(scr, event_handler, ID_SENSITIVITY_RETURN);
+}
+
+void lv_clear_homing_sensitivity_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && USE_SENSORLESS
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h
new file mode 100644
index 0000000..0c55470
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_homing_sensitivity_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_homing_sensitivity_settings(void);
+extern void lv_clear_homing_sensitivity_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp
new file mode 100644
index 0000000..38db624
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.cpp
@@ -0,0 +1,99 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, HAS_CLASSIC_JERK)
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_JERK_RETURN = 1,
+ ID_JERK_X,
+ ID_JERK_Y,
+ ID_JERK_Z,
+ ID_JERK_E
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_JERK_RETURN:
+ lv_clear_jerk_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_JERK_X:
+ value = XJerk;
+ lv_clear_jerk_settings();
+ lv_draw_number_key();
+ break;
+ case ID_JERK_Y:
+ value = YJerk;
+ lv_clear_jerk_settings();
+ lv_draw_number_key();
+ break;
+ case ID_JERK_Z:
+ value = ZJerk;
+ lv_clear_jerk_settings();
+ lv_draw_number_key();
+ break;
+ case ID_JERK_E:
+ value = EJerk;
+ lv_clear_jerk_settings();
+ lv_draw_number_key();
+ break;
+ }
+}
+
+void lv_draw_jerk_settings(void) {
+ char str_1[16];
+ scr = lv_screen_create(JERK_UI, machine_menu.JerkConfTitle);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[X_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.X_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_JERK_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[Y_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Y_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_JERK_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[Z_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_JERK_Z, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.max_jerk[E_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E_Jerk, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_JERK_E, 3, public_buf_l);
+
+ lv_screen_menu_item_return(scr, event_handler, ID_JERK_RETURN);
+}
+
+void lv_clear_jerk_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && HAS_CLASSIC_JERK
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h
new file mode 100644
index 0000000..0531dae
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_jerk_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_jerk_settings(void);
+extern void lv_clear_jerk_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp
new file mode 100644
index 0000000..08615dc
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.cpp
@@ -0,0 +1,289 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+#define LV_KB_CTRL_BTN_FLAGS (LV_BTNM_CTRL_NO_REPEAT | LV_BTNM_CTRL_CLICK_TRIG)
+
+#ifdef FRENCH_KEYBOARD
+static const char * kb_map_lc[] = {"1#", "a", "z", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
+ "ABC", "q", "s", "d", "f", "g", "h", "j", "k", "l", "m", LV_SYMBOL_NEW_LINE, "\n",
+ "_", "-", "w", "x", "c", "v", "b", "n", ",", ";", ":", "!", "\n",
+ LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
+
+static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = {
+ LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
+ LV_KB_CTRL_BTN_FLAGS | 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
+
+static const char * kb_map_uc[] = {"1#", "A", "Z", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
+ "abc", "Q", "S", "D", "F", "G", "H", "J", "K", "L", "M", LV_SYMBOL_NEW_LINE, "\n",
+ "_", "-", "W", "X", "C", "V", "B", "N", "?", ".", "/", "^", "\n",
+ LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
+
+static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = {
+ LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
+ LV_KB_CTRL_BTN_FLAGS | 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
+
+#else
+static const char * kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
+ "ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n",
+ "_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
+ LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
+
+static const lv_btnm_ctrl_t kb_ctrl_lc_map[] = {
+ LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
+ LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
+
+static const char * kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
+ "abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n",
+ "_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", "^", "\n",
+ LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
+
+static const lv_btnm_ctrl_t kb_ctrl_uc_map[] = {
+ LV_KB_CTRL_BTN_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
+ LV_KB_CTRL_BTN_FLAGS | 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
+
+#endif
+
+static const char * kb_map_spec[] = {"0", "1", "2", "3", "4" ,"5", "6", "7", "8", "9", ".", LV_SYMBOL_BACKSPACE, "\n",
+ "abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
+ "\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
+ LV_SYMBOL_CLOSE, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""};
+
+static const lv_btnm_ctrl_t kb_ctrl_spec_map[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,
+ LV_KB_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ LV_KB_CTRL_BTN_FLAGS | 2, 2, 6, 2, LV_KB_CTRL_BTN_FLAGS | 2};
+
+static const lv_btnm_ctrl_t kb_ctrl_num_map[] = {
+ 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,
+ 1, 1, 1, LV_KB_CTRL_BTN_FLAGS | 2,
+ 1, 1, 1, 2,
+ 1, 1, 1, 1, 1};
+
+static void lv_kb_event_cb(lv_obj_t *kb, lv_event_t event) {
+ if (event != LV_EVENT_VALUE_CHANGED) return;
+
+ lv_kb_ext_t * ext = (lv_kb_ext_t * )lv_obj_get_ext_attr(kb);
+ const uint16_t btn_id = lv_btnm_get_active_btn(kb);
+ if (btn_id == LV_BTNM_BTN_NONE) return;
+ if (lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_HIDDEN | LV_BTNM_CTRL_INACTIVE)) return;
+ if (lv_btnm_get_btn_ctrl(kb, btn_id, LV_BTNM_CTRL_NO_REPEAT) && event == LV_EVENT_LONG_PRESSED_REPEAT) return;
+
+ const char * txt = lv_btnm_get_active_btn_text(kb);
+ if (!txt) return;
+
+ // Do the corresponding action according to the text of the button
+ if (strcmp(txt, "abc") == 0) {
+ lv_btnm_set_map(kb, kb_map_lc);
+ lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map);
+ return;
+ }
+ else if (strcmp(txt, "ABC") == 0) {
+ lv_btnm_set_map(kb, kb_map_uc);
+ lv_btnm_set_ctrl_map(kb, kb_ctrl_uc_map);
+ return;
+ }
+ else if (strcmp(txt, "1#") == 0) {
+ lv_btnm_set_map(kb, kb_map_spec);
+ lv_btnm_set_ctrl_map(kb, kb_ctrl_spec_map);
+ return;
+ }
+ else if (strcmp(txt, LV_SYMBOL_CLOSE) == 0) {
+ if (kb->event_cb != lv_kb_def_event_cb) {
+ lv_clear_keyboard();
+ lv_draw_return_ui();
+ }
+ else {
+ lv_kb_set_ta(kb, nullptr); // De-assign the text area to hide it cursor if needed
+ lv_obj_del(kb);
+ return;
+ }
+ return;
+ }
+ else if (strcmp(txt, LV_SYMBOL_OK) == 0) {
+ if (kb->event_cb != lv_kb_def_event_cb) {
+ const char * ret_ta_txt = lv_ta_get_text(ext->ta);
+ switch (keyboard_value) {
+ #if ENABLED(MKS_WIFI_MODULE)
+ case wifiName:
+ memcpy(uiCfg.wifi_name,ret_ta_txt,sizeof(uiCfg.wifi_name));
+ lv_clear_keyboard();
+ lv_draw_return_ui();
+ break;
+ case wifiPassWord:
+ memcpy(uiCfg.wifi_key,ret_ta_txt,sizeof(uiCfg.wifi_name));
+ lv_clear_keyboard();
+ lv_draw_return_ui();
+ break;
+ case wifiConfig:
+ ZERO(uiCfg.wifi_name);
+ memcpy((void *)uiCfg.wifi_name, wifi_list.wifiName[wifi_list.nameIndex], 32);
+
+ ZERO(uiCfg.wifi_key);
+ memcpy((void *)uiCfg.wifi_key, ret_ta_txt, sizeof(uiCfg.wifi_key));
+
+ gCfgItems.wifi_mode_sel = STA_MODEL;
+
+ package_to_wifi(WIFI_PARA_SET, (uint8_t *)0, 0);
+
+ public_buf_l[0] = 0xA5;
+ public_buf_l[1] = 0x09;
+ public_buf_l[2] = 0x01;
+ public_buf_l[3] = 0x00;
+ public_buf_l[4] = 0x01;
+ public_buf_l[5] = 0xFC;
+ public_buf_l[6] = 0x00;
+ raw_send_to_wifi((uint8_t*)public_buf_l, 6);
+
+ last_disp_state = KEY_BOARD_UI;
+ lv_clear_keyboard();
+ wifi_tips_type = TIPS_TYPE_JOINING;
+ lv_draw_wifi_tips();
+ break;
+ #endif // MKS_WIFI_MODULE
+ case gcodeCommand:
+ uint8_t buf[100];
+ strncpy((char *)buf,ret_ta_txt,sizeof(buf));
+ update_gcode_command(AUTO_LEVELING_COMMAND_ADDR,buf);
+ lv_clear_keyboard();
+ lv_draw_return_ui();
+ break;
+ default: break;
+ }
+ }
+ else
+ lv_kb_set_ta(kb, nullptr); // De-assign the text area to hide it cursor if needed
+ return;
+ }
+
+ // Add the characters to the text area if set
+ if (!ext->ta) return;
+
+ if (strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0)
+ lv_ta_add_char(ext->ta, '\n');
+ else if (strcmp(txt, LV_SYMBOL_LEFT) == 0)
+ lv_ta_cursor_left(ext->ta);
+ else if (strcmp(txt, LV_SYMBOL_RIGHT) == 0)
+ lv_ta_cursor_right(ext->ta);
+ else if (strcmp(txt, LV_SYMBOL_BACKSPACE) == 0)
+ lv_ta_del_char(ext->ta);
+ else if (strcmp(txt, "+/-") == 0) {
+ uint16_t cur = lv_ta_get_cursor_pos(ext->ta);
+ const char * ta_txt = lv_ta_get_text(ext->ta);
+ if (ta_txt[0] == '-') {
+ lv_ta_set_cursor_pos(ext->ta, 1);
+ lv_ta_del_char(ext->ta);
+ lv_ta_add_char(ext->ta, '+');
+ lv_ta_set_cursor_pos(ext->ta, cur);
+ }
+ else if (ta_txt[0] == '+') {
+ lv_ta_set_cursor_pos(ext->ta, 1);
+ lv_ta_del_char(ext->ta);
+ lv_ta_add_char(ext->ta, '-');
+ lv_ta_set_cursor_pos(ext->ta, cur);
+ }
+ else {
+ lv_ta_set_cursor_pos(ext->ta, 0);
+ lv_ta_add_char(ext->ta, '-');
+ lv_ta_set_cursor_pos(ext->ta, cur + 1);
+ }
+ }
+ else {
+ lv_ta_add_text(ext->ta, txt);
+ }
+}
+
+void lv_draw_keyboard() {
+ scr = lv_screen_create(KEY_BOARD_UI, "");
+
+ // Create styles for the keyboard
+ static lv_style_t rel_style, pr_style;
+
+ lv_style_copy(&rel_style, &lv_style_btn_rel);
+ rel_style.body.radius = 0;
+ rel_style.body.border.width = 1;
+ rel_style.body.main_color = lv_color_make(0xA9, 0x62, 0x1D);
+ rel_style.body.grad_color = lv_color_make(0xA7, 0x59, 0x0E);
+
+ lv_style_copy(&pr_style, &lv_style_btn_pr);
+ pr_style.body.radius = 0;
+ pr_style.body.border.width = 1;
+ pr_style.body.main_color = lv_color_make(0x72, 0x42, 0x15);
+ pr_style.body.grad_color = lv_color_make(0x6A, 0x3A, 0x0C);
+
+ // Create a keyboard and apply the styles
+ lv_obj_t *kb = lv_kb_create(scr, nullptr);
+ lv_btnm_set_map(kb, kb_map_lc);
+ lv_btnm_set_ctrl_map(kb, kb_ctrl_lc_map);
+ lv_obj_set_base_dir(kb, LV_BIDI_DIR_LTR);
+
+ lv_obj_set_event_cb(kb, lv_kb_event_cb);
+ lv_kb_set_cursor_manage(kb, true);
+ lv_kb_set_style(kb, LV_KB_STYLE_BG, &lv_style_transp_tight);
+ lv_kb_set_style(kb, LV_KB_STYLE_BTN_REL, &rel_style);
+ lv_kb_set_style(kb, LV_KB_STYLE_BTN_PR, &pr_style);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ }
+ #endif
+
+ // Create a text area. The keyboard will write here
+ lv_obj_t *ta = lv_ta_create(scr, nullptr);
+ lv_obj_align(ta, nullptr, LV_ALIGN_IN_TOP_MID, 0, 10);
+ if (keyboard_value == gcodeCommand) {
+ get_gcode_command(AUTO_LEVELING_COMMAND_ADDR,(uint8_t *)public_buf_m);
+ public_buf_m[sizeof(public_buf_m)-1] = 0;
+ lv_ta_set_text(ta, public_buf_m);
+ }
+ else {
+ lv_ta_set_text(ta, "");
+ }
+
+ // Assign the text area to the keyboard
+ lv_kb_set_ta(kb, ta);
+}
+
+void lv_clear_keyboard() {
+ lv_obj_del(scr);
+}
+
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h
new file mode 100644
index 0000000..0013dc4
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_keyboard.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_keyboard();
+extern void lv_clear_keyboard();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp
new file mode 100644
index 0000000..7edb73b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.cpp
@@ -0,0 +1,208 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+#include <string.h>
+
+enum {
+ ID_CN = 1,
+ ID_T_CN,
+ ID_EN,
+ ID_RU,
+ ID_ES,
+ ID_FR,
+ ID_IT,
+ ID_L_RETURN
+};
+
+#define SELECTED 1
+#define UNSELECTED 0
+
+static void disp_language(uint8_t language, uint8_t state);
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *buttonCN, *buttonT_CN, *buttonEN, *buttonRU;
+static lv_obj_t *buttonES, *buttonFR, *buttonIT;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_CN:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonCN, "F:/bmp_simplified_cn_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonCN);
+ gCfgItems.language = LANG_SIMPLE_CHINESE;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_T_CN:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonT_CN, "F:/bmp_traditional_cn_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonT_CN);
+ gCfgItems.language = LANG_COMPLEX_CHINESE;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_EN:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonEN, "F:/bmp_english_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonEN);
+ gCfgItems.language = LANG_ENGLISH;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_RU:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonRU, "F:/bmp_russian_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonRU);
+ gCfgItems.language = LANG_RUSSIAN;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_ES:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonES, "F:/bmp_spanish_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonES);
+ gCfgItems.language = LANG_SPANISH;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_FR:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonFR, "F:/bmp_french_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonFR);
+ gCfgItems.language = LANG_FRENCH;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_IT:
+ disp_language(gCfgItems.language, UNSELECTED);
+ lv_imgbtn_set_src_both(buttonIT, "F:/bmp_italy_sel.bin");
+ lv_obj_refresh_ext_draw_pad(buttonIT);
+ gCfgItems.language = LANG_ITALY;
+ update_spi_flash();
+ disp_language_init();
+ break;
+ case ID_L_RETURN:
+ buttonCN = nullptr;
+ buttonT_CN = nullptr;
+ buttonEN = nullptr;
+ buttonRU = nullptr;
+ buttonES = nullptr;
+ buttonFR = nullptr;
+ buttonFR = nullptr;
+ buttonIT = nullptr;
+ lv_clear_language();
+ lv_draw_set();
+ break;
+ }
+}
+
+static void disp_language(uint8_t language, uint8_t state) {
+ uint16_t id;
+ lv_obj_t *obj;
+
+ public_buf_l[0] = '\0';
+
+ switch (language) {
+ case LANG_SIMPLE_CHINESE:
+ id = ID_CN;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_simplified_cn"));
+ obj = buttonCN;
+ break;
+ case LANG_COMPLEX_CHINESE:
+ id = ID_T_CN;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_traditional_cn"));
+ obj = buttonT_CN;
+ break;
+ case LANG_ENGLISH:
+ id = ID_EN;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_english"));
+ obj = buttonEN;
+ break;
+ case LANG_RUSSIAN:
+ id = ID_RU;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_russian"));
+ obj = buttonRU;
+ break;
+ case LANG_SPANISH:
+ id = ID_ES;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_spanish"));
+ obj = buttonES;
+ break;
+ case LANG_FRENCH:
+ id = ID_FR;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_french"));
+ obj = buttonFR;
+ break;
+ case LANG_ITALY:
+ id = ID_IT;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_italy"));
+ obj = buttonIT;
+ break;
+ default:
+ id = ID_CN;
+ strcpy_P(public_buf_l, PSTR("F:/bmp_simplified_cn"));
+ obj = buttonCN;
+ break;
+ }
+
+ if (state == SELECTED) strcat_P(public_buf_l, PSTR("_sel"));
+
+ strcat_P(public_buf_l, PSTR(".bin"));
+
+ lv_obj_set_event_cb_mks(obj, event_handler, id, "", 0);
+ lv_imgbtn_set_src_both(obj, public_buf_l);
+
+ if (state == UNSELECTED) lv_obj_refresh_ext_draw_pad(obj);
+}
+
+void lv_draw_language(void) {
+ scr = lv_screen_create(LANGUAGE_UI);
+ // Create image buttons
+ buttonCN = lv_big_button_create(scr, "F:/bmp_simplified_cn.bin", language_menu.chinese_s, INTERVAL_V, titleHeight, event_handler, ID_CN);
+ lv_obj_clear_protect(buttonCN, LV_PROTECT_FOLLOW);
+ buttonT_CN = lv_big_button_create(scr, "F:/bmp_traditional_cn.bin", language_menu.chinese_t, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_T_CN);
+ buttonEN = lv_big_button_create(scr, "F:/bmp_english.bin", language_menu.english, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_EN);
+ buttonRU = lv_big_button_create(scr, "F:/bmp_russian.bin", language_menu.russian, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_RU);
+ buttonES = lv_big_button_create(scr, "F:/bmp_spanish.bin", language_menu.spanish, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_ES);
+ buttonFR = lv_big_button_create(scr, "F:/bmp_french.bin", language_menu.french, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_FR);
+ buttonIT = lv_big_button_create(scr, "F:/bmp_italy.bin", language_menu.italy, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_IT);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_L_RETURN);
+ disp_language(gCfgItems.language, SELECTED);
+}
+
+void lv_clear_language() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h
new file mode 100644
index 0000000..d4ee14f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_language.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_language(void);
+extern void lv_clear_language();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp
new file mode 100644
index 0000000..c1f3c57
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.cpp
@@ -0,0 +1,104 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_LEVEL_RETURN = 1,
+ ID_LEVEL_POSITION,
+ ID_LEVEL_COMMAND,
+ ID_LEVEL_ZOFFSET,
+ ID_LEVEL_BLTOUCH,
+ ID_LEVEL_TOUCHMI
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_LEVEL_RETURN:
+ lv_clear_level_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_LEVEL_POSITION:
+ lv_clear_level_settings();
+ lv_draw_manual_level_pos_settings();
+ break;
+ case ID_LEVEL_COMMAND:
+ keyboard_value = gcodeCommand;
+ lv_clear_level_settings();
+ lv_draw_keyboard();
+ break;
+ #if HAS_BED_PROBE
+ case ID_LEVEL_ZOFFSET:
+ lv_clear_level_settings();
+ lv_draw_auto_level_offset_settings();
+ break;
+ #endif
+ #if ENABLED(BLTOUCH)
+ case ID_LEVEL_BLTOUCH:
+ lv_clear_level_settings();
+ bltouch_do_init();
+ lv_draw_bltouch_settings();
+ break;
+ #endif
+ #if ENABLED(TOUCH_MI_PROBE)
+ case ID_LEVEL_TOUCHMI:
+ lv_clear_level_settings();
+ lv_draw_touchmi_settings();
+ break;
+ #endif
+ }
+}
+
+void lv_draw_level_settings(void) {
+
+ scr = lv_screen_create(LEVELING_PARA_UI, machine_menu.LevelingParaConfTitle);
+ lv_screen_menu_item(scr, machine_menu.LevelingManuPosConf, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_LEVEL_POSITION, 0);
+ lv_screen_menu_item(scr, machine_menu.LevelingAutoCommandConf, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_LEVEL_COMMAND, 1);
+ #if HAS_BED_PROBE
+ lv_screen_menu_item(scr, machine_menu.LevelingAutoZoffsetConf, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_LEVEL_ZOFFSET, 2);
+ #endif
+ #if ENABLED(BLTOUCH)
+ lv_screen_menu_item(scr, machine_menu.BLTouchLevelingConf, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_LEVEL_BLTOUCH, 3);
+ #endif
+ #if ENABLED(TOUCH_MI_PROBE)
+ lv_screen_menu_item(scr, machine_menu.LevelingTouchmiConf, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_LEVEL_TOUCHMI, 3);
+ #endif
+ lv_screen_menu_item_return(scr, event_handler, ID_LEVEL_RETURN);
+}
+
+void lv_clear_level_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h
new file mode 100644
index 0000000..cdca9c8
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_level_settings.h
@@ -0,0 +1,35 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_level_settings(void);
+extern void lv_draw_bltouch_settings(void);
+extern void lv_draw_touchmi_settings(void);
+extern void lv_clear_level_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp
new file mode 100644
index 0000000..ed98dca
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.cpp
@@ -0,0 +1,84 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_PARA_RETURN = 1,
+ ID_PARA_MACHINE,
+ ID_PARA_MOTOR,
+ ID_PARA_LEVEL,
+ ID_PARA_ADVANCE
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_PARA_RETURN:
+ lv_clear_machine_para();
+ lv_draw_return_ui();
+ break;
+ case ID_PARA_MACHINE:
+ lv_clear_machine_para();
+ lv_draw_machine_settings();
+ break;
+ case ID_PARA_MOTOR:
+ lv_clear_machine_para();
+ lv_draw_motor_settings();
+ break;
+ case ID_PARA_LEVEL:
+ lv_clear_machine_para();
+ lv_draw_level_settings();
+ break;
+ case ID_PARA_ADVANCE:
+ lv_clear_machine_para();
+ lv_draw_advance_settings();
+ break;
+ }
+}
+
+void lv_draw_machine_para(void) {
+ scr = lv_screen_create(MACHINE_PARA_UI);
+ lv_screen_menu_item(scr, MachinePara_menu.MachineSetting, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_PARA_MACHINE, 0);
+ lv_screen_menu_item(scr, MachinePara_menu.MotorSetting, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_PARA_MOTOR, 1);
+ lv_screen_menu_item(scr, MachinePara_menu.leveling, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_PARA_LEVEL, 2);
+ lv_screen_menu_item(scr, MachinePara_menu.AdvanceSetting, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_PARA_ADVANCE, 3);
+ lv_screen_menu_item_return(scr, event_handler, ID_PARA_RETURN);
+}
+
+void lv_clear_machine_para() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h
new file mode 100644
index 0000000..e830f75
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_para.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_machine_para(void);
+extern void lv_clear_machine_para();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp
new file mode 100644
index 0000000..7b7cc1e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.cpp
@@ -0,0 +1,82 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_MACHINE_RETURN = 1,
+ ID_MACHINE_ACCELERATION,
+ ID_MACHINE_FEEDRATE,
+ ID_MACHINE_JERK
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_MACHINE_RETURN:
+ lv_clear_machine_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_MACHINE_ACCELERATION:
+ lv_clear_machine_settings();
+ lv_draw_acceleration_settings();
+ break;
+ case ID_MACHINE_FEEDRATE:
+ lv_clear_machine_settings();
+ lv_draw_max_feedrate_settings();
+ break;
+ #if HAS_CLASSIC_JERK
+ case ID_MACHINE_JERK:
+ lv_clear_machine_settings();
+ lv_draw_jerk_settings();
+ break;
+ #endif
+ }
+}
+
+void lv_draw_machine_settings(void) {
+ scr = lv_screen_create(MACHINE_SETTINGS_UI, machine_menu.MachineConfigTitle);
+ lv_screen_menu_item(scr, machine_menu.AccelerationConf, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MACHINE_ACCELERATION, 0);
+ lv_screen_menu_item(scr, machine_menu.MaxFeedRateConf, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_MACHINE_FEEDRATE, 1);
+ #if HAS_CLASSIC_JERK
+ lv_screen_menu_item(scr, machine_menu.JerkConf, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_MACHINE_JERK, 2);
+ #endif
+ lv_screen_menu_item_return(scr, event_handler, ID_MACHINE_RETURN);
+}
+
+void lv_clear_machine_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h
new file mode 100644
index 0000000..38d02e7
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_machine_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_machine_settings(void);
+extern void lv_clear_machine_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp
new file mode 100644
index 0000000..338cb1f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.cpp
@@ -0,0 +1,135 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/queue.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_M_POINT1 = 1,
+ ID_M_POINT2,
+ ID_M_POINT3,
+ ID_M_POINT4,
+ ID_M_POINT5,
+ ID_MANUAL_RETURN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+
+ switch (obj->mks_obj_id) {
+ case ID_M_POINT1:
+ if (queue.length == 0) {
+ if (uiCfg.leveling_first_time) {
+ queue.enqueue_now_P(PSTR("G28"));
+ uiCfg.leveling_first_time = 0;
+ }
+ queue.enqueue_now_P(PSTR("G1 Z10"));
+ sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[0][0], (int)gCfgItems.levelingPos[0][1]);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G1 Z0"));
+ }
+ break;
+ case ID_M_POINT2:
+ if (queue.length == 0) {
+ if (uiCfg.leveling_first_time) {
+ queue.enqueue_now_P(PSTR("G28"));
+ uiCfg.leveling_first_time = 0;
+ }
+ queue.enqueue_now_P(PSTR("G1 Z10"));
+ sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[1][0], (int)gCfgItems.levelingPos[1][1]);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G1 Z0"));
+ }
+ break;
+ case ID_M_POINT3:
+ if (queue.length == 0) {
+ if (uiCfg.leveling_first_time) {
+ queue.enqueue_now_P(PSTR("G28"));
+ uiCfg.leveling_first_time = 0;
+ }
+ queue.enqueue_now_P(PSTR("G1 Z10"));
+ sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[2][0], (int)gCfgItems.levelingPos[2][1]);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G1 Z0"));
+ }
+
+ break;
+ case ID_M_POINT4:
+ if (queue.length == 0) {
+ if (uiCfg.leveling_first_time) {
+ queue.enqueue_now_P(PSTR("G28"));
+ uiCfg.leveling_first_time = 0;
+ }
+ queue.enqueue_now_P(PSTR("G1 Z10"));
+ sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[3][0], (int)gCfgItems.levelingPos[3][1]);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G1 Z0"));
+ }
+ break;
+ case ID_M_POINT5:
+ if (queue.length == 0) {
+ if (uiCfg.leveling_first_time) {
+ queue.enqueue_now_P(PSTR("G28"));
+ uiCfg.leveling_first_time = 0;
+ }
+ queue.enqueue_now_P(PSTR("G1 Z10"));
+ sprintf_P(public_buf_l, PSTR("G1 X%d Y%d"), (int)gCfgItems.levelingPos[4][0], (int)gCfgItems.levelingPos[4][1]);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G1 Z0"));
+ }
+ break;
+ case ID_MANUAL_RETURN:
+ lv_clear_manualLevel();
+ lv_draw_tool();
+ break;
+ }
+}
+
+void lv_draw_manualLevel(void) {
+ scr = lv_screen_create(LEVELING_UI);
+ // Create an Image button
+ lv_obj_t *buttonPoint1 = lv_big_button_create(scr, "F:/bmp_leveling1.bin", leveling_menu.position1, INTERVAL_V, titleHeight, event_handler, ID_M_POINT1);
+ lv_obj_clear_protect(buttonPoint1, LV_PROTECT_FOLLOW);
+ lv_big_button_create(scr, "F:/bmp_leveling2.bin", leveling_menu.position2, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_M_POINT2);
+ lv_big_button_create(scr, "F:/bmp_leveling3.bin", leveling_menu.position3, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_M_POINT3);
+ lv_big_button_create(scr, "F:/bmp_leveling4.bin", leveling_menu.position4, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_M_POINT4);
+ lv_big_button_create(scr, "F:/bmp_leveling5.bin", leveling_menu.position5, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_POINT5);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_MANUAL_RETURN);
+}
+
+void lv_clear_manualLevel() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h
new file mode 100644
index 0000000..60de0b4
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manuaLevel.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_manualLevel(void);
+extern void lv_clear_manualLevel();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp
new file mode 100644
index 0000000..60defc7
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.cpp
@@ -0,0 +1,146 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_MANUAL_POS_RETURN = 1,
+ ID_MANUAL_POS_X1,
+ ID_MANUAL_POS_Y1,
+ ID_MANUAL_POS_X2,
+ ID_MANUAL_POS_Y2,
+ ID_MANUAL_POS_X3,
+ ID_MANUAL_POS_Y3,
+ ID_MANUAL_POS_X4,
+ ID_MANUAL_POS_Y4,
+ ID_MANUAL_POS_X5,
+ ID_MANUAL_POS_Y5,
+ ID_MANUAL_POS_DOWN,
+ ID_MANUAL_POS_UP
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_MANUAL_POS_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_clear_manual_level_pos_settings();
+ lv_draw_return_ui();
+ return;
+ case ID_MANUAL_POS_X1:
+ value = level_pos_x1;
+ break;
+ case ID_MANUAL_POS_Y1:
+ value = level_pos_y1;
+ break;
+ case ID_MANUAL_POS_X2:
+ value = level_pos_x2;
+ break;
+ case ID_MANUAL_POS_Y2:
+ value = level_pos_y2;
+ break;
+ case ID_MANUAL_POS_X3:
+ value = level_pos_x3;
+ break;
+ case ID_MANUAL_POS_Y3:
+ value = level_pos_y3;
+ break;
+ case ID_MANUAL_POS_X4:
+ value = level_pos_x4;
+ break;
+ case ID_MANUAL_POS_Y4:
+ value = level_pos_y4;
+ break;
+ case ID_MANUAL_POS_X5:
+ value = level_pos_x5;
+ break;
+ case ID_MANUAL_POS_Y5:
+ value = level_pos_y5;
+ break;
+ case ID_MANUAL_POS_UP:
+ uiCfg.para_ui_page = 0;
+ lv_clear_manual_level_pos_settings();
+ lv_draw_manual_level_pos_settings();
+ return;
+ case ID_MANUAL_POS_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_clear_manual_level_pos_settings();
+ lv_draw_manual_level_pos_settings();
+ return;
+ }
+ lv_clear_manual_level_pos_settings();
+ lv_draw_number_key();
+}
+
+void lv_draw_manual_level_pos_settings(void) {
+ char buf2[50];
+
+ scr = lv_screen_create(MANUAL_LEVELING_POSIGION_UI, machine_menu.LevelingParaConfTitle);
+
+ if (uiCfg.para_ui_page != 1) {
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[0][0]);
+ sprintf_P(buf2, PSTR("%d"), gCfgItems.levelingPos[0][1]);
+ lv_screen_menu_item_2_edit(scr, leveling_menu.position1, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MANUAL_POS_Y1, 0, buf2, ID_MANUAL_POS_X1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[1][0]);
+ sprintf_P(buf2, PSTR("%d"), gCfgItems.levelingPos[1][1]);
+ lv_screen_menu_item_2_edit(scr, leveling_menu.position2, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_MANUAL_POS_Y2, 1, buf2, ID_MANUAL_POS_X2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[2][0]);
+ sprintf_P(buf2, PSTR("%d"), gCfgItems.levelingPos[2][1]);
+ lv_screen_menu_item_2_edit(scr, leveling_menu.position3, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_MANUAL_POS_Y3, 2, buf2, ID_MANUAL_POS_X3, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[3][0]);
+ sprintf_P(buf2, PSTR("%d"), gCfgItems.levelingPos[3][1]);
+ lv_screen_menu_item_2_edit(scr, leveling_menu.position4, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_MANUAL_POS_Y4, 3, buf2, ID_MANUAL_POS_X4, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_MANUAL_POS_DOWN);
+ }
+ else {
+ sprintf_P(public_buf_l, PSTR("%d"), gCfgItems.levelingPos[4][0]);
+ sprintf_P(buf2, PSTR("%d"), gCfgItems.levelingPos[4][1]);
+ lv_screen_menu_item_2_edit(scr, leveling_menu.position5, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MANUAL_POS_Y5, 0, buf2, ID_MANUAL_POS_X5, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_MANUAL_POS_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_MANUAL_POS_RETURN);
+}
+
+void lv_clear_manual_level_pos_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h
new file mode 100644
index 0000000..8e89ecf
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_manual_level_pos_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_manual_level_pos_settings(void);
+extern void lv_clear_manual_level_pos_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp
new file mode 100644
index 0000000..0877cf9
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.cpp
@@ -0,0 +1,119 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_FEED_RETURN = 1,
+ ID_FEED_X,
+ ID_FEED_Y,
+ ID_FEED_Z,
+ ID_FEED_E0,
+ ID_FEED_E1,
+ ID_FEED_DOWN,
+ ID_FEED_UP
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+
+ lv_clear_max_feedrate_settings();
+ switch (obj->mks_obj_id) {
+ case ID_FEED_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_draw_return_ui();
+ return;
+ case ID_FEED_X:
+ value = XMaxFeedRate;
+ break;
+ case ID_FEED_Y:
+ value = YMaxFeedRate;
+ break;
+ case ID_FEED_Z:
+ value = ZMaxFeedRate;
+ break;
+ case ID_FEED_E0:
+ value = E0MaxFeedRate;
+ break;
+ case ID_FEED_E1:
+ value = E1MaxFeedRate;
+ break;
+ case ID_FEED_UP:
+ uiCfg.para_ui_page = 0;
+ lv_draw_max_feedrate_settings();
+ return;
+ case ID_FEED_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_draw_max_feedrate_settings();
+ return;
+ }
+ lv_draw_number_key();
+
+}
+
+void lv_draw_max_feedrate_settings(void) {
+ char str_1[16];
+ scr = lv_screen_create(MAXFEEDRATE_UI, machine_menu.MaxFeedRateConfTitle);
+
+ if (uiCfg.para_ui_page != 1) {
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.XMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FEED_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.YMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_FEED_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.ZMaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_FEED_Z, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E0MaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_FEED_E0, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_FEED_DOWN);
+ }
+ else {
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E1MaxFeedRate, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_FEED_E1, 0, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_FEED_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_FEED_RETURN);
+}
+
+void lv_clear_max_feedrate_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h
new file mode 100644
index 0000000..78caca5
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_max_feedrate_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_max_feedrate_settings(void);
+extern void lv_clear_max_feedrate_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_more.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_more.cpp
new file mode 100644
index 0000000..dbc218b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_more.cpp
@@ -0,0 +1,119 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../../MarlinCore.h"
+#include "../../../../gcode/queue.h"
+
+#include "lv_conf.h"
+#include "draw_ui.h"
+
+extern lv_group_t * g;
+static lv_obj_t * scr;
+
+enum {
+ ID_CUSTOM_1 = 1,
+ ID_CUSTOM_2,
+ ID_CUSTOM_3,
+ ID_CUSTOM_4,
+ ID_CUSTOM_5,
+ ID_CUSTOM_6,
+ ID_CUSTOM_7,
+ ID_M_RETURN
+};
+
+static void event_handler(lv_obj_t * obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ #if ENABLED(USER_CMD_1_ENABLE)
+ case ID_CUSTOM_1: queue.inject_P(PSTR(USER_GCODE_1)); break;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ case ID_CUSTOM_2: queue.inject_P(PSTR(USER_GCODE_2)); break;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ case ID_CUSTOM_3: queue.inject_P(PSTR(USER_GCODE_3)); break;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ case ID_CUSTOM_4: queue.inject_P(PSTR(USER_GCODE_4)); break;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ case ID_CUSTOM_5: queue.inject_P(PSTR(USER_GCODE_5)); break;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ case ID_CUSTOM_6: queue.inject_P(PSTR(USER_GCODE_6)); break;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ case ID_CUSTOM_7: queue.inject_P(PSTR(USER_GCODE_7)); break;
+ #endif
+ case ID_M_RETURN:
+ lv_clear_more();
+ lv_draw_tool();
+ break;
+ }
+}
+
+void lv_draw_more(void) {
+ scr = lv_screen_create(MORE_UI);
+
+ #if ENABLED(USER_CMD_1_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom1.bin", more_menu.custom1, INTERVAL_V, titleHeight, event_handler, ID_CUSTOM_1);
+ #endif
+
+ #if ENABLED(USER_CMD_2_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom2.bin", more_menu.custom2, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_CUSTOM_2);
+ #endif
+
+ #if ENABLED(USER_CMD_3_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom3.bin", more_menu.custom3, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_CUSTOM_3);
+ #endif
+
+ #if ENABLED(USER_CMD_4_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom4.bin", more_menu.custom4, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_CUSTOM_4);
+ #endif
+
+ #if ENABLED(USER_CMD_5_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom5.bin", more_menu.custom5, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_CUSTOM_5);
+ #endif
+
+ #if ENABLED(USER_CMD_6_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom6.bin", more_menu.custom6, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_CUSTOM_6);
+ #endif
+
+ #if ENABLED(USER_CMD_7_ENABLE)
+ lv_big_button_create(scr, "F:/bmp_custom7.bin", more_menu.custom7, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_CUSTOM_7);
+ #endif
+
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_RETURN);
+
+}
+
+void lv_clear_more() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_more.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_more.h
new file mode 100644
index 0000000..9dfa705
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_more.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_more(void);
+extern void lv_clear_more();
+
+#ifdef __cplusplus
+} /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp
new file mode 100644
index 0000000..219ea5a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.cpp
@@ -0,0 +1,98 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_MOTOR_RETURN = 1,
+ ID_MOTOR_STEPS,
+ ID_MOTOR_TMC_CURRENT,
+ ID_MOTOR_STEP_MODE,
+ ID_HOME_SENSE
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_motor_settings();
+ switch (obj->mks_obj_id) {
+ case ID_MOTOR_RETURN:
+ lv_draw_return_ui();
+ break;
+ case ID_MOTOR_STEPS:
+ lv_draw_step_settings();
+ break;
+ #if USE_SENSORLESS
+ case ID_HOME_SENSE:
+ lv_draw_homing_sensitivity_settings();
+ break;
+ #endif
+
+ #if HAS_TRINAMIC_CONFIG
+ case ID_MOTOR_TMC_CURRENT:
+ lv_draw_tmc_current_settings();
+ break;
+ #if HAS_STEALTHCHOP
+ case ID_MOTOR_STEP_MODE:
+ lv_draw_tmc_step_mode_settings();
+ break;
+ #endif
+ #endif
+ }
+}
+
+void lv_draw_motor_settings(void) {
+ int index = 0;
+
+ scr = lv_screen_create(MOTOR_SETTINGS_UI, machine_menu.MotorConfTitle);
+ lv_screen_menu_item(scr, machine_menu.StepsConf, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_MOTOR_STEPS, index++);
+ #if USE_SENSORLESS
+ lv_screen_menu_item(scr, machine_menu.HomingSensitivityConf, PARA_UI_POS_X, PARA_UI_POS_Y * (index + 1), event_handler, ID_HOME_SENSE, index);
+ index++;
+ #endif
+ #if HAS_TRINAMIC_CONFIG
+ lv_screen_menu_item(scr, machine_menu.TMCcurrentConf, PARA_UI_POS_X, PARA_UI_POS_Y * (index + 1), event_handler, ID_MOTOR_TMC_CURRENT, index);
+ index++;
+ #if HAS_STEALTHCHOP
+ lv_screen_menu_item(scr, machine_menu.TMCStepModeConf, PARA_UI_POS_X, PARA_UI_POS_Y * (index + 1), event_handler, ID_MOTOR_STEP_MODE, index);
+ index++;
+ #endif
+ #endif
+ lv_screen_menu_item_return(scr, event_handler, ID_MOTOR_RETURN);
+}
+
+void lv_clear_motor_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h
new file mode 100644
index 0000000..9a1c7a4
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_motor_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_motor_settings(void);
+extern void lv_clear_motor_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp
new file mode 100644
index 0000000..2b76829
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.cpp
@@ -0,0 +1,211 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/queue.h"
+#include "../../../../module/motion.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+static lv_obj_t *labelV, *buttonV, *labelP;
+static lv_task_t *updatePosTask;
+static char cur_label = 'Z';
+static float cur_pos = 0;
+
+void disp_cur_pos();
+
+enum {
+ ID_M_X_P = 1,
+ ID_M_X_N,
+ ID_M_Y_P,
+ ID_M_Y_N,
+ ID_M_Z_P,
+ ID_M_Z_N,
+ ID_M_STEP,
+ ID_M_RETURN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ char str_1[16];
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_M_X_P:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_one_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 X%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_one_P(PSTR("G90"));
+ cur_label = 'X';
+ }
+ break;
+ case ID_M_X_N:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 X-%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ cur_label = 'X';
+ }
+ break;
+ case ID_M_Y_P:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Y%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ cur_label = 'Y';
+ }
+ break;
+ case ID_M_Y_N:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Y-%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ cur_label = 'Y';
+ }
+ break;
+ case ID_M_Z_P:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Z%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ cur_label = 'Z';
+ }
+ break;
+ case ID_M_Z_N:
+ if (queue.length <= (BUFSIZE - 3)) {
+ queue.enqueue_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Z-%s F%d"), dtostrf(uiCfg.move_dist, 1, 3, str_1), uiCfg.moveSpeed);
+ queue.enqueue_one_now(public_buf_l);
+ queue.enqueue_now_P(PSTR("G90"));
+ cur_label = 'Z';
+ }
+ break;
+ case ID_M_STEP:
+ if (abs(10 * (int)uiCfg.move_dist) == 100)
+ uiCfg.move_dist = 0.1;
+ else
+ uiCfg.move_dist *= (float)10;
+ disp_move_dist();
+ break;
+ case ID_M_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ return;
+ }
+ disp_cur_pos();
+}
+
+void refresh_pos(lv_task_t *)
+{
+ switch(cur_label) {
+ case 'X': cur_pos = current_position.x; break;
+ case 'Y': cur_pos = current_position.y; break;
+ case 'Z': cur_pos = current_position.z; break;
+ default: return;
+ }
+ disp_cur_pos();
+}
+void lv_draw_move_motor(void) {
+ scr = lv_screen_create(MOVE_MOTOR_UI);
+ lv_obj_t *buttonXI = lv_big_button_create(scr, "F:/bmp_xAdd.bin", move_menu.x_add, INTERVAL_V, titleHeight, event_handler, ID_M_X_P);
+ lv_obj_clear_protect(buttonXI, LV_PROTECT_FOLLOW);
+ lv_big_button_create(scr, "F:/bmp_xDec.bin", move_menu.x_dec, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_X_N);
+ lv_big_button_create(scr, "F:/bmp_yAdd.bin", move_menu.y_add, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_M_Y_P);
+ lv_big_button_create(scr, "F:/bmp_yDec.bin", move_menu.y_dec, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_Y_N);
+ lv_big_button_create(scr, "F:/bmp_zAdd.bin", move_menu.z_add, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_M_Z_P);
+ lv_big_button_create(scr, "F:/bmp_zDec.bin", move_menu.z_dec, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_Z_N);
+
+ // button with image and label changed dynamically by disp_move_dist
+ buttonV = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_M_STEP);
+ labelV = lv_label_create_empty(buttonV);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonV);
+ }
+ #endif
+
+
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_M_RETURN);
+
+ // We need to patch the title to leave some space on the right for displaying the status
+ lv_obj_t * title = lv_obj_get_child_back(scr, NULL);
+ if (title != NULL) lv_obj_set_width(title, TFT_WIDTH - 101);
+ labelP = lv_label_create(scr, TFT_WIDTH - 100, TITLE_YPOS, "Z:0.0mm");
+ if (labelP != NULL) {
+ updatePosTask = lv_task_create(refresh_pos, 300, LV_TASK_PRIO_LOWEST, 0);
+ }
+
+
+ disp_move_dist();
+ disp_cur_pos();
+}
+
+
+void disp_cur_pos() {
+ char str_1[16];
+ sprintf_P(public_buf_l, PSTR("%c:%s mm"), cur_label, dtostrf(cur_pos, 1, 1, str_1));
+ if (labelP) lv_label_set_text(labelP, public_buf_l);
+}
+
+void disp_move_dist() {
+ if ((int)(10 * uiCfg.move_dist) == 1)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move0_1.bin");
+ else if ((int)(10 * uiCfg.move_dist) == 10)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move1.bin");
+ else if ((int)(10 * uiCfg.move_dist) == 100)
+ lv_imgbtn_set_src_both(buttonV, "F:/bmp_step_move10.bin");
+
+ if (gCfgItems.multiple_language) {
+ if ((int)(10 * uiCfg.move_dist) == 1) {
+ lv_label_set_text(labelV, move_menu.step_01mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(10 * uiCfg.move_dist) == 10) {
+ lv_label_set_text(labelV, move_menu.step_1mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if ((int)(10 * uiCfg.move_dist) == 100) {
+ lv_label_set_text(labelV, move_menu.step_10mm);
+ lv_obj_align(labelV, buttonV, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void lv_clear_move_motor() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_task_del(updatePosTask);
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h
new file mode 100644
index 0000000..4e41c5f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_move_motor.h
@@ -0,0 +1,34 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_move_motor(void);
+extern void lv_clear_move_motor();
+extern void disp_move_dist();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp
new file mode 100644
index 0000000..9cacf2f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.cpp
@@ -0,0 +1,772 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/gcode.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../module/planner.h"
+#include "../../../../module/temperature.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+#if HAS_TRINAMIC_CONFIG
+ #include "../../../../module/stepper/indirection.h"
+ #include "../../../../feature/tmc_util.h"
+#endif
+
+#if HAS_BED_PROBE
+ #include "../../../../module/probe.h"
+#endif
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *buttonValue = nullptr;
+static lv_obj_t *labelValue = nullptr;
+
+static char key_value[11] = { 0 };
+static uint8_t cnt = 0;
+static bool point_flag = true;
+
+enum {
+ ID_NUM_KEY1 = 1,
+ ID_NUM_KEY2,
+ ID_NUM_KEY3,
+ ID_NUM_KEY4,
+ ID_NUM_KEY5,
+ ID_NUM_KEY6,
+ ID_NUM_KEY7,
+ ID_NUM_KEY8,
+ ID_NUM_KEY9,
+ ID_NUM_KEY0,
+ ID_NUM_BACK,
+ ID_NUM_RESET,
+ ID_NUM_CONFIRM,
+ ID_NUM_POINT,
+ ID_NUM_NEGATIVE
+};
+
+static void disp_key_value() {
+ char *temp;
+ char str_1[16];
+ #if HAS_TRINAMIC_CONFIG
+ float milliamps;
+ #endif
+
+ switch (value) {
+ case PrintAcceleration:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.acceleration, 1, 1, str_1));
+ break;
+ case RetractAcceleration:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.retract_acceleration, 1, 1, str_1));
+ break;
+ case TravelAcceleration:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.travel_acceleration, 1, 1, str_1));
+ break;
+ case XAcceleration:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[X_AXIS]);
+ break;
+ case YAcceleration:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Y_AXIS]);
+ break;
+ case ZAcceleration:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[Z_AXIS]);
+ break;
+ case E0Acceleration:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS]);
+ break;
+ case E1Acceleration:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)]);
+ break;
+ case XMaxFeedRate:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[X_AXIS], 1, 1, str_1));
+ break;
+ case YMaxFeedRate:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Y_AXIS], 1, 1, str_1));
+ break;
+ case ZMaxFeedRate:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[Z_AXIS], 1, 1, str_1));
+ break;
+ case E0MaxFeedRate:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS], 1, 1, str_1));
+ break;
+ case E1MaxFeedRate:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], 1, 1, str_1));
+ break;
+
+ case XJerk:
+ #if HAS_CLASSIC_JERK
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[X_AXIS], 1, 1, str_1));
+ #endif
+ break;
+ case YJerk:
+ #if HAS_CLASSIC_JERK
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[Y_AXIS], 1, 1, str_1));
+ #endif
+ break;
+ case ZJerk:
+ #if HAS_CLASSIC_JERK
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[Z_AXIS], 1, 1, str_1));
+ #endif
+ break;
+ case EJerk:
+ #if HAS_CLASSIC_JERK
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.max_jerk[E_AXIS], 1, 1, str_1));
+ #endif
+ break;
+
+ case Xstep:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, str_1));
+ break;
+ case Ystep:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, str_1));
+
+ break;
+ case Zstep:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, str_1));
+
+ break;
+ case E0step:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, str_1));
+
+ break;
+ case E1step:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, str_1));
+ break;
+
+ case Xcurrent:
+ #if AXIS_IS_TMC(X)
+ milliamps = stepperX.getMilliamps();
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ #endif
+ break;
+
+ case Ycurrent:
+ #if AXIS_IS_TMC(Y)
+ milliamps = stepperY.getMilliamps();
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ #endif
+ break;
+
+ case Zcurrent:
+ #if AXIS_IS_TMC(Z)
+ milliamps = stepperZ.getMilliamps();
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ #endif
+ break;
+
+ case E0current:
+ #if AXIS_IS_TMC(E0)
+ milliamps = stepperE0.getMilliamps();
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ #endif
+ break;
+
+ case E1current:
+ #if AXIS_IS_TMC(E1)
+ milliamps = stepperE1.getMilliamps();
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ #endif
+ break;
+
+ case pause_pos_x:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosX, 1, 1, str_1));
+ break;
+ case pause_pos_y:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosY, 1, 1, str_1));
+ break;
+ case pause_pos_z:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(gCfgItems.pausePosZ, 1, 1, str_1));
+ break;
+ case level_pos_x1:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[0][0]);
+ break;
+ case level_pos_y1:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[0][1]);
+ break;
+ case level_pos_x2:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[1][0]);
+ break;
+ case level_pos_y2:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[1][1]);
+ break;
+ case level_pos_x3:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[2][0]);
+ break;
+ case level_pos_y3:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[2][1]);
+ break;
+ case level_pos_x4:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[3][0]);
+ break;
+ case level_pos_y4:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[3][1]);
+ break;
+ case level_pos_x5:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[4][0]);
+ break;
+ case level_pos_y5:
+ sprintf_P(public_buf_m, PSTR("%d"), (int)gCfgItems.levelingPos[4][1]);
+ break;
+ #if HAS_BED_PROBE
+ case x_offset:
+ #if HAS_PROBE_XY_OFFSET
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.x, 1, 3, str_1));
+ #endif
+ break;
+ case y_offset:
+ #if HAS_PROBE_XY_OFFSET
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.y, 1, 3, str_1));
+ #endif
+ break;
+ case z_offset:
+ sprintf_P(public_buf_m, PSTR("%s"), dtostrf(probe.offset.z, 1, 3, str_1));
+ break;
+ #endif
+ case load_length:
+ sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_length);
+ break;
+ case load_speed:
+ sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_load_speed);
+ break;
+ case unload_length:
+ sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_length);
+ break;
+ case unload_speed:
+ sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filamentchange_unload_speed);
+ break;
+ case filament_temp:
+ sprintf_P(public_buf_m, PSTR("%d"), gCfgItems.filament_limit_temper);
+ break;
+ case x_sensitivity:
+ #if X_SENSORLESS
+ sprintf_P(public_buf_m, PSTR("%d"), TERN(X_SENSORLESS, stepperX.homing_threshold(), 0));
+ #endif
+ break;
+ case y_sensitivity:
+ #if Y_SENSORLESS
+ sprintf_P(public_buf_m, PSTR("%d"), TERN(Y_SENSORLESS, stepperY.homing_threshold(), 0));
+ #endif
+ break;
+ case z_sensitivity:
+ #if Z_SENSORLESS
+ sprintf_P(public_buf_m, PSTR("%d"), TERN(Z_SENSORLESS, stepperZ.homing_threshold(), 0));
+ #endif
+ break;
+ case z2_sensitivity:
+ #if Z2_SENSORLESS
+ sprintf_P(public_buf_m, PSTR("%d"), TERN(Z2_SENSORLESS, stepperZ2.homing_threshold(), 0));
+ #endif
+ break;
+ }
+
+ strcpy(key_value, public_buf_m);
+ cnt = strlen(key_value);
+ temp = strchr(key_value, '.');
+ point_flag = !temp;
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+
+}
+
+static void set_value_confirm() {
+ #if HAS_TRINAMIC_CONFIG
+ uint16_t current_mA;
+ #endif
+ switch (value) {
+ case PrintAcceleration:
+ planner.settings.acceleration = atof(key_value);
+ break;
+ case RetractAcceleration:
+ planner.settings.retract_acceleration = atof(key_value);
+ break;
+ case TravelAcceleration:
+ planner.settings.travel_acceleration = atof(key_value);
+ break;
+ case XAcceleration:
+ planner.settings.max_acceleration_mm_per_s2[X_AXIS] = atof(key_value);
+ break;
+ case YAcceleration:
+ planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = atof(key_value);
+ break;
+ case ZAcceleration:
+ planner.settings.max_acceleration_mm_per_s2[Z_AXIS] = atof(key_value);
+ break;
+ case E0Acceleration:
+ planner.settings.max_acceleration_mm_per_s2[E_AXIS] = atof(key_value);
+ break;
+ case E1Acceleration:
+ planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)] = atof(key_value);
+ break;
+ case XMaxFeedRate:
+ planner.settings.max_feedrate_mm_s[X_AXIS] = atof(key_value);
+ break;
+ case YMaxFeedRate:
+ planner.settings.max_feedrate_mm_s[Y_AXIS] = atof(key_value);
+ break;
+ case ZMaxFeedRate:
+ planner.settings.max_feedrate_mm_s[Z_AXIS] = atof(key_value);
+ break;
+ case E0MaxFeedRate:
+ planner.settings.max_feedrate_mm_s[E_AXIS] = atof(key_value);
+ break;
+ case E1MaxFeedRate:
+ planner.settings.max_feedrate_mm_s[E_AXIS_N(1)] = atof(key_value);
+ break;
+ case XJerk:
+ #if HAS_CLASSIC_JERK
+ planner.max_jerk[X_AXIS] = atof(key_value);
+ #endif
+ break;
+ case YJerk:
+ #if HAS_CLASSIC_JERK
+ planner.max_jerk[Y_AXIS] = atof(key_value);
+ #endif
+ break;
+ case ZJerk:
+ #if HAS_CLASSIC_JERK
+ planner.max_jerk[Z_AXIS] = atof(key_value);
+ #endif
+ break;
+ case EJerk:
+ #if HAS_CLASSIC_JERK
+ planner.max_jerk[E_AXIS] = atof(key_value);
+ #endif
+ break;
+ case Xstep:
+ planner.settings.axis_steps_per_mm[X_AXIS] = atof(key_value);
+ planner.refresh_positioning();
+ break;
+ case Ystep:
+ planner.settings.axis_steps_per_mm[Y_AXIS] = atof(key_value);
+ planner.refresh_positioning();
+ break;
+ case Zstep:
+ planner.settings.axis_steps_per_mm[Z_AXIS] = atof(key_value);
+ planner.refresh_positioning();
+ break;
+ case E0step:
+ planner.settings.axis_steps_per_mm[E_AXIS] = atof(key_value);
+ planner.refresh_positioning();
+ break;
+ case E1step:
+ planner.settings.axis_steps_per_mm[E_AXIS_N(1)] = atof(key_value);
+ planner.refresh_positioning();
+ break;
+ case Xcurrent:
+ #if AXIS_IS_TMC(X)
+ current_mA = atoi(key_value);
+ stepperX.rms_current(current_mA);
+ #endif
+ break;
+ case Ycurrent:
+ #if AXIS_IS_TMC(Y)
+ current_mA = atoi(key_value);
+ stepperY.rms_current(current_mA);
+ #endif
+ break;
+ case Zcurrent:
+ #if AXIS_IS_TMC(Z)
+ current_mA = atoi(key_value);
+ stepperZ.rms_current(current_mA);
+ #endif
+ break;
+ case E0current:
+ #if AXIS_IS_TMC(E0)
+ current_mA = atoi(key_value);
+ stepperE0.rms_current(current_mA);
+ #endif
+ break;
+ case E1current:
+ #if AXIS_IS_TMC(E1)
+ current_mA = atoi(key_value);
+ stepperE1.rms_current(current_mA);
+ #endif
+ break;
+ case pause_pos_x:
+ gCfgItems.pausePosX = atof(key_value);
+ update_spi_flash();
+ break;
+ case pause_pos_y:
+ gCfgItems.pausePosY = atof(key_value);
+ update_spi_flash();
+ break;
+ case pause_pos_z:
+ gCfgItems.pausePosZ = atof(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_x1:
+ gCfgItems.levelingPos[0][0] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_y1:
+ gCfgItems.levelingPos[0][1] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_x2:
+ gCfgItems.levelingPos[1][0] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_y2:
+ gCfgItems.levelingPos[1][1] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_x3:
+ gCfgItems.levelingPos[2][0] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_y3:
+ gCfgItems.levelingPos[2][1] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_x4:
+ gCfgItems.levelingPos[3][0] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_y4:
+ gCfgItems.levelingPos[3][1] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_x5:
+ gCfgItems.levelingPos[4][0] = atoi(key_value);
+ update_spi_flash();
+ break;
+ case level_pos_y5:
+ gCfgItems.levelingPos[4][1] = atoi(key_value);
+ update_spi_flash();
+ break;
+ #if HAS_BED_PROBE
+ case x_offset:
+ #if HAS_PROBE_XY_OFFSET
+ float x;
+ x = atof(key_value);
+ if (WITHIN(x, -(X_BED_SIZE), X_BED_SIZE))
+ probe.offset.x = x;
+ #endif
+ break;
+ case y_offset:
+ #if HAS_PROBE_XY_OFFSET
+ float y;
+ y = atof(key_value);
+ if (WITHIN(y, -(Y_BED_SIZE), Y_BED_SIZE))
+ probe.offset.y = y;
+ #endif
+ break;
+ case z_offset:
+ float z;
+ z = atof(key_value);
+ if (WITHIN(z, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX))
+ probe.offset.z = z;
+ break;
+ #endif
+ case load_length:
+ gCfgItems.filamentchange_load_length = atoi(key_value);
+ uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length*60.0/gCfgItems.filamentchange_load_speed)+0.5);
+ update_spi_flash();
+ break;
+ case load_speed:
+ gCfgItems.filamentchange_load_speed = atoi(key_value);
+ uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length*60.0/gCfgItems.filamentchange_load_speed)+0.5);
+ update_spi_flash();
+ break;
+ case unload_length:
+ gCfgItems.filamentchange_unload_length = atoi(key_value);
+ uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length*60.0/gCfgItems.filamentchange_unload_speed)+0.5);
+ update_spi_flash();
+ break;
+ case unload_speed:
+ gCfgItems.filamentchange_unload_speed = atoi(key_value);
+ uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length*60.0/gCfgItems.filamentchange_unload_speed)+0.5);
+ update_spi_flash();
+ break;
+ case filament_temp:
+ gCfgItems.filament_limit_temper = atoi(key_value);
+ update_spi_flash();
+ break;
+ case x_sensitivity:
+ #if X_SENSORLESS
+ stepperX.homing_threshold(atoi(key_value));
+ #endif
+ break;
+ case y_sensitivity:
+ #if Y_SENSORLESS
+ stepperY.homing_threshold(atoi(key_value));
+ #endif
+ break;
+ case z_sensitivity:
+ #if Z_SENSORLESS
+ stepperZ.homing_threshold(atoi(key_value));
+ #endif
+ break;
+ case z2_sensitivity:
+ #if Z2_SENSORLESS
+ stepperZ2.homing_threshold(atoi(key_value));
+ #endif
+ break;
+ }
+ watchdog_refresh();
+ gcode.process_subcommands_now_P(PSTR("M500"));
+}
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_NUM_KEY1:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'1';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY2:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'2';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY3:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'3';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY4:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'4';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY5:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'5';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY6:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'6';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY7:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'7';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY8:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'8';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY9:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'9';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_KEY0:
+ if (cnt <= 10) {
+ key_value[cnt] = (char)'0';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_BACK:
+ if (cnt > 0) cnt--;
+ if (key_value[cnt] == (char)'.') point_flag = true;
+ key_value[cnt] = (char)'\0';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ break;
+ case ID_NUM_RESET:
+ ZERO(key_value);
+ cnt = 0;
+ key_value[cnt] = (char)'0';
+ point_flag = true;
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ break;
+ case ID_NUM_POINT:
+ if (cnt != 0 && point_flag) {
+ point_flag = false;
+ key_value[cnt] = (char)'.';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_NEGATIVE:
+ if (cnt == 0) {
+ key_value[cnt] = (char)'-';
+ lv_label_set_text(labelValue, key_value);
+ lv_obj_align(labelValue, buttonValue, LV_ALIGN_CENTER, 0, 0);
+ cnt++;
+ }
+ break;
+ case ID_NUM_CONFIRM:
+ last_disp_state = NUMBER_KEY_UI;
+ if (strlen(key_value) != 0) set_value_confirm();
+ lv_clear_number_key();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_number_key(void) {
+ scr = lv_screen_create(NUMBER_KEY_UI, "");
+
+ buttonValue = lv_btn_create(scr, 92, 40, 296, 40, event_handler, 0, &style_num_text);
+ labelValue = lv_label_create_empty(buttonValue);
+
+ lv_obj_t *NumberKey_1 = lv_btn_create(scr, 92, 90, 68, 40, event_handler, ID_NUM_KEY1, &style_num_key_pre);
+ lv_obj_t *labelKey_1 = lv_label_create_empty(NumberKey_1);
+ lv_label_set_text(labelKey_1, machine_menu.key_1);
+ lv_obj_align(labelKey_1, NumberKey_1, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_2 = lv_btn_create(scr, 168, 90, 68, 40, event_handler, ID_NUM_KEY2, &style_num_key_pre);
+ lv_obj_t *labelKey_2 = lv_label_create_empty(NumberKey_2);
+ lv_label_set_text(labelKey_2, machine_menu.key_2);
+ lv_obj_align(labelKey_2, NumberKey_2, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_3 = lv_btn_create(scr, 244, 90, 68, 40, event_handler, ID_NUM_KEY3, &style_num_key_pre);
+ lv_obj_t *labelKey_3 = lv_label_create_empty(NumberKey_3);
+ lv_label_set_text(labelKey_3, machine_menu.key_3);
+ lv_obj_align(labelKey_3, NumberKey_3, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_4 = lv_btn_create(scr, 92, 140, 68, 40, event_handler, ID_NUM_KEY4, &style_num_key_pre);
+ lv_obj_t *labelKey_4 = lv_label_create_empty(NumberKey_4);
+ lv_label_set_text(labelKey_4, machine_menu.key_4);
+ lv_obj_align(labelKey_4, NumberKey_4, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_5 = lv_btn_create(scr, 168, 140, 68, 40, event_handler, ID_NUM_KEY5, &style_num_key_pre);
+ lv_obj_t *labelKey_5 = lv_label_create_empty(NumberKey_5);
+ lv_label_set_text(labelKey_5, machine_menu.key_5);
+ lv_obj_align(labelKey_5, NumberKey_5, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_6 = lv_btn_create(scr, 244, 140, 68, 40, event_handler, ID_NUM_KEY6, &style_num_key_pre);
+ lv_obj_t *labelKey_6 = lv_label_create_empty(NumberKey_6);
+ lv_label_set_text(labelKey_6, machine_menu.key_6);
+ lv_obj_align(labelKey_6, NumberKey_6, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_7 = lv_btn_create(scr, 92, 190, 68, 40, event_handler, ID_NUM_KEY7, &style_num_key_pre);
+ lv_obj_t *labelKey_7 = lv_label_create_empty(NumberKey_7);
+ lv_label_set_text(labelKey_7, machine_menu.key_7);
+ lv_obj_align(labelKey_7, NumberKey_7, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_8 = lv_btn_create(scr, 168, 190, 68, 40, event_handler, ID_NUM_KEY8, &style_num_key_pre);
+ lv_obj_t *labelKey_8 = lv_label_create_empty(NumberKey_8);
+ lv_label_set_text(labelKey_8, machine_menu.key_8);
+ lv_obj_align(labelKey_8, NumberKey_8, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_9 = lv_btn_create(scr, 244, 190, 68, 40, event_handler, ID_NUM_KEY9, &style_num_key_pre);
+ lv_obj_t *labelKey_9 = lv_label_create_empty(NumberKey_9);
+ lv_label_set_text(labelKey_9, machine_menu.key_9);
+ lv_obj_align(labelKey_9, NumberKey_9, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *NumberKey_0 = lv_btn_create(scr, 92, 240, 68, 40, event_handler, ID_NUM_KEY0, &style_num_key_pre);
+ lv_obj_t *labelKey_0 = lv_label_create_empty(NumberKey_0);
+ lv_label_set_text(labelKey_0, machine_menu.key_0);
+ lv_obj_align(labelKey_0, NumberKey_0, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *Minus = lv_btn_create(scr, 168, 240, 68, 40, event_handler, ID_NUM_NEGATIVE, &style_num_key_pre);
+ lv_obj_t *labelMinus = lv_label_create_empty(Minus);
+ lv_label_set_text(labelMinus, machine_menu.negative);
+ lv_obj_align(labelMinus, Minus, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *KeyPoint = lv_btn_create(scr, 244, 240, 68, 40, event_handler, ID_NUM_POINT, &style_num_key_pre);
+ lv_obj_t *labelKeyPoint = lv_label_create_empty(KeyPoint);
+ lv_label_set_text(labelKeyPoint, machine_menu.key_point);
+ lv_obj_align(labelKeyPoint, KeyPoint, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *KeyBack = lv_btn_create(scr, 320, 90, 68, 40, event_handler, ID_NUM_BACK, &style_num_key_pre);
+ lv_obj_t *labelKeyBack = lv_label_create_empty(KeyBack);
+ lv_label_set_text(labelKeyBack, machine_menu.key_back);
+ lv_obj_align(labelKeyBack, KeyBack, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *KeyReset = lv_btn_create(scr, 320, 140, 68, 40, event_handler, ID_NUM_RESET, &style_num_key_pre);
+ lv_obj_t *labelKeyReset = lv_label_create_empty(KeyReset);
+ lv_label_set_text(labelKeyReset, machine_menu.key_reset);
+ lv_obj_align(labelKeyReset, KeyReset, LV_ALIGN_CENTER, 0, 0);
+
+ lv_obj_t *KeyConfirm = lv_btn_create(scr, 320, 190, 68, 90, event_handler, ID_NUM_CONFIRM, &style_num_key_pre);
+ lv_obj_t *labelKeyConfirm = lv_label_create_empty(KeyConfirm);
+ lv_label_set_text(labelKeyConfirm, machine_menu.key_confirm);
+ lv_obj_align(labelKeyConfirm, KeyConfirm, LV_ALIGN_CENTER, 0, 0);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, NumberKey_1);
+ lv_group_add_obj(g, NumberKey_2);
+ lv_group_add_obj(g, NumberKey_3);
+ lv_group_add_obj(g, KeyBack);
+ lv_group_add_obj(g, NumberKey_4);
+ lv_group_add_obj(g, NumberKey_5);
+ lv_group_add_obj(g, NumberKey_6);
+ lv_group_add_obj(g, KeyReset);
+ lv_group_add_obj(g, NumberKey_7);
+ lv_group_add_obj(g, NumberKey_8);
+ lv_group_add_obj(g, NumberKey_9);
+ lv_group_add_obj(g, NumberKey_0);
+ lv_group_add_obj(g, Minus);
+ lv_group_add_obj(g, KeyPoint);
+ lv_group_add_obj(g, KeyConfirm);
+ }
+ #endif
+
+ disp_key_value();
+}
+
+void lv_clear_number_key() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h
new file mode 100644
index 0000000..7902da3
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_number_key.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_number_key(void);
+extern void lv_clear_number_key();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp
new file mode 100644
index 0000000..9233991
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.cpp
@@ -0,0 +1,230 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../module/motion.h"
+#include "../../../../sd/cardreader.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_O_PRE_HEAT = 1,
+ ID_O_EXTRUCT,
+ ID_O_MOV,
+ ID_O_FILAMENT,
+ ID_O_SPEED,
+ ID_O_RETURN,
+ ID_O_FAN,
+ ID_O_POWER_OFF,
+ ID_O_BABY_STEP
+};
+
+static lv_obj_t *label_PowerOff;
+static lv_obj_t *buttonPowerOff;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_O_PRE_HEAT:
+ lv_clear_operation();
+ lv_draw_preHeat();
+ break;
+ case ID_O_EXTRUCT:
+ uiCfg.moveSpeed_bak = (uint16_t)feedrate_mm_s;
+ lv_clear_operation();
+ lv_draw_extrusion();
+ break;
+ case ID_O_MOV:
+ lv_clear_operation();
+ lv_draw_move_motor();
+ break;
+ case ID_O_FILAMENT:
+ #if HAS_MULTI_EXTRUDER
+ uiCfg.curSprayerChoose_bak = active_extruder;
+ #endif
+ if (uiCfg.print_state == WORKING) {
+ #if ENABLED(SDSUPPORT)
+ card.pauseSDPrint();
+ stop_print_time();
+ uiCfg.print_state = PAUSING;
+ #endif
+ }
+ uiCfg.moveSpeed_bak = (uint16_t)feedrate_mm_s;
+ uiCfg.desireSprayerTempBak = thermalManager.temp_hotend[active_extruder].target;
+ lv_clear_operation();
+ lv_draw_filament_change();
+ break;
+ case ID_O_FAN:
+ lv_clear_operation();
+ lv_draw_fan();
+ break;
+ case ID_O_SPEED:
+ lv_clear_operation();
+ lv_draw_change_speed();
+ break;
+ case ID_O_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ case ID_O_POWER_OFF:
+ if (gCfgItems.finish_power_off) {
+ gCfgItems.finish_power_off = false;
+ lv_imgbtn_set_src_both(buttonPowerOff, "F:/bmp_manual_off.bin");
+ lv_label_set_text(label_PowerOff, printing_more_menu.manual);
+ }
+ else {
+ gCfgItems.finish_power_off = true;
+ lv_imgbtn_set_src_both(buttonPowerOff, "F:/bmp_auto_off.bin");
+ lv_label_set_text(label_PowerOff, printing_more_menu.auto_close);
+ }
+ lv_obj_align(label_PowerOff, buttonPowerOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ lv_obj_refresh_ext_draw_pad(label_PowerOff);
+ update_spi_flash();
+ break;
+ case ID_O_BABY_STEP:
+ lv_clear_operation();
+ lv_draw_baby_stepping();
+ break;
+ }
+}
+
+void lv_draw_operation(void) {
+ lv_obj_t *buttonExtrusion = nullptr, *buttonSpeed = nullptr,
+ *buttonBack = nullptr,
+ *labelPreHeat = nullptr, *labelExtrusion = nullptr,
+ *label_Back = nullptr, *label_Speed = nullptr, *label_Fan = nullptr,
+ *buttonMove = nullptr, *label_Move = nullptr,
+ *buttonBabyStep = nullptr, *label_BabyStep = nullptr,
+ *label_Filament = nullptr;
+
+ scr = lv_screen_create(OPERATE_UI);
+
+ // Create image buttons
+ lv_obj_t *buttonPreHeat = lv_imgbtn_create(scr, "F:/bmp_temp.bin", INTERVAL_V, titleHeight, event_handler, ID_O_PRE_HEAT);
+ lv_obj_t *buttonFilament = lv_imgbtn_create(scr, "F:/bmp_filamentchange.bin", BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_O_FILAMENT);
+ lv_obj_t *buttonFan = lv_imgbtn_create(scr, "F:/bmp_fan.bin", BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_O_FAN);
+ buttonPowerOff = lv_imgbtn_create(scr, gCfgItems.finish_power_off ? "F:/bmp_auto_off.bin" : "F:/bmp_manual_off.bin", BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_O_POWER_OFF);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonPreHeat);
+ lv_group_add_obj(g, buttonFilament);
+ lv_group_add_obj(g, buttonFan);
+ lv_group_add_obj(g, buttonPowerOff);
+ }
+ #endif
+
+ if (uiCfg.print_state != WORKING) {
+ buttonExtrusion = lv_imgbtn_create(scr, "F:/bmp_extrude_opr.bin", INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_O_EXTRUCT);
+ buttonMove = lv_imgbtn_create(scr, "F:/bmp_move_opr.bin", BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_O_MOV);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonExtrusion);
+ lv_group_add_obj(g, buttonMove);
+ }
+ #endif
+ }
+ else {
+ buttonSpeed = lv_imgbtn_create(scr, "F:/bmp_speed.bin", INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_O_SPEED);
+ buttonBabyStep = lv_imgbtn_create(scr, "F:/bmp_mov.bin", BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_O_BABY_STEP);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonSpeed);
+ lv_group_add_obj(g, buttonBabyStep);
+ }
+ #endif
+ }
+
+ buttonBack = lv_imgbtn_create(scr, "F:/bmp_return.bin", BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_O_RETURN);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonBack);
+ #endif
+
+ // Create labels on the image buttons
+ labelPreHeat = lv_label_create_empty(buttonPreHeat);
+ label_Filament = lv_label_create_empty(buttonFilament);
+ label_Fan = lv_label_create_empty(buttonFan);
+ label_PowerOff = lv_label_create_empty(buttonPowerOff);
+
+ if (uiCfg.print_state != WORKING) {
+ labelExtrusion = lv_label_create_empty(buttonExtrusion);
+ label_Move = lv_label_create_empty(buttonMove);
+ }
+ else {
+ label_Speed = lv_label_create_empty(buttonSpeed);
+ label_BabyStep = lv_label_create_empty(buttonBabyStep);
+ }
+ label_Back = lv_label_create_empty(buttonBack);
+
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelPreHeat, operation_menu.temp);
+ lv_obj_align(labelPreHeat, buttonPreHeat, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(label_Filament, operation_menu.filament);
+ lv_obj_align(label_Filament, buttonFilament, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(label_Fan, operation_menu.fan);
+ lv_obj_align(label_Fan, buttonFan, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ if (gCfgItems.finish_power_off)
+ lv_label_set_text(label_PowerOff, printing_more_menu.auto_close);
+ else
+ lv_label_set_text(label_PowerOff, printing_more_menu.manual);
+ lv_obj_align(label_PowerOff, buttonPowerOff, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ if (uiCfg.print_state != WORKING) {
+ lv_label_set_text(labelExtrusion, operation_menu.extr);
+ lv_obj_align(labelExtrusion, buttonExtrusion, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(label_Move, operation_menu.move);
+ lv_obj_align(label_Move, buttonMove, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else {
+ lv_label_set_text(label_Speed, operation_menu.speed);
+ lv_obj_align(label_Speed, buttonSpeed, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(label_BabyStep, operation_menu.babystep);
+ lv_obj_align(label_BabyStep, buttonBabyStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+
+ lv_label_set_text(label_Back, common_menu.text_back);
+ lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+}
+
+void lv_clear_operation() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h
new file mode 100644
index 0000000..0257812
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_operation.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_operation(void);
+extern void lv_clear_operation();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp
new file mode 100644
index 0000000..fb7434e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.cpp
@@ -0,0 +1,51 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, ADVANCED_PAUSE_FEATURE)
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../feature/pause.h"
+#include "../../../../inc/MarlinConfig.h"
+
+void lv_draw_pause_message(const PauseMessage msg) {
+ switch (msg) {
+ case PAUSE_MESSAGE_PAUSING: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_PAUSING); break;
+ case PAUSE_MESSAGE_CHANGING: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_CHANGING); break;
+ case PAUSE_MESSAGE_UNLOAD: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_UNLOAD); break;
+ case PAUSE_MESSAGE_WAITING: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_WAITING); break;
+ case PAUSE_MESSAGE_INSERT: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_INSERT); break;
+ case PAUSE_MESSAGE_LOAD: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_LOAD); break;
+ case PAUSE_MESSAGE_PURGE: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_PURGE); break;
+ case PAUSE_MESSAGE_RESUME: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_RESUME); break;
+ case PAUSE_MESSAGE_HEAT: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_HEAT); break;
+ case PAUSE_MESSAGE_HEATING: lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_HEATING); break;
+ case PAUSE_MESSAGE_OPTION: pause_menu_response = PAUSE_RESPONSE_WAIT_FOR;
+ lv_clear_cur_ui(); lv_draw_dialog(DIALOG_PAUSE_MESSAGE_OPTION); break;
+ case PAUSE_MESSAGE_STATUS:
+ default: break;
+ }
+}
+
+#endif // HAS_TFT_LVGL_UI && ADVANCED_PAUSE_FEATURE
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h
new file mode 100644
index 0000000..88222f0
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_message.h
@@ -0,0 +1,32 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_pause_message(const PauseMessage msg);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp
new file mode 100644
index 0000000..be7c81f
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.cpp
@@ -0,0 +1,85 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_PAUSE_RETURN = 1,
+ ID_PAUSE_X,
+ ID_PAUSE_Y,
+ ID_PAUSE_Z
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_pause_position();
+ switch (obj->mks_obj_id) {
+ case ID_PAUSE_RETURN:
+ lv_draw_return_ui();
+ return;
+ case ID_PAUSE_X:
+ value = pause_pos_x;
+ break;
+ case ID_PAUSE_Y:
+ value = pause_pos_y;
+ break;
+ case ID_PAUSE_Z:
+ value = pause_pos_z;
+ break;
+ }
+ lv_draw_number_key();
+}
+
+void lv_draw_pause_position(void) {
+ char str_1[16];
+ scr = lv_screen_create(PAUSE_POS_UI, machine_menu.PausePosText);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosX, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.xPos, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_PAUSE_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosY, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.yPos, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_PAUSE_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(gCfgItems.pausePosZ, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.zPos, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_PAUSE_Z, 2, public_buf_l);
+
+ lv_screen_menu_item_return(scr, event_handler, ID_PAUSE_RETURN);
+}
+
+void lv_clear_pause_position() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h
new file mode 100644
index 0000000..3e9e079
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_pause_position.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_pause_position(void);
+extern void lv_clear_pause_position();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp
new file mode 100644
index 0000000..b38dbf9
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.cpp
@@ -0,0 +1,297 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../inc/MarlinConfig.h"
+#include "../../../../module/motion.h"
+
+static lv_obj_t *scr;
+extern lv_group_t* g;
+static lv_obj_t *buttonType, *buttonStep;
+static lv_obj_t *labelType;
+static lv_obj_t *labelStep;
+static lv_obj_t *tempText1;
+
+enum {
+ ID_P_ADD = 1,
+ ID_P_DEC,
+ ID_P_TYPE,
+ ID_P_STEP,
+ ID_P_OFF,
+ ID_P_RETURN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_P_ADD:
+ if (uiCfg.curTempType == 0) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target += uiCfg.stepHeat;
+ if (uiCfg.curSprayerChoose == 0) {
+ if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > (HEATER_0_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)HEATER_0_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1);
+ }
+ }
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ else if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > (HEATER_1_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = (float)HEATER_1_MAXTEMP - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1);
+ }
+ #endif
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ }
+ #if HAS_HEATED_BED
+ else {
+ thermalManager.temp_bed.target += uiCfg.stepHeat;
+ if ((int)thermalManager.temp_bed.target > BED_MAXTEMP - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)) {
+ thermalManager.temp_bed.target = (float)BED_MAXTEMP - (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1);
+ }
+ thermalManager.start_watching_bed();
+ }
+ #endif
+ disp_desire_temp();
+ break;
+ case ID_P_DEC:
+ if (uiCfg.curTempType == 0) {
+ if ((int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target > uiCfg.stepHeat)
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target -= uiCfg.stepHeat;
+ else
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = 0;
+
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ }
+ #if HAS_HEATED_BED
+ else {
+ if ((int)thermalManager.temp_bed.target > uiCfg.stepHeat)
+ thermalManager.temp_bed.target -= uiCfg.stepHeat;
+ else
+ thermalManager.temp_bed.target = 0;
+
+ thermalManager.start_watching_bed();
+ }
+ #endif
+ disp_desire_temp();
+ break;
+ case ID_P_TYPE:
+ if (uiCfg.curTempType == 0) {
+ if (ENABLED(HAS_MULTI_EXTRUDER)) {
+ #if DISABLED(SINGLENOZZLE)
+ if (uiCfg.curSprayerChoose == 0) {
+ uiCfg.curSprayerChoose = 1;
+ }
+ else if (uiCfg.curSprayerChoose == 1) {
+ if (TEMP_SENSOR_BED != 0) {
+ uiCfg.curTempType = 1;
+ }
+ else {
+ uiCfg.curTempType = 0;
+ uiCfg.curSprayerChoose = 0;
+ }
+ }
+ #else
+ if (TEMP_SENSOR_BED != 0) {
+ uiCfg.curTempType = 1;
+ }
+ else {
+ uiCfg.curTempType = 0;
+ }
+ #endif
+ }
+ else if (uiCfg.curSprayerChoose == 0) {
+ if (TEMP_SENSOR_BED != 0)
+ uiCfg.curTempType = 1;
+ else
+ uiCfg.curTempType = 0;
+ }
+ }
+ else if (uiCfg.curTempType == 1) {
+ uiCfg.curSprayerChoose = 0;
+ uiCfg.curTempType = 0;
+ }
+ disp_temp_type();
+ break;
+ case ID_P_STEP:
+ switch (uiCfg.stepHeat) {
+ case 1: uiCfg.stepHeat = 5; break;
+ case 5: uiCfg.stepHeat = 10; break;
+ case 10: uiCfg.stepHeat = 1; break;
+ default: break;
+ }
+ disp_step_heat();
+ break;
+ case ID_P_OFF:
+ if (uiCfg.curTempType == 0) {
+ thermalManager.temp_hotend[uiCfg.curSprayerChoose].target = 0;
+ thermalManager.start_watching_hotend(uiCfg.curSprayerChoose);
+ }
+ #if HAS_HEATED_BED
+ else {
+ thermalManager.temp_bed.target = 0;
+ thermalManager.start_watching_bed();
+ }
+ #endif
+ disp_desire_temp();
+ break;
+ case ID_P_RETURN:
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_preHeat(void) {
+ scr = lv_screen_create(PRE_HEAT_UI);
+
+ // Create image buttons
+ lv_big_button_create(scr, "F:/bmp_Add.bin", preheat_menu.add, INTERVAL_V, titleHeight, event_handler, ID_P_ADD);
+ lv_big_button_create(scr, "F:/bmp_Dec.bin", preheat_menu.dec, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_P_DEC);
+
+ buttonType = lv_imgbtn_create(scr, nullptr, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_P_TYPE);
+ buttonStep = lv_imgbtn_create(scr, nullptr, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_P_STEP);
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonType);
+ lv_group_add_obj(g, buttonStep);
+ }
+ #endif
+
+ lv_big_button_create(scr, "F:/bmp_speed0.bin", preheat_menu.off, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_P_OFF);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_P_RETURN);
+
+ // Create labels on the image buttons
+ labelType = lv_label_create_empty(buttonType);
+ labelStep = lv_label_create_empty(buttonStep);
+
+ #if ENABLED(SINGLENOZZLE)
+ uiCfg.curSprayerChoose = 0;
+ #else
+ uiCfg.curSprayerChoose = active_extruder;
+ #endif
+
+ disp_temp_type();
+ disp_step_heat();
+
+ tempText1 = lv_label_create_empty(scr);
+ lv_obj_set_style(tempText1, &tft_style_label_rel);
+ disp_desire_temp();
+}
+
+void disp_temp_type() {
+ if (uiCfg.curTempType == 0) {
+ #if DISABLED(SINGLENOZZLE)
+ if (uiCfg.curSprayerChoose == 1) {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru2.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.ext2);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+ else {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru1.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.ext1);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+ #else
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_extru1.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.ext1);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ #endif
+ }
+ else {
+ lv_imgbtn_set_src_both(buttonType, "F:/bmp_bed.bin");
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelType, preheat_menu.hotbed);
+ lv_obj_align(labelType, buttonType, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void disp_desire_temp() {
+ char buf[20] = {0};
+
+ public_buf_l[0] = '\0';
+
+ if (uiCfg.curTempType == 0) {
+ #if DISABLED(SINGLENOZZLE)
+ strcat(public_buf_l, uiCfg.curSprayerChoose < 1 ? preheat_menu.ext1 : preheat_menu.ext2);
+ sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].celsius, (int)thermalManager.temp_hotend[uiCfg.curSprayerChoose].target);
+ #else
+ strcat(public_buf_l, preheat_menu.ext1);
+ sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target);
+ #endif
+ }
+ #if HAS_HEATED_BED
+ else {
+ strcat(public_buf_l, preheat_menu.hotbed);
+ sprintf(buf, preheat_menu.value_state, (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target);
+ }
+ #endif
+ strcat_P(public_buf_l, PSTR(": "));
+ strcat(public_buf_l, buf);
+ lv_label_set_text(tempText1, public_buf_l);
+ lv_obj_align(tempText1, nullptr, LV_ALIGN_CENTER, 0, -50);
+}
+
+void disp_step_heat() {
+ if (uiCfg.stepHeat == 1) {
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step1_degree.bin");
+ }
+ else if (uiCfg.stepHeat == 5) {
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step5_degree.bin");
+ }
+ else if (uiCfg.stepHeat == 10) {
+ lv_imgbtn_set_src_both(buttonStep, "F:/bmp_step10_degree.bin");
+ }
+
+ if (gCfgItems.multiple_language) {
+ if (uiCfg.stepHeat == 1) {
+ lv_label_set_text(labelStep, preheat_menu.step_1c);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.stepHeat == 5) {
+ lv_label_set_text(labelStep, preheat_menu.step_5c);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ else if (uiCfg.stepHeat == 10) {
+ lv_label_set_text(labelStep, preheat_menu.step_10c);
+ lv_obj_align(labelStep, buttonStep, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ }
+}
+
+void lv_clear_preHeat() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h
new file mode 100644
index 0000000..602f5e9
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_preHeat.h
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_preHeat(void);
+extern void lv_clear_preHeat();
+extern void disp_temp_type();
+extern void disp_step_heat();
+extern void disp_desire_temp();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp
new file mode 100644
index 0000000..0d95f14
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.cpp
@@ -0,0 +1,552 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+//#include "../lvgl/src/lv_objx/lv_imgbtn.h"
+//#include "../lvgl/src/lv_objx/lv_img.h"
+//#include "../lvgl/src/lv_core/lv_disp.h"
+//#include "../lvgl/src/lv_core/lv_refr.h"
+
+#include "../../../../sd/cardreader.h"
+#include "../../../../inc/MarlinConfig.h"
+
+static lv_obj_t *scr;
+extern lv_group_t* g;
+
+static lv_obj_t *buttonPageUp, *buttonPageDown, *buttonBack,
+ *buttonGcode[FILE_BTN_CNT], *labelPageUp[FILE_BTN_CNT], *buttonText[FILE_BTN_CNT];
+
+enum {
+ ID_P_UP = 7,
+ ID_P_DOWN,
+ ID_P_RETURN
+};
+
+int8_t curDirLever = 0;
+LIST_FILE list_file;
+DIR_OFFSET dir_offset[10];
+
+extern uint8_t public_buf[513];
+extern char public_buf_m[100];
+
+uint8_t sel_id = 0;
+
+#if ENABLED(SDSUPPORT)
+
+ static uint8_t search_file() {
+ int valid_name_cnt = 0;
+ //char tmp[SHORT_NEME_LEN*MAX_DIR_LEVEL+1];
+
+ list_file.Sd_file_cnt = 0;
+ //list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset;
+
+ //root2.rewind();
+ //SERIAL_ECHOLN(list_file.curDirPath);
+
+ if (curDirLever != 0) card.cd(list_file.curDirPath);
+ else card.cdroot(); // while(card.cdup());
+
+ const uint16_t fileCnt = card.get_num_Files();
+
+ for (uint16_t i = 0; i < fileCnt; i++) {
+ if (list_file.Sd_file_cnt == list_file.Sd_file_offset) {
+ const uint16_t nr = SD_ORDER(i, fileCnt);
+ card.getfilename_sorted(nr);
+
+ list_file.IsFolder[valid_name_cnt] = card.flag.filenameIsDir;
+ strcpy(list_file.file_name[valid_name_cnt], list_file.curDirPath);
+ strcat_P(list_file.file_name[valid_name_cnt], PSTR("/"));
+ strcat(list_file.file_name[valid_name_cnt], card.filename);
+ strcpy(list_file.long_name[valid_name_cnt], card.longest_filename());
+
+ valid_name_cnt++;
+ if (valid_name_cnt == 1)
+ dir_offset[curDirLever].cur_page_first_offset = list_file.Sd_file_offset;
+ if (valid_name_cnt >= FILE_NUM) {
+ dir_offset[curDirLever].cur_page_last_offset = list_file.Sd_file_offset;
+ list_file.Sd_file_offset++;
+ break;
+ }
+ list_file.Sd_file_offset++;
+ }
+ list_file.Sd_file_cnt++;
+ }
+ //card.closefile(false);
+ return valid_name_cnt;
+ }
+
+#endif // SDSUPPORT
+
+bool have_pre_pic(char *path) {
+ #if ENABLED(SDSUPPORT)
+ char *ps1;//, *ps2;//, *cur_name = strrchr(path, '/');
+ card.openFileRead(path);
+ card.read(public_buf, 256);
+ ps1 = strstr((char *)public_buf, ";simage:");
+ //card.read(public_buf, 512);
+ //ps2 = strstr((char *)public_buf, ";simage:");
+ card.closefile();
+ if (ps1) return true;
+ #endif
+
+ return false;
+}
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ uint8_t i, file_count = 0;
+ //switch (obj->mks_obj_id)
+ //{
+ if (obj->mks_obj_id == ID_P_UP) {
+ if (dir_offset[curDirLever].curPage > 0) {
+ // 2015.05.19
+ list_file.Sd_file_cnt = 0;
+
+ if (dir_offset[curDirLever].cur_page_first_offset >= FILE_NUM)
+ list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset - FILE_NUM;
+
+ #if ENABLED(SDSUPPORT)
+ file_count = search_file();
+ #endif
+ if (file_count != 0) {
+ dir_offset[curDirLever].curPage--;
+ lv_clear_print_file();
+ disp_gcode_icon(file_count);
+ }
+ }
+ }
+ else if (obj->mks_obj_id == ID_P_DOWN) {
+ if (dir_offset[curDirLever].cur_page_last_offset > 0) {
+ list_file.Sd_file_cnt = 0;
+ list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_last_offset + 1;
+ #if ENABLED(SDSUPPORT)
+ file_count = search_file();
+ #endif
+ if (file_count != 0) {
+ dir_offset[curDirLever].curPage++;
+ lv_clear_print_file();
+ disp_gcode_icon(file_count);
+ }
+ if (file_count < FILE_NUM)
+ dir_offset[curDirLever].cur_page_last_offset = 0;
+ }
+ }
+ else if (obj->mks_obj_id == ID_P_RETURN) {
+ if (curDirLever > 0) {
+ int8_t *ch = (int8_t *)strrchr(list_file.curDirPath, '/');
+ if (ch) {
+ *ch = 0;
+ #if ENABLED(SDSUPPORT)
+ card.cdup();
+ #endif
+ dir_offset[curDirLever].curPage = 0;
+ dir_offset[curDirLever].cur_page_first_offset = 0;
+ dir_offset[curDirLever].cur_page_last_offset = 0;
+ curDirLever--;
+ list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset;
+ #if ENABLED(SDSUPPORT)
+ file_count = search_file();
+ #endif
+ lv_clear_print_file();
+ disp_gcode_icon(file_count);
+ }
+ }
+ else {
+ lv_clear_print_file();
+ lv_draw_ready_print();
+ }
+ }
+ else {
+ for (i = 0; i < FILE_BTN_CNT; i++) {
+ if (obj->mks_obj_id == (i + 1)) {
+ if (list_file.file_name[i][0] != 0) {
+ if (list_file.IsFolder[i]) {
+ strcpy(list_file.curDirPath, list_file.file_name[i]);
+ curDirLever++;
+ list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset;
+ #if ENABLED(SDSUPPORT)
+ file_count = search_file();
+ #endif
+ lv_clear_print_file();
+ disp_gcode_icon(file_count);
+ }
+ else {
+ sel_id = i;
+ lv_clear_print_file();
+ lv_draw_dialog(DIALOG_TYPE_PRINT_FILE);
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void lv_draw_print_file(void) {
+ //uint8_t i;
+ uint8_t file_count;
+
+ curDirLever = 0;
+ dir_offset[curDirLever].curPage = 0;
+
+ list_file.Sd_file_offset = 0;
+ list_file.Sd_file_cnt = 0;
+
+ ZERO(dir_offset);
+ ZERO(list_file.IsFolder);
+ ZERO(list_file.curDirPath);
+
+ list_file.Sd_file_offset = dir_offset[curDirLever].cur_page_first_offset;
+ #if ENABLED(SDSUPPORT)
+ card.mount();
+ file_count = search_file();
+ #endif
+ disp_gcode_icon(file_count);
+
+ //lv_obj_t *labelPageUp = lv_label_create_empty(buttonPageUp);
+ //lv_obj_t *labelPageDown = lv_label_create_empty(buttonPageDown);
+ //lv_obj_t *label_Back = lv_label_create_empty(buttonBack);
+
+ /*
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelPageUp, tool_menu.preheat);
+ lv_obj_align(labelPageUp, buttonPageUp, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(labelPageDown, tool_menu.extrude);
+ lv_obj_align(labelPageDown, buttonPageDown, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET);
+
+ lv_label_set_text(label_Back, common_menu.text_back);
+ lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID,0, BUTTON_TEXT_Y_OFFSET);
+ }
+ */
+}
+static char test_public_buf_l[(SHORT_NAME_LEN + 1) * MAX_DIR_LEVEL + strlen("S:/") + 1];
+void disp_gcode_icon(uint8_t file_num) {
+ uint8_t i;
+
+ scr = lv_screen_create(PRINT_FILE_UI, "");
+
+ // Create image buttons
+ buttonPageUp = lv_imgbtn_create(scr, "F:/bmp_pageUp.bin", OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_P_UP);
+ buttonPageDown = lv_imgbtn_create(scr, "F:/bmp_pageDown.bin", OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + OTHER_BTN_YPIEL + INTERVAL_H, event_handler, ID_P_DOWN);
+ buttonBack = lv_imgbtn_create(scr, "F:/bmp_back.bin", OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + OTHER_BTN_YPIEL * 2 + INTERVAL_H * 2, event_handler, ID_P_RETURN);
+
+ // Create labels on the image buttons
+ for (i = 0; i < FILE_BTN_CNT; i++) {
+ /*
+ if (seq) {
+ j = (FILE_BTN_CNT-1) - i;
+ back_flg = 1;
+ }
+ else {
+ j = i;
+ back_flg = 0;
+ }
+ */
+ if (i >= file_num) break;
+
+ #ifdef TFT35
+ buttonGcode[i] = lv_imgbtn_create(scr, nullptr);
+
+ lv_imgbtn_use_label_style(buttonGcode[i]);
+ lv_obj_clear_protect(buttonGcode[i], LV_PROTECT_FOLLOW);
+ lv_btn_set_layout(buttonGcode[i], LV_LAYOUT_OFF);
+
+ ZERO(public_buf_m);
+ cutFileName((char *)list_file.long_name[i], 16, 8, (char *)public_buf_m);
+
+ if (list_file.IsFolder[i]) {
+ lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), "", 0);
+ lv_imgbtn_set_src_both(buttonGcode[i], "F:/bmp_dir.bin");
+ if (i < 3)
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1), titleHeight);
+ else
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1), BTN_Y_PIXEL + INTERVAL_H + titleHeight);
+
+ labelPageUp[i] = lv_label_create(buttonGcode[i], public_buf_m);
+ lv_obj_align(labelPageUp[i], buttonGcode[i], LV_ALIGN_IN_BOTTOM_MID, 0, -5);
+ }
+ else {
+ if (have_pre_pic((char *)list_file.file_name[i])) {
+
+ //lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), list_file.file_name[i], 1);
+
+ strcpy(test_public_buf_l, "S:");
+ strcat(test_public_buf_l, list_file.file_name[i]);
+ char *temp = strstr(test_public_buf_l, ".GCO");
+ if (temp) strcpy(temp, ".bin");
+ lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), test_public_buf_l, 0);
+ lv_imgbtn_set_src_both(buttonGcode[i], buttonGcode[i]->mks_pic_name);
+ if (i < 3) {
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1) + FILE_PRE_PIC_X_OFFSET, titleHeight + FILE_PRE_PIC_Y_OFFSET);
+ buttonText[i] = lv_btn_create(scr, nullptr);
+ //lv_obj_set_event_cb(buttonText[i], event_handler);
+
+ lv_btn_use_label_style(buttonText[i]);
+ lv_obj_clear_protect(buttonText[i], LV_PROTECT_FOLLOW);
+ lv_btn_set_layout(buttonText[i], LV_LAYOUT_OFF);
+ //lv_obj_set_event_cb_mks(buttonText[i], event_handler,(i+10),"", 0);
+ lv_obj_set_pos(buttonText[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1) + FILE_PRE_PIC_X_OFFSET, titleHeight + FILE_PRE_PIC_Y_OFFSET + 100);
+ lv_obj_set_size(buttonText[i], 100, 40);
+ }
+ else {
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1) + FILE_PRE_PIC_X_OFFSET, BTN_Y_PIXEL + INTERVAL_H + titleHeight + FILE_PRE_PIC_Y_OFFSET);
+ buttonText[i] = lv_btn_create(scr, nullptr);
+ //lv_obj_set_event_cb(buttonText[i], event_handler);
+
+ lv_btn_use_label_style(buttonText[i]);
+ lv_obj_clear_protect(buttonText[i], LV_PROTECT_FOLLOW);
+ lv_btn_set_layout(buttonText[i], LV_LAYOUT_OFF);
+ //lv_obj_set_event_cb_mks(buttonText[i], event_handler,(i+10),"", 0);
+ lv_obj_set_pos(buttonText[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1) + FILE_PRE_PIC_X_OFFSET, BTN_Y_PIXEL + INTERVAL_H + titleHeight + FILE_PRE_PIC_Y_OFFSET + 100);
+ lv_obj_set_size(buttonText[i], 100, 40);
+ }
+ labelPageUp[i] = lv_label_create(buttonText[i], public_buf_m);
+ lv_obj_align(labelPageUp[i], buttonText[i], LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+ }
+ else {
+ lv_obj_set_event_cb_mks(buttonGcode[i], event_handler, (i + 1), "", 0);
+ lv_imgbtn_set_src_both(buttonGcode[i], "F:/bmp_file.bin");
+ if (i < 3)
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * i + INTERVAL_V * (i + 1), titleHeight);
+ else
+ lv_obj_set_pos(buttonGcode[i], BTN_X_PIXEL * (i - 3) + INTERVAL_V * ((i - 3) + 1), BTN_Y_PIXEL + INTERVAL_H + titleHeight);
+
+ labelPageUp[i] = lv_label_create(buttonGcode[i], public_buf_m);
+ lv_obj_align(labelPageUp[i], buttonGcode[i], LV_ALIGN_IN_BOTTOM_MID, 0, -5);
+ }
+ }
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_add_obj(g, buttonGcode[i]);
+ #endif
+
+ #else // !TFT35
+ #endif // !TFT35
+ }
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonPageUp);
+ lv_group_add_obj(g, buttonPageDown);
+ lv_group_add_obj(g, buttonBack);
+ }
+ #endif
+}
+
+uint32_t lv_open_gcode_file(char *path) {
+ #if ENABLED(SDSUPPORT)
+ uint32_t *ps4;
+ uint32_t pre_sread_cnt = UINT32_MAX;
+ //char *cur_name;
+
+ //cur_name = strrchr(path, '/');
+
+ card.openFileRead(path);
+ card.read(public_buf, 256);
+ ps4 = (uint32_t *)strstr((char *)public_buf, ";simage:");
+ // Ignore the beginning message of gcode file
+ if (ps4) {
+ pre_sread_cnt = (uint32_t)ps4 - (uint32_t)((uint32_t *)(&public_buf[0]));
+ card.setIndex(pre_sread_cnt);
+ }
+ return pre_sread_cnt;
+ #endif // SDSUPPORT
+}
+
+int ascii2dec_test(char *ascii) {
+ int result = 0;
+ if (ascii == 0) return 0;
+
+ if (*(ascii) >= '0' && *(ascii) <= '9')
+ result = *(ascii) - '0';
+ else if (*(ascii) >= 'a' && *(ascii) <= 'f')
+ result = *(ascii) - 'a' + 0x0A;
+ else if (*(ascii) >= 'A' && *(ascii) <= 'F')
+ result = *(ascii) - 'A' + 0x0A;
+ else
+ return 0;
+
+ return result;
+}
+
+void lv_gcode_file_read(uint8_t *data_buf) {
+ #if ENABLED(SDSUPPORT)
+ uint16_t i = 0, j = 0, k = 0;
+ uint16_t row_1 = 0;
+ bool ignore_start = true;
+ char temp_test[200];
+ volatile uint16_t *p_index;
+
+ watchdog_refresh();
+ memset(public_buf, 0, 200);
+
+ while (card.isFileOpen()) {
+ if (ignore_start) card.read(temp_test, 8); // line start -> ignore
+ card.read(temp_test, 200); // data
+ // \r;;gimage: we got the bit img, so stop here
+ if (temp_test[1] == ';') {
+ card.closefile();
+ break;
+ }
+ for (i = 0; i < 200;) {
+ public_buf[row_1 * 200 + 100 * k + j] = (char)(ascii2dec_test(&temp_test[i]) << 4 | ascii2dec_test(&temp_test[i + 1]));
+ j++;
+ i += 2;
+ }
+
+ uint16_t c = card.get();
+ // check for more data or end of line (CR or LF)
+ if (ISEOL(c)) {
+ c = card.get(); // more eol?
+ if (!ISEOL(c)) card.setIndex(card.getIndex() - 1);
+ break;
+ }
+ card.setIndex(card.getIndex() - 1);
+ k++;
+ j = 0;
+ ignore_start = false;
+ if (k > 1) {
+ card.closefile();
+ break;
+ }
+ }
+ #if HAS_TFT_LVGL_UI_SPI
+ for (i = 0; i < 200;) {
+ p_index = (uint16_t *)(&public_buf[i]);
+
+ //Color = (*p_index >> 8);
+ //*p_index = Color | ((*p_index & 0xFF) << 8);
+ i += 2;
+ if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
+ }
+ #else // !HAS_TFT_LVGL_UI_SPI
+ for (i = 0; i < 200;) {
+ p_index = (uint16_t *)(&public_buf[i]);
+ //Color = (*p_index >> 8);
+ //*p_index = Color | ((*p_index & 0xFF) << 8);
+ i += 2;
+ if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full; // 0x18C3;
+ }
+ #endif // !HAS_TFT_LVGL_UI_SPI
+ memcpy(data_buf, public_buf, 200);
+ #endif // SDSUPPORT
+}
+
+void lv_close_gcode_file() {TERN_(SDSUPPORT, card.closefile());}
+
+void lv_gcode_file_seek(uint32_t pos) {
+ TERN_(SDSUPPORT, card.setIndex(pos));
+}
+
+void cutFileName(char *path, int len, int bytePerLine, char *outStr) {
+ #if _LFN_UNICODE
+ TCHAR *tmpFile;
+ TCHAR *strIndex1 = 0, *strIndex2 = 0, *beginIndex;
+ TCHAR secSeg[10] = {0};
+ TCHAR gFileTail[4] = {'~', '.', 'g', '\0'};
+ #else
+ char *tmpFile;
+ char *strIndex1 = 0, *strIndex2 = 0, *beginIndex;
+ char secSeg[10] = {0};
+ #endif
+
+ if (path == 0 || len <= 3 || outStr == 0) return;
+
+ tmpFile = path;
+ #if _LFN_UNICODE
+ strIndex1 = (WCHAR *)wcsstr((const WCHAR *)tmpFile, (const WCHAR *)'/');
+ strIndex2 = (WCHAR *)wcsstr((const WCHAR *)tmpFile, (const WCHAR *)'.');
+ #else
+ strIndex1 = (char *)strrchr(tmpFile, '/');
+ strIndex2 = (char *)strrchr(tmpFile, '.');
+ #endif
+
+ beginIndex = (strIndex1 != 0
+ //&& (strIndex2 != 0) && (strIndex1 < strIndex2)
+ ) ? strIndex1 + 1 : tmpFile;
+
+ if (strIndex2 == 0 || (strIndex1 > strIndex2)) { // not gcode file
+ #if _LFN_UNICODE
+ if (wcslen(beginIndex) > len)
+ wcsncpy(outStr, beginIndex, len);
+ else
+ wcscpy(outStr, beginIndex);
+ #else
+ if ((int)strlen(beginIndex) > len)
+ strncpy(outStr, beginIndex, len);
+ else
+ strcpy(outStr, beginIndex);
+ #endif
+ }
+ else { // gcode file
+ if (strIndex2 - beginIndex > (len - 2)) {
+ #if _LFN_UNICODE
+ wcsncpy(outStr, (const WCHAR *)beginIndex, len - 3);
+ wcscat(outStr, (const WCHAR *)gFileTail);
+ #else
+ //strncpy(outStr, beginIndex, len - 3);
+ strncpy(outStr, beginIndex, len - 4);
+ strcat_P(outStr, PSTR("~.g"));
+ #endif
+ }
+ else {
+ #if _LFN_UNICODE
+ wcsncpy(outStr, (const WCHAR *)beginIndex, strIndex2 - beginIndex + 1);
+ wcscat(outStr, (const WCHAR *)&gFileTail[3]);
+ #else
+ strncpy(outStr, beginIndex, strIndex2 - beginIndex + 1);
+ strcat_P(outStr, PSTR("g"));
+ #endif
+ }
+ }
+
+ #if _LFN_UNICODE
+ if (wcslen(outStr) > bytePerLine) {
+ wcscpy(secSeg, (const WCHAR *)&outStr[bytePerLine]);
+ outStr[bytePerLine] = '\n';
+ outStr[bytePerLine + 1] = '\0';
+ wcscat(outStr, (const WCHAR *)secSeg);
+ }
+ #else
+ if ((int)strlen(outStr) > bytePerLine) {
+ strcpy(secSeg, &outStr[bytePerLine]);
+ outStr[bytePerLine] = '\n';
+ outStr[bytePerLine + 1] = '\0';
+ strcat(outStr, secSeg);
+ }
+ else {
+ strcat_P(outStr, PSTR("\n"));
+ }
+ #endif
+}
+
+void lv_clear_print_file() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h
new file mode 100644
index 0000000..126dab0
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_print_file.h
@@ -0,0 +1,64 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+typedef struct {
+ int cur_page_first_offset;
+ int cur_page_last_offset;
+ int curPage;
+} DIR_OFFSET;
+extern DIR_OFFSET dir_offset[10];
+
+#define FILE_NUM 6
+#define SHORT_NAME_LEN 13
+#define NAME_CUT_LEN 23
+
+#define MAX_DIR_LEVEL 10
+
+typedef struct {
+ char file_name[FILE_NUM][(SHORT_NAME_LEN + 1) * MAX_DIR_LEVEL + 1];
+ char curDirPath[(SHORT_NAME_LEN + 1) * MAX_DIR_LEVEL + 1];
+ char long_name[FILE_NUM][SHORT_NAME_LEN * 2 + 1];
+ bool IsFolder[FILE_NUM];
+ char Sd_file_cnt;
+ char sd_file_index;
+ char Sd_file_offset;
+} LIST_FILE;
+extern LIST_FILE list_file;
+
+extern void disp_gcode_icon(uint8_t file_num);
+extern void lv_draw_print_file(void);
+extern uint32_t lv_open_gcode_file(char *path);
+extern void lv_gcode_file_read(uint8_t *data_buf);
+extern void lv_close_gcode_file();
+extern void cutFileName(char *path, int len, int bytePerLine, char *outStr);
+extern int ascii2dec_test(char *ascii);
+extern void lv_clear_print_file();
+extern void lv_gcode_file_seek(uint32_t pos);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp
new file mode 100644
index 0000000..5a474ce
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.cpp
@@ -0,0 +1,290 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../MarlinCore.h" // for marlin_state
+#include "../../../../module/temperature.h"
+#include "../../../../module/motion.h"
+#include "../../../../sd/cardreader.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
+ #include "../../../marlinui.h"
+#endif
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *labelExt1, *labelFan, *labelZpos, *labelTime;
+static lv_obj_t *labelPause, *labelStop, *labelOperat;
+static lv_obj_t *bar1, *bar1ValueText;
+static lv_obj_t *buttonPause, *buttonOperat, *buttonStop;
+
+#if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ static lv_obj_t *labelExt2;
+#endif
+
+#if HAS_HEATED_BED
+ static lv_obj_t* labelBed;
+#endif
+
+enum {
+ ID_PAUSE = 1,
+ ID_STOP,
+ ID_OPTION
+};
+
+bool once_flag; // = false
+extern bool flash_preview_begin, default_preview_flg, gcode_preview_over;
+extern uint32_t To_pre_view;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ if (gcode_preview_over) return;
+ switch (obj->mks_obj_id) {
+ case ID_PAUSE:
+ if (uiCfg.print_state == WORKING) {
+ #if ENABLED(SDSUPPORT)
+ card.pauseSDPrint();
+ stop_print_time();
+ uiCfg.print_state = PAUSING;
+ #endif
+ lv_imgbtn_set_src_both(buttonPause, "F:/bmp_resume.bin");
+ lv_label_set_text(labelPause, printing_menu.resume);
+ lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0);
+ }
+ else if (uiCfg.print_state == PAUSED) {
+ uiCfg.print_state = RESUMING;
+ lv_imgbtn_set_src_both(obj, "F:/bmp_pause.bin");
+ lv_label_set_text(labelPause, printing_menu.pause);
+ lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0);
+ }
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ else if (uiCfg.print_state == REPRINTING) {
+ uiCfg.print_state = REPRINTED;
+ lv_imgbtn_set_src_both(obj, "F:/bmp_pause.bin");
+ lv_label_set_text(labelPause, printing_menu.pause);
+ lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 30, 0);
+ print_time.minutes = recovery.info.print_job_elapsed / 60;
+ print_time.seconds = recovery.info.print_job_elapsed % 60;
+ print_time.hours = print_time.minutes / 60;
+ }
+ #endif
+ break;
+
+ case ID_STOP:
+ lv_clear_printing();
+ lv_draw_dialog(DIALOG_TYPE_STOP);
+ break;
+ case ID_OPTION:
+ lv_clear_printing();
+ lv_draw_operation();
+ break;
+ }
+}
+
+void lv_draw_printing(void) {
+ disp_state_stack._disp_index = 0;
+ ZERO(disp_state_stack._disp_state);
+ scr = lv_screen_create(PRINTING_UI);
+
+ // Create image buttons
+ lv_obj_t *buttonExt1 = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonExt1, "F:/bmp_ext1_state.bin");
+ lv_obj_set_pos(buttonExt1, 205, 136);
+
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ lv_obj_t *buttonExt2 = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonExt2, "F:/bmp_ext2_state.bin");
+ lv_obj_set_pos(buttonExt2, 350, 136);
+ #endif
+
+ #if HAS_HEATED_BED
+ lv_obj_t *buttonBedstate = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonBedstate, "F:/bmp_bed_state.bin");
+ lv_obj_set_pos(buttonBedstate, 205, 186);
+ #endif
+
+ lv_obj_t *buttonFanstate = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonFanstate, "F:/bmp_fan_state.bin");
+ lv_obj_set_pos(buttonFanstate, 350, 186);
+
+ lv_obj_t *buttonTime = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonTime, "F:/bmp_time_state.bin");
+ lv_obj_set_pos(buttonTime, 205, 86);
+
+ lv_obj_t *buttonZpos = lv_img_create(scr, nullptr);
+ lv_img_set_src(buttonZpos, "F:/bmp_zpos_state.bin");
+ lv_obj_set_pos(buttonZpos, 350, 86);
+
+ buttonPause = lv_imgbtn_create(scr, uiCfg.print_state == WORKING ? "F:/bmp_pause.bin" : "F:/bmp_resume.bin", 5, 240, event_handler, ID_PAUSE);
+ buttonStop = lv_imgbtn_create(scr, "F:/bmp_stop.bin", 165, 240, event_handler, ID_STOP);
+ buttonOperat = lv_imgbtn_create(scr, "F:/bmp_operate.bin", 325, 240, event_handler, ID_OPTION);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonPause);
+ lv_group_add_obj(g, buttonStop);
+ lv_group_add_obj(g, buttonOperat);
+ }
+ #endif
+
+ labelExt1 = lv_label_create(scr, 250, 146, nullptr);
+
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ labelExt2 = lv_label_create(scr, 395, 146, nullptr);
+ #endif
+
+ #if HAS_HEATED_BED
+ labelBed = lv_label_create(scr, 250, 196, nullptr);
+ #endif
+
+ labelFan = lv_label_create(scr, 395, 196, nullptr);
+ labelTime = lv_label_create(scr, 250, 96, nullptr);
+ labelZpos = lv_label_create(scr, 395, 96, nullptr);
+
+ labelPause = lv_label_create_empty(buttonPause);
+ labelStop = lv_label_create_empty(buttonStop);
+ labelOperat = lv_label_create_empty(buttonOperat);
+
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(labelPause, uiCfg.print_state == WORKING ? printing_menu.pause : printing_menu.resume);
+ lv_obj_align(labelPause, buttonPause, LV_ALIGN_CENTER, 20, 0);
+
+ lv_label_set_text(labelStop, printing_menu.stop);
+ lv_obj_align(labelStop, buttonStop, LV_ALIGN_CENTER, 20, 0);
+
+ lv_label_set_text(labelOperat, printing_menu.option);
+ lv_obj_align(labelOperat, buttonOperat, LV_ALIGN_CENTER, 20, 0);
+ }
+
+ bar1 = lv_bar_create(scr, nullptr);
+ lv_obj_set_pos(bar1, 205, 36);
+ lv_obj_set_size(bar1, 270, 40);
+ lv_bar_set_style(bar1, LV_BAR_STYLE_INDIC, &lv_bar_style_indic);
+ lv_bar_set_anim_time(bar1, 1000);
+ lv_bar_set_value(bar1, 0, LV_ANIM_ON);
+ bar1ValueText = lv_label_create_empty(bar1);
+ lv_label_set_text(bar1ValueText,"0%");
+ lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0);
+
+ disp_ext_temp();
+ disp_bed_temp();
+ disp_fan_speed();
+ disp_print_time();
+ disp_fan_Zpos();
+}
+
+void disp_ext_temp() {
+ sprintf(public_buf_l, printing_menu.temp1, (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target);
+ lv_label_set_text(labelExt1, public_buf_l);
+
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ sprintf(public_buf_l, printing_menu.temp1, (int)thermalManager.temp_hotend[1].celsius, (int)thermalManager.temp_hotend[1].target);
+ lv_label_set_text(labelExt2, public_buf_l);
+ #endif
+}
+
+void disp_bed_temp() {
+ #if HAS_HEATED_BED
+ sprintf(public_buf_l, printing_menu.bed_temp, (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target);
+ lv_label_set_text(labelBed, public_buf_l);
+ #endif
+}
+
+void disp_fan_speed() {
+ sprintf_P(public_buf_l, PSTR("%3d"), thermalManager.fan_speed[0]);
+ lv_label_set_text(labelFan, public_buf_l);
+}
+
+void disp_print_time() {
+ #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
+ const uint32_t r = ui.get_remaining_time();
+ sprintf_P(public_buf_l, PSTR("%02d:%02d R"), r / 3600, (r % 3600) / 60);
+ #else
+ sprintf_P(public_buf_l, PSTR("%d%d:%d%d:%d%d"), print_time.hours / 10, print_time.hours % 10, print_time.minutes / 10, print_time.minutes % 10, print_time.seconds / 10, print_time.seconds % 10);
+ #endif
+ lv_label_set_text(labelTime, public_buf_l);
+}
+
+void disp_fan_Zpos() {
+ char str_1[16];
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(current_position[Z_AXIS], 1, 3, str_1));
+ lv_label_set_text(labelZpos, public_buf_l);
+}
+
+void reset_print_time() {
+ print_time.hours = 0;
+ print_time.minutes = 0;
+ print_time.seconds = 0;
+ print_time.ms_10 = 0;
+}
+
+void start_print_time() { print_time.start = 1; }
+
+void stop_print_time() { print_time.start = 0; }
+
+void setProBarRate() {
+ int rate;
+ volatile long long rate_tmp_r;
+
+ if (!gCfgItems.from_flash_pic) {
+ #if ENABLED(SDSUPPORT)
+ rate_tmp_r = (long long)card.getIndex() * 100;
+ #endif
+ rate = rate_tmp_r / gCfgItems.curFilesize;
+ }
+ else {
+ #if ENABLED(SDSUPPORT)
+ rate_tmp_r = (long long)card.getIndex();
+ #endif
+ rate = (rate_tmp_r - (PREVIEW_SIZE + To_pre_view)) * 100 / (gCfgItems.curFilesize - (PREVIEW_SIZE + To_pre_view));
+ }
+
+ if (rate <= 0) return;
+
+ if (disp_state == PRINTING_UI) {
+ lv_bar_set_value(bar1, rate, LV_ANIM_ON);
+ sprintf_P(public_buf_l, "%d%%", rate);
+ lv_label_set_text(bar1ValueText,public_buf_l);
+ lv_obj_align(bar1ValueText, bar1, LV_ALIGN_CENTER, 0, 0);
+ }
+}
+
+void lv_clear_printing() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h
new file mode 100644
index 0000000..d6da1a1
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_printing.h
@@ -0,0 +1,53 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+enum {
+ IDLE,
+ WORKING,
+ PAUSING,
+ PAUSED,
+ REPRINTING,
+ REPRINTED,
+ RESUMING,
+ STOP
+};
+
+extern void lv_draw_printing(void);
+extern void lv_clear_printing();
+extern void disp_ext_temp();
+extern void disp_bed_temp();
+extern void disp_fan_speed();
+extern void disp_print_time();
+extern void disp_fan_Zpos();
+extern void reset_print_time();
+extern void start_print_time();
+extern void stop_print_time();
+extern void setProBarRate();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp
new file mode 100644
index 0000000..de4e41c
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.cpp
@@ -0,0 +1,220 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ready_print.h"
+#include "draw_tool.h"
+#include <lv_conf.h>
+#include "tft_lvgl_configuration.h"
+#include "mks_hardware_test.h"
+#include "draw_ui.h"
+
+#include <lvgl.h>
+
+#include "../../../../module/temperature.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ #include "../../../tft_io/touch_calibration.h"
+ #include "draw_touch_calibration.h"
+#endif
+
+#include <stdio.h>
+
+extern lv_group_t* g;
+static lv_obj_t *scr;
+#if ENABLED(MKS_TEST)
+ uint8_t curent_disp_ui = 0;
+#endif
+
+enum {
+ ID_TOOL = 1,
+ ID_SET,
+ ID_PRINT
+};
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_ready_print();
+
+ switch (obj->mks_obj_id) {
+ case ID_TOOL:
+ lv_draw_tool();
+ break;
+ case ID_SET:
+ lv_draw_set();
+ break;
+ case ID_PRINT:
+ lv_draw_print_file();
+ break;
+ }
+}
+
+lv_obj_t *limit_info, *det_info;
+lv_obj_t *tmc_state_info;
+lv_style_t limit_style, det_style, tmc_state_style;
+void disp_Limit_ok() {
+ limit_style.text.color.full = 0xFFFF;
+ lv_obj_set_style(limit_info, &limit_style);
+ lv_label_set_text(limit_info, "Limit:ok");
+}
+void disp_Limit_error() {
+ limit_style.text.color.full = 0xF800;
+ lv_obj_set_style(limit_info, &limit_style);
+ lv_label_set_text(limit_info, "Limit:error");
+}
+
+void disp_det_ok() {
+ det_style.text.color.full = 0xFFFF;
+ lv_obj_set_style(det_info, &det_style);
+ lv_label_set_text(det_info, "det:ok");
+}
+void disp_det_error() {
+ det_style.text.color.full = 0xF800;
+ lv_obj_set_style(det_info, &det_style);
+ lv_label_set_text(det_info, "det:error");
+}
+
+void disp_tmc_ok() {
+ tmc_state_style.text.color.full = 0xFFFF;
+ lv_obj_set_style(tmc_state_info, &tmc_state_style);
+ lv_label_set_text(tmc_state_info, "TMC CONNECTION OK");
+}
+void disp_tmc_error() {
+ tmc_state_style.text.color.full = 0xF800;
+ lv_obj_set_style(tmc_state_info, &tmc_state_style);
+ lv_label_set_text(tmc_state_info, "TMC CONNECTION ERROR");
+}
+
+lv_obj_t *e1, *e2, *e3, *bed;
+void mks_disp_test() {
+ char buf[30] = {0};
+ sprintf_P(buf, PSTR("e1:%d"), (int)thermalManager.temp_hotend[0].celsius);
+ lv_label_set_text(e1, buf);
+ #if HAS_MULTI_HOTEND
+ sprintf_P(buf, PSTR("e2:%d"), (int)thermalManager.temp_hotend[1].celsius);
+ lv_label_set_text(e2, buf);
+ #endif
+ #if HAS_HEATED_BED
+ sprintf_P(buf, PSTR("bed:%d"), (int)thermalManager.temp_bed.celsius);
+ lv_label_set_text(bed, buf);
+ #endif
+}
+
+void lv_draw_ready_print(void) {
+ char buf[30] = {0};
+ lv_obj_t *buttonTool;
+
+ disp_state_stack._disp_index = 0;
+ ZERO(disp_state_stack._disp_state);
+ scr = lv_screen_create(PRINT_READY_UI, "");
+
+ if (mks_test_flag == 0x1E) {
+ // Create image buttons
+ buttonTool = lv_imgbtn_create(scr, "F:/bmp_tool.bin", event_handler, ID_TOOL);
+
+ lv_obj_set_pos(buttonTool, 360, 180);
+
+ lv_obj_t *label_tool = lv_label_create_empty(buttonTool);
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(label_tool, main_menu.tool);
+ lv_obj_align(label_tool, buttonTool, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+
+ #if 1
+ e1 = lv_label_create_empty(scr);
+ lv_obj_set_pos(e1, 20, 20);
+ sprintf_P(buf, PSTR("e1: %d"), (int)thermalManager.temp_hotend[0].celsius);
+ lv_label_set_text(e1, buf);
+ #if HAS_MULTI_HOTEND
+ e2 = lv_label_create_empty(scr);
+ lv_obj_set_pos(e2, 20, 45);
+ sprintf_P(buf, PSTR("e1: %d"), (int)thermalManager.temp_hotend[1].celsius);
+ lv_label_set_text(e2, buf);
+ #endif
+
+ #if HAS_HEATED_BED
+ bed = lv_label_create_empty(scr);
+ lv_obj_set_pos(bed, 20, 95);
+ sprintf_P(buf, PSTR("bed: %d"), (int)thermalManager.temp_bed.celsius);
+ lv_label_set_text(bed, buf);
+ #endif
+
+ limit_info = lv_label_create_empty(scr);
+
+ lv_style_copy(&limit_style, &lv_style_scr);
+ limit_style.body.main_color.full = 0X0000;
+ limit_style.body.grad_color.full = 0X0000;
+ limit_style.text.color.full = 0Xffff;
+ lv_obj_set_style(limit_info, &limit_style);
+
+ lv_obj_set_pos(limit_info, 20, 120);
+ lv_label_set_text(limit_info, " ");
+
+ det_info = lv_label_create_empty(scr);
+
+ lv_style_copy(&det_style, &lv_style_scr);
+ det_style.body.main_color.full = 0X0000;
+ det_style.body.grad_color.full = 0X0000;
+ det_style.text.color.full = 0Xffff;
+ lv_obj_set_style(det_info, &det_style);
+
+ lv_obj_set_pos(det_info, 20, 145);
+ lv_label_set_text(det_info, " ");
+
+ tmc_state_info = lv_label_create_empty(scr);
+
+ lv_style_copy(&tmc_state_style, &lv_style_scr);
+ tmc_state_style.body.main_color.full = 0X0000;
+ tmc_state_style.body.grad_color.full = 0X0000;
+ tmc_state_style.text.color.full = 0Xffff;
+ lv_obj_set_style(tmc_state_info, &tmc_state_style);
+
+ lv_obj_set_pos(tmc_state_info, 20, 170);
+ lv_label_set_text(tmc_state_info, " ");
+ #endif // if 1
+
+ }
+ else {
+ lv_big_button_create(scr, "F:/bmp_tool.bin", main_menu.tool, 20, 90, event_handler, ID_TOOL);
+ lv_big_button_create(scr, "F:/bmp_set.bin", main_menu.set, 180, 90, event_handler, ID_SET);
+ lv_big_button_create(scr, "F:/bmp_printing.bin", main_menu.print, 340, 90, event_handler, ID_PRINT);
+ }
+
+ #if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ // If calibration is required, let's trigger it now, handles the case when there is default value in configuration files
+ if (!touch_calibration.calibration_loaded()) {
+ lv_clear_ready_print();
+ lv_draw_touch_calibration_screen();
+ }
+ #endif
+}
+
+void lv_clear_ready_print() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h
new file mode 100644
index 0000000..7d17fb2
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ready_print.h
@@ -0,0 +1,40 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_ready_print(void);
+extern void mks_disp_test();
+extern void disp_Limit_ok();
+extern void disp_Limit_error();
+extern void disp_det_error();
+extern void disp_det_ok();
+extern void disp_tmc_ok();
+extern void disp_tmc_error();
+extern void lv_clear_ready_print();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp
new file mode 100644
index 0000000..328f795
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.cpp
@@ -0,0 +1,134 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ready_print.h"
+#include "draw_set.h"
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "pic_manager.h"
+
+#include "../../../../gcode/queue.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if HAS_SUICIDE
+ #include "../../../../MarlinCore.h"
+#endif
+
+static lv_obj_t *scr;
+extern lv_group_t* g;
+
+enum {
+ ID_S_WIFI = 1,
+ ID_S_FAN,
+ ID_S_ABOUT,
+ ID_S_CONTINUE,
+ ID_S_MOTOR_OFF,
+ ID_S_LANGUAGE,
+ ID_S_MACHINE_PARA,
+ ID_S_EEPROM_SET,
+ ID_S_RETURN
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ if(obj->mks_obj_id != ID_S_MOTOR_OFF) lv_clear_set();
+ switch (obj->mks_obj_id) {
+ case ID_S_FAN:
+ lv_draw_fan();
+ break;
+ case ID_S_ABOUT:
+ lv_draw_about();
+ break;
+ case ID_S_CONTINUE: return;
+ case ID_S_MOTOR_OFF:
+ TERN(HAS_SUICIDE, suicide(), queue.enqueue_now_P(PSTR("M84")));
+ return;
+ case ID_S_LANGUAGE:
+ lv_draw_language();
+ break;
+ case ID_S_MACHINE_PARA:
+ lv_draw_machine_para();
+ break;
+ case ID_S_EEPROM_SET:
+ lv_draw_eeprom_settings();
+ break;
+ case ID_S_RETURN:
+ lv_draw_ready_print();
+ break;
+
+ #if ENABLED(MKS_WIFI_MODULE)
+ case ID_S_WIFI:
+ if (gCfgItems.wifi_mode_sel == STA_MODEL) {
+ if (wifi_link_state == WIFI_CONNECTED) {
+ last_disp_state = SET_UI;
+ lv_draw_wifi();
+ }
+ else {
+ if (uiCfg.command_send == 1) {
+ uint8_t cmd_wifi_list[] = { 0xA5, 0x07, 0x00, 0x00, 0xFC };
+ raw_send_to_wifi(cmd_wifi_list, COUNT(cmd_wifi_list));
+ last_disp_state = SET_UI;
+ lv_draw_wifi_list();
+ }
+ else {
+ last_disp_state = SET_UI;
+ lv_draw_dialog(DIALOG_WIFI_ENABLE_TIPS);
+ }
+ }
+ }
+ else {
+ last_disp_state = SET_UI;
+ lv_draw_wifi();
+ }
+ break;
+ #endif
+ }
+}
+
+void lv_draw_set(void) {
+ scr = lv_screen_create(SET_UI);
+ lv_big_button_create(scr, "F:/bmp_eeprom_settings.bin", set_menu.eepromSet, INTERVAL_V, titleHeight, event_handler, ID_S_EEPROM_SET);
+ lv_big_button_create(scr, "F:/bmp_fan.bin", set_menu.fan, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_S_FAN);
+ lv_big_button_create(scr, "F:/bmp_about.bin", set_menu.about, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_S_ABOUT);
+ lv_big_button_create(scr, ENABLED(HAS_SUICIDE) ? "F:/bmp_manual_off.bin" : "F:/bmp_function1.bin", set_menu.TERN(HAS_SUICIDE, shutdown, motoroff), BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_S_MOTOR_OFF);
+ lv_big_button_create(scr, "F:/bmp_machine_para.bin", set_menu.machine_para, INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_S_MACHINE_PARA);
+ #if HAS_LANG_SELECT_SCREEN
+ lv_big_button_create(scr, "F:/bmp_language.bin", set_menu.language, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_S_LANGUAGE);
+ #endif
+ #if ENABLED(MKS_WIFI_MODULE)
+ lv_big_button_create(scr, "F:/bmp_wifi.bin", set_menu.wifi, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_S_WIFI);
+ #endif
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_S_RETURN);
+}
+
+void lv_clear_set() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h
new file mode 100644
index 0000000..eed0c6c
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_set.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_set(void);
+extern void lv_clear_set();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp
new file mode 100644
index 0000000..e3f26d8
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.cpp
@@ -0,0 +1,115 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_STEP_RETURN = 1,
+ ID_STEP_X,
+ ID_STEP_Y,
+ ID_STEP_Z,
+ ID_STEP_E0,
+ ID_STEP_E1,
+ ID_STEP_DOWN,
+ ID_STEP_UP
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_step_settings();
+ switch (obj->mks_obj_id) {
+ case ID_STEP_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_draw_return_ui();
+ return;
+ case ID_STEP_X:
+ value = Xstep;
+ break;
+ case ID_STEP_Y:
+ value = Ystep;
+ break;
+ case ID_STEP_Z:
+ value = Zstep;
+ break;
+ case ID_STEP_E0:
+ value = E0step;
+ break;
+ case ID_STEP_E1:
+ value = E1step;
+ break;
+ case ID_STEP_UP:
+ uiCfg.para_ui_page = 0;
+ lv_draw_step_settings();
+ return;
+ case ID_STEP_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_draw_step_settings();
+ return;
+ }
+ lv_draw_number_key();
+}
+
+void lv_draw_step_settings(void) {
+ char str_1[16];
+ scr = lv_screen_create(STEPS_UI, machine_menu.StepsConfTitle);
+
+ if (uiCfg.para_ui_page != 1) {
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[X_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.X_Steps, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_STEP_X, 0, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Y_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Y_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_STEP_Y, 1, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[Z_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_STEP_Z, 2, public_buf_l);
+
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E0_Steps, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_STEP_E0, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_STEP_DOWN);
+ }
+ else {
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(planner.settings.axis_steps_per_mm[E_AXIS_N(1)], 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E1_Steps, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_STEP_E1, 0, public_buf_l);
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_STEP_UP);
+ }
+ lv_screen_menu_item_return(scr, event_handler, ID_STEP_RETURN);
+}
+
+void lv_clear_step_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h
new file mode 100644
index 0000000..b7eaeb4
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_step_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_step_settings(void);
+extern void lv_clear_step_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp
new file mode 100644
index 0000000..acea430
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.cpp
@@ -0,0 +1,156 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, HAS_TRINAMIC_CONFIG)
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/stepper/indirection.h"
+#include "../../../../feature/tmc_util.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_TMC_CURRENT_RETURN = 1,
+ ID_TMC_CURRENT_X,
+ ID_TMC_CURRENT_Y,
+ ID_TMC_CURRENT_Z,
+ ID_TMC_CURRENT_E0,
+ ID_TMC_CURRENT_E1,
+ ID_TMC_CURRENT_DOWN,
+ ID_TMC_CURRENT_UP
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_tmc_current_settings();
+ switch (obj->mks_obj_id) {
+ case ID_TMC_CURRENT_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_draw_return_ui();
+ return;
+ #if AXIS_IS_TMC(X)
+ case ID_TMC_CURRENT_X:
+ value = Xcurrent;
+ break;
+ #endif
+ #if AXIS_IS_TMC(Y)
+ case ID_TMC_CURRENT_Y:
+ value = Ycurrent;
+ break;
+ #endif
+ #if AXIS_IS_TMC(Z)
+ case ID_TMC_CURRENT_Z:
+ value = Zcurrent;
+ break;
+ #endif
+ #if AXIS_IS_TMC(E0)
+ case ID_TMC_CURRENT_E0:
+ value = E0current;
+ break;
+ #endif
+ #if AXIS_IS_TMC(E1)
+ case ID_TMC_CURRENT_E1:
+ value = E1current;
+ break;
+ #endif
+
+ case ID_TMC_CURRENT_UP:
+ uiCfg.para_ui_page = 0;
+ lv_draw_tmc_current_settings();
+ return;
+ case ID_TMC_CURRENT_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_draw_tmc_current_settings();
+ return;
+ }
+ lv_draw_number_key();
+
+}
+
+void lv_draw_tmc_current_settings(void) {
+ scr = lv_screen_create(TMC_CURRENT_UI, machine_menu.TmcCurrentConfTitle);
+
+ float milliamps;
+ char str_1[16];
+ if (uiCfg.para_ui_page != 1) {
+ #if AXIS_IS_TMC(X)
+ milliamps = stepperX.getMilliamps();
+ #else
+ milliamps = -1;
+ #endif
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.X_Current, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_CURRENT_X, 0, public_buf_l);
+
+ #if AXIS_IS_TMC(Y)
+ milliamps = stepperY.getMilliamps();
+ #else
+ milliamps = -1;
+ #endif
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Y_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_TMC_CURRENT_Y, 1, public_buf_l);
+
+ #if AXIS_IS_TMC(Z)
+ milliamps = stepperZ.getMilliamps();
+ #else
+ milliamps = -1;
+ #endif
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.Z_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_TMC_CURRENT_Z, 2, public_buf_l);
+
+ #if AXIS_IS_TMC(E0)
+ milliamps = stepperE0.getMilliamps();
+ #else
+ milliamps = -1;
+ #endif
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E0_Current, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_TMC_CURRENT_E0, 3, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_TMC_CURRENT_DOWN);
+ }
+ else {
+ #if AXIS_IS_TMC(E1)
+ milliamps = stepperE1.getMilliamps();
+ #else
+ milliamps = -1;
+ #endif
+ sprintf_P(public_buf_l, PSTR("%s"), dtostrf(milliamps, 1, 1, str_1));
+ lv_screen_menu_item_1_edit(scr, machine_menu.E1_Current, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_CURRENT_E1, 0, public_buf_l);
+
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_TMC_CURRENT_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_TMC_CURRENT_RETURN);
+}
+
+void lv_clear_tmc_current_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && HAS_TRINAMIC_CONFIG
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h
new file mode 100644
index 0000000..927db37
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_current_settings.h
@@ -0,0 +1,34 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_tmc_current_settings(void);
+extern void lv_clear_tmc_current_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
+
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp
new file mode 100644
index 0000000..5ba7fe3
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.cpp
@@ -0,0 +1,154 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, HAS_STEALTHCHOP)
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../module/stepper/indirection.h"
+#include "../../../../feature/tmc_util.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS)
+ #include "../../../../module/settings.h"
+#endif
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_TMC_MODE_RETURN = 1,
+ ID_TMC_MODE_X,
+ ID_TMC_MODE_Y,
+ ID_TMC_MODE_Z,
+ ID_TMC_MODE_E0,
+ ID_TMC_MODE_E1,
+ ID_TMC_MODE_DOWN,
+ ID_TMC_MODE_UP
+};
+
+static lv_obj_t *buttonXState = nullptr, *buttonYState = nullptr, *buttonZState = nullptr, *buttonE0State = nullptr;
+
+static lv_obj_t *buttonE1State = nullptr;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+
+ auto toggle_chop = [&](auto &stepper, auto &button) {
+ const bool isena = stepper.toggle_stepping_mode();
+ lv_screen_menu_item_onoff_update(button, isena);
+ TERN_(EEPROM_SETTINGS, (void)settings.save());
+ };
+
+ switch (obj->mks_obj_id) {
+ case ID_TMC_MODE_RETURN:
+ uiCfg.para_ui_page = 0;
+ lv_clear_tmc_step_mode_settings();
+ lv_draw_return_ui();
+ break;
+
+ #if AXIS_HAS_STEALTHCHOP(X)
+ case ID_TMC_MODE_X:
+ toggle_chop(stepperX, buttonXState);
+ break;
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(Y)
+ case ID_TMC_MODE_Y:
+ toggle_chop(stepperY, buttonYState);
+ break;
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(Z)
+ case ID_TMC_MODE_Z:
+ toggle_chop(stepperZ, buttonZState);
+ break;
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(E0)
+ case ID_TMC_MODE_E0:
+ toggle_chop(stepperE0, buttonE0State);
+ break;
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(E1)
+ case ID_TMC_MODE_E1:
+ toggle_chop(stepperE1, buttonE1State);
+ break;
+ #endif
+
+ case ID_TMC_MODE_UP:
+ uiCfg.para_ui_page = 0;
+ lv_clear_tmc_step_mode_settings();
+ lv_draw_tmc_step_mode_settings();
+ break;
+ case ID_TMC_MODE_DOWN:
+ uiCfg.para_ui_page = 1;
+ lv_clear_tmc_step_mode_settings();
+ lv_draw_tmc_step_mode_settings();
+ break;
+ }
+}
+
+void lv_draw_tmc_step_mode_settings(void) {
+ buttonXState = buttonYState = buttonZState = buttonE0State = buttonE1State = nullptr;
+
+ scr = lv_screen_create(TMC_MODE_UI, machine_menu.TmcStepModeConfTitle);
+
+ bool stealth_X = false, stealth_Y = false, stealth_Z = false, stealth_E0 = false, stealth_E1 = false;
+ #if AXIS_HAS_STEALTHCHOP(X)
+ stealth_X = stepperX.get_stealthChop();
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(Y)
+ stealth_Y = stepperY.get_stealthChop();
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(Z)
+ stealth_Z = stepperZ.get_stealthChop();
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(E0)
+ stealth_E0 = stepperE0.get_stealthChop();
+ #endif
+ #if AXIS_HAS_STEALTHCHOP(E1)
+ stealth_E1 = stepperE1.get_stealthChop();
+ #endif
+
+ if (uiCfg.para_ui_page != 1) {
+ buttonXState = lv_screen_menu_item_onoff(scr, machine_menu.X_StepMode, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_MODE_X, 0, stealth_X);
+ buttonYState = lv_screen_menu_item_onoff(scr, machine_menu.Y_StepMode, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_TMC_MODE_Y, 1, stealth_Y);
+ buttonZState = lv_screen_menu_item_onoff(scr, machine_menu.Z_StepMode, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_TMC_MODE_Z, 2, stealth_Z);
+ buttonE0State = lv_screen_menu_item_onoff(scr, machine_menu.E0_StepMode, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_TMC_MODE_E0, 2, stealth_E0);
+ lv_screen_menu_item_turn_page(scr, machine_menu.next, event_handler, ID_TMC_MODE_DOWN);
+ }
+ else {
+ buttonE1State = lv_screen_menu_item_onoff(scr, machine_menu.E1_StepMode, PARA_UI_POS_X, PARA_UI_POS_Y, event_handler, ID_TMC_MODE_E1, 0, stealth_E1);
+ lv_screen_menu_item_turn_page(scr, machine_menu.previous, event_handler, ID_TMC_MODE_UP);
+ }
+
+ lv_screen_menu_item_return(scr, event_handler, ID_TMC_MODE_RETURN);
+}
+
+void lv_clear_tmc_step_mode_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && HAS_STEALTHCHOP
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h
new file mode 100644
index 0000000..35c57ab
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tmc_step_mode_settings.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_tmc_step_mode_settings(void);
+extern void lv_clear_tmc_step_mode_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp
new file mode 100644
index 0000000..559d166
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.cpp
@@ -0,0 +1,113 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/queue.h"
+#include "../../../../module/temperature.h"
+#include "../../../../inc/MarlinConfig.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+
+enum {
+ ID_T_PRE_HEAT = 1,
+ ID_T_EXTRUCT,
+ ID_T_MOV,
+ ID_T_HOME,
+ ID_T_LEVELING,
+ ID_T_FILAMENT,
+ ID_T_MORE,
+ ID_T_RETURN
+};
+
+#if ENABLED(MKS_TEST)
+ extern uint8_t curent_disp_ui;
+#endif
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
+ bool clear = (obj->mks_obj_id != ID_T_LEVELING);
+ #else
+ constexpr bool clear = true;
+ #endif
+ if (clear) lv_clear_tool();
+ switch (obj->mks_obj_id) {
+ case ID_T_PRE_HEAT:
+ lv_draw_preHeat();
+ break;
+ case ID_T_EXTRUCT:
+ lv_draw_extrusion();
+ break;
+ case ID_T_MOV:
+ lv_draw_move_motor();
+ break;
+ case ID_T_HOME:
+ lv_draw_home();
+ break;
+ case ID_T_LEVELING:
+ #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
+ get_gcode_command(AUTO_LEVELING_COMMAND_ADDR,(uint8_t *)public_buf_m);
+ public_buf_m[sizeof(public_buf_m)-1] = 0;
+ queue.inject_P(PSTR(public_buf_m));
+ #else
+ uiCfg.leveling_first_time = 1;
+ lv_draw_manualLevel();
+ #endif
+ break;
+ case ID_T_FILAMENT:
+ uiCfg.desireSprayerTempBak = thermalManager.temp_hotend[uiCfg.curSprayerChoose].target;
+ lv_draw_filament_change();
+ break;
+ case ID_T_MORE: lv_draw_more(); break;
+ case ID_T_RETURN:
+ TERN_(MKS_TEST, curent_disp_ui = 1);
+ lv_draw_ready_print();
+ break;
+ }
+}
+
+void lv_draw_tool(void) {
+ scr = lv_screen_create(TOOL_UI);
+ lv_big_button_create(scr, "F:/bmp_preHeat.bin", tool_menu.preheat, INTERVAL_V, titleHeight, event_handler, ID_T_PRE_HEAT);
+ lv_big_button_create(scr, "F:/bmp_extruct.bin", tool_menu.extrude, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_T_EXTRUCT);
+ lv_big_button_create(scr, "F:/bmp_mov.bin", tool_menu.move, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_T_MOV);
+ lv_big_button_create(scr, "F:/bmp_zero.bin", tool_menu.home, BTN_X_PIXEL * 3 + INTERVAL_V * 4, titleHeight, event_handler, ID_T_HOME);
+ lv_big_button_create(scr, "F:/bmp_leveling.bin", tool_menu.TERN(AUTO_BED_LEVELING_BILINEAR, autoleveling, leveling), INTERVAL_V, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_T_LEVELING);
+ lv_big_button_create(scr, "F:/bmp_filamentchange.bin", tool_menu.filament, BTN_X_PIXEL+INTERVAL_V*2,BTN_Y_PIXEL+INTERVAL_H+titleHeight, event_handler,ID_T_FILAMENT);
+ lv_big_button_create(scr, "F:/bmp_more.bin", tool_menu.more, BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_T_MORE);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_T_RETURN);
+}
+
+void lv_clear_tool() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h
new file mode 100644
index 0000000..2191adc
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_tool.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_tool(void);
+extern void lv_clear_tool();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.cpp
new file mode 100644
index 0000000..f997f29
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.cpp
@@ -0,0 +1,117 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, TOUCH_SCREEN_CALIBRATION)
+
+#include "draw_ui.h"
+#include "draw_touch_calibration.h"
+#include <lv_conf.h>
+
+#include "../../../../inc/MarlinConfig.h"
+#include "../../../tft_io/touch_calibration.h"
+#include "SPI_TFT.h"
+
+static lv_obj_t *scr;
+static lv_obj_t *status_label;
+
+static void event_handler(lv_obj_t *obj, lv_event_t event);
+
+enum {
+ ID_TC_RETURN = 1
+};
+
+static void drawCross(uint16_t x, uint16_t y, uint16_t color) {
+ SPI_TFT.tftio.set_window(x - 15, y, x + 15, y);
+ SPI_TFT.tftio.WriteMultiple(color, 31);
+ SPI_TFT.tftio.set_window(x, y - 15, x, y + 15);
+ SPI_TFT.tftio.WriteMultiple(color, 31);
+}
+
+void lv_update_touch_calibration_screen() {
+ uint16_t x, y;
+
+ calibrationState calibration_stage = touch_calibration.get_calibration_state();
+ if (calibration_stage == CALIBRATION_NONE) {
+ // start and clear screen
+ calibration_stage = touch_calibration.calibration_start();
+ }
+ else {
+ // clear last cross
+ x = touch_calibration.calibration_points[_MIN(calibration_stage - 1, CALIBRATION_BOTTOM_RIGHT)].x;
+ y = touch_calibration.calibration_points[_MIN(calibration_stage - 1, CALIBRATION_BOTTOM_RIGHT)].y;
+ drawCross(x, y, LV_COLOR_BACKGROUND.full);
+ }
+
+ const char *str = nullptr;
+ if (calibration_stage < CALIBRATION_SUCCESS) {
+ // handle current state
+ switch (calibration_stage) {
+ case CALIBRATION_TOP_LEFT: str = GET_TEXT(MSG_TOP_LEFT); break;
+ case CALIBRATION_BOTTOM_LEFT: str = GET_TEXT(MSG_BOTTOM_LEFT); break;
+ case CALIBRATION_TOP_RIGHT: str = GET_TEXT(MSG_TOP_RIGHT); break;
+ case CALIBRATION_BOTTOM_RIGHT: str = GET_TEXT(MSG_BOTTOM_RIGHT); break;
+ default: break;
+ }
+
+ x = touch_calibration.calibration_points[calibration_stage].x;
+ y = touch_calibration.calibration_points[calibration_stage].y;
+ drawCross(x, y, LV_COLOR_WHITE.full);
+ }
+ else {
+ // end calibration
+ str = calibration_stage == CALIBRATION_SUCCESS ? GET_TEXT(MSG_CALIBRATION_COMPLETED) : GET_TEXT(MSG_CALIBRATION_FAILED);
+ touch_calibration.calibration_end();
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_TC_RETURN);
+ }
+
+ // draw current message
+ lv_label_set_text(status_label, str);
+ lv_obj_align(status_label, nullptr, LV_ALIGN_CENTER, 0, 0);
+}
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_TC_RETURN:
+ lv_clear_touch_calibration_screen();
+ lv_draw_return_ui();
+ break;
+ }
+}
+
+void lv_draw_touch_calibration_screen() {
+ scr = lv_screen_create(TOUCH_CALIBRATION_UI, "");
+
+ status_label = lv_label_create(scr, "");
+ lv_obj_align(status_label, nullptr, LV_ALIGN_CENTER, 0, 0);
+
+ lv_refr_now(lv_refr_get_disp_refreshing());
+
+ lv_update_touch_calibration_screen();
+}
+
+void lv_clear_touch_calibration_screen() {
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI && TOUCH_SCREEN_CALIBRATION
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.h
new file mode 100644
index 0000000..63749a2
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_touch_calibration.h
@@ -0,0 +1,34 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_touch_calibration_screen();
+extern void lv_clear_touch_calibration_screen();
+extern void lv_update_touch_calibration_screen();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.cpp
new file mode 100644
index 0000000..55d8a1b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.cpp
@@ -0,0 +1,101 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../../MarlinCore.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../module/probe.h"
+
+#include "draw_ui.h"
+
+extern lv_group_t * g;
+static lv_obj_t * scr, * zOffsetText;
+
+enum {
+ ID_TM_INIT = 1,
+ ID_TM_ZOFFSETPOS,
+ ID_TM_ZOFFSETNEG,
+ ID_TM_SAVE,
+ ID_TM_TEST,
+ ID_TM_RETURN
+ };
+
+static void event_handler(lv_obj_t * obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_TM_INIT:
+ queue.inject_P(PSTR("M851 Z0\nG28\nG1 Z0 F200\nM211 S0"));
+ break;
+ case ID_TM_ZOFFSETPOS:
+ queue.inject_P(PSTR("M290 Z0.1"));
+ break;
+ case ID_TM_ZOFFSETNEG:
+ queue.inject_P(PSTR("M290 Z-0.1"));
+ break;
+ case ID_TM_SAVE:
+ queue.inject_P(PSTR("M211 S1\nM500\nG28 X Y"));
+ break;
+ case ID_TM_TEST:
+ queue.inject_P(PSTR("G28\nG1 Z0"));
+ break;
+ case ID_TM_RETURN:
+ lv_clear_touchmi_settings();
+ lv_draw_return_ui();
+ break;
+
+ }
+}
+
+void lv_draw_touchmi_settings(void) {
+ scr = lv_screen_create(TOUCHMI_UI, machine_menu.LevelingTouchmiConf);
+ lv_big_button_create(scr, "F:/bmp_speed0.bin", machine_menu.TouchmiInit, INTERVAL_V, titleHeight, event_handler, ID_TM_INIT);
+ lv_big_button_create(scr, "F:/bmp_zAdd.bin", machine_menu.TouchmiOffsetpos, BTN_X_PIXEL + INTERVAL_V * 2, titleHeight, event_handler, ID_TM_ZOFFSETPOS);
+ lv_big_button_create(scr, "F:/bmp_zDec.bin", machine_menu.TouchmiOffsetneg, BTN_X_PIXEL + INTERVAL_V * 2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_TM_ZOFFSETNEG);
+ lv_big_button_create(scr, "F:/bmp_set.bin", machine_menu.TouchmiSave, BTN_X_PIXEL * 2 + INTERVAL_V * 3, titleHeight, event_handler, ID_TM_SAVE);
+ lv_big_button_create(scr, "F:/bmp_in.bin", machine_menu.TouchmiTest, BTN_X_PIXEL * 3 + INTERVAL_V * 4,titleHeight, event_handler, ID_TM_TEST);
+ lv_big_button_create(scr, "F:/bmp_return.bin", common_menu.text_back, BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_TM_RETURN);
+
+
+ zOffsetText = lv_label_create(scr, 290, TITLE_YPOS, nullptr);
+ disp_z_offset_value_TM();
+}
+
+void disp_z_offset_value_TM() {
+ char buf[20];
+ #if HAS_BED_PROBE
+ char str_1[16];
+ #endif
+ sprintf_P(buf, PSTR("offset Z: %s mm"), TERN(HAS_BED_PROBE, dtostrf(probe.offset.z, 1, 2, str_1), "0"));
+ lv_label_set_text(zOffsetText, buf);
+}
+
+
+void lv_clear_touchmi_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.h
new file mode 100644
index 0000000..cea28df
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_touchmi_settings.h
@@ -0,0 +1,35 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_touchmi_settings(void);
+extern void lv_clear_touchmi_settings();
+extern void disp_z_offset_value_TM();
+
+//extern void disp_temp_ready_print();
+#ifdef __cplusplus
+} /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp
new file mode 100644
index 0000000..8fc399e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.cpp
@@ -0,0 +1,1510 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "SPI_TFT.h"
+
+#include "tft_lvgl_configuration.h"
+
+#include "pic_manager.h"
+
+#include "draw_ui.h"
+#include "mks_hardware_test.h"
+
+#include <SPI.h>
+
+#include "../../../../MarlinCore.h" // for marlin_state
+#include "../../../../sd/cardreader.h"
+#include "../../../../module/motion.h"
+#include "../../../../module/planner.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+#if ENABLED(PARK_HEAD_ON_PAUSE)
+ #include "../../../../feature/pause.h"
+#endif
+
+#if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ #include "draw_touch_calibration.h"
+#endif
+
+CFG_ITMES gCfgItems;
+UI_CFG uiCfg;
+DISP_STATE_STACK disp_state_stack;
+DISP_STATE disp_state = MAIN_UI;
+DISP_STATE last_disp_state;
+PRINT_TIME print_time;
+num_key_value_state value;
+keyboard_value_state keyboard_value;
+
+uint32_t To_pre_view;
+bool gcode_preview_over, flash_preview_begin, default_preview_flg;
+uint32_t size = 809;
+uint16_t row;
+bool temps_update_flag;
+uint8_t printing_rate_update_flag;
+
+extern bool once_flag;
+extern uint8_t sel_id;
+extern lv_group_t *g;
+
+extern uint8_t bmp_public_buf[14 * 1024];
+extern uint8_t public_buf[513];
+
+extern void LCD_IO_WriteData(uint16_t RegValue);
+
+static const char custom_gcode_command[][100] = {
+ "G28\nG29\nM500",
+ "G28",
+ "G28",
+ "G28",
+ "G28"
+};
+
+lv_point_t line_points[4][2] = {
+ {{PARA_UI_POS_X, PARA_UI_POS_Y + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y + PARA_UI_SIZE_Y}},
+ {{PARA_UI_POS_X, PARA_UI_POS_Y*2 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*2 + PARA_UI_SIZE_Y}},
+ {{PARA_UI_POS_X, PARA_UI_POS_Y*3 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*3 + PARA_UI_SIZE_Y}},
+ {{PARA_UI_POS_X, PARA_UI_POS_Y*4 + PARA_UI_SIZE_Y}, {TFT_WIDTH, PARA_UI_POS_Y*4 + PARA_UI_SIZE_Y}}
+};
+void gCfgItems_init() {
+ gCfgItems.multiple_language = MULTI_LANGUAGE_ENABLE;
+ #if 1 // LCD_LANGUAGE == en
+ gCfgItems.language = LANG_ENGLISH;
+ #elif LCD_LANGUAGE == zh_CN
+ gCfgItems.language = LANG_SIMPLE_CHINESE;
+ #elif LCD_LANGUAGE == zh_TW
+ gCfgItems.language = LANG_COMPLEX_CHINESE;
+ #elif LCD_LANGUAGE == jp_kana
+ gCfgItems.language = LANG_JAPAN;
+ #elif LCD_LANGUAGE == de
+ gCfgItems.language = LANG_GERMAN;
+ #elif LCD_LANGUAGE == fr
+ gCfgItems.language = LANG_FRENCH;
+ #elif LCD_LANGUAGE == ru
+ gCfgItems.language = LANG_RUSSIAN;
+ #elif LCD_LANGUAGE == ko_KR
+ gCfgItems.language = LANG_KOREAN;
+ #elif LCD_LANGUAGE == tr
+ gCfgItems.language = LANG_TURKISH;
+ #elif LCD_LANGUAGE == es
+ gCfgItems.language = LANG_SPANISH;
+ #elif LCD_LANGUAGE == el
+ gCfgItems.language = LANG_GREEK;
+ #elif LCD_LANGUAGE == it
+ gCfgItems.language = LANG_ITALY;
+ #elif LCD_LANGUAGE == pt
+ gCfgItems.language = LANG_PORTUGUESE;
+ #endif
+ gCfgItems.leveling_mode = 0;
+ gCfgItems.from_flash_pic = false;
+ gCfgItems.curFilesize = 0;
+ gCfgItems.finish_power_off = false;
+ gCfgItems.pause_reprint = false;
+ gCfgItems.pausePosX = -1;
+ gCfgItems.pausePosY = -1;
+ gCfgItems.pausePosZ = 5;
+ gCfgItems.levelingPos[0][0] = X_MIN_POS + 30;
+ gCfgItems.levelingPos[0][1] = Y_MIN_POS + 30;
+ gCfgItems.levelingPos[1][0] = X_MAX_POS - 30;
+ gCfgItems.levelingPos[1][1] = Y_MIN_POS + 30;
+ gCfgItems.levelingPos[2][0] = X_MAX_POS - 30;
+ gCfgItems.levelingPos[2][1] = Y_MAX_POS - 30;
+ gCfgItems.levelingPos[3][0] = X_MIN_POS + 30;
+ gCfgItems.levelingPos[3][1] = Y_MAX_POS - 30;
+ gCfgItems.levelingPos[4][0] = X_BED_SIZE / 2;
+ gCfgItems.levelingPos[4][1] = Y_BED_SIZE / 2;
+ gCfgItems.cloud_enable = false;
+ gCfgItems.wifi_mode_sel = STA_MODEL;
+ gCfgItems.fileSysType = FILE_SYS_SD;
+ gCfgItems.wifi_type = ESP_WIFI;
+ gCfgItems.filamentchange_load_length = 200;
+ gCfgItems.filamentchange_load_speed = 1000;
+ gCfgItems.filamentchange_unload_length = 200;
+ gCfgItems.filamentchange_unload_speed = 1000;
+ gCfgItems.filament_limit_temper = 200;
+
+ gCfgItems.encoder_enable = true;
+
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)&gCfgItems.spi_flash_flag, VAR_INF_ADDR, sizeof(gCfgItems.spi_flash_flag));
+ if (gCfgItems.spi_flash_flag == FLASH_INF_VALID_FLAG) {
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems));
+ }
+ else {
+ gCfgItems.spi_flash_flag = FLASH_INF_VALID_FLAG;
+ W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems));
+ //init gcode command
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[0], AUTO_LEVELING_COMMAND_ADDR, 100);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[1], OTHERS_COMMAND_ADDR_1, 100);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[2], OTHERS_COMMAND_ADDR_2, 100);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[3], OTHERS_COMMAND_ADDR_3, 100);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&custom_gcode_command[4], OTHERS_COMMAND_ADDR_4, 100);
+ }
+
+ const byte rot = (TFT_ROTATION & TFT_ROTATE_180) ? 0xEE : 0x00;
+ if (gCfgItems.disp_rotation_180 != rot) {
+ gCfgItems.disp_rotation_180 = rot;
+ update_spi_flash();
+ }
+
+ uiCfg.F[0] = 'N';
+ uiCfg.F[1] = 'A';
+ uiCfg.F[2] = 'N';
+ uiCfg.F[3] = 'O';
+ W25QXX.SPI_FLASH_BlockErase(REFLSHE_FLGA_ADD + 32 - 64*1024);
+ W25QXX.SPI_FLASH_BufferWrite(uiCfg.F,REFLSHE_FLGA_ADD,4);
+}
+
+void ui_cfg_init() {
+ uiCfg.curTempType = 0;
+ uiCfg.curSprayerChoose = 0;
+ uiCfg.stepHeat = 10;
+ uiCfg.leveling_first_time = 0;
+ uiCfg.para_ui_page = 0;
+ uiCfg.extruStep = 5;
+ uiCfg.extruSpeed = 10;
+ uiCfg.move_dist = 1;
+ uiCfg.moveSpeed = 3000;
+ uiCfg.stepPrintSpeed = 10;
+ uiCfg.command_send = 0;
+ uiCfg.dialogType = 0;
+ uiCfg.filament_heat_completed_load = 0;
+ uiCfg.filament_rate = 0;
+ uiCfg.filament_loading_completed = 0;
+ uiCfg.filament_unloading_completed = 0;
+ uiCfg.filament_loading_time_flg = 0;
+ uiCfg.filament_loading_time_cnt = 0;
+ uiCfg.filament_unloading_time_flg = 0;
+ uiCfg.filament_unloading_time_cnt = 0;
+
+ #if ENABLED(MKS_WIFI_MODULE)
+ memset(&wifiPara, 0, sizeof(wifiPara));
+ memset(&ipPara, 0, sizeof(ipPara));
+ strcpy(wifiPara.ap_name, WIFI_AP_NAME);
+ strcpy(wifiPara.keyCode, WIFI_KEY_CODE);
+ //client
+ strcpy(ipPara.ip_addr, IP_ADDR);
+ strcpy(ipPara.mask, IP_MASK);
+ strcpy(ipPara.gate, IP_GATE);
+ strcpy(ipPara.dns, IP_DNS);
+
+ ipPara.dhcp_flag = IP_DHCP_FLAG;
+
+ //AP
+ strcpy(ipPara.dhcpd_ip, AP_IP_ADDR);
+ strcpy(ipPara.dhcpd_mask, AP_IP_MASK);
+ strcpy(ipPara.dhcpd_gate, AP_IP_GATE);
+ strcpy(ipPara.dhcpd_dns, AP_IP_DNS);
+ strcpy(ipPara.start_ip_addr, IP_START_IP);
+ strcpy(ipPara.end_ip_addr, IP_END_IP);
+
+ ipPara.dhcpd_flag = AP_IP_DHCP_FLAG;
+
+ strcpy((char*)uiCfg.cloud_hostUrl, "baizhongyun.cn");
+ uiCfg.cloud_port = 10086;
+ #endif
+
+ uiCfg.filament_loading_time = (uint32_t)((gCfgItems.filamentchange_load_length * 60.0 / gCfgItems.filamentchange_load_speed) + 0.5);
+ uiCfg.filament_unloading_time = (uint32_t)((gCfgItems.filamentchange_unload_length * 60.0 / gCfgItems.filamentchange_unload_speed) + 0.5);
+}
+
+void update_spi_flash() {
+ uint8_t command_buf[512];
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+ //read back the gcode command befor erase spi flash
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf));
+ W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems));
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf));
+}
+
+void update_gcode_command(int addr,uint8_t *s) {
+ uint8_t command_buf[512];
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+ //read back the gcode command befor erase spi flash
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf));
+ W25QXX.SPI_FLASH_SectorErase(VAR_INF_ADDR);
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&gCfgItems, VAR_INF_ADDR, sizeof(gCfgItems));
+ switch (addr) {
+ case AUTO_LEVELING_COMMAND_ADDR: memcpy(&command_buf[0*100], s, 100); break;
+ case OTHERS_COMMAND_ADDR_1: memcpy(&command_buf[1*100], s, 100); break;
+ case OTHERS_COMMAND_ADDR_2: memcpy(&command_buf[2*100], s, 100); break;
+ case OTHERS_COMMAND_ADDR_3: memcpy(&command_buf[3*100], s, 100); break;
+ case OTHERS_COMMAND_ADDR_4: memcpy(&command_buf[4*100], s, 100); break;
+ default: break;
+ }
+ W25QXX.SPI_FLASH_BufferWrite((uint8_t *)&command_buf, GCODE_COMMAND_ADDR, sizeof(command_buf));
+}
+
+void get_gcode_command(int addr,uint8_t *d) {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)d, addr, 100);
+}
+
+lv_style_t tft_style_scr;
+lv_style_t tft_style_label_pre;
+lv_style_t tft_style_label_rel;
+lv_style_t style_line;
+lv_style_t style_para_value_pre;
+lv_style_t style_para_value_rel;
+
+lv_style_t style_num_key_pre;
+lv_style_t style_num_key_rel;
+
+lv_style_t style_num_text;
+lv_style_t style_sel_text;
+
+lv_style_t style_para_value;
+lv_style_t style_para_back;
+
+lv_style_t lv_bar_style_indic;
+
+lv_style_t style_btn_pr;
+lv_style_t style_btn_rel;
+
+void tft_style_init() {
+ lv_style_copy(&tft_style_scr, &lv_style_scr);
+ tft_style_scr.body.main_color = LV_COLOR_BACKGROUND;
+ tft_style_scr.body.grad_color = LV_COLOR_BACKGROUND;
+ tft_style_scr.text.color = LV_COLOR_TEXT;
+ tft_style_scr.text.sel_color = LV_COLOR_TEXT;
+ tft_style_scr.line.width = 0;
+ tft_style_scr.text.letter_space = 0;
+ tft_style_scr.text.line_space = 0;
+
+ lv_style_copy(&tft_style_label_pre, &lv_style_scr);
+ lv_style_copy(&tft_style_label_rel, &lv_style_scr);
+ tft_style_label_pre.body.main_color = LV_COLOR_BACKGROUND;
+ tft_style_label_pre.body.grad_color = LV_COLOR_BACKGROUND;
+ tft_style_label_pre.text.color = LV_COLOR_TEXT;
+ tft_style_label_pre.text.sel_color = LV_COLOR_TEXT;
+ tft_style_label_rel.body.main_color = LV_COLOR_BACKGROUND;
+ tft_style_label_rel.body.grad_color = LV_COLOR_BACKGROUND;
+ tft_style_label_rel.text.color = LV_COLOR_TEXT;
+ tft_style_label_rel.text.sel_color = LV_COLOR_TEXT;
+ tft_style_label_pre.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT);
+ tft_style_label_rel.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT);
+ tft_style_label_pre.line.width = 0;
+ tft_style_label_rel.line.width = 0;
+ tft_style_label_pre.text.letter_space = 0;
+ tft_style_label_rel.text.letter_space = 0;
+ tft_style_label_pre.text.line_space = 0;
+ tft_style_label_rel.text.line_space = 0;
+
+ lv_style_copy(&style_para_value_pre, &lv_style_scr);
+ lv_style_copy(&style_para_value_rel, &lv_style_scr);
+ style_para_value_pre.body.main_color = LV_COLOR_BACKGROUND;
+ style_para_value_pre.body.grad_color = LV_COLOR_BACKGROUND;
+ style_para_value_pre.text.color = LV_COLOR_TEXT;
+ style_para_value_pre.text.sel_color = LV_COLOR_TEXT;
+ style_para_value_rel.body.main_color = LV_COLOR_BACKGROUND;
+ style_para_value_rel.body.grad_color = LV_COLOR_BACKGROUND;
+ style_para_value_rel.text.color = LV_COLOR_BLACK;
+ style_para_value_rel.text.sel_color = LV_COLOR_BLACK;
+ style_para_value_pre.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT);
+ style_para_value_rel.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT);
+ style_para_value_pre.line.width = 0;
+ style_para_value_rel.line.width = 0;
+ style_para_value_pre.text.letter_space = 0;
+ style_para_value_rel.text.letter_space = 0;
+ style_para_value_pre.text.line_space = 0;
+ style_para_value_rel.text.line_space = 0;
+
+ lv_style_copy(&style_num_key_pre, &lv_style_scr);
+ lv_style_copy(&style_num_key_rel, &lv_style_scr);
+ style_num_key_pre.body.main_color = LV_COLOR_KEY_BACKGROUND;
+ style_num_key_pre.body.grad_color = LV_COLOR_KEY_BACKGROUND;
+ style_num_key_pre.text.color = LV_COLOR_TEXT;
+ style_num_key_pre.text.sel_color = LV_COLOR_TEXT;
+ style_num_key_rel.body.main_color = LV_COLOR_KEY_BACKGROUND;
+ style_num_key_rel.body.grad_color = LV_COLOR_KEY_BACKGROUND;
+ style_num_key_rel.text.color = LV_COLOR_TEXT;
+ style_num_key_rel.text.sel_color = LV_COLOR_TEXT;
+ #if HAS_SPI_FLASH_FONT
+ style_num_key_pre.text.font = &gb2312_puhui32;
+ style_num_key_rel.text.font = &gb2312_puhui32;
+ #else
+ style_num_key_pre.text.font = LV_FONT_DEFAULT;
+ style_num_key_rel.text.font = LV_FONT_DEFAULT;
+ #endif
+ style_num_key_pre.line.width = 0;
+ style_num_key_rel.line.width = 0;
+ style_num_key_pre.text.letter_space = 0;
+ style_num_key_rel.text.letter_space = 0;
+ style_num_key_pre.text.line_space = 0;
+ style_num_key_rel.text.line_space = 0;
+
+ lv_style_copy(&style_num_text, &lv_style_scr);
+ style_num_text.body.main_color = LV_COLOR_WHITE;
+ style_num_text.body.grad_color = LV_COLOR_WHITE;
+ style_num_text.text.color = LV_COLOR_BLACK;
+ style_num_text.text.sel_color = LV_COLOR_BLACK;
+ style_num_text.text.font = TERN(HAS_SPI_FLASH_FONT, &gb2312_puhui32, LV_FONT_DEFAULT);
+ style_num_text.line.width = 0;
+ style_num_text.text.letter_space = 0;
+ style_num_text.text.line_space = 0;
+
+ lv_style_copy(&style_sel_text, &lv_style_scr);
+ style_sel_text.body.main_color = LV_COLOR_BACKGROUND;
+ style_sel_text.body.grad_color = LV_COLOR_BACKGROUND;
+ style_sel_text.text.color = LV_COLOR_YELLOW;
+ style_sel_text.text.sel_color = LV_COLOR_YELLOW;
+ style_sel_text.text.font = &gb2312_puhui32;
+ style_sel_text.line.width = 0;
+ style_sel_text.text.letter_space = 0;
+ style_sel_text.text.line_space = 0;
+ lv_style_copy(&style_line, &lv_style_plain);
+ style_line.line.color = LV_COLOR_MAKE(0x49, 0x54, 0xFF);
+ style_line.line.width = 1;
+ style_line.line.rounded = 1;
+
+ lv_style_copy(&style_para_value, &lv_style_plain);
+ style_para_value.body.border.color = LV_COLOR_BACKGROUND;
+ style_para_value.body.border.width = 1;
+ style_para_value.body.main_color = LV_COLOR_WHITE;
+ style_para_value.body.grad_color = LV_COLOR_WHITE;
+ style_para_value.body.shadow.width = 0;
+ style_para_value.body.radius = 3;
+ style_para_value.text.color = LV_COLOR_BLACK;
+ style_para_value.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22);
+
+ lv_style_copy(&style_para_back, &lv_style_plain);
+ style_para_back.body.border.color = LV_COLOR_BACKGROUND;
+ style_para_back.body.border.width = 1;
+ style_para_back.body.main_color = TFT_LV_PARA_BACK_BODY_COLOR;
+ style_para_back.body.grad_color = TFT_LV_PARA_BACK_BODY_COLOR;
+ style_para_back.body.shadow.width = 0;
+ style_para_back.body.radius = 3;
+ style_para_back.text.color = LV_COLOR_WHITE;
+ style_para_back.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22);
+
+ lv_style_copy(&style_btn_rel, &lv_style_plain);
+ style_btn_rel.body.border.color = lv_color_hex3(0x269);
+ style_btn_rel.body.border.width = 1;
+ style_btn_rel.body.main_color = lv_color_hex3(0xADF);
+ style_btn_rel.body.grad_color = lv_color_hex3(0x46B);
+ style_btn_rel.body.shadow.width = 4;
+ style_btn_rel.body.shadow.type = LV_SHADOW_BOTTOM;
+ style_btn_rel.body.radius = LV_RADIUS_CIRCLE;
+ style_btn_rel.text.color = lv_color_hex3(0xDEF);
+ style_btn_rel.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22);
+
+ lv_style_copy(&style_btn_pr, &style_btn_rel);
+ style_btn_pr.body.border.color = lv_color_hex3(0x46B);
+ style_btn_pr.body.main_color = lv_color_hex3(0x8BD);
+ style_btn_pr.body.grad_color = lv_color_hex3(0x24A);
+ style_btn_pr.body.shadow.width = 2;
+ style_btn_pr.text.color = lv_color_hex3(0xBCD);
+ style_btn_pr.text.font = &TERN(HAS_SPI_FLASH_FONT, gb2312_puhui32, lv_font_roboto_22);
+
+ lv_style_copy(&lv_bar_style_indic, &lv_style_pretty_color);
+ lv_bar_style_indic.text.color = lv_color_hex3(0xADF);
+ lv_bar_style_indic.image.color = lv_color_hex3(0xADF);
+ lv_bar_style_indic.line.color = lv_color_hex3(0xADF);
+ lv_bar_style_indic.body.main_color = lv_color_hex3(0xADF);
+ lv_bar_style_indic.body.grad_color = lv_color_hex3(0xADF);
+ lv_bar_style_indic.body.border.color = lv_color_hex3(0xADF);
+}
+
+#define MAX_TITLE_LEN 28
+
+char public_buf_m[100] = {0};
+char public_buf_l[30];
+
+void titleText_cat(char *str, int strSize, char *addPart) {
+ if (str == 0 || addPart == 0) return;
+ if ((int)(strlen(str) + strlen(addPart)) >= strSize) return;
+ strcat(str, addPart);
+}
+
+char *getDispText(int index) {
+
+ ZERO(public_buf_l);
+
+ switch (disp_state_stack._disp_state[index]) {
+ case PRINT_READY_UI:
+ strcpy(public_buf_l, main_menu.title);
+ break;
+ case PRINT_FILE_UI:
+ strcpy(public_buf_l, file_menu.title);
+ break;
+ case PRINTING_UI:
+ if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
+ #ifndef TFT35
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
+ #endif
+ ) strcpy(public_buf_l, common_menu.print_special_title);
+ else strcpy(public_buf_l, printing_menu.title);
+ break;
+ case MOVE_MOTOR_UI:
+ strcpy(public_buf_l, move_menu.title);
+ break;
+ case OPERATE_UI:
+ if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
+ #ifndef TFT35
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
+ #endif
+ ) strcpy(public_buf_l, common_menu.operate_special_title);
+ else strcpy(public_buf_l, operation_menu.title);
+ break;
+
+ case PAUSE_UI:
+ if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == OPERATE_UI
+ || disp_state_stack._disp_state[disp_state_stack._disp_index] == PAUSE_UI
+ ) strcpy(public_buf_l, common_menu.pause_special_title);
+ else strcpy(public_buf_l, pause_menu.title);
+ break;
+
+ case EXTRUSION_UI:
+ strcpy(public_buf_l, extrude_menu.title);
+ break;
+ case CHANGE_SPEED_UI:
+ strcpy(public_buf_l, speed_menu.title);
+ break;
+ case FAN_UI:
+ strcpy(public_buf_l, fan_menu.title);
+ break;
+ case PRE_HEAT_UI:
+ if ((disp_state_stack._disp_state[disp_state_stack._disp_index - 1] == OPERATE_UI))
+ strcpy(public_buf_l, preheat_menu.adjust_title);
+ else strcpy(public_buf_l, preheat_menu.title);
+ break;
+ case SET_UI:
+ strcpy(public_buf_l, set_menu.title);
+ break;
+ case ZERO_UI:
+ strcpy(public_buf_l, home_menu.title);
+ break;
+ case SPRAYER_UI: break;
+ case MACHINE_UI: break;
+ case LANGUAGE_UI:
+ strcpy(public_buf_l, language_menu.title);
+ break;
+ case ABOUT_UI:
+ strcpy(public_buf_l, about_menu.title);
+ break;
+ case LOG_UI: break;
+ case DISK_UI:
+ strcpy(public_buf_l, filesys_menu.title);
+ break;
+ case DIALOG_UI:
+ strcpy(public_buf_l, common_menu.dialog_confirm_title);
+ break;
+ case WIFI_UI:
+ strcpy(public_buf_l, wifi_menu.title);
+ break;
+ case MORE_UI:
+ case PRINT_MORE_UI:
+ strcpy(public_buf_l, more_menu.title);
+ break;
+ case FILAMENTCHANGE_UI:
+ strcpy(public_buf_l, filament_menu.title);
+ break;
+ case LEVELING_UI:
+ case MESHLEVELING_UI:
+ strcpy(public_buf_l, leveling_menu.title);
+ break;
+ case BIND_UI:
+ strcpy(public_buf_l, cloud_menu.title);
+ break;
+ case TOOL_UI:
+ strcpy(public_buf_l, tool_menu.title);
+ break;
+ case WIFI_LIST_UI:
+ #if ENABLED(MKS_WIFI_MODULE)
+ strcpy(public_buf_l, list_menu.title);
+ break;
+ #endif
+ case MACHINE_PARA_UI:
+ strcpy(public_buf_l, MachinePara_menu.title);
+ break;
+ case BABY_STEP_UI:
+ strcpy(public_buf_l, operation_menu.babystep);
+ break;
+ case EEPROM_SETTINGS_UI:
+ strcpy(public_buf_l, eeprom_menu.title);
+ break;
+ default: break;
+ }
+
+ return public_buf_l;
+}
+
+char *creat_title_text() {
+ int index = 0;
+ char *tmpText = 0;
+ char tmpCurFileStr[20];
+
+ ZERO(tmpCurFileStr);
+
+ cutFileName(list_file.long_name[sel_id], 16, 16, tmpCurFileStr);
+
+ ZERO(public_buf_m);
+
+ while (index <= disp_state_stack._disp_index) {
+ tmpText = getDispText(index);
+ if ((*tmpText == 0) || (tmpText == 0)) {
+ index++;
+ continue;
+ }
+
+ titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText);
+ if (index < disp_state_stack._disp_index) titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)">");
+
+ index++;
+ }
+
+ if (disp_state_stack._disp_state[disp_state_stack._disp_index] == PRINTING_UI) {
+ titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)":");
+ titleText_cat(public_buf_m, sizeof(public_buf_m), tmpCurFileStr);
+ }
+
+ if (strlen(public_buf_m) > MAX_TITLE_LEN) {
+ ZERO(public_buf_m);
+ tmpText = 0;
+ for (index = 0; index <= disp_state_stack._disp_index && (!tmpText || *tmpText == 0); index++)
+ tmpText = getDispText(index);
+ if (*tmpText != 0) {
+ titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText);
+ titleText_cat(public_buf_m, sizeof(public_buf_m), (char *)">...>");
+ tmpText = getDispText(disp_state_stack._disp_index);
+ if (*tmpText != 0) titleText_cat(public_buf_m, sizeof(public_buf_m), tmpText);
+ }
+ }
+
+ return public_buf_m;
+}
+
+#if HAS_GCODE_PREVIEW
+
+ uint32_t gPicturePreviewStart = 0;
+
+ void preview_gcode_prehandle(char *path) {
+ #if ENABLED(SDSUPPORT)
+ uint32_t pre_read_cnt = 0;
+ uint32_t *p1;
+ //char *cur_name;
+
+ gPicturePreviewStart = 0;
+ //cur_name = strrchr(path, '/');
+ card.openFileRead(path);
+ card.read(public_buf, 512);
+ p1 = (uint32_t *)strstr((char *)public_buf, ";simage:");
+
+ if (p1) {
+ pre_read_cnt = (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0]));
+
+ To_pre_view = pre_read_cnt;
+ gcode_preview_over = true;
+ gCfgItems.from_flash_pic = true;
+ update_spi_flash();
+ }
+ else {
+ gcode_preview_over = false;
+ default_preview_flg = true;
+ gCfgItems.from_flash_pic = false;
+ update_spi_flash();
+ }
+ card.closefile();
+ #endif
+ }
+
+ void gcode_preview(char *path, int xpos_pixel, int ypos_pixel) {
+ #if ENABLED(SDSUPPORT)
+ volatile uint32_t i, j;
+ volatile uint16_t *p_index;
+ //char *cur_name;
+
+ //cur_name = strrchr(path, '/');
+ card.openFileRead(path);
+
+ if (gPicturePreviewStart <= 0) {
+ while (1) {
+ uint32_t br = card.read(public_buf, 400);
+ uint32_t* p1 = (uint32_t *)strstr((char *)public_buf, ";gimage:");
+ if (p1) {
+ gPicturePreviewStart += (uint32_t)p1 - (uint32_t)((uint32_t *)(&public_buf[0]));
+ break;
+ }
+ else {
+ gPicturePreviewStart += br;
+ }
+ if (br < 400) break;
+ }
+ }
+
+ card.setIndex(gPicturePreviewStart + size * row + 8);
+ SPI_TFT.setWindow(xpos_pixel, ypos_pixel + row, 200, 1);
+
+ j = i = 0;
+
+ while (1) {
+ card.read(public_buf, 400);
+ for (i = 0; i < 400;) {
+ bmp_public_buf[j] = ascii2dec_test((char*)&public_buf[i]) << 4 | ascii2dec_test((char*)&public_buf[i + 1]);
+ i += 2;
+ j++;
+ }
+ if (j >= 400) break;
+ }
+ for (i = 0; i < 400; i += 2) {
+ p_index = (uint16_t *)(&bmp_public_buf[i]);
+ if (*p_index == 0x0000) *p_index = LV_COLOR_BACKGROUND.full;
+ }
+ SPI_TFT.tftio.WriteSequence((uint16_t*)bmp_public_buf, 200);
+ #if HAS_BAK_VIEW_IN_FLASH
+ W25QXX.init(SPI_QUARTER_SPEED);
+ if (row < 20) W25QXX.SPI_FLASH_SectorErase(BAK_VIEW_ADDR_TFT35 + row * 4096);
+ W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400);
+ #endif
+ row++;
+ if (row >= 200) {
+ size = 809;
+ row = 0;
+
+ gcode_preview_over = false;
+
+ card.closefile();
+ //char *cur_name;
+
+ //cur_name = strrchr(list_file.file_name[sel_id], '/');
+
+ //SdFile file;
+ //SdFile *curDir;
+ card.endFilePrint();
+ //const char * const fname = card.diveToFile(true, curDir, cur_name);
+ //if (!fname) return;
+ //if (file.open(curDir, fname, O_READ)) {
+ //gCfgItems.curFilesize = file.fileSize();
+ //file.close();
+ //update_spi_flash();
+ //}
+
+ card.openFileRead(list_file.file_name[sel_id]);
+ if (card.isFileOpen()) {
+ gCfgItems.curFilesize = card.getFileSize();
+ update_spi_flash();
+ feedrate_percentage = 100;
+ planner.flow_percentage[0] = 100;
+ planner.e_factor[0] = planner.flow_percentage[0] * 0.01;
+ #if HAS_MULTI_EXTRUDER
+ planner.flow_percentage[1] = 100;
+ planner.e_factor[1] = planner.flow_percentage[1] * 0.01;
+ #endif
+ card.startFileprint();
+ TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
+ once_flag = false;
+ }
+ return;
+ }
+ card.closefile();
+ #endif // SDSUPPORT
+ }
+
+ void draw_default_preview(int xpos_pixel, int ypos_pixel, uint8_t sel) {
+ int index;
+ int y_off = 0;
+ W25QXX.init(SPI_QUARTER_SPEED);
+ for (index = 0; index < 10; index++) { // 200*200
+ #if HAS_BAK_VIEW_IN_FLASH
+ if (sel == 1) {
+ flash_view_Read(bmp_public_buf, 8000); // 20k
+ }
+ else {
+ default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
+ }
+ #else
+ default_view_Read(bmp_public_buf, DEFAULT_VIEW_MAX_SIZE / 10); // 8k
+ #endif
+
+ SPI_TFT.setWindow(xpos_pixel, y_off * 20 + ypos_pixel, 200, 20); // 200*200
+ SPI_TFT.tftio.WriteSequence((uint16_t*)(bmp_public_buf), DEFAULT_VIEW_MAX_SIZE / 20);
+
+ y_off++;
+ }
+ W25QXX.init(SPI_QUARTER_SPEED);
+ }
+
+ void disp_pre_gcode(int xpos_pixel, int ypos_pixel) {
+ if (gcode_preview_over) gcode_preview(list_file.file_name[sel_id], xpos_pixel, ypos_pixel);
+ #if HAS_BAK_VIEW_IN_FLASH
+ if (flash_preview_begin) {
+ flash_preview_begin = false;
+ draw_default_preview(xpos_pixel, ypos_pixel, 1);
+ }
+ #endif
+ #if HAS_GCODE_DEFAULT_VIEW_IN_FLASH
+ if (default_preview_flg) {
+ draw_default_preview(xpos_pixel, ypos_pixel, 0);
+ default_preview_flg = false;
+ }
+ #endif
+ }
+#endif // HAS_GCODE_PREVIEW
+
+void print_time_run() {
+ static uint8_t lastSec = 0;
+
+ if (print_time.seconds >= 60) {
+ print_time.seconds = 0;
+ print_time.minutes++;
+ if (print_time.minutes >= 60) {
+ print_time.minutes = 0;
+ print_time.hours++;
+ }
+ }
+ if (disp_state == PRINTING_UI) {
+ if (lastSec != print_time.seconds) disp_print_time();
+ lastSec = print_time.seconds;
+ }
+}
+
+void GUI_RefreshPage() {
+ if ((systick_uptime_millis % 1000) == 0) temps_update_flag = true;
+ if ((systick_uptime_millis % 3000) == 0) printing_rate_update_flag = true;
+
+ switch (disp_state) {
+ case MAIN_UI:
+ break;
+ case EXTRUSION_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_hotend_temp();
+ }
+ break;
+ case PRE_HEAT_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_desire_temp();
+ }
+ break;
+ case PRINT_READY_UI:
+ break;
+
+ case PRINT_FILE_UI: break;
+
+ case PRINTING_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_ext_temp();
+ disp_bed_temp();
+ disp_fan_speed();
+ disp_print_time();
+ disp_fan_Zpos();
+ }
+ if (printing_rate_update_flag || marlin_state == MF_SD_COMPLETE) {
+ printing_rate_update_flag = false;
+ if (!gcode_preview_over) setProBarRate();
+ }
+ break;
+
+ case OPERATE_UI:
+ break;
+
+ case PAUSE_UI:
+ break;
+
+ case FAN_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_fan_value();
+ }
+ break;
+
+ case MOVE_MOTOR_UI:
+ break;
+
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_UI:
+ if (temps_update_flag) {
+ disp_wifi_state();
+ temps_update_flag = false;
+ }
+ break;
+
+ case BIND_UI:
+ refresh_bind_ui();
+ break;
+ #endif
+ case FILAMENTCHANGE_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_filament_temp();
+ }
+ break;
+ case DIALOG_UI:
+ filament_dialog_handle();
+ TERN_(MKS_WIFI_MODULE, wifi_scan_handle());
+ break;
+ case MESHLEVELING_UI:
+ break;
+ case HARDWARE_TEST_UI:
+ break;
+ case WIFI_LIST_UI:
+ #if ENABLED(MKS_WIFI_MODULE)
+ if (printing_rate_update_flag) {
+ disp_wifi_list();
+ printing_rate_update_flag = false;
+ }
+ #endif
+ break;
+ case KEY_BOARD_UI:
+ break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_TIPS_UI:
+ switch (wifi_tips_type) {
+ case TIPS_TYPE_JOINING:
+ if (wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName,(const char *)wifi_list.wifiName[wifi_list.nameIndex]) == 0) {
+ tips_disp.timer = TIPS_TIMER_STOP;
+ tips_disp.timer_count = 0;
+
+ lv_clear_wifi_tips();
+ wifi_tips_type = TIPS_TYPE_WIFI_CONECTED;
+ lv_draw_wifi_tips();
+
+ }
+ if (tips_disp.timer_count >= 30 * 1000) {
+ tips_disp.timer = TIPS_TIMER_STOP;
+ tips_disp.timer_count = 0;
+ lv_clear_wifi_tips();
+ wifi_tips_type = TIPS_TYPE_TAILED_JOIN;
+ lv_draw_wifi_tips();
+ }
+ break;
+ case TIPS_TYPE_TAILED_JOIN:
+ if (tips_disp.timer_count >= 3 * 1000) {
+ tips_disp.timer = TIPS_TIMER_STOP;
+ tips_disp.timer_count = 0;
+
+ last_disp_state = WIFI_TIPS_UI;
+ lv_clear_wifi_tips();
+ lv_draw_wifi_list();
+ }
+ break;
+ case TIPS_TYPE_WIFI_CONECTED:
+ if (tips_disp.timer_count >= 3 * 1000) {
+ tips_disp.timer = TIPS_TIMER_STOP;
+ tips_disp.timer_count = 0;
+
+ last_disp_state = WIFI_TIPS_UI;
+ lv_clear_wifi_tips();
+ lv_draw_wifi();
+ }
+ break;
+ default: break;
+ }
+ break;
+ #endif
+
+ case BABY_STEP_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_z_offset_value();
+ }
+ break;
+
+ #if ENABLED(BLTOUCH)
+ case BLTOUCH_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_bltouch_z_offset_value();
+ }
+ break;
+ #endif
+
+ #if ENABLED(TOUCH_MI_PROBE)
+ case TOUCHMI_UI:
+ if (temps_update_flag) {
+ temps_update_flag = false;
+ disp_z_offset_value_TM();
+ }
+ break;
+ #endif
+ default: break;
+ }
+
+ print_time_run();
+}
+
+void lv_clear_cur_ui() {
+ last_disp_state = disp_state_stack._disp_state[disp_state_stack._disp_index];
+
+ switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
+ case PRINT_READY_UI:
+ lv_clear_ready_print(); break;
+ case PRINT_FILE_UI: lv_clear_print_file(); break;
+ case PRINTING_UI: lv_clear_printing(); break;
+ case MOVE_MOTOR_UI: lv_clear_move_motor(); break;
+ case OPERATE_UI: lv_clear_operation(); break;
+ case PAUSE_UI: break;
+ case EXTRUSION_UI: lv_clear_extrusion(); break;
+ case PRE_HEAT_UI: lv_clear_preHeat(); break;
+ case CHANGE_SPEED_UI: lv_clear_change_speed(); break;
+ case FAN_UI: lv_clear_fan(); break;
+ case SET_UI: lv_clear_set(); break;
+ case ZERO_UI: lv_clear_home(); break;
+ case SPRAYER_UI: break;
+ case MACHINE_UI: break;
+ case LANGUAGE_UI: lv_clear_language(); break;
+ case ABOUT_UI: lv_clear_about(); break;
+ case LOG_UI: break;
+ case DISK_UI: break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_UI: lv_clear_wifi(); break;
+ #endif
+ case MORE_UI: lv_clear_more(); break;
+ case FILETRANSFER_UI: break;
+ case DIALOG_UI: lv_clear_dialog(); break;
+ case FILETRANSFERSTATE_UI: break;
+ case PRINT_MORE_UI: break;
+ case FILAMENTCHANGE_UI: lv_clear_filament_change(); break;
+ case LEVELING_UI: lv_clear_manualLevel(); break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case BIND_UI: lv_clear_cloud_bind(); break;
+ #endif
+ #if HAS_BED_PROBE
+ case NOZZLE_PROBE_OFFSET_UI: lv_clear_auto_level_offset_settings(); break;
+ #endif
+ case TOOL_UI: lv_clear_tool(); break;
+ case MESHLEVELING_UI: break;
+ case HARDWARE_TEST_UI: break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_LIST_UI: lv_clear_wifi_list(); break;
+ #endif
+ case KEY_BOARD_UI: lv_clear_keyboard(); break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_TIPS_UI: lv_clear_wifi_tips(); break;
+ #endif
+ case MACHINE_PARA_UI: lv_clear_machine_para(); break;
+ case MACHINE_SETTINGS_UI: lv_clear_machine_settings(); break;
+ case TEMPERATURE_SETTINGS_UI: break;
+ case MOTOR_SETTINGS_UI: lv_clear_motor_settings(); break;
+ case MACHINETYPE_UI: break;
+ case STROKE_UI: break;
+ case HOME_DIR_UI: break;
+ case ENDSTOP_TYPE_UI: break;
+ case FILAMENT_SETTINGS_UI: break;
+ case LEVELING_SETTIGNS_UI: break;
+ case LEVELING_PARA_UI: lv_clear_level_settings(); break;
+ case DELTA_LEVELING_PARA_UI: break;
+ case MANUAL_LEVELING_POSIGION_UI: lv_clear_manual_level_pos_settings(); break;
+ case MAXFEEDRATE_UI: lv_clear_max_feedrate_settings(); break;
+ case STEPS_UI: lv_clear_step_settings(); break;
+ case ACCELERATION_UI: lv_clear_acceleration_settings(); break;
+ case JERK_UI: TERN_(HAS_CLASSIC_JERK, lv_clear_jerk_settings()); break;
+ case MOTORDIR_UI: break;
+ case HOMESPEED_UI: break;
+ case NOZZLE_CONFIG_UI: break;
+ case HOTBED_CONFIG_UI: break;
+ case ADVANCED_UI: lv_clear_advance_settings(); break;
+ case DOUBLE_Z_UI: break;
+ case ENABLE_INVERT_UI: break;
+ case NUMBER_KEY_UI: lv_clear_number_key(); break;
+ case BABY_STEP_UI: lv_clear_baby_stepping(); break;
+ #if ENABLED(BLTOUCH)
+ case BLTOUCH_UI: lv_clear_bltouch_settings(); break;
+ #endif
+ #if ENABLED(TOUCH_MI_PROBE)
+ case TOUCHMI_UI: lv_clear_touchmi_settings(); break;
+ #endif
+ case PAUSE_POS_UI: lv_clear_pause_position(); break;
+ #if HAS_TRINAMIC_CONFIG
+ case TMC_CURRENT_UI: lv_clear_tmc_current_settings(); break;
+ #endif
+ case EEPROM_SETTINGS_UI: lv_clear_eeprom_settings(); break;
+ #if HAS_STEALTHCHOP
+ case TMC_MODE_UI: lv_clear_tmc_step_mode_settings(); break;
+ #endif
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_SETTINGS_UI: lv_clear_wifi_settings(); break;
+ #endif
+ #if USE_SENSORLESS
+ case HOMING_SENSITIVITY_UI: lv_clear_homing_sensitivity_settings(); break;
+ #endif
+ #if HAS_ROTARY_ENCODER
+ case ENCODER_SETTINGS_UI: lv_clear_encoder_settings(); break;
+ #endif
+ #if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ case TOUCH_CALIBRATION_UI: lv_clear_touch_calibration_screen(); break;
+ #endif
+ default: break;
+ }
+}
+
+void lv_draw_return_ui() {
+ if (disp_state_stack._disp_index > 0) {
+ disp_state_stack._disp_index--;
+
+ switch (disp_state_stack._disp_state[disp_state_stack._disp_index]) {
+ case PRINT_READY_UI: lv_draw_ready_print(); break;
+ case PRINT_FILE_UI: lv_draw_print_file(); break;
+
+ case PRINTING_UI: if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+ lv_draw_printing();
+ break;
+
+ case MOVE_MOTOR_UI: lv_draw_move_motor(); break;
+ case OPERATE_UI: lv_draw_operation(); break;
+ case PAUSE_UI: break;
+ case EXTRUSION_UI: lv_draw_extrusion(); break;
+ case PRE_HEAT_UI: lv_draw_preHeat(); break;
+ case CHANGE_SPEED_UI: lv_draw_change_speed(); break;
+ case FAN_UI: lv_draw_fan(); break;
+ case SET_UI: lv_draw_set(); break;
+ case ZERO_UI: lv_draw_home(); break;
+ case SPRAYER_UI: break;
+ case MACHINE_UI: break;
+ case LANGUAGE_UI: lv_draw_language(); break;
+ case ABOUT_UI: lv_draw_about(); break;
+
+ case CALIBRATE_UI: break;
+ case DISK_UI: break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_UI: lv_draw_wifi(); break;
+ #endif
+ case MORE_UI: break;
+ case PRINT_MORE_UI: lv_draw_more(); break;
+ case FILAMENTCHANGE_UI: lv_draw_filament_change(); break;
+ case LEVELING_UI: lv_draw_manualLevel(); break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case BIND_UI: lv_draw_cloud_bind(); break;
+ #endif
+ #if HAS_BED_PROBE
+ case NOZZLE_PROBE_OFFSET_UI: lv_draw_auto_level_offset_settings(); break;
+ #endif
+ case TOOL_UI: lv_draw_tool(); break;
+ case MESHLEVELING_UI: break;
+ case HARDWARE_TEST_UI: break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_LIST_UI: lv_draw_wifi_list(); break;
+ #endif
+ case KEY_BOARD_UI: lv_draw_keyboard(); break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_TIPS_UI: lv_draw_wifi_tips(); break;
+ #endif
+ case MACHINE_PARA_UI: lv_draw_machine_para(); break;
+ case MACHINE_SETTINGS_UI: lv_draw_machine_settings(); break;
+ case TEMPERATURE_SETTINGS_UI: break;
+ case MOTOR_SETTINGS_UI: lv_draw_motor_settings(); break;
+ case MACHINETYPE_UI: break;
+ case STROKE_UI: break;
+ case HOME_DIR_UI: break;
+ case ENDSTOP_TYPE_UI: break;
+ case FILAMENT_SETTINGS_UI: lv_draw_filament_settings(); break;
+ case LEVELING_SETTIGNS_UI: break;
+ case LEVELING_PARA_UI: lv_draw_level_settings(); break;
+ case DELTA_LEVELING_PARA_UI: break;
+ case MANUAL_LEVELING_POSIGION_UI: lv_draw_manual_level_pos_settings(); break;
+ case MAXFEEDRATE_UI: lv_draw_max_feedrate_settings(); break;
+ case STEPS_UI: lv_draw_step_settings(); break;
+ case ACCELERATION_UI: lv_draw_acceleration_settings(); break;
+ #if HAS_CLASSIC_JERK
+ case JERK_UI: lv_draw_jerk_settings(); break;
+ #endif
+ case MOTORDIR_UI: break;
+ case HOMESPEED_UI: break;
+ case NOZZLE_CONFIG_UI: break;
+ case HOTBED_CONFIG_UI: break;
+ case ADVANCED_UI: lv_draw_advance_settings(); break;
+ case DOUBLE_Z_UI: break;
+ case ENABLE_INVERT_UI: break;
+ case NUMBER_KEY_UI: lv_draw_number_key(); break;
+ case DIALOG_UI: break;
+ case BABY_STEP_UI: lv_draw_baby_stepping(); break;
+ case PAUSE_POS_UI: lv_draw_pause_position(); break;
+ #if HAS_TRINAMIC_CONFIG
+ case TMC_CURRENT_UI: lv_draw_tmc_current_settings(); break;
+ #endif
+ case EEPROM_SETTINGS_UI: lv_draw_eeprom_settings(); break;
+ #if HAS_STEALTHCHOP
+ case TMC_MODE_UI: lv_draw_tmc_step_mode_settings(); break;
+ #endif
+ #if ENABLED(MKS_WIFI_MODULE)
+ case WIFI_SETTINGS_UI: lv_draw_wifi_settings(); break;
+ #endif
+ #if USE_SENSORLESS
+ case HOMING_SENSITIVITY_UI: lv_draw_homing_sensitivity_settings(); break;
+ #endif
+ #if HAS_ROTARY_ENCODER
+ case ENCODER_SETTINGS_UI: lv_draw_encoder_settings(); break;
+ #endif
+ case TOUCHMI_UI: lv_draw_touchmi_settings(); break;
+ default: break;
+ }
+ }
+}
+
+// Set the same image for both Released and Pressed
+void lv_imgbtn_set_src_both(lv_obj_t *imgbtn, const void *src) {
+ lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_REL, src);
+ lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PR, src);
+}
+
+// Use label style for the image button
+void lv_imgbtn_use_label_style(lv_obj_t *imgbtn) {
+ lv_imgbtn_set_style(imgbtn, LV_BTN_STATE_REL, &tft_style_label_rel);
+ lv_imgbtn_set_style(imgbtn, LV_BTN_STATE_PR, &tft_style_label_pre);
+}
+
+// Use label style for the button
+void lv_btn_use_label_style(lv_obj_t *btn) {
+ lv_btn_set_style(btn, LV_BTN_STYLE_REL, &tft_style_label_rel);
+ lv_btn_set_style(btn, LV_BTN_STYLE_PR, &tft_style_label_pre);
+}
+
+// Use button style for the button
+void lv_btn_use_button_style(lv_obj_t *btn) {
+ lv_btn_set_style(btn, LV_BTN_STYLE_REL, &style_btn_rel);
+ lv_btn_set_style(btn, LV_BTN_STYLE_PR, &style_btn_pr);
+}
+
+// Use a single style for both Released and Pressed
+void lv_btn_set_style_both(lv_obj_t *btn, lv_style_t *style) {
+ lv_btn_set_style(btn, LV_BTN_STYLE_REL, style);
+ lv_btn_set_style(btn, LV_BTN_STYLE_PR, style);
+}
+
+// Create a screen
+lv_obj_t* lv_screen_create(DISP_STATE newScreenType, const char* title) {
+ lv_obj_t *scr = lv_obj_create(nullptr, nullptr);
+ lv_obj_set_style(scr, &tft_style_scr);
+ lv_scr_load(scr);
+ lv_obj_clean(scr);
+
+ // breadcrumbs
+ if (disp_state_stack._disp_state[disp_state_stack._disp_index] != newScreenType) {
+ disp_state_stack._disp_index++;
+ disp_state_stack._disp_state[disp_state_stack._disp_index] = newScreenType;
+ }
+ disp_state = newScreenType;
+
+ // title
+ lv_obj_t *titleLabel = nullptr;
+ if (!title)
+ titleLabel = lv_label_create(scr, TITLE_XPOS, TITLE_YPOS, creat_title_text());
+ else if (title[0] != '\0')
+ titleLabel = lv_label_create(scr, TITLE_XPOS, TITLE_YPOS, title);
+ if (titleLabel)
+ lv_obj_set_style(titleLabel, &tft_style_label_rel);
+
+ lv_refr_now(lv_refr_get_disp_refreshing());
+
+ return scr;
+}
+
+// Create an empty label
+lv_obj_t* lv_label_create_empty(lv_obj_t *par) {
+ lv_obj_t *label = lv_label_create(par, (lv_obj_t*)nullptr);
+ return label;
+}
+
+// Create a label with style and text
+lv_obj_t* lv_label_create(lv_obj_t *par, const char *text) {
+ lv_obj_t *label = lv_label_create_empty(par);
+ if (text) lv_label_set_text(label, text);
+ lv_obj_set_style(label, &tft_style_label_rel);
+ return label;
+}
+
+// Create a label with style, position, and text
+lv_obj_t* lv_label_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, const char *text) {
+ lv_obj_t *label = lv_label_create(par, text);
+ lv_obj_set_pos(label, x, y);
+ return label;
+}
+
+// Create a button with callback, ID, and Style.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id/*=0*/, lv_style_t *style/*=&style_para_value*/) {
+ lv_obj_t *btn = lv_btn_create(par, nullptr);
+ if (id)
+ lv_obj_set_event_cb_mks(btn, cb, id, "", 0);
+ else
+ lv_obj_set_event_cb(btn, cb);
+ lv_btn_set_style_both(btn, style);
+ return btn;
+}
+
+// Create a button with callback and ID, with label style.
+lv_obj_t* lv_label_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_btn_create(par, cb, id, nullptr);
+ lv_btn_use_label_style(btn);
+ return btn;
+}
+
+// Create a button with callback and ID, with button style.
+lv_obj_t* lv_button_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_btn_create(par, cb, id, nullptr);
+ lv_btn_use_button_style(btn);
+ return btn;
+}
+
+// Create a button with position, size, callback, ID, and style.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id, lv_style_t *style) {
+ lv_obj_t *btn = lv_btn_create(par, cb, id, style);
+ lv_obj_set_pos(btn, x, y);
+ lv_obj_set_size(btn, w, h);
+ return btn;
+}
+
+// Create a button with position, size, callback, and ID. Style set to style_para_value.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_btn_create(par, x, y, w, h, cb, id, &style_para_value);
+ return btn;
+}
+
+// Create a button with position, size, callback, and ID, with label style.
+lv_obj_t* lv_label_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_label_btn_create(par, cb, id);
+ lv_obj_set_pos(btn, x, y);
+ lv_obj_set_size(btn, w, h);
+ return btn;
+}
+
+// Create a button with position, size, callback, and ID, with label style.
+lv_obj_t* lv_button_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_button_btn_create(par, cb, id);
+ lv_obj_set_pos(btn, x, y);
+ lv_obj_set_size(btn, w, h);
+ return btn;
+}
+
+// Create a button with callback and ID. Style set to style_para_back.
+lv_obj_t* lv_btn_create_back(lv_obj_t *par, lv_event_cb_t cb, const int id/*=0*/) {
+ return lv_btn_create(par, cb, id, &style_para_back);
+}
+// Create a button with position, size, callback, and ID. Style set to style_para_back.
+lv_obj_t* lv_btn_create_back(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_btn_create_back(par, cb, id);
+ lv_obj_set_pos(btn, x, y);
+ lv_obj_set_size(btn, w, h);
+ return btn;
+}
+
+// Create an image button with image, callback, and ID. Use label style.
+lv_obj_t* lv_imgbtn_create(lv_obj_t *par, const char *img, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_imgbtn_create(par, nullptr);
+ if (img) lv_imgbtn_set_src_both(btn, img);
+ if (id)
+ lv_obj_set_event_cb_mks(btn, cb, id, "", 0);
+ else
+ lv_obj_set_event_cb(btn, cb);
+ lv_imgbtn_use_label_style(btn);
+ lv_btn_set_layout(btn, LV_LAYOUT_OFF);
+ return btn;
+}
+
+// Create an image button with image, position, callback, and ID. Use label style.
+lv_obj_t* lv_imgbtn_create(lv_obj_t *par, const char *img, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id/*=0*/) {
+ lv_obj_t *btn = lv_imgbtn_create(par, img, cb, id);
+ lv_obj_set_pos(btn, x, y);
+ return btn;
+}
+
+lv_obj_t* lv_big_button_create(lv_obj_t *par, const char *img, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, bool centerLabel) {
+ lv_obj_t *btn = lv_imgbtn_create(par, img, cb, id);
+ lv_obj_set_pos(btn, x, y);
+ lv_obj_t *label = lv_label_create_empty(btn);
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(label, text);
+ if (centerLabel)
+ lv_obj_align(label, btn, LV_ALIGN_CENTER, 0, 0);
+ else
+ lv_obj_align(label, btn, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable))
+ lv_group_add_obj(g, btn);
+ return btn;
+}
+
+lv_obj_t* lv_screen_menu_item(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, bool drawArrow) {
+ lv_obj_t *btn = lv_btn_create(par, nullptr); /*Add a button the current screen*/
+ lv_obj_set_pos(btn, x, y); /*Set its position*/
+ lv_obj_set_size(btn, PARA_UI_SIZE_X, PARA_UI_SIZE_Y); /*Set its size*/
+ if (id > -1) lv_obj_set_event_cb_mks(btn, cb, id, "", 0);
+ lv_btn_use_label_style(btn);
+ lv_btn_set_layout(btn, LV_LAYOUT_OFF);
+ lv_obj_t *label = lv_label_create_empty(btn); /*Add a label to the button*/
+ if (gCfgItems.multiple_language) {
+ lv_label_set_text(label, text);
+ lv_obj_align(label, btn, LV_ALIGN_IN_LEFT_MID, PARA_UI_ITEM_TEXT_H, 0);
+ }
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable))
+ lv_group_add_obj(g, btn);
+
+ if (drawArrow) (void)lv_imgbtn_create(par, "F:/bmp_arrow.bin", x + PARA_UI_SIZE_X, y + PARA_UI_ARROW_V, cb, id);
+
+ lv_obj_t *line1 = lv_line_create(par, nullptr);
+ lv_ex_line(line1, line_points[index]);
+
+ return btn;
+}
+
+lv_obj_t* lv_screen_menu_item_onoff(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const bool curValue) {
+ lv_label_create(par, x + PARA_UI_ITEM_TEXT_H, y + PARA_UI_ITEM_TEXT_V, text);
+
+ lv_obj_t* btnValue = lv_imgbtn_create(par, curValue ? "F:/bmp_enable.bin" : "F:/bmp_disable.bin", PARA_UI_STATE_POS_X, y + PARA_UI_STATE_V, cb, id);
+ lv_obj_t* labelValue = lv_label_create_empty(btnValue);
+ lv_label_set_text(labelValue, curValue ? machine_menu.enable : machine_menu.disable);
+ lv_obj_align(labelValue, btnValue, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, btnValue);
+ lv_obj_t *line1 = lv_line_create(par, nullptr);
+ lv_ex_line(line1, line_points[index]);
+ return btnValue;
+}
+
+void lv_screen_menu_item_1_edit(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const char *editValue) {
+ lv_label_create(par, x + PARA_UI_ITEM_TEXT_H, y + PARA_UI_ITEM_TEXT_V, text);
+
+ lv_obj_t* btnValue = lv_btn_create(par, PARA_UI_VALUE_POS_X, y + PARA_UI_VALUE_V, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE, cb, id);
+ lv_obj_t* labelValue = lv_label_create_empty(btnValue);
+ lv_label_set_text(labelValue, editValue);
+ lv_obj_align(labelValue, btnValue, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, btnValue);
+
+ lv_obj_t *line1 = lv_line_create(par, nullptr);
+ lv_ex_line(line1, line_points[index]);
+}
+
+void lv_screen_menu_item_2_edit(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const char *editValue, const int idEdit2, const char *editValue2) {
+ lv_label_create(par, x + PARA_UI_ITEM_TEXT_H, y + PARA_UI_ITEM_TEXT_V, text);
+
+ lv_obj_t* btnValue = lv_btn_create(par, PARA_UI_VALUE_POS_X_2, y + PARA_UI_VALUE_V_2, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE, cb, idEdit2);
+ lv_obj_t* labelValue = lv_label_create_empty(btnValue);
+ lv_label_set_text(labelValue, editValue2);
+ lv_obj_align(labelValue, btnValue, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, btnValue);
+
+ btnValue = lv_btn_create(par, PARA_UI_VALUE_POS_X, y + PARA_UI_VALUE_V, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE, cb, id);
+ labelValue = lv_label_create_empty(btnValue);
+ lv_label_set_text(labelValue, editValue);
+ lv_obj_align(labelValue, btnValue, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, btnValue);
+
+ lv_obj_t *line1 = lv_line_create(par, nullptr);
+ lv_ex_line(line1, line_points[index]);
+}
+
+void lv_screen_menu_item_onoff_update(lv_obj_t *btn, const bool curValue) {
+ lv_imgbtn_set_src_both(btn, curValue ? "F:/bmp_enable.bin" : "F:/bmp_disable.bin");
+ lv_label_set_text((lv_obj_t*)btn->child_ll.head, curValue ? machine_menu.enable : machine_menu.disable);
+}
+
+void lv_screen_menu_item_turn_page(lv_obj_t *par, const char *text, lv_event_cb_t cb, const int id) {
+ lv_obj_t* btnTurnPage = lv_btn_create(par, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, PARA_UI_TURN_BTN_X_SIZE, PARA_UI_TURN_BTN_Y_SIZE, cb, id);
+ lv_obj_t* labelTurnPage = lv_label_create_empty(btnTurnPage);
+ lv_btn_set_style_both(btnTurnPage, &style_para_back);
+ lv_label_set_text(labelTurnPage, text);
+ lv_obj_align(labelTurnPage, btnTurnPage, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable))
+ lv_group_add_obj(g, btnTurnPage);
+}
+
+void lv_screen_menu_item_return(lv_obj_t *par, lv_event_cb_t cb, const int id) {
+ lv_obj_t* btnReturn = lv_btn_create(par, PARA_UI_BACL_POS_X, PARA_UI_BACL_POS_Y, PARA_UI_BACK_BTN_X_SIZE, PARA_UI_BACK_BTN_Y_SIZE, cb, id);
+ lv_obj_t* labelReturn = lv_label_create_empty(btnReturn);
+ lv_btn_set_style_both(btnReturn, &style_para_back);
+ lv_label_set_text(labelReturn, common_menu.text_back);
+ lv_obj_align(labelReturn, btnReturn, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable))
+ lv_group_add_obj(g, btnReturn);
+}
+
+#if ENABLED(SDSUPPORT)
+
+ void sd_detection() {
+ static bool last_sd_status;
+ const bool sd_status = IS_SD_INSERTED();
+ if (sd_status != last_sd_status) {
+ last_sd_status = sd_status;
+ if (sd_status) card.mount(); else card.release();
+ }
+ }
+
+#endif
+
+void lv_ex_line(lv_obj_t *line, lv_point_t *points) {
+ // Copy the previous line and apply the new style
+ lv_line_set_points(line, points, 2); // Set the points
+ lv_line_set_style(line, LV_LINE_STYLE_MAIN, &style_line);
+ lv_obj_align(line, nullptr, LV_ALIGN_IN_TOP_MID, 0, 0);
+}
+
+extern volatile uint32_t systick_uptime_millis;
+
+void print_time_count() {
+ if ((systick_uptime_millis % 1000) == 0)
+ if (print_time.start == 1) print_time.seconds++;
+}
+
+void lv_print_finished() {
+ if (once_flag == 0) {
+ stop_print_time();
+
+ flash_preview_begin = false;
+ default_preview_flg = false;
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TYPE_FINISH_PRINT);
+
+ once_flag = true;
+
+ #if HAS_SUICIDE
+ if (gCfgItems.finish_power_off) {
+ gcode.process_subcommands_now_P(PSTR("M1001"));
+ queue.inject_P(PSTR("M81"));
+ marlin_state = MF_RUNNING;
+ }
+ #endif
+ uiCfg.print_state = IDLE;
+ }
+}
+
+void LV_TASK_HANDLER() {
+ lv_task_handler();
+ if (mks_test_flag == 0x1E) mks_hardware_test();
+
+ TERN_(HAS_GCODE_PREVIEW, disp_pre_gcode(2, 36));
+
+ GUI_RefreshPage();
+
+ TERN_(MKS_WIFI_MODULE, get_wifi_commands());
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_update_encoder();
+ #endif
+ if (marlin_state == MF_SD_COMPLETE) lv_print_finished();
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h
new file mode 100644
index 0000000..5f27123
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_ui.h
@@ -0,0 +1,551 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include <lvgl.h>
+
+#include <stdint.h>
+#include <string.h>
+
+// the colors of the last MKS Ui
+#undef LV_COLOR_BACKGROUND
+#define LV_COLOR_BACKGROUND LV_COLOR_MAKE(0x1A, 0x1A, 0x1A)
+
+#define TFT_LV_PARA_BACK_BODY_COLOR LV_COLOR_MAKE(0x4A, 0x52, 0xFF)
+
+#include "tft_lvgl_configuration.h"
+#include "tft_multi_language.h"
+#include "pic_manager.h"
+#include "draw_ready_print.h"
+#include "draw_language.h"
+#include "draw_set.h"
+#include "draw_tool.h"
+#include "draw_print_file.h"
+#include "draw_dialog.h"
+#include "draw_printing.h"
+#include "draw_operation.h"
+#include "draw_preHeat.h"
+#include "draw_extrusion.h"
+#include "draw_home.h"
+#include "draw_more.h"
+#include "draw_move_motor.h"
+#include "draw_fan.h"
+#include "draw_about.h"
+#include "draw_change_speed.h"
+#include "draw_manuaLevel.h"
+#include "draw_error_message.h"
+#include "printer_operation.h"
+#include "draw_machine_para.h"
+#include "draw_machine_settings.h"
+#include "draw_motor_settings.h"
+#include "draw_advance_settings.h"
+#include "draw_acceleration_settings.h"
+#include "draw_number_key.h"
+#include "draw_jerk_settings.h"
+#include "draw_pause_position.h"
+#include "draw_step_settings.h"
+#include "draw_tmc_current_settings.h"
+#include "draw_eeprom_settings.h"
+#include "draw_max_feedrate_settings.h"
+#include "draw_tmc_step_mode_settings.h"
+#include "draw_level_settings.h"
+#include "draw_manual_level_pos_settings.h"
+#include "draw_auto_level_offset_settings.h"
+#include "draw_filament_change.h"
+#include "draw_filament_settings.h"
+#include "draw_homing_sensitivity_settings.h"
+#include "draw_baby_stepping.h"
+#include "draw_keyboard.h"
+#include "draw_encoder_settings.h"
+#include "draw_touchmi_settings.h"
+#include "draw_bltouch_settings.h"
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+ #include "wifiSerial.h"
+ #include "wifi_module.h"
+ #include "wifi_upload.h"
+ #include "draw_wifi_settings.h"
+ #include "draw_wifi.h"
+ #include "draw_wifi_list.h"
+ #include "draw_wifi_tips.h"
+ #include "draw_cloud_bind.h"
+#endif
+
+#define ESP_WIFI 0x02
+#define AP_MODEL 0x01
+#define STA_MODEL 0x02
+
+#define FILE_SYS_USB 0
+#define FILE_SYS_SD 1
+
+#define TICK_CYCLE 1
+
+#define PARA_SEL_ICON_TEXT_COLOR LV_COLOR_MAKE(0x4A, 0x52, 0xFF);
+
+#define TFT35
+
+#ifdef TFT35
+
+ #define TFT_WIDTH 480
+ #define TFT_HEIGHT 320
+
+ #define titleHeight 36 // TFT_screen.title_high
+ #define INTERVAL_H 2 // TFT_screen.gap_h // 2
+ #define INTERVAL_V 2 // TFT_screen.gap_v // 2
+ #define BTN_X_PIXEL 117 // TFT_screen.btn_x_pixel
+ #define BTN_Y_PIXEL 140 // TFT_screen.btn_y_pixel
+
+ #define SIMPLE_FIRST_PAGE_GRAP 30
+
+ #define BUTTON_TEXT_Y_OFFSET -20
+
+ #define TITLE_XPOS 3 // TFT_screen.title_xpos
+ #define TITLE_YPOS 5 // TFT_screen.title_ypos
+
+ #define FILE_BTN_CNT 6
+
+ #define OTHER_BTN_XPIEL 117
+ #define OTHER_BTN_YPIEL 92
+
+ #define FILE_PRE_PIC_X_OFFSET 8
+ #define FILE_PRE_PIC_Y_OFFSET 0
+
+ #define PREVIEW_LITTLE_PIC_SIZE 40910 // 400*100+9*101+1
+ #define PREVIEW_SIZE 202720 // (PREVIEW_LITTLE_PIC_SIZE+800*200+201*9+1)
+
+ // machine parameter ui
+ #define PARA_UI_POS_X 10
+ #define PARA_UI_POS_Y 50
+
+ #define PARA_UI_SIZE_X 450
+ #define PARA_UI_SIZE_Y 40
+
+ #define PARA_UI_ARROW_V 12
+ #define PARA_UI_ITEM_TEXT_V 10
+ #define PARA_UI_ITEM_TEXT_H 10
+
+ #define PARA_UI_BACL_POS_X 400
+ #define PARA_UI_BACL_POS_Y 270
+
+ #define PARA_UI_TURN_PAGE_POS_X 320
+ #define PARA_UI_TURN_PAGE_POS_Y 270
+
+ #define PARA_UI_VALUE_SIZE_X 370
+ #define PARA_UI_VALUE_POS_X 400
+ #define PARA_UI_VALUE_V 5
+
+ #define PARA_UI_STATE_POS_X 380
+ #define PARA_UI_STATE_V 2
+
+ #define PARA_UI_VALUE_SIZE_X_2 200
+ #define PARA_UI_VALUE_POS_X_2 320
+ #define PARA_UI_VALUE_V_2 5
+
+ #define PARA_UI_VALUE_BTN_X_SIZE 70
+ #define PARA_UI_VALUE_BTN_Y_SIZE 28
+
+ #define PARA_UI_TURN_BTN_X_SIZE 70
+ #define PARA_UI_TURN_BTN_Y_SIZE 40
+
+ #define PARA_UI_BACK_BTN_X_SIZE 70
+ #define PARA_UI_BACK_BTN_Y_SIZE 40
+
+ #define QRCODE_X 20
+ #define QRCODE_Y 40
+ #define QRCODE_WIDTH 160
+
+#else // ifdef TFT35
+
+ #define TFT_WIDTH 320
+ #define TFT_HEIGHT 240
+
+#endif // ifdef TFT35
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern char public_buf_m[100];
+extern char public_buf_l[30];
+
+typedef struct {
+ uint32_t spi_flash_flag;
+ uint8_t disp_rotation_180;
+ bool multiple_language;
+ uint8_t language;
+ uint8_t leveling_mode;
+ bool from_flash_pic;
+ bool finish_power_off;
+ bool pause_reprint;
+ uint8_t wifi_mode_sel;
+ uint8_t fileSysType;
+ uint8_t wifi_type;
+ bool cloud_enable;
+ bool encoder_enable;
+ int levelingPos[5][2];
+ int filamentchange_load_length;
+ int filamentchange_load_speed;
+ int filamentchange_unload_length;
+ int filamentchange_unload_speed;
+ int filament_limit_temper;
+ float pausePosX;
+ float pausePosY;
+ float pausePosZ;
+ uint32_t curFilesize;
+} CFG_ITMES;
+
+typedef struct {
+ uint8_t curTempType:1,
+ curSprayerChoose:3,
+ stepHeat:4;
+ uint8_t leveling_first_time:1,
+ para_ui_page:1,
+ configWifi:1,
+ command_send:1,
+ filament_load_heat_flg:1,
+ filament_heat_completed_load:1,
+ filament_unload_heat_flg:1,
+ filament_heat_completed_unload:1;
+ uint8_t filament_loading_completed:1,
+ filament_unloading_completed:1,
+ filament_loading_time_flg:1,
+ filament_unloading_time_flg:1,
+ curSprayerChoose_bak:4;
+ uint8_t tmc_connect_state:1;
+ uint8_t wifi_name[32];
+ uint8_t wifi_key[64];
+ uint8_t cloud_hostUrl[96];
+ uint8_t extruStep;
+ uint8_t extruSpeed;
+ uint8_t print_state;
+ uint8_t stepPrintSpeed;
+ uint8_t waitEndMoves;
+ uint8_t dialogType;
+ uint8_t F[4];
+ uint8_t filament_rate;
+ uint16_t moveSpeed;
+ uint16_t cloud_port;
+ uint16_t moveSpeed_bak;
+ uint32_t totalSend;
+ uint32_t filament_loading_time;
+ uint32_t filament_unloading_time;
+ uint32_t filament_loading_time_cnt;
+ uint32_t filament_unloading_time_cnt;
+ float move_dist;
+ float desireSprayerTempBak;
+ float current_x_position_bak;
+ float current_y_position_bak;
+ float current_z_position_bak;
+ float current_e_position_bak;
+} UI_CFG;
+
+typedef enum {
+ MAIN_UI,
+ PRINT_READY_UI,
+ PRINT_FILE_UI,
+ PRINTING_UI,
+ MOVE_MOTOR_UI,
+ OPERATE_UI,
+ PAUSE_UI,
+ EXTRUSION_UI,
+ FAN_UI,
+ PRE_HEAT_UI,
+ CHANGE_SPEED_UI,
+ TEMP_UI,
+ SET_UI,
+ ZERO_UI,
+ BLTOUCH_UI,
+ TOUCHMI_UI,
+ SPRAYER_UI,
+ MACHINE_UI,
+ LANGUAGE_UI,
+ ABOUT_UI,
+ LOG_UI,
+ DISK_UI,
+ CALIBRATE_UI,
+ DIALOG_UI,
+ WIFI_UI,
+ MORE_UI,
+ FILETRANSFER_UI,
+ FILETRANSFERSTATE_UI,
+ PRINT_MORE_UI,
+ FILAMENTCHANGE_UI,
+ LEVELING_UI,
+ MESHLEVELING_UI,
+ BIND_UI,
+ #if HAS_BED_PROBE
+ NOZZLE_PROBE_OFFSET_UI,
+ #endif
+ TOOL_UI,
+ HARDWARE_TEST_UI,
+ WIFI_LIST_UI,
+ KEY_BOARD_UI,
+ WIFI_TIPS_UI,
+ MACHINE_PARA_UI,
+ MACHINE_SETTINGS_UI,
+ TEMPERATURE_SETTINGS_UI,
+ MOTOR_SETTINGS_UI,
+ MACHINETYPE_UI,
+ STROKE_UI,
+ HOME_DIR_UI,
+ ENDSTOP_TYPE_UI,
+ FILAMENT_SETTINGS_UI,
+ LEVELING_SETTIGNS_UI,
+ LEVELING_PARA_UI,
+ DELTA_LEVELING_PARA_UI,
+ MANUAL_LEVELING_POSIGION_UI,
+ MAXFEEDRATE_UI,
+ STEPS_UI,
+ ACCELERATION_UI,
+ JERK_UI,
+ MOTORDIR_UI,
+ HOMESPEED_UI,
+ NOZZLE_CONFIG_UI,
+ HOTBED_CONFIG_UI,
+ ADVANCED_UI,
+ DOUBLE_Z_UI,
+ ENABLE_INVERT_UI,
+ NUMBER_KEY_UI,
+ BABY_STEP_UI,
+ ERROR_MESSAGE_UI,
+ PAUSE_POS_UI,
+ TMC_CURRENT_UI,
+ TMC_MODE_UI,
+ EEPROM_SETTINGS_UI,
+ WIFI_SETTINGS_UI,
+ HOMING_SENSITIVITY_UI,
+ ENCODER_SETTINGS_UI,
+ TOUCH_CALIBRATION_UI
+} DISP_STATE;
+
+typedef struct {
+ DISP_STATE _disp_state[100];
+ int _disp_index;
+} DISP_STATE_STACK;
+
+typedef struct {
+ int16_t days;
+ uint16_t hours;
+ uint8_t minutes;
+ volatile int8_t seconds;
+ int8_t ms_10;
+ int8_t start;
+} PRINT_TIME;
+extern PRINT_TIME print_time;
+
+typedef enum {
+ PrintAcceleration,
+ RetractAcceleration,
+ TravelAcceleration,
+ XAcceleration,
+ YAcceleration,
+ ZAcceleration,
+ E0Acceleration,
+ E1Acceleration,
+
+ XMaxFeedRate,
+ YMaxFeedRate,
+ ZMaxFeedRate,
+ E0MaxFeedRate,
+ E1MaxFeedRate,
+
+ XJerk,
+ YJerk,
+ ZJerk,
+ EJerk,
+
+ Xstep,
+ Ystep,
+ Zstep,
+ E0step,
+ E1step,
+
+ Xcurrent,
+ Ycurrent,
+ Zcurrent,
+ E0current,
+ E1current,
+
+ pause_pos_x,
+ pause_pos_y,
+ pause_pos_z,
+
+ level_pos_x1,
+ level_pos_y1,
+ level_pos_x2,
+ level_pos_y2,
+ level_pos_x3,
+ level_pos_y3,
+ level_pos_x4,
+ level_pos_y4,
+ level_pos_x5,
+ level_pos_y5,
+ #if HAS_BED_PROBE
+ x_offset,
+ y_offset,
+ z_offset,
+ #endif
+ load_length,
+ load_speed,
+ unload_length,
+ unload_speed,
+ filament_temp,
+
+ x_sensitivity,
+ y_sensitivity,
+ z_sensitivity,
+ z2_sensitivity
+} num_key_value_state;
+extern num_key_value_state value;
+
+typedef enum {
+ wifiName,
+ wifiPassWord,
+ wifiConfig,
+ gcodeCommand
+} keyboard_value_state;
+extern keyboard_value_state keyboard_value;
+
+extern CFG_ITMES gCfgItems;
+extern UI_CFG uiCfg;
+extern DISP_STATE disp_state;
+extern DISP_STATE last_disp_state;
+extern DISP_STATE_STACK disp_state_stack;
+
+extern lv_style_t tft_style_scr;
+extern lv_style_t tft_style_label_pre;
+extern lv_style_t tft_style_label_rel;
+extern lv_style_t style_line;
+extern lv_style_t style_para_value_pre;
+extern lv_style_t style_para_value_rel;
+extern lv_style_t style_num_key_pre;
+extern lv_style_t style_num_key_rel;
+extern lv_style_t style_num_text;
+extern lv_style_t style_sel_text;
+extern lv_style_t style_para_value;
+extern lv_style_t style_para_back;
+extern lv_style_t lv_bar_style_indic;
+extern lv_style_t style_btn_pr;
+extern lv_style_t style_btn_rel;
+
+extern lv_point_t line_points[4][2];
+
+extern void gCfgItems_init();
+extern void ui_cfg_init();
+extern void tft_style_init();
+extern char *creat_title_text(void);
+extern void preview_gcode_prehandle(char *path);
+extern void update_spi_flash();
+extern void update_gcode_command(int addr,uint8_t *s);
+extern void get_gcode_command(int addr,uint8_t *d);
+#if HAS_GCODE_PREVIEW
+ extern void disp_pre_gcode(int xpos_pixel, int ypos_pixel);
+#endif
+extern void GUI_RefreshPage();
+extern void lv_clear_cur_ui();
+extern void lv_draw_return_ui();
+extern void sd_detection();
+extern void gCfg_to_spiFlah();
+extern void print_time_count();
+
+extern void LV_TASK_HANDLER();
+extern void lv_ex_line(lv_obj_t *line, lv_point_t *points);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
+
+// Set the same image for both Released and Pressed
+void lv_imgbtn_set_src_both(lv_obj_t *imgbtn, const void *src);
+
+// Set label styles for Released and Pressed
+void lv_imgbtn_use_label_style(lv_obj_t *imgbtn);
+
+// Set label styles for Released and Pressed
+void lv_btn_use_label_style(lv_obj_t *btn);
+
+// Set the same style for both Released and Pressed
+void lv_btn_set_style_both(lv_obj_t *btn, lv_style_t *style);
+
+// Create a screen
+lv_obj_t* lv_screen_create(DISP_STATE newScreenType, const char* title = nullptr);
+
+// Create an empty label
+lv_obj_t* lv_label_create_empty(lv_obj_t *par);
+
+// Create a label with style and text
+lv_obj_t* lv_label_create(lv_obj_t *par, const char *text);
+
+// Create a label with style, position, and text
+lv_obj_t* lv_label_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, const char *text);
+
+// Create a button with callback, ID, and Style.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id, lv_style_t *style=&style_para_value);
+
+// Create a button with callback and ID, with label style.
+lv_obj_t* lv_label_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id=0);
+
+// Create a button with callback and ID, with button style.
+lv_obj_t* lv_button_btn_create(lv_obj_t *par, lv_event_cb_t cb, const int id=0);
+
+// Create a button with position, size, callback, ID, and style.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id, lv_style_t *style);
+
+// Create a button with position, size, callback, and ID. Style set to style_para_value.
+lv_obj_t* lv_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id=0);
+
+// Create a button with position, size, callback, and ID, with label style.
+lv_obj_t* lv_label_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id=0);
+
+// Create a button with position, size, callback, and ID, with button style.
+lv_obj_t* lv_button_btn_create(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id=0);
+
+// Create a button with callback and ID. Style set to style_para_back.
+lv_obj_t* lv_btn_create_back(lv_obj_t *par, lv_event_cb_t cb, const int id=0);
+
+// Create a button with position, size, callback, and ID. Style set to style_para_back.
+lv_obj_t* lv_btn_create_back(lv_obj_t *par, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, lv_event_cb_t cb, const int id=0);
+
+// Create an image button with image, callback, and ID. Use label style.
+lv_obj_t* lv_imgbtn_create(lv_obj_t *par, const char *img, lv_event_cb_t cb, const int id=0);
+
+// Create an image button with image, position, callback, and ID. Use label style.
+lv_obj_t* lv_imgbtn_create(lv_obj_t *par, const char *img, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id=0);
+
+// Create a big image button with a label, follow the LVGL UI standard.
+lv_obj_t* lv_big_button_create(lv_obj_t *par, const char *img, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, bool centerLabel = false);
+
+// Create a menu item, follow the LVGL UI standard.
+lv_obj_t* lv_screen_menu_item(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, bool drawArrow = true);
+
+lv_obj_t* lv_screen_menu_item_onoff(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const bool curValue);
+
+void lv_screen_menu_item_1_edit(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const char *editValue);
+void lv_screen_menu_item_2_edit(lv_obj_t *par, const char *text, lv_coord_t x, lv_coord_t y, lv_event_cb_t cb, const int id, const int index, const char *editValue, const int idEdit2, const char *editValue2);
+void lv_screen_menu_item_onoff_update(lv_obj_t *btn, const bool curValue);
+void lv_screen_menu_item_turn_page(lv_obj_t *par, const char *text, lv_event_cb_t cb, const int id);
+void lv_screen_menu_item_return(lv_obj_t *par, lv_event_cb_t cb, const int id);
+
+#define _DIA_1(T) (uiCfg.dialogType == DIALOG_##T)
+#define DIALOG_IS(V...) DO(DIA,||,V)
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp
new file mode 100644
index 0000000..416905e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.cpp
@@ -0,0 +1,166 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include <lv_conf.h>
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr, *wifi_name_text, *wifi_key_text, *wifi_state_text, *wifi_ip_text;
+
+enum {
+ ID_W_RETURN = 1,
+ ID_W_CLOUD,
+ ID_W_RECONNECT
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ lv_clear_cur_ui();
+ switch (obj->mks_obj_id) {
+ case ID_W_RETURN:
+ lv_draw_set();
+ break;
+ case ID_W_CLOUD:
+ lv_draw_cloud_bind();
+ break;
+ #if ENABLED(MKS_WIFI_MODULE)
+ case ID_W_RECONNECT: {
+ uint8_t cmd_wifi_list[] = { 0xA5, 0x07, 0x00, 0x00, 0xFC };
+ raw_send_to_wifi(cmd_wifi_list, COUNT(cmd_wifi_list));
+ lv_draw_wifi_list();
+ } break;
+ #endif
+ }
+}
+
+void lv_draw_wifi(void) {
+ scr = lv_screen_create(WIFI_UI);
+
+ lv_obj_t *buttonReconnect = nullptr, *label_Reconnect = nullptr;
+ lv_obj_t *buttonCloud = nullptr, *label_Cloud = nullptr;
+
+ const bool enc_ena = TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable);
+
+ if (gCfgItems.wifi_mode_sel == STA_MODEL) {
+
+ if (gCfgItems.cloud_enable)
+ buttonCloud = lv_imgbtn_create(scr, "F:/bmp_cloud.bin", BTN_X_PIXEL+INTERVAL_V*2, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_W_CLOUD);
+
+ buttonReconnect = lv_imgbtn_create(scr, "F:/bmp_wifi.bin", BTN_X_PIXEL * 2 + INTERVAL_V * 3, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_W_RECONNECT);
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.cloud_enable) lv_group_add_obj(g, buttonCloud);
+ if (enc_ena) lv_group_add_obj(g, buttonReconnect);
+ #endif
+
+ label_Reconnect = lv_label_create_empty(buttonReconnect);
+ if (gCfgItems.cloud_enable) label_Cloud = lv_label_create_empty(buttonCloud);
+ }
+
+ // Create an Image button
+ lv_obj_t *buttonBack = lv_imgbtn_create(scr, "F:/bmp_return.bin", BTN_X_PIXEL * 3 + INTERVAL_V * 4, BTN_Y_PIXEL + INTERVAL_H + titleHeight, event_handler, ID_W_RETURN);
+ if (enc_ena) lv_group_add_obj(g, buttonBack);
+ lv_obj_t *label_Back = lv_label_create_empty(buttonBack);
+
+ if (gCfgItems.multiple_language) {
+ if (gCfgItems.wifi_mode_sel == STA_MODEL) {
+ if (gCfgItems.cloud_enable) {
+ lv_label_set_text(label_Cloud, wifi_menu.cloud);
+ lv_obj_align(label_Cloud, buttonCloud, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ lv_label_set_text(label_Reconnect, wifi_menu.reconnect);
+ lv_obj_align(label_Reconnect, buttonReconnect, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+ lv_label_set_text(label_Back, common_menu.text_back);
+ lv_obj_align(label_Back, buttonBack, LV_ALIGN_IN_BOTTOM_MID, 0, BUTTON_TEXT_Y_OFFSET);
+ }
+
+ wifi_ip_text = lv_label_create_empty(scr);
+ lv_obj_set_style(wifi_ip_text, &tft_style_label_rel);
+ wifi_name_text = lv_label_create_empty(scr);
+ lv_obj_set_style(wifi_name_text, &tft_style_label_rel);
+ wifi_key_text = lv_label_create_empty(scr);
+ lv_obj_set_style(wifi_key_text, &tft_style_label_rel);
+ wifi_state_text = lv_label_create_empty(scr);
+ lv_obj_set_style(wifi_state_text, &tft_style_label_rel);
+
+ disp_wifi_state();
+}
+
+void disp_wifi_state() {
+ strcpy(public_buf_m, wifi_menu.ip);
+ strcat(public_buf_m, ipPara.ip_addr);
+ lv_label_set_text(wifi_ip_text, public_buf_m);
+ lv_obj_align(wifi_ip_text, nullptr, LV_ALIGN_CENTER, 0, -100);
+
+ strcpy(public_buf_m, wifi_menu.wifi);
+ strcat(public_buf_m, wifiPara.ap_name);
+ lv_label_set_text(wifi_name_text, public_buf_m);
+ lv_obj_align(wifi_name_text, nullptr, LV_ALIGN_CENTER, 0, -70);
+
+ if (wifiPara.mode == AP_MODEL) {
+ strcpy(public_buf_m, wifi_menu.key);
+ strcat(public_buf_m, wifiPara.keyCode);
+ lv_label_set_text(wifi_key_text, public_buf_m);
+ lv_obj_align(wifi_key_text, nullptr, LV_ALIGN_CENTER, 0, -40);
+
+ strcpy(public_buf_m, wifi_menu.state_ap);
+ if (wifi_link_state == WIFI_CONNECTED)
+ strcat(public_buf_m, wifi_menu.connected);
+ else if (wifi_link_state == WIFI_NOT_CONFIG)
+ strcat(public_buf_m, wifi_menu.disconnected);
+ else
+ strcat(public_buf_m, wifi_menu.exception);
+ lv_label_set_text(wifi_state_text, public_buf_m);
+ lv_obj_align(wifi_state_text, nullptr, LV_ALIGN_CENTER, 0, -10);
+ }
+ else {
+ strcpy(public_buf_m, wifi_menu.state_sta);
+ if (wifi_link_state == WIFI_CONNECTED)
+ strcat(public_buf_m, wifi_menu.connected);
+ else if (wifi_link_state == WIFI_NOT_CONFIG)
+ strcat(public_buf_m, wifi_menu.disconnected);
+ else
+ strcat(public_buf_m, wifi_menu.exception);
+ lv_label_set_text(wifi_state_text, public_buf_m);
+ lv_obj_align(wifi_state_text, nullptr, LV_ALIGN_CENTER, 0, -40);
+
+ lv_label_set_text(wifi_key_text, "");
+ lv_obj_align(wifi_key_text, nullptr, LV_ALIGN_CENTER, 0, -10);
+ }
+}
+
+void lv_clear_wifi() {
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable))
+ lv_group_remove_all_objs(g);
+ lv_obj_del(scr);
+}
+
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h
new file mode 100644
index 0000000..966a84d
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi.h
@@ -0,0 +1,38 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+
+extern void lv_draw_wifi(void);
+extern void lv_clear_wifi();
+extern void disp_wifi_state();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
+
+
+
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp
new file mode 100644
index 0000000..b0f3848
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.cpp
@@ -0,0 +1,177 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include <lv_conf.h>
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+
+#define NAME_BTN_X 330
+#define NAME_BTN_Y 48
+
+#define MARK_BTN_X 0
+#define MARK_BTN_Y 68
+
+WIFI_LIST wifi_list;
+list_menu_def list_menu;
+
+extern lv_group_t *g;
+static lv_obj_t *scr;
+static lv_obj_t *buttonWifiN[NUMBER_OF_PAGE];
+static lv_obj_t *labelWifiText[NUMBER_OF_PAGE];
+static lv_obj_t *labelPageText;
+
+#define ID_WL_RETURN 11
+#define ID_WL_DOWN 12
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+
+ if (obj->mks_obj_id == ID_WL_RETURN) {
+ lv_clear_cur_ui();
+ lv_draw_set();
+ }
+ else if (obj->mks_obj_id == ID_WL_DOWN) {
+ if (wifi_list.getNameNum > 0) {
+ if ((wifi_list.nameIndex + NUMBER_OF_PAGE) >= wifi_list.getNameNum) {
+ wifi_list.nameIndex = 0;
+ wifi_list.currentWifipage = 1;
+ }
+ else {
+ wifi_list.nameIndex += NUMBER_OF_PAGE;
+ wifi_list.currentWifipage++;
+ }
+ disp_wifi_list();
+ }
+ }
+ else {
+ for (uint8_t i = 0; i < NUMBER_OF_PAGE; i++) {
+ if (obj->mks_obj_id == i + 1) {
+ if (wifi_list.getNameNum != 0) {
+ const bool do_wifi = wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName, (const char *)wifi_list.wifiName[wifi_list.nameIndex + i]) == 0;
+ wifi_list.nameIndex += i;
+ last_disp_state = WIFI_LIST_UI;
+ lv_clear_wifi_list();
+ if (do_wifi)
+ lv_draw_wifi();
+ else {
+ keyboard_value = wifiConfig;
+ lv_draw_keyboard();
+ }
+ }
+ }
+ }
+ }
+}
+
+void lv_draw_wifi_list(void) {
+ scr = lv_screen_create(WIFI_LIST_UI);
+
+ lv_obj_t *buttonDown = lv_imgbtn_create(scr, "F:/bmp_pageDown.bin", OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + OTHER_BTN_YPIEL + INTERVAL_H, event_handler, ID_WL_DOWN);
+ lv_obj_t *buttonBack = lv_imgbtn_create(scr, "F:/bmp_back.bin", OTHER_BTN_XPIEL * 3 + INTERVAL_V * 4, titleHeight + (OTHER_BTN_YPIEL + INTERVAL_H) * 2, event_handler, ID_WL_RETURN);
+
+ for (uint8_t i = 0; i < NUMBER_OF_PAGE; i++) {
+ buttonWifiN[i] = lv_label_btn_create(scr, 0, NAME_BTN_Y * i + 10 + titleHeight, NAME_BTN_X, NAME_BTN_Y, event_handler, i + 1);
+ labelWifiText[i] = lv_label_create_empty(buttonWifiN[i]);
+ #if HAS_ROTARY_ENCODER
+ uint8_t j = 0;
+ if (gCfgItems.encoder_enable) {
+ j = wifi_list.nameIndex + i;
+ if (j < wifi_list.getNameNum) lv_group_add_obj(g, buttonWifiN[i]);
+ }
+ #endif
+ }
+
+ labelPageText = lv_label_create_empty(scr);
+ lv_obj_set_style(labelPageText, &tft_style_label_rel);
+
+ wifi_list.nameIndex = 0;
+ wifi_list.currentWifipage = 1;
+
+ if (wifi_link_state == WIFI_CONNECTED && wifiPara.mode == STA_MODEL) {
+ ZERO(wifi_list.wifiConnectedName);
+ memcpy(wifi_list.wifiConnectedName, wifiPara.ap_name, sizeof(wifi_list.wifiConnectedName));
+ }
+
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) {
+ lv_group_add_obj(g, buttonDown);
+ lv_group_add_obj(g, buttonBack);
+ }
+ #else
+ UNUSED(buttonDown);
+ UNUSED(buttonBack);
+ #endif
+
+ disp_wifi_list();
+}
+
+void disp_wifi_list(void) {
+ int8_t tmpStr[WIFI_NAME_BUFFER_SIZE] = { 0 };
+ uint8_t i, j;
+
+ sprintf((char *)tmpStr, list_menu.file_pages, wifi_list.currentWifipage, wifi_list.getPage);
+ lv_label_set_text(labelPageText, (const char *)tmpStr);
+ lv_obj_align(labelPageText, nullptr, LV_ALIGN_CENTER, 50, -100);
+
+ for (i = 0; i < NUMBER_OF_PAGE; i++) {
+ ZERO(tmpStr);
+
+ j = wifi_list.nameIndex + i;
+ if (j >= wifi_list.getNameNum) {
+ lv_label_set_text(labelWifiText[i], (const char *)tmpStr);
+ lv_obj_align(labelWifiText[i], buttonWifiN[i], LV_ALIGN_IN_LEFT_MID, 20, 0);
+ }
+ else {
+ lv_label_set_text(labelWifiText[i], (char const *)wifi_list.wifiName[j]);
+ lv_obj_align(labelWifiText[i], buttonWifiN[i], LV_ALIGN_IN_LEFT_MID, 20, 0);
+
+ const bool btext = (wifi_link_state == WIFI_CONNECTED && strcmp((const char *)wifi_list.wifiConnectedName, (const char *)wifi_list.wifiName[j]) == 0);
+ lv_btn_set_style(buttonWifiN[i], LV_BTN_STYLE_REL, btext ? &style_sel_text : &tft_style_label_rel);
+ }
+ }
+}
+
+void wifi_scan_handle() {
+ if (!DIALOG_IS(WIFI_ENABLE_TIPS) || uiCfg.command_send != 1) return;
+ last_disp_state = DIALOG_UI;
+ lv_clear_dialog();
+ if (wifi_link_state == WIFI_CONNECTED && wifiPara.mode != AP_MODEL)
+ lv_draw_wifi();
+ else
+ lv_draw_wifi_list();
+}
+
+void lv_clear_wifi_list() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h
new file mode 100644
index 0000000..e2d9275
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_list.h
@@ -0,0 +1,76 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+extern void lv_draw_wifi_list();
+extern void lv_clear_wifi_list();
+extern void disp_wifi_list(void);
+extern void cutWifiName(char *name, int len,char *outStr);
+extern void wifi_scan_handle();
+
+#define NUMBER_OF_PAGE 5
+
+#define WIFI_TOTAL_NUMBER 20
+#define WIFI_NAME_BUFFER_SIZE 33
+
+typedef struct {
+ int8_t getNameNum;
+ int8_t nameIndex;
+ int8_t currentWifipage;
+ int8_t getPage;
+ int8_t RSSI[WIFI_TOTAL_NUMBER];
+ uint8_t wifiName[WIFI_TOTAL_NUMBER][WIFI_NAME_BUFFER_SIZE];
+ uint8_t wifiConnectedName[WIFI_NAME_BUFFER_SIZE];
+} WIFI_LIST;
+extern WIFI_LIST wifi_list;
+
+typedef struct list_menu_disp {
+ const char *title;
+ const char *file_pages;
+} list_menu_def;
+extern list_menu_def list_menu;
+
+typedef struct keyboard_menu_disp {
+ const char *title;
+ const char *apply;
+ const char *password;
+ const char *letter;
+ const char *digital;
+ const char *symbol;
+ const char *space;
+} keyboard_menu_def;
+extern keyboard_menu_def keyboard_menu;
+
+typedef struct tips_menu_disp {
+ const char *joining;
+ const char *failedJoin;
+ const char *wifiConected;
+} tips_menu_def;
+extern tips_menu_def tips_menu;
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp
new file mode 100644
index 0000000..7c1b0af
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.cpp
@@ -0,0 +1,141 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include <lv_conf.h>
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+
+extern lv_group_t *g;
+static lv_obj_t *scr, *labelModelAP = nullptr, *buttonModelAP = nullptr, *labelModelSTA = nullptr, *buttonModelSTA = nullptr, *btnCloudState = nullptr;
+
+enum {
+ ID_WIFI_RETURN = 1,
+ ID_WIFI_AP,
+ ID_WIFI_STA,
+ ID_WIFI_NAME,
+ ID_WIFI_PASSWORD,
+ ID_WIFI_CLOUD,
+ ID_WIFI_CONFIG
+};
+
+static void event_handler(lv_obj_t *obj, lv_event_t event) {
+ if (event != LV_EVENT_RELEASED) return;
+ switch (obj->mks_obj_id) {
+ case ID_WIFI_RETURN:
+ lv_clear_wifi_settings();
+ lv_draw_return_ui();
+ break;
+ case ID_WIFI_AP:
+ if (gCfgItems.wifi_mode_sel == AP_MODEL) return;
+ gCfgItems.wifi_mode_sel = AP_MODEL;
+ lv_btn_set_style_both(buttonModelAP, &style_para_back);
+ lv_btn_set_style_both(buttonModelSTA, &style_para_value);
+ update_spi_flash();
+ break;
+ case ID_WIFI_STA:
+ if (gCfgItems.wifi_mode_sel == STA_MODEL) return;
+ gCfgItems.wifi_mode_sel = STA_MODEL;
+ lv_btn_set_style_both(buttonModelSTA, &style_para_back);
+ lv_btn_set_style_both(buttonModelAP, &style_para_value);
+ update_spi_flash();
+ break;
+ case ID_WIFI_NAME:
+ keyboard_value = wifiName;
+ lv_clear_wifi_settings();
+ lv_draw_keyboard();
+ break;
+ case ID_WIFI_PASSWORD:
+ keyboard_value = wifiPassWord;
+ lv_clear_wifi_settings();
+ lv_draw_keyboard();
+ break;
+ case ID_WIFI_CLOUD:
+ gCfgItems.cloud_enable ^= true;
+ lv_screen_menu_item_onoff_update(btnCloudState, gCfgItems.cloud_enable);
+ update_spi_flash();
+ break;
+ case ID_WIFI_CONFIG:
+ lv_clear_wifi_settings();
+ lv_draw_dialog(DIALOG_WIFI_CONFIG_TIPS);
+ break;
+ }
+}
+
+void lv_draw_wifi_settings(void) {
+ scr = lv_screen_create(WIFI_SETTINGS_UI, machine_menu.WifiConfTitle);
+
+ lv_label_create(scr, PARA_UI_POS_X + PARA_UI_ITEM_TEXT_H, PARA_UI_POS_Y + 10, machine_menu.wifiMode);
+ buttonModelAP = lv_btn_create(scr, nullptr);
+ lv_obj_set_pos(buttonModelAP, PARA_UI_VALUE_POS_X_2, PARA_UI_POS_Y + PARA_UI_VALUE_V_2);
+ lv_obj_set_size(buttonModelAP, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE);
+ lv_obj_set_event_cb_mks(buttonModelAP, event_handler, ID_WIFI_AP, "", 0);
+ lv_btn_use_label_style(buttonModelAP);
+ lv_btn_set_layout(buttonModelAP, LV_LAYOUT_OFF);
+ lv_btn_set_style_both(buttonModelAP, gCfgItems.wifi_mode_sel == AP_MODEL ? &style_para_back : &style_para_value);
+ labelModelAP = lv_label_create_empty(buttonModelAP);
+ lv_label_set_text(labelModelAP, WIFI_AP_TEXT);
+ lv_obj_align(labelModelAP, buttonModelAP, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, buttonModelAP);
+
+ buttonModelSTA = lv_btn_create(scr, nullptr);
+ lv_obj_set_pos(buttonModelSTA, PARA_UI_VALUE_POS_X, PARA_UI_POS_Y + PARA_UI_VALUE_V);
+ lv_obj_set_size(buttonModelSTA, PARA_UI_VALUE_BTN_X_SIZE, PARA_UI_VALUE_BTN_Y_SIZE);
+ lv_obj_set_event_cb_mks(buttonModelSTA, event_handler, ID_WIFI_STA, "", 0);
+ lv_btn_use_label_style(buttonModelSTA);
+ lv_btn_set_layout(buttonModelSTA, LV_LAYOUT_OFF);
+ labelModelSTA = lv_label_create_empty(buttonModelSTA);
+ lv_btn_set_style_both(buttonModelSTA, gCfgItems.wifi_mode_sel == STA_MODEL ? &style_para_back : &style_para_value);
+ lv_label_set_text(labelModelSTA, WIFI_STA_TEXT);
+ lv_obj_align(labelModelSTA, buttonModelSTA, LV_ALIGN_CENTER, 0, 0);
+ if (TERN0(HAS_ROTARY_ENCODER, gCfgItems.encoder_enable)) lv_group_add_obj(g, buttonModelSTA);
+
+ lv_obj_t *line1 = lv_line_create(scr, nullptr);
+ lv_ex_line(line1, line_points[0]);
+
+ strcpy_P(public_buf_m, PSTR(machine_menu.wifiName));
+ strcat_P(public_buf_m, PSTR((const char *)uiCfg.wifi_name));
+ lv_screen_menu_item_1_edit(scr, public_buf_m, PARA_UI_POS_X, PARA_UI_POS_Y * 2, event_handler, ID_WIFI_NAME, 1, machine_menu.wifiEdit);
+
+ strcpy_P(public_buf_m, PSTR(machine_menu.wifiPassWord));
+ strcat_P(public_buf_m, PSTR((const char *)uiCfg.wifi_key));
+ lv_screen_menu_item_1_edit(scr, public_buf_m, PARA_UI_POS_X, PARA_UI_POS_Y * 3, event_handler, ID_WIFI_PASSWORD, 2, machine_menu.wifiEdit);
+
+ btnCloudState = lv_screen_menu_item_onoff(scr, machine_menu.wifiCloud, PARA_UI_POS_X, PARA_UI_POS_Y * 4, event_handler, ID_WIFI_CLOUD, 3, gCfgItems.cloud_enable);
+ lv_screen_menu_item_turn_page(scr, machine_menu.wifiConfig, event_handler, ID_WIFI_CONFIG);
+ lv_screen_menu_item_return(scr, event_handler, ID_WIFI_RETURN);
+}
+
+void lv_clear_wifi_settings() {
+ #if HAS_ROTARY_ENCODER
+ if (gCfgItems.encoder_enable) lv_group_remove_all_objs(g);
+ #endif
+ lv_obj_del(scr);
+}
+
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h
new file mode 100644
index 0000000..c0d6e0c
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_settings.h
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#define WIFI_AP_TEXT "AP"
+#define WIFI_STA_TEXT "STA"
+
+extern void lv_draw_wifi_settings(void);
+extern void lv_clear_wifi_settings();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp
new file mode 100644
index 0000000..7428d36
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.cpp
@@ -0,0 +1,68 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include <lv_conf.h>
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+
+static lv_obj_t *scr;
+
+TIPS_TYPE wifi_tips_type;
+TIPS_DISP tips_disp;
+tips_menu_def tips_menu;
+
+void lv_draw_wifi_tips(void) {
+ static lv_obj_t *text_tips,*wifi_name;
+
+ scr = lv_screen_create(WIFI_TIPS_UI, "");
+
+ wifi_name = lv_label_create(scr, (const char *)wifi_list.wifiName[wifi_list.nameIndex]);
+ lv_obj_align(wifi_name, nullptr, LV_ALIGN_CENTER, 0, -20);
+
+ text_tips = lv_label_create_empty(scr);
+ if (wifi_tips_type == TIPS_TYPE_JOINING) {
+ lv_label_set_text(text_tips, tips_menu.joining);
+ lv_obj_align(text_tips, nullptr, LV_ALIGN_CENTER, 0, -60);
+ }
+ else if (wifi_tips_type == TIPS_TYPE_TAILED_JOIN) {
+ lv_label_set_text(text_tips, tips_menu.failedJoin);
+ lv_obj_align(text_tips, nullptr, LV_ALIGN_CENTER, 0, -60);
+ }
+ else if (wifi_tips_type == TIPS_TYPE_WIFI_CONECTED) {
+ lv_label_set_text(text_tips, tips_menu.wifiConected);
+ lv_obj_align(text_tips, nullptr, LV_ALIGN_CENTER, 0, -60);
+ }
+
+ tips_disp.timer = TIPS_TIMER_START;
+ tips_disp.timer_count = 0;
+}
+
+void lv_clear_wifi_tips() { lv_obj_del(scr); }
+
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h
new file mode 100644
index 0000000..4f81f00
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/draw_wifi_tips.h
@@ -0,0 +1,51 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+
+extern void lv_draw_wifi_tips(void);
+extern void lv_clear_wifi_tips();
+
+typedef enum {
+ TIPS_TYPE_JOINING,
+ TIPS_TYPE_TAILED_JOIN,
+ TIPS_TYPE_WIFI_CONECTED
+} TIPS_TYPE;
+extern TIPS_TYPE wifi_tips_type;
+
+typedef struct {
+ unsigned char timer;
+ unsigned int timer_count;
+} TIPS_DISP;
+extern TIPS_DISP tips_disp;
+
+#define TIPS_TIMER_START 1
+#define TIPS_TIMER_STOP 0
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
+
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp b/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp
new file mode 100644
index 0000000..f3585cc
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/gb2312_puhui16.cpp
@@ -0,0 +1,105 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "pic_manager.h"
+#include <lvgl.h>
+
+#include "../../../../inc/MarlinConfig.h"
+
+#if HAS_SPI_FLASH_FONT
+
+typedef struct {
+ uint16_t min;
+ uint16_t max;
+ uint8_t bpp;
+ uint8_t reserved[3];
+} x_header_t;
+
+typedef struct {
+ uint32_t pos;
+} x_table_t;
+
+typedef struct {
+ uint8_t adv_w;
+ uint8_t box_w;
+} glyph_dsc_t;
+
+static x_header_t __g_xbf_hd = { .min = 0, .max = 0, .bpp = 0 };
+static uint8_t __g_font_buf[63];
+
+static uint8_t *__user_font_getdata(int offset, int size) {
+ get_spi_flash_data((char *)__g_font_buf, offset, size);
+ return __g_font_buf;
+}
+
+static const uint8_t * __user_font_get_bitmap(const lv_font_t * font, uint32_t unicode_letter) {
+ if (__g_xbf_hd.max == 0) {
+ uint8_t *p = __user_font_getdata(0, sizeof(x_header_t));
+ memcpy(&__g_xbf_hd, p, sizeof(x_header_t));
+ }
+ if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min)
+ return nullptr;
+ uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4;
+ uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
+ if (p_pos[0] != 0) {
+ uint32_t pos = p_pos[0];
+ __user_font_getdata(pos, 2);
+ return __user_font_getdata(pos + 2, sizeof(__g_font_buf));
+ }
+ return nullptr;
+}
+
+static bool __user_font_get_glyph_dsc(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) {
+ if (__g_xbf_hd.max == 0) {
+ uint8_t *p = __user_font_getdata(0, sizeof(x_header_t));
+ memcpy(&__g_xbf_hd, p, sizeof(x_header_t));
+ }
+ if (unicode_letter > __g_xbf_hd.max || unicode_letter < __g_xbf_hd.min)
+ return false;
+ uint32_t unicode_offset = sizeof(x_header_t) + (unicode_letter - __g_xbf_hd.min) * 4;
+ uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset, 4);
+ if (p_pos[0] != 0) {
+ glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(p_pos[0], 2);
+ dsc_out->adv_w = gdsc->adv_w;
+ dsc_out->box_h = font->line_height;
+ dsc_out->box_w = gdsc->box_w;
+ dsc_out->ofs_x = 0;
+ dsc_out->ofs_y = 0;
+ dsc_out->bpp = __g_xbf_hd.bpp;
+ return true;
+ }
+ return false;
+}
+
+lv_font_t gb2312_puhui32;
+void init_gb2312_font() {
+ gb2312_puhui32.get_glyph_bitmap = __user_font_get_bitmap;
+ gb2312_puhui32.get_glyph_dsc = __user_font_get_glyph_dsc;
+ gb2312_puhui32.line_height = 21;
+ gb2312_puhui32.base_line = 0;
+}
+
+#endif // HAS_SPI_FLASH_FONT
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp b/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp
new file mode 100644
index 0000000..a26116a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/irq_overrid.cpp
@@ -0,0 +1,63 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "tft_lvgl_configuration.h"
+
+#ifdef __STM32F1__
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+ #include "draw_ui.h"
+ #include "wifiSerial.h"
+
+ #include <libmaple/libmaple.h>
+ #include <libmaple/gpio.h>
+ #include <libmaple/timer.h>
+ #include <libmaple/usart.h>
+ #include <libmaple/ring_buffer.h>
+
+ #include "../../../../inc/MarlinConfig.h"
+
+ #ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+ #endif
+
+ #define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH);
+ #define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW);
+
+ void __irq_usart1(void) {
+ if ((USART1_BASE->CR1 & USART_CR1_RXNEIE) && (USART1_BASE->SR & USART_SR_RXNE))
+ WRITE(WIFI_IO1_PIN, HIGH);
+
+ WIFISERIAL.wifi_usart_irq(USART1_BASE);
+ }
+
+ #ifdef __cplusplus
+ } /* C-declarations for C++ */
+ #endif
+
+#endif // MKS_WIFI_MODULE
+#endif // __STM32F1__
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp
new file mode 100644
index 0000000..4a6a5ce
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.cpp
@@ -0,0 +1,655 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "SPI_TFT.h"
+
+#include "tft_lvgl_configuration.h"
+#include "draw_ready_print.h"
+#include "mks_hardware_test.h"
+#include "draw_ui.h"
+#include "pic_manager.h"
+#include <lvgl.h>
+
+#include "../../../../MarlinCore.h"
+#include "../../../../module/temperature.h"
+#include "../../../../sd/cardreader.h"
+
+bool pw_det_sta, pw_off_sta, mt_det_sta, mt_det3_sta;
+#if PIN_EXISTS(MT_DET_2)
+ bool mt_det2_sta;
+#endif
+bool endstopx1_sta, endstopx2_sta, endstopy1_sta, endstopy2_sta, endstopz1_sta, endstopz2_sta;
+void test_gpio_readlevel_L() {
+ #if ENABLED(MKS_TEST)
+ volatile uint32_t itest;
+ WRITE(WIFI_IO0_PIN, HIGH);
+ itest = 10000;
+ while (itest--);
+ pw_det_sta = !READ(MKS_TEST_POWER_LOSS_PIN);
+ pw_off_sta = !READ(MKS_TEST_PS_ON_PIN);
+ mt_det_sta = !READ(MT_DET_1_PIN);
+ #if PIN_EXISTS(MT_DET_2)
+ mt_det2_sta = !READ(MT_DET_2_PIN);
+ #endif
+ endstopx1_sta = !READ(X_MIN_PIN);
+ endstopy1_sta = !READ(Y_MIN_PIN);
+ endstopz1_sta = !READ(Z_MIN_PIN);
+ endstopz2_sta = !READ(Z_MAX_PIN);
+ #endif
+}
+
+void test_gpio_readlevel_H() {
+ #if ENABLED(MKS_TEST)
+ volatile uint32_t itest;
+ WRITE(WIFI_IO0_PIN, LOW);
+ itest = 10000;
+ while (itest--);
+ pw_det_sta = READ(MKS_TEST_POWER_LOSS_PIN);
+ pw_off_sta = READ(MKS_TEST_PS_ON_PIN);
+ mt_det_sta = READ(MT_DET_1_PIN);
+ #if PIN_EXISTS(MT_DET_2)
+ mt_det2_sta = READ(MT_DET_2_PIN);
+ #endif
+ endstopx1_sta = READ(X_MIN_PIN);
+ endstopy1_sta = READ(Y_MIN_PIN);
+ endstopz1_sta = READ(Z_MIN_PIN);
+ endstopz2_sta = READ(Z_MAX_PIN);
+ #endif
+}
+
+void init_test_gpio() {
+ #ifdef MKS_TEST
+ SET_INPUT_PULLUP(X_MIN_PIN);
+ SET_INPUT_PULLUP(Y_MIN_PIN);
+ SET_INPUT_PULLUP(Z_MIN_PIN);
+ SET_INPUT_PULLUP(Z_MAX_PIN);
+
+ SET_OUTPUT(WIFI_IO0_PIN);
+
+ SET_INPUT_PULLUP(MT_DET_1_PIN);
+ #if PIN_EXISTS(MT_DET_2)
+ SET_INPUT_PULLUP(MT_DET_2_PIN);
+ #endif
+
+ SET_INPUT_PULLUP(MKS_TEST_POWER_LOSS_PIN);
+ SET_INPUT_PULLUP(MKS_TEST_PS_ON_PIN);
+
+ SET_INPUT_PULLUP(SERVO0_PIN);
+
+ SET_OUTPUT(X_ENABLE_PIN);
+ SET_OUTPUT(Y_ENABLE_PIN);
+ SET_OUTPUT(Z_ENABLE_PIN);
+ SET_OUTPUT(E0_ENABLE_PIN);
+ #if !MB(MKS_ROBIN_E3P)
+ SET_OUTPUT(E1_ENABLE_PIN);
+ #endif
+
+ WRITE(X_ENABLE_PIN, LOW);
+ WRITE(Y_ENABLE_PIN, LOW);
+ WRITE(Z_ENABLE_PIN, LOW);
+ WRITE(E0_ENABLE_PIN, LOW);
+ #if !MB(MKS_ROBIN_E3P)
+ WRITE(E1_ENABLE_PIN, LOW);
+ #endif
+
+ #if MB(MKS_ROBIN_E3P)
+ SET_INPUT_PULLUP(PA1);
+ SET_INPUT_PULLUP(PA3);
+ SET_INPUT_PULLUP(PC2);
+ SET_INPUT_PULLUP(PD8);
+ SET_INPUT_PULLUP(PE5);
+ SET_INPUT_PULLUP(PE6);
+ SET_INPUT_PULLUP(PE7);
+ #endif
+ #endif
+}
+
+void mks_test_beeper() {
+ #ifdef MKS_TEST
+ WRITE(BEEPER_PIN, HIGH);
+ delay(100);
+ WRITE(BEEPER_PIN, LOW);
+ delay(100);
+ #endif
+}
+
+void mks_gpio_test() {
+ #if ENABLED(MKS_TEST)
+ init_test_gpio();
+
+ test_gpio_readlevel_L();
+ test_gpio_readlevel_H();
+ test_gpio_readlevel_L();
+ if ((pw_det_sta == true)
+ && (pw_off_sta == true)
+ && (mt_det_sta == true)
+ #if PIN_EXISTS(MT_DET_2)
+ && (mt_det2_sta == true)
+ #endif
+ #if MB(MKS_ROBIN_E3P)
+ && (READ(PA1) == false)
+ && (READ(PA3) == false)
+ && (READ(PC2) == false)
+ && (READ(PD8) == false)
+ && (READ(PE5) == false)
+ && (READ(PE6) == false)
+ && (READ(PE7) == false)
+ #endif
+ )
+ disp_det_ok();
+ else
+ disp_det_error();
+
+ if ( (endstopx1_sta == true)
+ && (endstopy1_sta == true)
+ && (endstopz1_sta == true)
+ && (endstopz2_sta == true)
+ )
+ disp_Limit_ok();
+ else
+ disp_Limit_error();
+ #endif
+
+ if (uiCfg.tmc_connect_state) disp_tmc_ok();
+ else disp_tmc_error();
+}
+
+void mks_hardware_test() {
+ #if ENABLED(MKS_TEST)
+ if (millis() % 1000 < 500) {
+ WRITE(X_DIR_PIN, LOW);
+ WRITE(Y_DIR_PIN, LOW);
+ WRITE(Z_DIR_PIN, LOW);
+ WRITE(E0_DIR_PIN, LOW);
+ #if !MB(MKS_ROBIN_E3P)
+ WRITE(E1_DIR_PIN, LOW);
+ #endif
+ thermalManager.fan_speed[0] = 255;
+ #if PIN_EXISTS(FAN1)
+ thermalManager.fan_speed[1] = 255;
+ #endif
+ #if !MB(MKS_ROBIN_E3P)
+ WRITE(HEATER_1_PIN, HIGH); // HE1
+ #endif
+ WRITE(HEATER_0_PIN, HIGH); // HE0
+ WRITE(HEATER_BED_PIN, HIGH); // HOT-BED
+ }
+ else {
+ WRITE(X_DIR_PIN, HIGH);
+ WRITE(Y_DIR_PIN, HIGH);
+ WRITE(Z_DIR_PIN, HIGH);
+ WRITE(E0_DIR_PIN, HIGH);
+ #if !MB(MKS_ROBIN_E3P)
+ WRITE(E1_DIR_PIN, HIGH);
+ #endif
+ thermalManager.fan_speed[0] = 0;
+ #if PIN_EXISTS(FAN1)
+ thermalManager.fan_speed[1] = 0;
+ #endif
+ #if !MB(MKS_ROBIN_E3P)
+ WRITE(HEATER_1_PIN, LOW); // HE1
+ #endif
+ WRITE(HEATER_0_PIN, LOW); // HE0
+ WRITE(HEATER_BED_PIN, LOW); // HOT-BED
+ }
+
+ if ( (endstopx1_sta == 1) && (endstopx2_sta == 1)
+ && (endstopy1_sta == 1) && (endstopy2_sta == 1)
+ && (endstopz1_sta == 1) && (endstopz2_sta == 1)
+ ) {
+ // nothing here
+ }
+ else {
+ }
+
+ if (disp_state == PRINT_READY_UI) mks_disp_test();
+
+ #endif
+}
+
+static const uint16_t ASCII_Table_16x24[] PROGMEM = {
+ // Space ' '
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '!'
+ 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, 0x0000,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '"'
+ 0x0000, 0x0000, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '#'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C60, 0x0C60,
+ 0x0C60, 0x0630, 0x0630, 0x1FFE, 0x1FFE, 0x0630, 0x0738, 0x0318,
+ 0x1FFE, 0x1FFE, 0x0318, 0x0318, 0x018C, 0x018C, 0x018C, 0x0000,
+ // '$'
+ 0x0000, 0x0080, 0x03E0, 0x0FF8, 0x0E9C, 0x1C8C, 0x188C, 0x008C,
+ 0x0098, 0x01F8, 0x07E0, 0x0E80, 0x1C80, 0x188C, 0x188C, 0x189C,
+ 0x0CB8, 0x0FF0, 0x03E0, 0x0080, 0x0080, 0x0000, 0x0000, 0x0000,
+ // '%'
+ 0x0000, 0x0000, 0x0000, 0x180E, 0x0C1B, 0x0C11, 0x0611, 0x0611,
+ 0x0311, 0x0311, 0x019B, 0x018E, 0x38C0, 0x6CC0, 0x4460, 0x4460,
+ 0x4430, 0x4430, 0x4418, 0x6C18, 0x380C, 0x0000, 0x0000, 0x0000,
+ // '&'
+ 0x0000, 0x01E0, 0x03F0, 0x0738, 0x0618, 0x0618, 0x0330, 0x01F0,
+ 0x00F0, 0x00F8, 0x319C, 0x330E, 0x1E06, 0x1C06, 0x1C06, 0x3F06,
+ 0x73FC, 0x21F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // "'"
+ 0x0000, 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '('
+ 0x0000, 0x0200, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x0060, 0x0060,
+ 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
+ 0x0060, 0x0060, 0x00C0, 0x00C0, 0x0180, 0x0300, 0x0200, 0x0000,
+ // ')'
+ 0x0000, 0x0020, 0x0060, 0x00C0, 0x0180, 0x0180, 0x0300, 0x0300,
+ 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600,
+ 0x0300, 0x0300, 0x0180, 0x0180, 0x00C0, 0x0060, 0x0020, 0x0000,
+ // '*'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0,
+ 0x06D8, 0x07F8, 0x01E0, 0x0330, 0x0738, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '+'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x3FFC, 0x3FFC, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // ','
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0180, 0x0180, 0x0100, 0x0100, 0x0080, 0x0000, 0x0000,
+ // '-'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x07E0, 0x07E0, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '.'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '/'
+ 0x0000, 0x0C00, 0x0C00, 0x0600, 0x0600, 0x0600, 0x0300, 0x0300,
+ 0x0300, 0x0380, 0x0180, 0x0180, 0x0180, 0x00C0, 0x00C0, 0x00C0,
+ 0x0060, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '0'
+ 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C18, 0x180C, 0x180C, 0x180C,
+ 0x180C, 0x180C, 0x180C, 0x180C, 0x180C, 0x180C, 0x0C18, 0x0E38,
+ 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '1'
+ 0x0000, 0x0100, 0x0180, 0x01C0, 0x01F0, 0x0198, 0x0188, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '2'
+ 0x0000, 0x03E0, 0x0FF8, 0x0C18, 0x180C, 0x180C, 0x1800, 0x1800,
+ 0x0C00, 0x0600, 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018,
+ 0x1FFC, 0x1FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '3'
+ 0x0000, 0x01E0, 0x07F8, 0x0E18, 0x0C0C, 0x0C0C, 0x0C00, 0x0600,
+ 0x03C0, 0x07C0, 0x0C00, 0x1800, 0x1800, 0x180C, 0x180C, 0x0C18,
+ 0x07F8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '4'
+ 0x0000, 0x0C00, 0x0E00, 0x0F00, 0x0F00, 0x0D80, 0x0CC0, 0x0C60,
+ 0x0C60, 0x0C30, 0x0C18, 0x0C0C, 0x3FFC, 0x3FFC, 0x0C00, 0x0C00,
+ 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '5'
+ 0x0000, 0x0FF8, 0x0FF8, 0x0018, 0x0018, 0x000C, 0x03EC, 0x07FC,
+ 0x0E1C, 0x1C00, 0x1800, 0x1800, 0x1800, 0x180C, 0x0C1C, 0x0E18,
+ 0x07F8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '6'
+ 0x0000, 0x07C0, 0x0FF0, 0x1C38, 0x1818, 0x0018, 0x000C, 0x03CC,
+ 0x0FEC, 0x0E3C, 0x1C1C, 0x180C, 0x180C, 0x180C, 0x1C18, 0x0E38,
+ 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '7'
+ 0x0000, 0x1FFC, 0x1FFC, 0x0C00, 0x0600, 0x0600, 0x0300, 0x0380,
+ 0x0180, 0x01C0, 0x00C0, 0x00E0, 0x0060, 0x0060, 0x0070, 0x0030,
+ 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '8'
+ 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C18, 0x0C18, 0x0C18, 0x0638,
+ 0x07F0, 0x07F0, 0x0C18, 0x180C, 0x180C, 0x180C, 0x180C, 0x0C38,
+ 0x0FF8, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '9'
+ 0x0000, 0x03E0, 0x07F0, 0x0E38, 0x0C1C, 0x180C, 0x180C, 0x180C,
+ 0x1C1C, 0x1E38, 0x1BF8, 0x19E0, 0x1800, 0x0C00, 0x0C00, 0x0E1C,
+ 0x07F8, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // ':'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // ';'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0180, 0x0180,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0180, 0x0180, 0x0100, 0x0100, 0x0080, 0x0000, 0x0000, 0x0000,
+ // '<'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1000, 0x1C00, 0x0F80, 0x03E0, 0x00F8, 0x0018, 0x00F8, 0x03E0,
+ 0x0F80, 0x1C00, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '='
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x1FF8, 0x0000, 0x0000, 0x0000, 0x1FF8, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '>'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0008, 0x0038, 0x01F0, 0x07C0, 0x1F00, 0x1800, 0x1F00, 0x07C0,
+ 0x01F0, 0x0038, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '?'
+ 0x0000, 0x03E0, 0x0FF8, 0x0C18, 0x180C, 0x180C, 0x1800, 0x0C00,
+ 0x0600, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x00C0, 0x0000, 0x0000,
+ 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '@'
+ 0x0000, 0x0000, 0x07E0, 0x1818, 0x2004, 0x29C2, 0x4A22, 0x4411,
+ 0x4409, 0x4409, 0x4409, 0x2209, 0x1311, 0x0CE2, 0x4002, 0x2004,
+ 0x1818, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'A'
+ 0x0000, 0x0380, 0x0380, 0x06C0, 0x06C0, 0x06C0, 0x0C60, 0x0C60,
+ 0x1830, 0x1830, 0x1830, 0x3FF8, 0x3FF8, 0x701C, 0x600C, 0x600C,
+ 0xC006, 0xC006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'B'
+ 0x0000, 0x03FC, 0x0FFC, 0x0C0C, 0x180C, 0x180C, 0x180C, 0x0C0C,
+ 0x07FC, 0x0FFC, 0x180C, 0x300C, 0x300C, 0x300C, 0x300C, 0x180C,
+ 0x1FFC, 0x07FC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'C'
+ 0x0000, 0x07C0, 0x1FF0, 0x3838, 0x301C, 0x700C, 0x6006, 0x0006,
+ 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x6006, 0x700C, 0x301C,
+ 0x1FF0, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'D'
+ 0x0000, 0x03FE, 0x0FFE, 0x0E06, 0x1806, 0x1806, 0x3006, 0x3006,
+ 0x3006, 0x3006, 0x3006, 0x3006, 0x3006, 0x1806, 0x1806, 0x0E06,
+ 0x0FFE, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'E'
+ 0x0000, 0x3FFC, 0x3FFC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C,
+ 0x1FFC, 0x1FFC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C,
+ 0x3FFC, 0x3FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'F'
+ 0x0000, 0x3FF8, 0x3FF8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+ 0x1FF8, 0x1FF8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+ 0x0018, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'G'
+ 0x0000, 0x0FE0, 0x3FF8, 0x783C, 0x600E, 0xE006, 0xC007, 0x0003,
+ 0x0003, 0xFE03, 0xFE03, 0xC003, 0xC007, 0xC006, 0xC00E, 0xF03C,
+ 0x3FF8, 0x0FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'H'
+ 0x0000, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C,
+ 0x3FFC, 0x3FFC, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C,
+ 0x300C, 0x300C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'I'
+ 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'J'
+ 0x0000, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600,
+ 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0618, 0x0618, 0x0738,
+ 0x03F0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'K'
+ 0x0000, 0x3006, 0x1806, 0x0C06, 0x0606, 0x0306, 0x0186, 0x00C6,
+ 0x0066, 0x0076, 0x00DE, 0x018E, 0x0306, 0x0606, 0x0C06, 0x1806,
+ 0x3006, 0x6006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'L'
+ 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+ 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+ 0x1FF8, 0x1FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'M'
+ 0x0000, 0xE00E, 0xF01E, 0xF01E, 0xF01E, 0xD836, 0xD836, 0xD836,
+ 0xD836, 0xCC66, 0xCC66, 0xCC66, 0xC6C6, 0xC6C6, 0xC6C6, 0xC6C6,
+ 0xC386, 0xC386, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'N'
+ 0x0000, 0x300C, 0x301C, 0x303C, 0x303C, 0x306C, 0x306C, 0x30CC,
+ 0x30CC, 0x318C, 0x330C, 0x330C, 0x360C, 0x360C, 0x3C0C, 0x3C0C,
+ 0x380C, 0x300C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'O'
+ 0x0000, 0x07E0, 0x1FF8, 0x381C, 0x700E, 0x6006, 0xC003, 0xC003,
+ 0xC003, 0xC003, 0xC003, 0xC003, 0xC003, 0x6006, 0x700E, 0x381C,
+ 0x1FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'P'
+ 0x0000, 0x0FFC, 0x1FFC, 0x380C, 0x300C, 0x300C, 0x300C, 0x300C,
+ 0x180C, 0x1FFC, 0x07FC, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C,
+ 0x000C, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'Q'
+ 0x0000, 0x07E0, 0x1FF8, 0x381C, 0x700E, 0x6006, 0xE003, 0xC003,
+ 0xC003, 0xC003, 0xC003, 0xC003, 0xE007, 0x6306, 0x3F0E, 0x3C1C,
+ 0x3FF8, 0xF7E0, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'R'
+ 0x0000, 0x0FFE, 0x1FFE, 0x3806, 0x3006, 0x3006, 0x3006, 0x3806,
+ 0x1FFE, 0x07FE, 0x0306, 0x0606, 0x0C06, 0x1806, 0x1806, 0x3006,
+ 0x3006, 0x6006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'S'
+ 0x0000, 0x03E0, 0x0FF8, 0x0C1C, 0x180C, 0x180C, 0x000C, 0x001C,
+ 0x03F8, 0x0FE0, 0x1E00, 0x3800, 0x3006, 0x3006, 0x300E, 0x1C1C,
+ 0x0FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'T'
+ 0x0000, 0x7FFE, 0x7FFE, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'U'
+ 0x0000, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C,
+ 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x300C, 0x1818,
+ 0x1FF8, 0x07E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'V'
+ 0x0000, 0x6003, 0x3006, 0x3006, 0x3006, 0x180C, 0x180C, 0x180C,
+ 0x0C18, 0x0C18, 0x0E38, 0x0630, 0x0630, 0x0770, 0x0360, 0x0360,
+ 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'W'
+ 0x0000, 0x6003, 0x61C3, 0x61C3, 0x61C3, 0x3366, 0x3366, 0x3366,
+ 0x3366, 0x3366, 0x3366, 0x1B6C, 0x1B6C, 0x1B6C, 0x1A2C, 0x1E3C,
+ 0x0E38, 0x0E38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'X'
+ 0x0000, 0xE00F, 0x700C, 0x3018, 0x1830, 0x0C70, 0x0E60, 0x07C0,
+ 0x0380, 0x0380, 0x03C0, 0x06E0, 0x0C70, 0x1C30, 0x1818, 0x300C,
+ 0x600E, 0xE007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'Y'
+ 0x0000, 0xC003, 0x6006, 0x300C, 0x381C, 0x1838, 0x0C30, 0x0660,
+ 0x07E0, 0x03C0, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'Z'
+ 0x0000, 0x7FFC, 0x7FFC, 0x6000, 0x3000, 0x1800, 0x0C00, 0x0600,
+ 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018, 0x000C, 0x0006,
+ 0x7FFE, 0x7FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '['
+ 0x0000, 0x03E0, 0x03E0, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060,
+ 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060,
+ 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x03E0, 0x03E0, 0x0000,
+ // '\'
+ 0x0000, 0x0030, 0x0030, 0x0060, 0x0060, 0x0060, 0x00C0, 0x00C0,
+ 0x00C0, 0x01C0, 0x0180, 0x0180, 0x0180, 0x0300, 0x0300, 0x0300,
+ 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // ']'
+ 0x0000, 0x03E0, 0x03E0, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300,
+ 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x0300,
+ 0x0300, 0x0300, 0x0300, 0x0300, 0x0300, 0x03E0, 0x03E0, 0x0000,
+ // '^'
+ 0x0000, 0x0000, 0x01C0, 0x01C0, 0x0360, 0x0360, 0x0360, 0x0630,
+ 0x0630, 0x0C18, 0x0C18, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '_'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '''
+ 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'a'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F0, 0x07F8,
+ 0x0C1C, 0x0C0C, 0x0F00, 0x0FF0, 0x0CF8, 0x0C0C, 0x0C0C, 0x0F1C,
+ 0x0FF8, 0x18F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'b'
+ 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x03D8, 0x0FF8,
+ 0x0C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C38,
+ 0x0FF8, 0x03D8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'c'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x07F0,
+ 0x0E30, 0x0C18, 0x0018, 0x0018, 0x0018, 0x0018, 0x0C18, 0x0E30,
+ 0x07F0, 0x03C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'd'
+ 0x0000, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x1BC0, 0x1FF0,
+ 0x1C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C30,
+ 0x1FF0, 0x1BC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'e'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x0FF0,
+ 0x0C30, 0x1818, 0x1FF8, 0x1FF8, 0x0018, 0x0018, 0x1838, 0x1C30,
+ 0x0FF0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'f'
+ 0x0000, 0x0F80, 0x0FC0, 0x00C0, 0x00C0, 0x00C0, 0x07F0, 0x07F0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'g'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0DE0, 0x0FF8,
+ 0x0E18, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0E18,
+ 0x0FF8, 0x0DE0, 0x0C00, 0x0C0C, 0x061C, 0x07F8, 0x01F0, 0x0000,
+ // 'h'
+ 0x0000, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x07D8, 0x0FF8,
+ 0x1C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818,
+ 0x1818, 0x1818, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'i'
+ 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'j'
+ 0x0000, 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00F8, 0x0078, 0x0000,
+ // 'k'
+ 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x0C0C, 0x060C,
+ 0x030C, 0x018C, 0x00CC, 0x006C, 0x00FC, 0x019C, 0x038C, 0x030C,
+ 0x060C, 0x0C0C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'l'
+ 0x0000, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'm'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C7C, 0x7EFF,
+ 0xE3C7, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183, 0xC183,
+ 0xC183, 0xC183, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'n'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0798, 0x0FF8,
+ 0x1C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818,
+ 0x1818, 0x1818, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'o'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x0FF0,
+ 0x0C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C30,
+ 0x0FF0, 0x03C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'p'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03D8, 0x0FF8,
+ 0x0C38, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x0C38,
+ 0x0FF8, 0x03D8, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0000,
+ // 'q'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1BC0, 0x1FF0,
+ 0x1C30, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C30,
+ 0x1FF0, 0x1BC0, 0x1800, 0x1800, 0x1800, 0x1800, 0x1800, 0x0000,
+ // 'r'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07B0, 0x03F0,
+ 0x0070, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
+ 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 's'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03F0,
+ 0x0E38, 0x0C18, 0x0038, 0x03F0, 0x07C0, 0x0C00, 0x0C18, 0x0E38,
+ 0x07F0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 't'
+ 0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00C0, 0x07F0, 0x07F0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x07C0, 0x0780, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'u'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1818, 0x1818,
+ 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1818, 0x1C38,
+ 0x1FF0, 0x19E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'v'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x180C, 0x0C18,
+ 0x0C18, 0x0C18, 0x0630, 0x0630, 0x0630, 0x0360, 0x0360, 0x0360,
+ 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'w'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x41C1, 0x41C1,
+ 0x61C3, 0x6363, 0x6363, 0x6363, 0x3636, 0x3636, 0x3636, 0x1C1C,
+ 0x1C1C, 0x1C1C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'x'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x381C, 0x1C38,
+ 0x0C30, 0x0660, 0x0360, 0x0360, 0x0360, 0x0360, 0x0660, 0x0C30,
+ 0x1C38, 0x381C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // 'y'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3018, 0x1830,
+ 0x1830, 0x1870, 0x0C60, 0x0C60, 0x0CE0, 0x06C0, 0x06C0, 0x0380,
+ 0x0380, 0x0380, 0x0180, 0x0180, 0x01C0, 0x00F0, 0x0070, 0x0000,
+ // 'z'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC,
+ 0x0C00, 0x0600, 0x0300, 0x0180, 0x00C0, 0x0060, 0x0030, 0x0018,
+ 0x1FFC, 0x1FFC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ // '{'
+ 0x0000, 0x0300, 0x0180, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
+ 0x00C0, 0x0060, 0x0060, 0x0030, 0x0060, 0x0040, 0x00C0, 0x00C0,
+ 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x0180, 0x0300, 0x0000, 0x0000,
+ // '|'
+ 0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000,
+ // '}'
+ 0x0000, 0x0060, 0x00C0, 0x01C0, 0x0180, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0300, 0x0300, 0x0600, 0x0300, 0x0100, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0180, 0x00C0, 0x0060, 0x0000, 0x0000,
+ // '~'
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x10F0, 0x1FF8, 0x0F08, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint16_t bkColor) {
+ for (uint16_t i = 0; i < 24; i++) {
+ const uint16_t tmp_char = pgm_read_word(&ASCII_Table_16x24[((c - 0x20) * 24) + i]);
+ for (uint16_t j = 0; j < 16; j++)
+ SPI_TFT.SetPoint(x + j, y + i, ((tmp_char >> j) & 0x01) ? charColor : bkColor);
+ }
+}
+
+void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor, uint16_t bkColor) {
+ while (*string != '\0') {
+ disp_char_1624(x, y, *string, charColor, bkColor);
+ string++;
+ x += 16;
+ }
+}
+
+void disp_assets_update() {
+ SPI_TFT.LCD_clear(0x0000);
+ disp_string(100, 140, "Assets Updating...", 0xFFFF, 0x0000);
+}
+
+void disp_assets_update_progress(const char *msg) {
+ char buf[30];
+ memset(buf, ' ', COUNT(buf));
+ strncpy(buf, msg, strlen(msg));
+ buf[COUNT(buf)-1] = '\0';
+ disp_string(100, 165, buf, 0xFFFF, 0x0000);
+}
+
+uint8_t mks_test_flag = 0;
+const char *MKSTestPath = "MKS_TEST";
+
+#if ENABLED(SDSUPPORT)
+ void mks_test_get() {
+ SdFile dir, root = card.getroot();
+ if (dir.open(&root, MKSTestPath, O_RDONLY))
+ mks_test_flag = 0x1E;
+ }
+#endif
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h
new file mode 100644
index 0000000..0e2d809
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/mks_hardware_test.h
@@ -0,0 +1,33 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include <lvgl.h>
+
+void mks_gpio_test();
+void disp_char_1624(uint16_t x, uint16_t y, uint8_t c, uint16_t charColor, uint16_t bkColor);
+void disp_string(uint16_t x, uint16_t y, const char * string, uint16_t charColor, uint16_t bkColor);
+void mks_hardware_test();
+void disp_assets_update();
+void disp_assets_update_progress(const char *msg);
+void mks_test_get();
+extern uint8_t mks_test_flag;
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp
new file mode 100644
index 0000000..51aab0a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.cpp
@@ -0,0 +1,622 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "string.h"
+#include "draw_ui.h"
+#include "pic_manager.h"
+#include "draw_ready_print.h"
+#include "mks_hardware_test.h"
+
+#include "SPIFlashStorage.h"
+#include "../../../../libs/W25Qxx.h"
+
+#include "../../../../sd/cardreader.h"
+#include "../../../../MarlinCore.h"
+
+extern uint16_t DeviceCode;
+
+#if ENABLED(SDSUPPORT)
+ extern char *createFilename(char * const buffer, const dir_t &p);
+#endif
+
+static const char assets[][LONG_FILENAME_LENGTH] = {
+ //homing screen
+ "bmp_zeroAll.bin",
+ "bmp_zero.bin",
+ "bmp_zeroX.bin",
+ "bmp_zeroY.bin",
+ "bmp_zeroZ.bin",
+ "bmp_manual_off.bin",
+
+ //tool screen
+ "bmp_preHeat.bin",
+ "bmp_extruct.bin",
+ "bmp_mov.bin",
+ "bmp_leveling.bin",
+ "bmp_filamentchange.bin",
+ "bmp_more.bin",
+
+ //fan screen
+ "bmp_Add.bin",
+ "bmp_Dec.bin",
+ "bmp_speed255.bin",
+ "bmp_speed127.bin",
+ "bmp_speed0.bin",
+ "bmp_speed0.bin",
+
+ "bmp_bed.bin",
+ "bmp_step1_degree.bin",
+ "bmp_step5_degree.bin",
+ "bmp_step10_degree.bin",
+
+ //extrusion screen
+ "bmp_in.bin",
+ "bmp_out.bin",
+ "bmp_extru1.bin",
+ #if HAS_MULTI_EXTRUDER
+ "bmp_extru2.bin",
+ #endif
+ "bmp_speed_high.bin",
+ "bmp_speed_slow.bin",
+ "bmp_speed_normal.bin",
+ "bmp_step1_mm.bin",
+ "bmp_step5_mm.bin",
+ "bmp_step10_mm.bin",
+
+ //select file screen
+ "bmp_pageUp.bin",
+ "bmp_pageDown.bin",
+ "bmp_back.bin", //TODO: why two back buttons? Why not just one? (return / back)
+ "bmp_dir.bin",
+ "bmp_file.bin",
+
+ //move motor screen
+ //TODO: 6 equal icons, just in diffenct rotation... it may be optimized too
+ "bmp_xAdd.bin",
+ "bmp_xDec.bin",
+ "bmp_yAdd.bin",
+ "bmp_yDec.bin",
+ "bmp_zAdd.bin",
+ "bmp_zDec.bin",
+ "bmp_step_move0_1.bin",
+ "bmp_step_move1.bin",
+ "bmp_step_move10.bin",
+
+ //operation screen
+ "bmp_auto_off.bin",
+ "bmp_speed.bin",
+ "bmp_fan.bin",
+ "bmp_temp.bin",
+ "bmp_extrude_opr.bin",
+ "bmp_move_opr.bin",
+
+ //change speed screen
+ "bmp_step1_percent.bin",
+ "bmp_step5_percent.bin",
+ "bmp_step10_percent.bin",
+ "bmp_extruct_sel.bin",
+ "bmp_mov_changespeed.bin",
+ "bmp_mov_sel.bin",
+ "bmp_speed_extruct.bin",
+
+ //printing screen
+ "bmp_pause.bin",
+ "bmp_resume.bin",
+ "bmp_stop.bin",
+ "bmp_ext1_state.bin",
+ #if HAS_MULTI_EXTRUDER
+ "bmp_ext2_state.bin",
+ #endif
+ "bmp_bed_state.bin",
+ "bmp_fan_state.bin",
+ "bmp_time_state.bin",
+ "bmp_zpos_state.bin",
+ "bmp_operate.bin",
+
+ //manual leval screen (only if disabled auto level)
+ #if DISABLED(AUTO_BED_LEVELING_BILINEAR)
+ "bmp_leveling1.bin",
+ "bmp_leveling2.bin",
+ "bmp_leveling3.bin",
+ "bmp_leveling4.bin",
+ "bmp_leveling5.bin",
+ #endif
+
+ //lang select screen
+ #if HAS_LANG_SELECT_SCREEN
+ "bmp_language.bin",
+ "bmp_simplified_cn.bin",
+ "bmp_simplified_cn_sel.bin",
+ "bmp_traditional_cn.bin",
+ "bmp_traditional_cn_sel.bin",
+ "bmp_english.bin",
+ "bmp_english_sel.bin",
+ "bmp_russian.bin",
+ "bmp_russian_sel.bin",
+ "bmp_spanish.bin",
+ "bmp_spanish_sel.bin",
+ "bmp_french.bin",
+ "bmp_french_sel.bin",
+ "bmp_italy.bin",
+ "bmp_italy_sel.bin",
+ #endif // HAS_LANG_SELECT_SCREEN
+
+ // gcode preview
+ #if HAS_GCODE_DEFAULT_VIEW_IN_FLASH
+ "bmp_preview.bin",
+ #endif
+
+ #if HAS_LOGO_IN_FLASH
+ "bmp_logo.bin",
+ #endif
+
+ // settings screen
+ "bmp_about.bin",
+ "bmp_eeprom_settings.bin",
+ "bmp_machine_para.bin",
+ "bmp_function1.bin",
+
+ //start screen
+ "bmp_printing.bin",
+ "bmp_set.bin",
+ "bmp_tool.bin",
+
+ // base icons
+ "bmp_arrow.bin",
+ "bmp_back70x40.bin",
+ "bmp_value_blank.bin",
+ "bmp_blank_sel.bin",
+ "bmp_disable.bin",
+ "bmp_enable.bin",
+ "bmp_return.bin",
+
+ #if ENABLED(MKS_WIFI_MODULE)
+ // wifi screen
+ "bmp_wifi.bin",
+ "bmp_cloud.bin",
+ #endif
+
+ // babystep screen
+ "bmp_baby_move0_01.bin",
+ "bmp_baby_move0_05.bin",
+ "bmp_baby_move0_1.bin",
+
+ // more screen
+ "bmp_custom1.bin",
+ "bmp_custom2.bin",
+ "bmp_custom3.bin",
+ "bmp_custom4.bin",
+ "bmp_custom5.bin",
+ "bmp_custom6.bin",
+ "bmp_custom7.bin"
+};
+
+#if HAS_SPI_FLASH_FONT
+ static char fonts[][LONG_FILENAME_LENGTH] = { "FontUNIGBK.bin" };
+#endif
+
+uint8_t currentFlashPage = 0;
+
+uint32_t lv_get_pic_addr(uint8_t *Pname) {
+ uint8_t Pic_cnt;
+ uint8_t i, j;
+ PIC_MSG PIC;
+ uint32_t tmp_cnt = 0;
+ uint32_t addr = 0;
+
+ currentFlashPage = 0;
+
+ #if ENABLED(MARLIN_DEV_MODE)
+ SERIAL_ECHOLNPAIR("Getting picture SPI Flash Address: ", (const char*)Pname);
+ #endif
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+
+ W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
+ if (Pic_cnt == 0xFF) Pic_cnt = 0;
+ for (i = 0; i < Pic_cnt; i++) {
+ j = 0;
+ do {
+ W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1);
+ tmp_cnt++;
+ } while (PIC.name[j++] != '\0');
+
+ if ((strcasecmp((char*)Pname, (char*)PIC.name)) == 0) {
+ if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761))
+ addr = PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35;
+ else
+ addr = PIC_DATA_ADDR_TFT32 + i * PER_PIC_MAX_SPACE_TFT32;
+ return addr;
+ }
+ }
+
+ return addr;
+}
+
+const char *assetsPath = "assets";
+const char *bakPath = "_assets";
+
+void spiFlashErase_PIC() {
+ volatile uint32_t pic_sectorcnt = 0;
+ W25QXX.init(SPI_QUARTER_SPEED);
+ //erase 0x001000 -64K
+ for (pic_sectorcnt = 0; pic_sectorcnt < (64 - 4) / 4; pic_sectorcnt++) {
+ watchdog_refresh();
+ W25QXX.SPI_FLASH_SectorErase(PICINFOADDR + pic_sectorcnt * 4 * 1024);
+ }
+ //erase 64K -- 6M
+ for (pic_sectorcnt = 0; pic_sectorcnt < (PIC_SIZE_xM * 1024 / 64 - 1); pic_sectorcnt++) {
+ watchdog_refresh();
+ W25QXX.SPI_FLASH_BlockErase((pic_sectorcnt + 1) * 64 * 1024);
+ }
+}
+
+#if HAS_SPI_FLASH_FONT
+ void spiFlashErase_FONT() {
+ volatile uint32_t Font_sectorcnt = 0;
+ W25QXX.init(SPI_QUARTER_SPEED);
+ for (Font_sectorcnt = 0; Font_sectorcnt < 32-1; Font_sectorcnt++) {
+ watchdog_refresh();
+ W25QXX.SPI_FLASH_BlockErase(FONTINFOADDR + Font_sectorcnt * 64 * 1024);
+ }
+ }
+#endif
+
+uint32_t LogoWrite_Addroffset = 0;
+
+uint8_t Pic_Logo_Write(uint8_t *LogoName, uint8_t *Logo_Wbuff, uint32_t LogoWriteSize) {
+ if (LogoWriteSize <= 0) return 0;
+
+ W25QXX.SPI_FLASH_BufferWrite(Logo_Wbuff, PIC_LOGO_ADDR + LogoWrite_Addroffset, LogoWriteSize);
+
+ for (uint32_t i = 0; i < LogoWriteSize; i++) {
+ uint8_t temp1;
+ W25QXX.SPI_FLASH_BufferRead(&temp1, PIC_LOGO_ADDR + LogoWrite_Addroffset + i, 1);
+ if (*(Logo_Wbuff + i) != temp1) return 0;
+ }
+ LogoWrite_Addroffset += LogoWriteSize;
+ const uint32_t logo_maxsize = DeviceCode == 0x9488 || DeviceCode == 0x5761 ? LOGO_MAX_SIZE_TFT35 : LOGO_MAX_SIZE_TFT32;
+ if (LogoWrite_Addroffset >= logo_maxsize) LogoWrite_Addroffset = 0;
+ return 1;
+}
+
+uint32_t TitleLogoWrite_Addroffset = 0;
+uint8_t Pic_TitleLogo_Write(uint8_t *TitleLogoName, uint8_t *TitleLogo_Wbuff, uint32_t TitleLogoWriteSize) {
+ if (TitleLogoWriteSize <= 0)
+ return 0;
+ if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761))
+ W25QXX.SPI_FLASH_BufferWrite(TitleLogo_Wbuff, PIC_ICON_LOGO_ADDR_TFT35 + TitleLogoWrite_Addroffset, TitleLogoWriteSize);
+ else
+ W25QXX.SPI_FLASH_BufferWrite(TitleLogo_Wbuff, PIC_ICON_LOGO_ADDR_TFT32 + TitleLogoWrite_Addroffset, TitleLogoWriteSize);
+ TitleLogoWrite_Addroffset += TitleLogoWriteSize;
+ if (TitleLogoWrite_Addroffset >= TITLELOGO_MAX_SIZE)
+ TitleLogoWrite_Addroffset = 0;
+ return 1;
+}
+
+uint32_t default_view_addroffset_r = 0;
+void default_view_Write(uint8_t *default_view__Rbuff, uint32_t default_view_Writesize) {
+ W25QXX.SPI_FLASH_BufferWrite(default_view__Rbuff, DEFAULT_VIEW_ADDR_TFT35 + default_view_addroffset_r, default_view_Writesize);
+ default_view_addroffset_r += default_view_Writesize;
+ if (default_view_addroffset_r >= DEFAULT_VIEW_MAX_SIZE)
+ default_view_addroffset_r = 0;
+}
+
+uint32_t Pic_Info_Write(uint8_t *P_name, uint32_t P_size) {
+ uint8_t pic_counter = 0;
+ uint32_t Pic_SaveAddr;
+ uint32_t Pic_SizeSaveAddr;
+ uint32_t Pic_NameSaveAddr;
+ uint8_t Pname_temp;
+ uint32_t i, j;
+ uint32_t name_len = 0;
+ uint32_t SaveName_len = 0;
+ union union32 size_tmp;
+
+ W25QXX.SPI_FLASH_BufferRead(&pic_counter, PIC_COUNTER_ADDR, 1);
+
+ if (pic_counter == 0xFF)
+ pic_counter = 0;
+
+ if ((DeviceCode == 0x9488) || (DeviceCode == 0x5761))
+ Pic_SaveAddr = PIC_DATA_ADDR_TFT35 + pic_counter * PER_PIC_MAX_SPACE_TFT35;
+ else
+ Pic_SaveAddr = PIC_DATA_ADDR_TFT32 + pic_counter * PER_PIC_MAX_SPACE_TFT32;
+
+ for (j = 0; j < pic_counter; j++) {
+ do {
+ W25QXX.SPI_FLASH_BufferRead(&Pname_temp, PIC_NAME_ADDR + SaveName_len, 1);
+ SaveName_len++;
+ } while (Pname_temp != '\0');
+ }
+ i = 0;
+ while ((*(P_name + i) != '\0')) {
+ i++;
+ name_len++;
+ }
+
+ Pic_NameSaveAddr = PIC_NAME_ADDR + SaveName_len;
+ W25QXX.SPI_FLASH_BufferWrite(P_name, Pic_NameSaveAddr, name_len + 1);
+ Pic_SizeSaveAddr = PIC_SIZE_ADDR + 4 * pic_counter;
+ size_tmp.dwords = P_size;
+ W25QXX.SPI_FLASH_BufferWrite(size_tmp.bytes, Pic_SizeSaveAddr, 4);
+
+ pic_counter++;
+ W25QXX.SPI_FLASH_SectorErase(PIC_COUNTER_ADDR);
+ W25QXX.SPI_FLASH_BufferWrite(&pic_counter, PIC_COUNTER_ADDR, 1);
+
+ return Pic_SaveAddr;
+}
+
+#if ENABLED(SDSUPPORT)
+
+ static void dosName2LongName(const char dosName[11], char* longName) {
+ uint8_t j = 0;
+ LOOP_L_N(i, 11) {
+ if (i == 8) longName[j++] = '.';
+ if (dosName[i] == '\0' || dosName[i] == ' ') continue;
+ longName[j++] = dosName[i];
+ }
+ longName[j] = '\0';
+ }
+
+ static int8_t arrayFindStr(const char arr[][LONG_FILENAME_LENGTH], uint8_t arraySize, const char* str) {
+ for (uint8_t a = 0; a < arraySize; a++) {
+ if (strcasecmp(arr[a], str) == 0)
+ return a;
+ }
+ return -1;
+ }
+
+ #if ENABLED(MARLIN_DEV_MODE)
+ static uint32_t totalSizes = 0, totalCompressed = 0;
+ #endif
+
+ #define ASSET_TYPE_ICON 0
+ #define ASSET_TYPE_LOGO 1
+ #define ASSET_TYPE_TITLE_LOGO 2
+ #define ASSET_TYPE_G_PREVIEW 3
+ #define ASSET_TYPE_FONT 4
+ static void loadAsset(SdFile &dir, dir_t& entry, const char *fn, int8_t assetType) {
+ SdFile file;
+ char dosFilename[FILENAME_LENGTH];
+ createFilename(dosFilename, entry);
+ if (!file.open(&dir, dosFilename, O_READ)) {
+ #if ENABLED(MARLIN_DEV_MODE)
+ SERIAL_ECHOLNPAIR("Error opening Asset: ", fn);
+ #endif
+ return;
+ }
+
+ watchdog_refresh();
+ disp_assets_update_progress(fn);
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+
+ uint16_t pbr;
+ uint32_t pfileSize;
+ uint32_t totalSizeLoaded = 0;
+ uint32_t Pic_Write_Addr;
+ pfileSize = file.fileSize();
+ totalSizeLoaded += pfileSize;
+ if (assetType == ASSET_TYPE_LOGO) {
+ do {
+ watchdog_refresh();
+ pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
+ Pic_Logo_Write((uint8_t *)fn, public_buf, pbr);
+ } while (pbr >= BMP_WRITE_BUF_LEN);
+ }
+ else if (assetType == ASSET_TYPE_TITLE_LOGO) {
+ do {
+ watchdog_refresh();
+ pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
+ Pic_TitleLogo_Write((uint8_t *)fn, public_buf, pbr);
+ } while (pbr >= BMP_WRITE_BUF_LEN);
+ }
+ else if (assetType == ASSET_TYPE_G_PREVIEW) {
+ do {
+ watchdog_refresh();
+ pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
+ default_view_Write(public_buf, pbr);
+ } while (pbr >= BMP_WRITE_BUF_LEN);
+ }
+ else if (assetType == ASSET_TYPE_ICON) {
+ Pic_Write_Addr = Pic_Info_Write((uint8_t *)fn, pfileSize);
+ SPIFlash.beginWrite(Pic_Write_Addr);
+ #if HAS_SPI_FLASH_COMPRESSION
+ do {
+ watchdog_refresh();
+ pbr = file.read(public_buf, SPI_FLASH_PageSize);
+ TERN_(MARLIN_DEV_MODE, totalSizes += pbr);
+ SPIFlash.writeData(public_buf, SPI_FLASH_PageSize);
+ } while (pbr >= SPI_FLASH_PageSize);
+ #else
+ do {
+ pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
+ W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr);
+ Pic_Write_Addr += pbr;
+ } while (pbr >= BMP_WRITE_BUF_LEN);
+ #endif
+ #if ENABLED(MARLIN_DEV_MODE)
+ SERIAL_ECHOLNPAIR("Space used: ", fn, " - ", (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize / 1024, "KB");
+ totalCompressed += (SPIFlash.getCurrentPage() + 1) * SPI_FLASH_PageSize;
+ #endif
+ SPIFlash.endWrite();
+ }
+ else if (assetType == ASSET_TYPE_FONT) {
+ Pic_Write_Addr = UNIGBK_FLASH_ADDR;
+ do {
+ watchdog_refresh();
+ pbr = file.read(public_buf, BMP_WRITE_BUF_LEN);
+ W25QXX.SPI_FLASH_BufferWrite(public_buf, Pic_Write_Addr, pbr);
+ Pic_Write_Addr += pbr;
+ } while (pbr >= BMP_WRITE_BUF_LEN);
+ }
+
+ file.close();
+
+ #if ENABLED(MARLIN_DEV_MODE)
+ SERIAL_ECHOLNPAIR("Asset added: ", fn);
+ #endif
+ }
+
+ void UpdateAssets() {
+ if (!card.isMounted()) return;
+ SdFile dir, root = card.getroot();
+ if (dir.open(&root, assetsPath, O_RDONLY)) {
+
+ disp_assets_update();
+ disp_assets_update_progress("Erasing pics...");
+ watchdog_refresh();
+ spiFlashErase_PIC();
+ #if HAS_SPI_FLASH_FONT
+ disp_assets_update_progress("Erasing fonts...");
+ watchdog_refresh();
+ spiFlashErase_FONT();
+ #endif
+
+ disp_assets_update_progress("Reading files...");
+ dir_t d;
+ while (dir.readDir(&d, card.longFilename) > 0) {
+ // If we dont get a long name, but gets a short one, try it
+ if (card.longFilename[0] == 0 && d.name[0] != 0)
+ dosName2LongName((const char*)d.name, card.longFilename);
+ if (card.longFilename[0] == 0) continue;
+ if (card.longFilename[0] == '.') continue;
+
+ int8_t a = arrayFindStr(assets, COUNT(assets), card.longFilename);
+ if (a >= 0 && a < (int8_t)COUNT(assets)) {
+ uint8_t assetType = ASSET_TYPE_ICON;
+ if (strstr(assets[a], "_logo"))
+ assetType = ASSET_TYPE_LOGO;
+ else if (strstr(assets[a], "_titlelogo"))
+ assetType = ASSET_TYPE_TITLE_LOGO;
+ else if (strstr(assets[a], "_preview"))
+ assetType = ASSET_TYPE_G_PREVIEW;
+
+ loadAsset(dir, d, assets[a], assetType);
+
+ continue;
+ }
+
+ #if HAS_SPI_FLASH_FONT
+ a = arrayFindStr(fonts, COUNT(fonts), card.longFilename);
+ if (a >= 0 && a < (int8_t)COUNT(fonts))
+ loadAsset(dir, d, fonts[a], ASSET_TYPE_FONT);
+ #endif
+ }
+ dir.rename(&root, bakPath);
+ }
+ dir.close();
+
+ #if ENABLED(MARLIN_DEV_MODE)
+ uint8_t pic_counter = 0;
+ W25QXX.SPI_FLASH_BufferRead(&pic_counter, PIC_COUNTER_ADDR, 1);
+ SERIAL_ECHOLNPAIR("Total assets loaded: ", pic_counter);
+ SERIAL_ECHOLNPAIR("Total Uncompressed: ", totalSizes, ", Compressed: ", totalCompressed);
+ #endif
+ }
+
+ #if HAS_SPI_FLASH_FONT
+ void spi_flash_read_test() { W25QXX.SPI_FLASH_BufferRead(public_buf, UNIGBK_FLASH_ADDR, BMP_WRITE_BUF_LEN); }
+ #endif
+
+#endif // SDSUPPORT
+
+void Pic_Read(uint8_t *Pname, uint8_t *P_Rbuff) {
+ uint8_t i, j;
+ uint8_t Pic_cnt;
+ uint32_t tmp_cnt = 0;
+ PIC_MSG PIC;
+
+ W25QXX.SPI_FLASH_BufferRead(&Pic_cnt, PIC_COUNTER_ADDR, 1);
+ if (Pic_cnt == 0xFF)
+ Pic_cnt = 0;
+
+ for (i = 0; i < Pic_cnt; i++) {
+ j = 0;
+ do {
+ W25QXX.SPI_FLASH_BufferRead(&PIC.name[j], PIC_NAME_ADDR + tmp_cnt, 1);
+ tmp_cnt++;
+ } while (PIC.name[j++] != '\0');
+ //pic size
+ W25QXX.SPI_FLASH_BufferRead(PIC.size.bytes, PIC_SIZE_ADDR + i * 4, 4);
+
+ if ((strcmp((char*)Pname, (char*)PIC.name)) == 0) {
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, PIC_DATA_ADDR_TFT35 + i * PER_PIC_MAX_SPACE_TFT35, PIC.size.dwords);
+ break;
+ }
+ }
+}
+
+void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size) {
+ #if HAS_SPI_FLASH_COMPRESSION
+ if (currentFlashPage == 0)
+ SPIFlash.beginRead(addr);
+ SPIFlash.readData(P_Rbuff, size);
+ currentFlashPage++;
+ #else
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, addr, size);
+ #endif
+}
+
+#if HAS_SPI_FLASH_FONT
+ void get_spi_flash_data(const char *rec_buf, int addr, int size) {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead((uint8_t *)rec_buf, UNIGBK_FLASH_ADDR + addr, size);
+ }
+#endif
+
+uint32_t logo_addroffset = 0;
+void Pic_Logo_Read(uint8_t *LogoName, uint8_t *Logo_Rbuff, uint32_t LogoReadsize) {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead(Logo_Rbuff, PIC_LOGO_ADDR + logo_addroffset, LogoReadsize);
+ logo_addroffset += LogoReadsize;
+ if (logo_addroffset >= LOGO_MAX_SIZE_TFT35)
+ logo_addroffset = 0;
+}
+
+uint32_t default_view_addroffset = 0;
+void default_view_Read(uint8_t *default_view_Rbuff, uint32_t default_view_Readsize) {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead(default_view_Rbuff, DEFAULT_VIEW_ADDR_TFT35 + default_view_addroffset, default_view_Readsize);
+ default_view_addroffset += default_view_Readsize;
+ if (default_view_addroffset >= DEFAULT_VIEW_MAX_SIZE)
+ default_view_addroffset = 0;
+}
+
+#if HAS_BAK_VIEW_IN_FLASH
+ uint32_t flash_view_addroffset = 0;
+ void flash_view_Read(uint8_t *flash_view_Rbuff, uint32_t flash_view_Readsize) {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ W25QXX.SPI_FLASH_BufferRead(flash_view_Rbuff, BAK_VIEW_ADDR_TFT35 + flash_view_addroffset, flash_view_Readsize);
+ flash_view_addroffset += flash_view_Readsize;
+ if (flash_view_addroffset >= FLASH_VIEW_MAX_SIZE)
+ flash_view_addroffset = 0;
+ }
+#endif
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h
new file mode 100644
index 0000000..83d7431
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/pic_manager.h
@@ -0,0 +1,168 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "../../../../inc/MarlinConfig.h"
+
+#include "../../../../libs/W25Qxx.h"
+
+#include <lvgl.h>
+
+#include <stdint.h>
+#include <string.h>
+
+#ifndef HAS_SPI_FLASH_FONT
+ #define HAS_SPI_FLASH_FONT 1 // Disabled until fix the font load code
+#endif
+#ifndef HAS_GCODE_PREVIEW
+ #define HAS_GCODE_PREVIEW 1
+#endif
+#ifndef HAS_LANG_SELECT_SCREEN
+ #define HAS_LANG_SELECT_SCREEN 1
+#endif
+#ifndef HAS_BAK_VIEW_IN_FLASH
+ #define HAS_BAK_VIEW_IN_FLASH 1
+#endif
+#ifndef HAS_GCODE_DEFAULT_VIEW_IN_FLASH
+ #define HAS_GCODE_DEFAULT_VIEW_IN_FLASH 1
+#endif
+#ifndef HAS_LOGO_IN_FLASH
+ #define HAS_LOGO_IN_FLASH 1
+#endif
+#ifndef SPI_FLASH_SIZE
+ #define SPI_FLASH_SIZE 0x1000000 // 16MB
+#endif
+
+#define PIC_MAX_CN 100 // Maximum number of pictures
+#define PIC_NAME_MAX_LEN 50 // Picture name maximum length
+
+#define LOGO_MAX_SIZE_TFT35 (300*1024)
+#define LOGO_MAX_SIZE_TFT32 (150*1024)
+#define TITLELOGO_MAX_SIZE (150*1024) // Little logo maximum
+#define DEFAULT_VIEW_MAX_SIZE (200*200*2)
+#define FLASH_VIEW_MAX_SIZE (200*200*2)
+
+#define PER_PIC_MAX_SPACE_TFT35 (9*1024)
+#define PER_PIC_MAX_SPACE_TFT32 (16*1024)
+#define PER_FONT_MAX_SPACE (16*1024)
+
+#if SPI_FLASH_SIZE == 0x200000
+ //pic
+ //Robin_pro pic addr
+ #define PIC_NAME_ADDR 0x001000 // Pic information addr
+ #define PIC_SIZE_ADDR 0x001800 // Pic size information addr
+ #define PIC_COUNTER_ADDR 0x002000 // Pic total number
+ #define PER_PIC_SAVE_ADDR 0x000000 // Storage address of each picture
+ #define PIC_LOGO_ADDR 0x000000 // Logo addr
+ #define PIC_DATA_ADDR 0x003000 //
+
+ // TFT35
+ #define DEFAULT_VIEW_ADDR_TFT35 0x1EA070
+ #define BAK_VIEW_ADDR_TFT35 (DEFAULT_VIEW_ADDR_TFT35+90*1024)
+ #define PIC_ICON_LOGO_ADDR_TFT35 (BAK_VIEW_ADDR_TFT35+80*1024)
+ #define PIC_DATA_ADDR_TFT35 0x003000 // (PIC_ICON_LOGO_ADDR_TFT35+350*1024) //0xC5800
+
+ #define PIC_DATA_ADDR_TFT32 0x00F000
+ #define PIC_ICON_LOGO_ADDR_TFT32 0x5D8000
+ #define PIC_OTHER_SIZE_ADDR_TFT32 0x5EE000
+
+ // font
+ #define FONTINFOADDR 0x150000 // 6M -- font addr
+ #define UNIGBK_FLASH_ADDR (FONTINFOADDR+4096) // 4*1024
+
+#else
+ //pic
+ // pic addr
+ #define PIC_NAME_ADDR 0x003000 // Pic information addr
+ #define PIC_SIZE_ADDR 0x007000 // Pic size information addr
+ #define PIC_COUNTER_ADDR 0x008000 // Pic total number
+ #define PIC_LOGO_ADDR 0x009000 // Logo addr
+
+ // TFT35
+ #define DEFAULT_VIEW_ADDR_TFT35 0xC5800
+ #define BAK_VIEW_ADDR_TFT35 (DEFAULT_VIEW_ADDR_TFT35+90*1024)
+ #define PIC_ICON_LOGO_ADDR_TFT35 (BAK_VIEW_ADDR_TFT35+80*1024)
+ #define PIC_DATA_ADDR_TFT35 (PIC_ICON_LOGO_ADDR_TFT35+350*1024) //0xC5800
+
+ // TFT32
+ #define PIC_DATA_ADDR_TFT32 0x02F000
+ #define PIC_ICON_LOGO_ADDR_TFT32 0x5D8000
+ #define PIC_OTHER_SIZE_ADDR_TFT32 0x5EE000
+
+ // font
+ #define FONTINFOADDR 0x600000 // 6M -- font addr
+ #define UNIGBK_FLASH_ADDR (FONTINFOADDR+4096) // 4*1024
+ #define GBK_FLASH_ADDR (UNIGBK_FLASH_ADDR+180224) // 176*1024
+
+#endif
+
+// Flash flag
+#define REFLSHE_FLGA_ADD (0X800000-32)
+
+// SD card information first addr
+#define VAR_INF_ADDR 0x000000
+#define FLASH_INF_VALID_FLAG 0x20201118
+
+//Store some gcode commands, such as auto leveling commands
+#define GCODE_COMMAND_ADDR VAR_INF_ADDR + 3*1024
+#define AUTO_LEVELING_COMMAND_ADDR GCODE_COMMAND_ADDR
+#define OTHERS_COMMAND_ADDR_1 AUTO_LEVELING_COMMAND_ADDR + 100
+#define OTHERS_COMMAND_ADDR_2 OTHERS_COMMAND_ADDR_1 + 100
+#define OTHERS_COMMAND_ADDR_3 OTHERS_COMMAND_ADDR_2 + 100
+#define OTHERS_COMMAND_ADDR_4 OTHERS_COMMAND_ADDR_3 + 100
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+union union32 {
+ uint8_t bytes[4];
+ uint32_t dwords;
+};
+
+// pic information
+struct pic_msg {
+ uint8_t name[PIC_NAME_MAX_LEN];
+ union union32 size;
+};
+
+typedef struct pic_msg PIC_MSG;
+
+#define BMP_WRITE_BUF_LEN 512
+
+#define PICINFOADDR 0x1000
+
+#define PIC_SIZE_xM 6
+#define FONT_SIZE_xM 2
+
+extern void Pic_Read(uint8_t *Pname, uint8_t *P_Rbuff);
+extern void Pic_Logo_Read(uint8_t *LogoName,uint8_t *Logo_Rbuff,uint32_t LogoReadsize);
+extern void lv_pic_test(uint8_t *P_Rbuff, uint32_t addr, uint32_t size);
+extern uint32_t lv_get_pic_addr(uint8_t *Pname);
+extern void get_spi_flash_data(const char *rec_buf, int offset, int size);
+extern void spi_flash_read_test();
+extern void default_view_Read(uint8_t *default_view_Rbuff, uint32_t default_view_Readsize);
+extern void flash_view_Read(uint8_t *flash_view_Rbuff, uint32_t flash_view_Readsize);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp
new file mode 100644
index 0000000..379eb42
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.cpp
@@ -0,0 +1,250 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include <lv_conf.h>
+
+#include "../../../../gcode/gcode.h"
+#include "../../../../module/temperature.h"
+#include "../../../../module/planner.h"
+#include "../../../../module/motion.h"
+#include "../../../../sd/cardreader.h"
+#include "../../../../inc/MarlinConfig.h"
+#include "../../../../MarlinCore.h"
+#include "../../../../gcode/queue.h"
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+extern uint32_t To_pre_view;
+extern bool flash_preview_begin, default_preview_flg, gcode_preview_over;
+void esp_port_begin(uint8_t interrupt);
+void printer_state_polling() {
+ char str_1[16];
+ if (uiCfg.print_state == PAUSING) {
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TYPE_MACHINE_PAUSING_TIPS);
+ #if ENABLED(SDSUPPORT)
+ while(queue.length) {
+ queue.advance();
+ }
+ planner.synchronize();
+ gcode.process_subcommands_now_P(PSTR("M25"));
+ //save the positon
+ uiCfg.current_x_position_bak = current_position.x;
+ uiCfg.current_y_position_bak = current_position.y;
+ uiCfg.current_z_position_bak = current_position.z;
+
+ if (gCfgItems.pausePosZ != (float)-1) {
+ gcode.process_subcommands_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Z%s"), dtostrf(gCfgItems.pausePosZ, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_l);
+ gcode.process_subcommands_now_P(PSTR("G90"));
+ }
+ if (gCfgItems.pausePosX != (float)-1) {
+ sprintf_P(public_buf_l, PSTR("G1 X%s"), dtostrf(gCfgItems.pausePosX, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_l);
+ }
+ if (gCfgItems.pausePosY != (float)-1) {
+ sprintf_P(public_buf_l, PSTR("G1 Y%s"), dtostrf(gCfgItems.pausePosY, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_l);
+ }
+ uiCfg.print_state = PAUSED;
+ uiCfg.current_e_position_bak = current_position.e;
+
+ gCfgItems.pause_reprint = true;
+ update_spi_flash();
+ lv_clear_cur_ui();
+ lv_draw_return_ui();
+ #endif
+ }
+
+ if (uiCfg.print_state == PAUSED) {
+ }
+
+ if (uiCfg.print_state == RESUMING) {
+ if (IS_SD_PAUSED()) {
+ if (gCfgItems.pausePosX != (float)-1) {
+ sprintf_P(public_buf_m, PSTR("G1 X%s"), dtostrf(uiCfg.current_x_position_bak, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_m);
+ }
+ if (gCfgItems.pausePosY != (float)-1) {
+ sprintf_P(public_buf_m, PSTR("G1 Y%s"), dtostrf(uiCfg.current_y_position_bak, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_m);
+ }
+ if (gCfgItems.pausePosZ != (float)-1) {
+ ZERO(public_buf_m);
+ sprintf_P(public_buf_m, PSTR("G1 Z%s"), dtostrf(uiCfg.current_z_position_bak, 1, 1, str_1));
+ gcode.process_subcommands_now(public_buf_m);
+ }
+ gcode.process_subcommands_now_P(M24_STR);
+ uiCfg.print_state = WORKING;
+ start_print_time();
+
+ gCfgItems.pause_reprint = false;
+ update_spi_flash();
+ }
+ }
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ if (uiCfg.print_state == REPRINTED) {
+ #if HAS_HOTEND
+ HOTEND_LOOP() {
+ const int16_t et = recovery.info.target_temperature[e];
+ if (et) {
+ #if HAS_MULTI_HOTEND
+ sprintf_P(public_buf_m, PSTR("T%i"), e);
+ gcode.process_subcommands_now(public_buf_m);
+ #endif
+ sprintf_P(public_buf_m, PSTR("M109 S%i"), et);
+ gcode.process_subcommands_now(public_buf_m);
+ }
+ }
+ #endif
+
+ recovery.resume();
+ #if 0
+ // Move back to the saved XY
+ char str_1[16], str_2[16];
+ sprintf_P(public_buf_m, PSTR("G1 X%s Y%s F2000"),
+ dtostrf(recovery.info.current_position.x, 1, 3, str_1),
+ dtostrf(recovery.info.current_position.y, 1, 3, str_2)
+ );
+ gcode.process_subcommands_now(public_buf_m);
+
+ if (gCfgItems.pause_reprint && gCfgItems.pausePosZ != -1.0f) {
+ gcode.process_subcommands_now_P(PSTR("G91"));
+ sprintf_P(public_buf_l, PSTR("G1 Z-%.1f"), gCfgItems.pausePosZ);
+ gcode.process_subcommands_now(public_buf_l);
+ gcode.process_subcommands_now_P(PSTR("G90"));
+ }
+ #endif
+ uiCfg.print_state = WORKING;
+ start_print_time();
+
+ gCfgItems.pause_reprint = false;
+ update_spi_flash();
+ }
+ #endif
+
+ if (uiCfg.print_state == WORKING)
+ filament_check();
+
+ TERN_(MKS_WIFI_MODULE, wifi_looping());
+}
+
+void filament_pin_setup() {
+ #if PIN_EXISTS(MT_DET_1)
+ SET_INPUT_PULLUP(MT_DET_1_PIN);
+ #endif
+ #if PIN_EXISTS(MT_DET_2)
+ SET_INPUT_PULLUP(MT_DET_2_PIN);
+ #endif
+ #if PIN_EXISTS(MT_DET_3)
+ SET_INPUT_PULLUP(MT_DET_3_PIN);
+ #endif
+}
+
+void filament_check() {
+ #if (PIN_EXISTS(MT_DET_1) || PIN_EXISTS(MT_DET_2) || PIN_EXISTS(MT_DET_3))
+ const int FIL_DELAY = 20;
+ #endif
+ #if PIN_EXISTS(MT_DET_1)
+ static int fil_det_count_1 = 0;
+ if (!READ(MT_DET_1_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_1++;
+ else if (READ(MT_DET_1_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_1++;
+ else if (fil_det_count_1 > 0)
+ fil_det_count_1--;
+
+ if (!READ(MT_DET_1_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_1++;
+ else if (READ(MT_DET_1_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_1++;
+ else if (fil_det_count_1 > 0)
+ fil_det_count_1--;
+ #endif
+
+ #if PIN_EXISTS(MT_DET_2)
+ static int fil_det_count_2 = 0;
+ if (!READ(MT_DET_2_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_2++;
+ else if (READ(MT_DET_2_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_2++;
+ else if (fil_det_count_2 > 0)
+ fil_det_count_2--;
+
+ if (!READ(MT_DET_2_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_2++;
+ else if (READ(MT_DET_2_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_2++;
+ else if (fil_det_count_2 > 0)
+ fil_det_count_2--;
+ #endif
+
+ #if PIN_EXISTS(MT_DET_3)
+ static int fil_det_count_3 = 0;
+ if (!READ(MT_DET_3_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_3++;
+ else if (READ(MT_DET_3_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_3++;
+ else if (fil_det_count_3 > 0)
+ fil_det_count_3--;
+
+ if (!READ(MT_DET_3_PIN) && !MT_DET_PIN_INVERTING)
+ fil_det_count_3++;
+ else if (READ(MT_DET_3_PIN) && MT_DET_PIN_INVERTING)
+ fil_det_count_3++;
+ else if (fil_det_count_3 > 0)
+ fil_det_count_3--;
+ #endif
+
+ if (false
+ #if PIN_EXISTS(MT_DET_1)
+ || fil_det_count_1 >= FIL_DELAY
+ #endif
+ #if PIN_EXISTS(MT_DET_2)
+ || fil_det_count_2 >= FIL_DELAY
+ #endif
+ #if PIN_EXISTS(MT_DET_3)
+ || fil_det_count_3 >= FIL_DELAY
+ #endif
+ ) {
+ lv_clear_cur_ui();
+ TERN_(SDSUPPORT, card.pauseSDPrint());
+ stop_print_time();
+ uiCfg.print_state = PAUSING;
+
+ if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+
+ lv_draw_printing();
+ }
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h
new file mode 100644
index 0000000..f304158
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/printer_operation.h
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#define MIN_FILE_PRINTED 100 //5000
+
+extern void printer_state_polling();
+extern void filament_pin_setup();
+extern void filament_check();
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h
new file mode 100644
index 0000000..78abb21
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_en.h
@@ -0,0 +1,751 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//****************英文***************************//
+#define MACHINE_CONFIG_EN "Config"
+
+#define NEXT_EN "Next"
+#define PREVIOUS_EN "Previous"
+#define DEFAULT_EN "Default"
+#define KEY_BACK_EN "Del"
+#define KEY_REST_EN "Reset"
+#define KEY_CONFIRM_EN "Confirm"
+
+#define KEYBOARD_KEY0_EN "0"
+#define KEYBOARD_KEY1_EN "1"
+#define KEYBOARD_KEY2_EN "2"
+#define KEYBOARD_KEY3_EN "3"
+#define KEYBOARD_KEY4_EN "4"
+#define KEYBOARD_KEY5_EN "5"
+#define KEYBOARD_KEY6_EN "6"
+#define KEYBOARD_KEY7_EN "7"
+#define KEYBOARD_KEY8_EN "8"
+#define KEYBOARD_KEY9_EN "9"
+#define KEYBOARD_KEY_POINT_EN "."
+#define KEYBOARD_KEY_NEGATIVE_EN "-"
+
+#define MACHINE_PARA_TITLE_EN "Config"
+#define MACHINE_TYPE_CNOFIG_EN "Machine settings"
+#define MOTOR_CONFIG_EN "Motor settings"
+#define MACHINE_LEVELING_CONFIG_EN "Leveling settings"
+#define ADVANCE_CONFIG_EN "Advanced settings"
+
+#define MACHINE_CONFIG_TITLE_EN "Machine Settings"
+#define MACHINE_TYPE_EN "Machine type"
+#define MACHINE_STROKE_EN "Machine Size"
+#define MACHINE_HOMEDIR_EN "Home direction"
+#define MACHINE_ENDSTOP_TYPE_EN "Endstop type"
+#define MACHINE_FILAMENT_CONFIG_EN "Filament settings"
+
+#define MACHINE_TYPE_CONFIG_TITLE_EN "Machine Settings>Machine type"
+#define MACHINE_TYPE_XYZ_EN "XYZ Machine"
+#define MACHINE_TYPE_DELTA_EN "Delta Machine"
+#define MACHINE_TYPE_COREXY_EN "Corexy Machine"
+
+#define MACHINE_STROKE_CONF_TITLE_EN "Machine Settings>Machine Size"
+#define X_MAX_LENGTH_EN "X-axis maximum stroke"
+#define Y_MAX_LENGTH_EN "Y-axis maximum stroke"
+#define Z_MAX_LENGTH_EN "Z-axis maximum stroke"
+
+#define X_MIN_LENGTH_EN "X-axis minimum stroke"
+#define Y_MIN_LENGTH_EN "Y-axis minimum stroke"
+#define Z_MIN_LENGTH_EN "Z-axis minimum stroke"
+
+#define HOME_DIR_CONF_TITLE_EN "Machine Settings>Home direction"
+#define HOME_DIR_X_EN "X-axis home direction"
+#define HOME_DIR_Y_EN "Y-axis home direction"
+#define HOME_DIR_Z_EN "Z-axis home direction"
+#define HOME_MIN_EN "MIN"
+#define HOME_MAX_EN "MAX"
+
+#define ENDSTOP_CONF_TITLE_EN "Machine Settings>Endstop type"
+#define MIN_ENDSTOP_X_EN "X-axis minimum Endstop"
+#define MIN_ENDSTOP_Y_EN "Y-axis minimum Endstop"
+#define MIN_ENDSTOP_Z_EN "Z-axis minimum Endstop"
+#define MAX_ENDSTOP_X_EN "X-axis maximum Endstop"
+#define MAX_ENDSTOP_Y_EN "Y-axis maximum Endstop"
+#define MAX_ENDSTOP_Z_EN "Z-axis maximum Endstop"
+#define ENDSTOP_FIL_EN "Filament sensor"
+#define ENDSTOP_LEVEL_EN "Leveling sensor"
+#define ENDSTOP_OPENED_EN "Open"
+#define ENDSTOP_CLOSED_EN "Close"
+
+#define FILAMENT_CONF_TITLE_EN "Machine Settings>Filament settings"
+#define FILAMENT_IN_LENGTH_EN "Load length"
+#define FILAMENT_IN_SPEED_EN "Load speed"
+#define FILAMENT_TEMPERATURE_EN "Filament temperature"
+#define FILAMENT_OUT_LENGTH_EN "Unload length"
+#define FILAMENT_OUT_SPEED_EN "Unload speed"
+
+#define LEVELING_CONF_TITLE_EN "Machine Settings>Leveling settings"
+#define LEVELING_PARA_CONF_EN "Leveling settings"
+#define LEVELING_MANUAL_POS_EN "Manual leveling coordinate settings"
+#define LEVELING_AUTO_COMMAND_EN "AutoLeveling command settings"
+#define LEVELING_AUTO_ZOFFSET_EN "Nozzle-to-probe offsets settings"
+#define LEVELING_TOUCHMI_EN "Settings-TouchMi-Probe"
+#define TM_INIT_EN "Init"
+#define TM_ZOFFSETPOS_EN "Zoffset+"
+#define TM_ZOFFSETNEG_EN "Zoffset-"
+#define TM_SAVE_EN "Save"
+#define TM_TEST_EN "Test"
+
+#define BLTOUCH_LEVELING_TITTLE_EN "Machine Settings>BL-Touch Probe"
+#define BLTOUCH_LEVELING_EN "BL-Touch Probe"
+#define BLTOUCH_INIT_EN "Init"
+#define BLTOUCH_ZOFFSETPOS_EN "Zoffset+"
+#define BLTOUCH_ZOFFSETNEG_EN "Zoffset-"
+#define BLTOUCH_SAVE_EN "Save"
+#define BLTOUCH_TEST_EN "Test"
+
+#define LEVELING_PARA_CONF_TITLE_EN "leveling setting"
+#define AUTO_LEVELING_ENABLE_EN "Enable auto leveling"
+#define BLTOUCH_LEVELING_ENABLE_EN "Enable BLtouch"
+#define PROBE_PORT_EN "Probe connector"
+#define PROBE_X_OFFSET_EN "Probe X-axis offset"
+#define PROBE_Y_OFFSET_EN "Probe Y-axis offset"
+#define PROBE_Z_OFFSET_EN "Probe Z-axis offset"
+#define PROBE_XY_SPEED_EN "Probe XY-axis speed"
+#define PROBE_Z_SPEED_EN "Probe Z-axis speed"
+#define ENABLE_EN "YES"
+#define DISABLE_EN "NO"
+#define LOCKED_EN "N/A"
+#define Z_MIN_EN "ZMin"
+#define Z_MAX_EN "ZMax"
+
+#define DELTA_LEVEL_CONF_TITLE_EN "Delta Machine settings"
+#define DELTA_LEVEL_CONF_EN "Delta Machine Leveling"
+#define DELTA_MACHINE_RADIUS_EN "Machine Radius"
+#define DELTA_DIAGONAL_ROD_EN "Machine rod length"
+#define DELTA_PRINT_RADIUS_EN "Print radius"
+#define DELTA_HEIGHT_EN "Print height"
+#define SMOOTH_ROD_OFFSET_EN "Slider offset"
+#define EFFECTOR_OFFSET_EN "Effector offset"
+#define CALIBRATION_RADIUS_EN "Leveling radius"
+
+#define XYZ_LEVEL_CONF_TITLE_EN "Cartesian Machine Settings"
+#define PROBE_REACH_MAX_LEFT_EN "Probe reaches leftmost position"
+#define PROBE_REACH_MAX_RIGHT_EN "Probe reaches rightmost position"
+#define PROBE_REACH_MAX_FRONT_EN "Probe reaches front position"
+#define PROBE_REACH_MAX_BACK_EN "Probe reaches final position"
+
+#define TEMPERATURE_CONF_TITLE_EN "Machine Settings>Temperature settings"
+#define NOZZLE_CONF_EN "Nozzle settings"
+#define HOTBED_CONF_EN "Hotbed settings"
+#define PREHEAT_TEMPER_EN "Preset temperature"
+
+#define NOZZLE_CONF_TITLE_EN "Machine Settings>Nozzle settings"
+#define NOZZLECNT_EN "Number of nozzles"
+#define NOZZLE_TYPE_EN "E0 Temperature type"
+#define NOZZLE_ADJUST_TYPE_EN "PID thermostat"
+#define NOZZLE_MIN_TEMPERATURE_EN "lowest temperature"
+#define NOZZLE_MAX_TEMPERATURE_EN "Maximum temperature"
+#define EXTRUD_MIN_TEMPER_EN "Minimum extrusion temperature"
+
+#define HOTBED_CONF_TITLE_EN "Machine Settings>Hotbed settings"
+#define HOTBED_ADJUST_EN "PID thermostat"
+#define HOTBED_MIN_TEMPERATURE_EN "lowest temperature"
+#define HOTBED_MAX_TEMPERATURE_EN "Maximum temperature"
+
+#define MOTOR_CONF_TITLE_EN "Machine Settings>Motor settings"
+#define MAXFEEDRATE_CONF_EN "Maximum speed settings"
+#define ACCELERATION_CONF_EN "Acceleration settings"
+#define JERKCONF_EN "Jerk settings"
+#define STEPSCONF_EN "Steps settings"
+#define TMC_CURRENT_EN "TMC Current settings"
+#define TMC_STEP_MODE_EN "TMC Step mode settings"
+#define MOTORDIRCONF_EN "Motor direction settings"
+#define HOMEFEEDRATECONF_EN "Home speed setting"
+
+#define MAXFEEDRATE_CONF_TITLE_EN "Machine Settings>Maximum speed"
+#define X_MAXFEEDRATE_EN "X-axis maximum speed"
+#define Y_MAXFEEDRATE_EN "Y-axis maximum speed"
+#define Z_MAXFEEDRATE_EN "Z-axis maximum speed"
+#define E0_MAXFEEDRATE_EN "E0 maximum speed"
+#define E1_MAXFEEDRATE_EN "E1 maximum speed"
+
+#define ACCELERATION_CONF_TITLE_EN "Machine Settings>Acceleration"
+#define PRINT_ACCELERATION_EN "Print acceleration"
+#define RETRACT_ACCELERATION_EN "Retraction acceleration"
+#define TRAVEL_ACCELERATION_EN "Travel acceleration"
+#define X_ACCELERATION_EN "X-axis acceleration"
+#define Y_ACCELERATION_EN "Y-axis acceleration"
+#define Z_ACCELERATION_EN "Z-axis acceleration"
+#define E0_ACCELERATION_EN "E0 acceleration"
+#define E1_ACCELERATION_EN "E1 acceleration"
+
+#define JERK_CONF_TITLE_EN "Machine Settings>Jerk speed"
+#define X_JERK_EN "X-axis jerk speed"
+#define Y_JERK_EN "Y-axis jerk speed"
+#define Z_JERK_EN "Z-axis jerk speed"
+#define E_JERK_EN "Extruder jerk speed"
+
+#define STEPS_CONF_TITLE_EN "Machine Settings>Steps settings"
+#define X_STEPS_EN "X-axis steps"
+#define Y_STEPS_EN "Y-axis steps"
+#define Z_STEPS_EN "Z-axis steps"
+#define E0_STEPS_EN "E0 steps"
+#define E1_STEPS_EN "E1 steps"
+
+#define TMC_CURRENT_CONF_TITLE_EN "Machine Settings>TMC current settings"
+#define X_TMC_CURRENT_EN "X-axis current (mA)"
+#define Y_TMC_CURRENT_EN "Y-axis current (mA)"
+#define Z_TMC_CURRENT_EN "Z-axis current (mA)"
+#define E0_TMC_CURRENT_EN "E0 current (mA)"
+#define E1_TMC_CURRENT_EN "E1 current (mA)"
+
+#define TMC_MODE_CONF_TITLE_EN "Machine Settings>TMC step mode settings"
+#define X_TMC_MODE_EN "Whether X-axis enables stealthChop mode"
+#define Y_TMC_MODE_EN "Whether Y-axis enables stealthChop mode"
+#define Z_TMC_MODE_EN "Whether Z-axis enables stealthChop mode"
+#define E0_TMC_MODE_EN "Whether E0 enables stealthChop mode"
+#define E1_TMC_MODE_EN "Whether E1 enables stealthChop mode"
+
+#define MOTORDIR_CONF_TITLE_EN "Machine Settings>Motor direction"
+#define X_MOTORDIR_EN "X-axis motor direction invert"
+#define Y_MOTORDIR_EN "Y-axis motor direction invert"
+#define Z_MOTORDIR_EN "Z-axis motor direction invert"
+#define E0_MOTORDIR_EN "E0 motor direction invert"
+#define E1_MOTORDIR_EN "E1 motor direction invert"
+#define INVERT_P_EN "YES"
+#define INVERT_N_EN "NO"
+
+#define HOMEFEEDRATE_CONF_TITLE_EN "Machine Settings>Home speed"
+#define X_HOMESPEED_EN "XY-axis home speed"
+#define Y_HOMESPEED_EN "Y-axis home speed"
+#define Z_HOMESPEED_EN "Z-axis home speed"
+
+#define ADVANCED_CONF_TITLE_EN "Machine Settings>Advance"
+#define PWROFF_DECTION_EN "power off dection module"
+#define PWROFF_AFTER_PRINT_EN "Auto Shutdown after print"
+#define HAVE_UPS_EN "Has UPS power supply"
+#define Z2_AND_Z2ENDSTOP_CONF_EN "Z2 Settings"
+#define ENABLE_PINS_CONF_EN "Enable pins level settings"
+#define WIFI_SETTINGS_EN "Wi-Fi parameter settings"
+#define HOMING_SENSITIVITY_CONF_EN "Homing sensitivity settings"
+#define ENCODER_SETTINGS_EN "Rotary encoder settings"
+
+#define Z2_AND_Z2ENDSTOP_CONF_TITLE_EN "Z2 Settings"
+#define Z2_ENABLE_EN "Z2 Enable"
+#define Z2_ENDSTOP_EN "Z2_EndStop Enable"
+#define Z2_PORT_EN "Z2 Connector"
+
+#define ENABLE_PINS_CONF_TITLE_EN "ENABLE_PINS_LEVEL"
+#define X_ENABLE_PINS_INVERT_EN "X_ENABLE_PIN_INVERT"
+#define Y_ENABLE_PINS_INVERT_EN "Y_ENABLE_PIN_INVERT"
+#define Z_ENABLE_PINS_INVERT_EN "Z_ENABLE_PIN_INVERT"
+#define E_ENABLE_PINS_INVERT_EN "E_ENABLE_PIN_INVERT"
+
+#define PAUSE_POSITION_EN "Printing pause position settings"
+#define PAUSE_POSITION_X_EN "X-axis position (Absolute position,-1 invalid)"
+#define PAUSE_POSITION_Y_EN "Y-axis position (Absolute position,-1 invalid)"
+#define PAUSE_POSITION_Z_EN "Z-axis position (Relative position,-1 invalid)"
+
+#define WIFI_SETTINGS_TITLE_EN "Machine Settings>Wi-Fi Parameter"
+#define WIFI_SETTINGS_MODE_EN "Wi-Fi Mode"
+#define WIFI_SETTINGS_NAME_EN "Wi-Fi Name: "
+#define WIFI_SETTINGS_PASSWORD_EN "Wi-Fi Password: "
+#define WIFI_SETTINGS_CLOUD_EN "Do you use cloud services?"
+#define WIFI_SETTINGS_CONFIG_EN "Config"
+#define WIFI_SETTINGS_EDIT_EN "Edit"
+#define WIFI_CONFIG_TIPS_EN "Wi-Fi configuration?"
+
+#define OFFSET_TITLE_EN "Machine Settings>Offset"
+#define OFFSET_X_EN "X offset"
+#define OFFSET_Y_EN "Y offset"
+#define OFFSET_Z_EN "Z offset"
+
+#define HOMING_SENSITIVITY_CONF_TITLE_EN "Machine Settings>Sensitivity"
+#define X_SENSITIVITY_EN "X-axis sensitivity"
+#define Y_SENSITIVITY_EN "Y-axis sensitivity"
+#define Z_SENSITIVITY_EN "Z-axis sensitivity"
+#define Z2_SENSITIVITY_EN "Z2-axis sensitivity"
+
+#define ENCODER_CONF_TITLE_EN "Machine Settings>Rotary encoder settings"
+#define ENCODER_CONF_TEXT_EN "Is the encoder function used?"
+
+#define TOOL_TEXT_EN "Tool"
+#define PREHEAT_TEXT_EN "Preheat"
+#define MOVE_TEXT_EN "Move"
+#define HOME_TEXT_EN "Home"
+#define PRINT_TEXT_EN "Printing"
+#define EXTRUDE_TEXT_EN "Extrusion"
+#define LEVELING_TEXT_EN "Leveling"
+#define AUTO_LEVELING_TEXT_EN "AutoLevel"
+#define SET_TEXT_EN "Settings"
+#define MORE_TEXT_EN "More"
+
+#define ADD_TEXT_EN "Add"
+#define DEC_TEXT_EN "Dec"
+#define EXTRUDER_1_TEXT_EN "Extrusion1"
+#define EXTRUDER_2_TEXT_EN "Extrusion2"
+#define HEATBED_TEXT_EN "HeatBed"
+#define TEXT_1C_EN "1℃"
+#define TEXT_5C_EN "5℃"
+#define TEXT_10C_EN "10℃"
+#define CLOSE_TEXT_EN "Close"
+
+#define BACK_TEXT_EN "Back"
+
+#define TOOL_PREHEAT_EN "Preheat"
+#define TOOL_EXTRUDE_EN "Extrusion"
+#define TOOL_MOVE_EN "Move"
+#define TOOL_HOME_EN "Home"
+#define TOOL_LEVELING_EN "Leveling"
+#define TOOL_AUTO_LEVELING_EN "AutoLevel"
+#define TOOL_FILAMENT_EN "Filament"
+#define TOOL_MORE_EN "More"
+
+#define AXIS_X_ADD_TEXT_EN "X+"
+#define AXIS_X_DEC_TEXT_EN "X-"
+#define AXIS_Y_ADD_TEXT_EN "Y+"
+#define AXIS_Y_DEC_TEXT_EN "Y-"
+#define AXIS_Z_ADD_TEXT_EN "Z+"
+#define AXIS_Z_DEC_TEXT_EN "Z-"
+#define TEXT_01MM_EN "0.1mm"
+#define TEXT_1MM_EN "1mm"
+#define TEXT_10MM_EN "10mm"
+
+#define HOME_X_TEXT_EN "X"
+#define HOME_Y_TEXT_EN "Y"
+#define HOME_Z_TEXT_EN "Z"
+#define HOME_ALL_TEXT_EN "Home"
+#define HOME_STOPMOVE_EN "Quickstop"
+
+#define PAGE_UP_TEXT_EN "Page up"
+#define PAGE_DOWN_TEXT_EN "Page down"
+
+#define EXTRUDER_IN_TEXT_EN "In"
+#define EXTRUDER_OUT_TEXT_EN "Out"
+#define EXTRUDE_1MM_TEXT_EN "1mm"
+#define EXTRUDE_5MM_TEXT_EN "5mm"
+#define EXTRUDE_10MM_TEXT_EN "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_EN "Low"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_EN "Normal"
+#define EXTRUDE_HIGH_SPEED_TEXT_EN "High"
+
+#define LEVELING_POINT1_TEXT_EN "Point1"
+#define LEVELING_POINT2_TEXT_EN "Point2"
+#define LEVELING_POINT3_TEXT_EN "Point3"
+#define LEVELING_POINT4_TEXT_EN "Point4"
+#define LEVELING_POINT5_TEXT_EN "Point5"
+
+#define FILESYS_TEXT_EN "FileSys"
+#define WIFI_TEXT_EN "WiFi"
+#define FAN_TEXT_EN "Fan"
+#define ABOUT_TEXT_EN "About"
+#define BREAK_POINT_TEXT_EN "Continue"
+#define FILAMENT_TEXT_EN "Filament"
+#define LANGUAGE_TEXT_EN "Language"
+#define MOTOR_OFF_TEXT_EN "Motor-off"
+#define MOTOR_OFF_XY_TEXT_EN "Off-XY"
+#define SHUTDOWN_TEXT_EN "Shutdown"
+#define MACHINE_PARA_EN "Config"
+#define EEPROM_SETTINGS_EN "Eeprom Set"
+
+#define U_DISK_TEXT_EN "USB"
+#define SD_CARD_TEXT_EN "SD"
+#define WIFI_NAME_TEXT_EN "WiFi: "
+#define WIFI_KEY_TEXT_EN "Key: "
+#define WIFI_IP_TEXT_EN "IP: "
+#define WIFI_AP_TEXT_EN "State: AP"
+#define WIFI_STA_TEXT_EN "State: STA"
+#define WIFI_CONNECTED_TEXT_EN "Connected"
+#define WIFI_DISCONNECTED_TEXT_EN "Disconnected"
+#define WIFI_EXCEPTION_TEXT_EN "Exception"
+#define WIFI_RECONNECT_TEXT_EN "Reconnect"
+#define CLOUD_TEXT_EN "Cloud"
+#define CLOUD_BIND_EN "Bind"
+#define CLOUD_UNBIND_EN "Unbind"
+#define CLOUD_UNBINDING_EN "Unbinding"
+#define CLOUD_DISCONNECTED_EN "Disconnected"
+#define CLOUD_UNBINDED_EN "Unbinded"
+#define CLOUD_BINDED_EN "Binded"
+#define CLOUD_DISABLE_EN "Disable"
+
+#define FAN_ADD_TEXT_EN "Add"
+#define FAN_DEC_TEXT_EN "Dec"
+#define FAN_OPEN_TEXT_EN "100%"
+#define FAN_HALF_TEXT_EN "50%"
+#define FAN_CLOSE_TEXT_EN "Close"
+#define FAN_TIPS1_TEXT_EN "FAN"
+#define FAN_TIPS2_TEXT_EN "FAN\nClose"
+
+#define FILAMENT_IN_TEXT_EN "Load"
+#define FILAMENT_OUT_TEXT_EN "Unload"
+#define FILAMENT_EXT0_TEXT_EN "Extrusion1"
+#define FILAMENT_EXT1_TEXT_EN "Extrusion2"
+#define FILAMENT_HEAT_TEXT_EN "Preheat"
+#define FILAMENT_STOP_TEXT_EN "Stop"
+#define FILAMENT_TIPS2_TEXT_EN "T:"
+#define FILAMENT_TIPS3_TEXT_EN "Loading..."
+#define FILAMENT_TIPS4_TEXT_EN "Unloading..."
+#define FILAMENT_TIPS5_TEXT_EN "Temp is too low to go,please heat"
+#define FILAMENT_TIPS6_TEXT_EN "Completed"
+
+#define FILAMENT_CHANGE_TEXT_EN "Please click <Load> \nor <unload>,After \npinter pause."
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN "Heat completed,please load filament \nto extruder,and click <confirm> \nfor start loading."
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_EN "Please load filament to extruder,\nand click <confirm> for start loading."
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN "Heat completed,please \nclick <confirm> for start unloading.!"
+#define FILAMENT_DIALOG_LOADING_TIPS_EN "Is loading ,please wait!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_EN "Is unloading,please wait!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN "Load filament completed,\nclick <confirm> for return!"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN "Unload filament completed,\nclick <confirm> for return!"
+
+
+#define PRE_HEAT_EXT_TEXT_EN "E"
+#define PRE_HEAT_BED_TEXT_EN "Bed"
+
+#define FILE_LOADING_EN "Loading......"
+#define NO_FILE_AND_CHECK_EN " No files found!\n Check the file system configuration!"
+
+#define NO_FILE_EN "No files found!"
+
+#define EXTRUDER_TEMP_TEXT_EN "Temper"
+#define EXTRUDER_E_LENGTH1_TEXT_EN "Extrusion1"
+#define EXTRUDER_E_LENGTH2_TEXT_EN "Extrusion2"
+#define EXTRUDER_E_LENGTH3_TEXT_EN "Extrusion3"
+
+#define ABOUT_TYPE_TEXT_EN "Type: "
+#define ABOUT_VERSION_TEXT_EN "Firmware: "
+#define ABOUT_WIFI_TEXT_EN "WiFi: "
+
+#define PRINTING_OPERATION_EN "Option"
+#define PRINTING_PAUSE_EN "Pause"
+#define PRINTING_TEMP_EN "Temp."
+#define PRINTING_CHANGESPEED_EN "Speed"
+#define PRINTING_RESUME_EN "Resume"
+#define PRINTING_STOP_EN "Stop"
+#define PRINTING_MORE_EN "More"
+#define PRINTING_EXTRUDER_EN "Extrusion"
+#define PRINTING_MOVE_EN "Move"
+
+#define EXTRUDER_SPEED_EN "Extrusion"
+#define MOVE_SPEED_EN "Move"
+#define EXTRUDER_SPEED_STATE_EN "Extrude Speed"
+#define MOVE_SPEED_STATE_EN "Move Speed"
+#define STEP_1PERCENT_EN "1%"
+#define STEP_5PERCENT_EN "5%"
+#define STEP_10PERCENT_EN "10%"
+
+#define TITLE_READYPRINT_EN "ReadyPrint"
+#define TITLE_PREHEAT_EN "Preheat"
+#define TITLE_MOVE_EN "Move"
+#define TITLE_HOME_EN "Home"
+#define TITLE_EXTRUDE_EN "Extrusion"
+#define TITLE_LEVELING_EN "Leveling"
+#define TITLE_SET_EN "Settings"
+#define TITLE_MORE_EN "More"
+#define TITLE_CHOOSEFILE_EN "ChooseFile"
+#define TITLE_PRINTING_EN "Printing"
+#define TITLE_OPERATION_EN "Operation"
+#define TITLE_ADJUST_EN "Adjust"
+#define TITLE_WIRELESS_EN "Wireless"
+#define TITLE_FILAMENT_EN "Filament"
+#define TITLE_ABOUT_EN "About"
+#define TITLE_FAN_EN "Fan"
+#define TITLE_LANGUAGE_EN "Language"
+#define TITLE_PAUSE_EN "Pause"
+#define TITLE_CHANGESPEED_EN "Speed"
+#define TITLE_CLOUD_TEXT_EN "Cloud"
+#define TITLE_DIALOG_CONFIRM_EN "Confirm"
+#define TITLE_FILESYS_EN "FileSys"
+
+#define AUTO_SHUTDOWN_EN "Auto"
+#define MANUAL_SHUTDOWN_EN "Manual"
+
+#define DIALOG_CONFIRM_EN "Confirm"
+#define DIALOG_CANCLE_EN "Cancel"
+#define DIALOG_OK_EN "OK"
+#define DIALOG_RESET_EN "Reset"
+#define DIALOG_RETRY_EN "Retry"
+#define DIALOG_DISABLE_EN "Disable"
+#define DIALOG_PRINT_MODEL_EN "Print this model?"
+#define DIALOG_CANCEL_PRINT_EN "Stop print?"
+#define DIALOG_RETRY_EN "Retry"
+#define DIALOG_STOP_EN "Stop"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_EN "Reprint from breakpoint?"
+#define DIALOG_ERROR_TIPS1_EN "Error:no file,please check it again."
+#define DIALOG_ERROR_TIPS2_EN "Error:transaction failed.please check display baudrate \nwhether as the same as mainboard!"
+#define DIALOG_ERROR_TIPS3_EN "Error:file name or path is too long!"
+#define DIALOG_CLOSE_MACHINE_EN "Closing machine......"
+#define DIALOG_UNBIND_PRINTER_EN "Unbind the printer?"
+#define DIALOG_FILAMENT_NO_PRESS_EN "Filament detection switch is not pressed"
+#define DIALOG_PRINT_FINISH_EN "Done print!"
+#define DIALOG_PRINT_TIME_EN "Print time: "
+#define DIALOG_REPRINT_EN "Print again"
+#define DIALOG_WIFI_ENABLE_TIPS_EN "The wifi module is being configured\nplease wait a moment....."
+#define DIALOG_PAUSING_TIPS_EN "The machine pauses..."
+
+#define HOTBED_ENABLE_EN "Enable heatbed"
+#define MOTOR_EN_HIGH_LEVEL_EN "High"
+#define MOTOR_EN_LOW_LEVEL_EN "Low"
+
+#define TEXT_WIFI_MENU_TITLE_EN "WI-FI"
+#define TEXT_WIFI_SAPCE_EN "space"
+#define TEXT_WIFI_LETTER_EN "abc"
+#define TEXT_WIFI_DIGITAL_EN "123"
+#define TEXT_WIFI_SYMBOL_EN "#+="
+#define TEXT_WIFI_PASSWORD_EN "Password"
+
+#define TEXT_WIFI_JOINING_EN "Joining Network..."
+#define TEXT_WIFI_FAILED_JOIN_EN "Failed to Join Wi-Fi"
+#define TEXT_WIFI_WIFI_CONECTED_EN "Wi-Fi Connected"
+
+#define TEXT_BUTTON_DISCONECTED_EN "Disconnect"
+#define TEXT_WIFI_FORGET_EN "Forget Network"
+#define TEXT_DISCONECTED_EN "Wi-Fi Connected"
+
+//wifi-list
+#define MAIN_BUILT_EN "Build"
+#define MAIN_FILAMENT_EN "Filament"
+#define MAIN_SETUP_EN "Setup"
+#define MAIN_ABOUT_EN "About"
+#define MAIN_MENU_EN "Menu"
+#define FILE_MENU_BUILD_EN "Build"
+#define FILE_MENU_MENU_EN " < Menu"
+
+//about
+#define ABOUT_TITLE_EN "About"
+#define ABOUT_BUILT_MACHINES_EN "Built Machines"
+#define ABOUT_SPARK_EN "Spark"
+#define ABOUT_VERSION_EN "Version 1.1.0"
+#define ABOUT_SERIAL_NUMBER_EN "Serial Number:"
+#define ABOUT_S_NUMBER_EN "DCPLX02KFC6P"
+
+//set
+#define SETUP_TITLE_EN "Setup"
+#define SETUP_WIFI_EN "Wi-Fi"
+#define SETUP_MANUAL_IP_EN "Manual IP"
+#define SETUP_WIFI_NOT_CONNECTED_EN "Not Connected"
+#define SETUP_WIFI_NETWORK_EN "WiFi_Network"
+
+//build
+#define BUILD_TITLE_EN "Build"
+#define BUILD_SD_CARD_EN "SD Card"
+#define BUILD_USB_DRIVE_EN "USB Drive"
+
+//SD card
+#define SD_CARD_TITLE_EN "SD Card"
+#define SD_CARD_BACK_EN "< Back"
+//USB Drive
+#define USB_DRIVE_TITLE_EN "USB Drive"
+#define USB_DRIVE_BACK_EN "< Back"
+#define FILE_PAGES_EN "%d/%d"
+#define FILE_NEXT_PAGE_EN "Next Page"
+
+//BUILD PLATE
+#define PLATE_TITLE_EN "Build Plate"
+#define PLATE_BACK_EN "< Back"
+#define PLATE_CONFIRM_EN "Confirm >"
+#define PLATE_TIPS_EN "Confirm that there is a Clear\nBuild Plate installed in the\nmachine."
+
+//build model
+#define MODEL_TITLE_EN "Build Model"
+#define MODEL_START_BUILD_EN "Start Build"
+#define MODEL_BACK_EN "< Back"
+
+//building
+#define BUILDING_TITLE_EN "Building"
+#define BUILDING_MENU_EN "Build Menu"
+#define BUILDING_COMPLETED "Build\nComplete"
+
+//building menu
+#define BUILDING_MENU_TITLE_EN "Build Menu"
+#define BUILDING_MENU_SETTINGS_EN "Build Settings"
+#define BUILDING_MENU_PAUSE_EN "Pause Build"
+#define BUILDING_MENU_CANCEL_EN "Cancel Build"
+#define BUILDING_MENU_BACK_EN "< Back"
+
+//build settings
+#define SETTINGS_TITLE_EN "Build Settings"
+#define SETTINGS_NOZZLE_TEMPER_EN "Nozzle Temp:"
+#define SETTINGS_NOZZLE_VALUE_EN "%d"
+#define SETTINGS_BED_TEMPER_EN "Bed Temp:"
+#define SETTINGS_BED_VALUE_EN "%d"
+#define SETTINGS_BUILD_SPEED_EN "Build Speed:"
+#define SETTINGS_SPEED_VALUE_EN "Standard"
+#define SETTINGS_BACK_EN "< Back"
+
+//build paused
+#define PAUSED_TITLE_EN "Build Paused"
+#define PAUSED_RESUME_EN "Resume Build"
+#define PAUSED_CANCEL_EN "Cancel Build"
+#define PAUSED_BACK_EN "< Back"
+
+//build cancel
+#define CANCEL_TITLE_EN "Cancel Build"
+#define CANCEL_BUILD_EN "Cancel Build"
+#define CANCEL_TIPS_EN "Are you sure you want to\ncancel this build? The model\nwill be deleted from this\nmachine. It will need to be\nresent from your computer\nbefore it can be built in the\nfuture."
+#define CANCEL_BACK_EN "< Back"
+#define CANCEL_BUILD_DISPLAY_EN "Build\nCanceled"
+#define CANCEL_OVER_PLATE_TIPS_EN "Confirm that the Build Plate\nhas been removed from the\nmachine."
+
+//filament model enter
+#define FILAMENT_MODEL_ENTER_TITLE_EN "Model-PLA"
+#define FILAMENT_MODEL_ENTER_BACK_EN "< Back"
+#define FILAMENT_MODEL_ENTER_BEGIN_EN "Begin >"
+#define FILAMENT_MODEL_ENTER_TIPS_EN "The Model Filament spool\ncompartment is located on\nthe right side of the machine."
+
+//filament model PLA
+#define FILAMENT_MODEL_PLA_TITLE_EN "Model-PLA"
+#define FILAMENT_PLA_LOAD_TITLE_EN "Load Filament"
+#define FILAMENT_PLA_UNLOAD_TITLE_EN "Unload Filament"
+#define FILAMENT_MODEL_PLA_LOAD_EN "Load Filament"
+#define FILAMENT_MODEL_PLA_UNLOAD_EN "Unload Filament"
+//filament support enter
+#define FILAMENT_SUPPORT_ENTER_TITLE_EN "Support-PVA"
+#define FILAMENT_SUPPORT_ENTER_BACK_EN "< Back"
+#define FILAMENT_SUPPORT_ENTER_BEGIN_EN "Begin >"
+#define FILAMENT_SUPPORT_ENTER_TIPS_EN "The Support Filament spool\ncompartment is located on\nthe left side of the machine."
+//filament heating
+#define FILAMENT_HEATING_LOAD_TITLE_EN "Load Filament"
+#define FILAMENT_HEATING_UNLOAD_TITLE_EN "Unload Filament"
+#define FILAMENT_HEATING_CANCEL_EN "< Cancel"
+#define FILAMENT_HEATING_MATERIAL_EN "Material:"
+#define FILAMENT_HEATING_PLA_EN "Model-PLA"
+#define FILAMENT_HEATING_TIPS_EN "Print head is heating..."
+//rotate left
+#define ROTATE_LEFT_LOAD_TITLE_EN "Load Filament"
+#define ROTATE_LEFT_UNLOAD_TITLE_EN "Unload Filament"
+#define ROTATE_LEFT_CANCEL_EN "< Cancel"
+#define ROTATE_LEFT_MATERIAL_EN "Material:"
+#define ROTATE_LEFT_PLA_EN "Model-PLA"
+#define ROTATE_LEFT_NEXT_EN "Next >"
+#define ROTATE_LEFT_TIPS_EN "Rotate extruder selection\ndial to the left."
+
+//hang spool
+#define HANG_SPOOL_TITLE_EN "Load Filament"
+#define HANG_SPOOL_PREVIOUS_EN "< Previous"
+#define HANG_SPOOL_MATERIAL_EN "Material:"
+#define HANG_SPOOL_PLA_EN "Model-PLA"
+#define HANG_SPOOL_NEXT_EN "Next >"
+#define HANG_SPOOL_TIPS_EN "Hang the spool in the spool\ncompartment as shown."
+
+//feed filament
+#define FEED_FILAMENT_TITLE_EN "Load Filament"
+#define FEED_FILAMENT_PREVIOUS_EN "< Previous"
+#define FEED_FILAMENT_MATERIAL_EN "Material:"
+#define FEED_FILAMENT_PLA_EN "Model-PLA"
+#define FEED_FILAMENT_NEXT_EN "Next >"
+#define FEED_FILAMENT_TIPS_EN "Feed filament into extruder\nup beyond the gears."
+
+//feed filament
+#define ROTATE_UP_TITLE_EN "Load Filament"
+#define ROTATE_UP_PREVIOUS_EN "< Previous"
+#define ROTATE_UP_MATERIAL_EN "Material:"
+#define ROTATE_UP_PLA_EN "Model-PLA"
+#define ROTATE_UP_NEXT_EN "Next >"
+#define ROTATE_UP_TIPS_EN "Rotate extruder selection\ndial up."
+
+//filament begin
+#define FEED_BEGIN_TITLE_EN "Load Filament"
+#define FEED_BEGIN_MATERIAL_EN "Material:"
+#define FEED_BEGIN_PLA_EN "Model-PLA"
+#define FEED_BEGIN_NEXT_EN "Next >"
+#define FEED_BEGIN_TIPS_EN "Press Next when filament\nbegins to extrude."
+
+//filament finish
+#define FEED_FINISH_TITLE_EN "Load Filament"
+#define FEED_FINISH_MATERIAL_EN "Material:"
+#define FEED_FINISH_PLA_EN "Model-PLA"
+#define FEED_FINISH_NEXT_EN "Finish >"
+#define FEED_FINISH_TIPS_EN "Remove filament from the\nnozzle and discard."
+//fiament remove
+#define REMOVE_SPOOL_TITLE_EN "Unload Filament"
+#define REMOVE_SPOOL_PREVIOUS_EN "< Previous"
+#define REMOVE_SPOOL_FINISH_EN "Finish >"
+#define REMOVE_SPOOL_MATERIAL_EN "Material:"
+#define REMOVE_SPOOL_PLA_EN "Model-PLA"
+#define REMOVE_SPOOL_TIPS_EN "Remove the spool and pull\nfilament out of the machine."
+
+#define FILAMENT_SUPPORT_PVA_EN "Support-PVA"
+#define LOAD_FINISH_EN "Load\nFilament\nComplete"
+#define UNLOAD_FINISH_EN "Unload\nFilament\nComplete"
+
+//manual ip
+#define MANUAL_IP_TITLE_EN "Manual IP"
+#define MANUAL_IP_CANCEL_EN "< Cancel"
+#define MANUAL_IP_APPLY_EN "Join >"
+#define MANUAL_IP_ADDRESS_EN "IP Address"
+#define MANUAL_IP_MASK_EN "Subnet Mask"
+#define MANUAL_IP_GATEWAY_EN "Default Gateway"
+#define MANUAL_IP_SERVER_EN "Name Server"
+#define MANUAL_IP_INIT_DATA_EN "0.0.0.0"
+#define MANUAL_TEXT_POINT_EN "."
+#define MANUAL_TEXT_ENTER_EN "enter"
+
+#define TEXT_FORGET_TIPS_TITLE_EN "Forget Network"
+#define TEXT_FORGET_NETWORK_TIPS1_EN "Are you sure you want to\nforget this network?"
+#define TEXT_FORGET_NETWORK_TIPS2_EN "This machine will no longer\njoin this Wi-Fi Network."
+
+#define TEXT_IPADDRESS_EN "IP Address: "
+
+#define TEXT_BUILD_FROM_CURA_CANCEL_TIPS1_EN "Are you sure you want to\ncancel this build?"
+#define TEXT_BUILD_FROM_CURA_CANCEL_TIPS2_EN "The model will be deleted\nfrom this machine.It will\nneed to be resent from your\ncomputer before it can be\nbuilt in the future."
+
+#define DIALOG_CONFIRM_EN2 "Confirm"
+
+#define HEATING_TITLE_EN "Heating"
+#define LEVELING_TITLE_EN "Leveling"
+
+#define ABOUT_SPARK_ADD_EN "Spark+"
+
+#define TEXT_RECEIVING_DATA_EN "Receiving Data"
+
+#define TEXT_BABY_STEP_EN "Babystep"
+
+#define PRINTING_OTHER_LANGUGE "Printing"
+#define PRINTING_OPERATION_OTHER_LANGUGE "Operation"
+#define PRINTING_PAUSE_OTHER_LANGUGE "Pause"
+
+#define MESSAGE_PAUSING_EN "Parking..."
+#define MESSAGE_CHANGING_EN "Wait for filament change to start"
+#define MESSAGE_UNLOAD_EN "Wait for filament unload"
+#define MESSAGE_WAITING_EN "Press Button to resume print"
+#define MESSAGE_INSERT_EN "Insert filament and press button to continue"
+#define MESSAGE_LOAD_EN "Wait for filament load"
+#define MESSAGE_PURGE_EN "Wait for filament purge"
+#define MESSAGE_RESUME_EN "Wait for print to resume..."
+#define MESSAGE_HEAT_EN "Press button to heat nozzle"
+#define MESSAGE_HEATING_EN "Nozzle heating Please wait..."
+#define MESSAGE_OPTION_EN "Purge more or continue print?"
+#define MESSAGE_PURGE_MORE_EN "Purge"
+#define MESSAGE_CONTINUE_PRINT_EN "Print"
+#define EEPROM_SETTINGS_TITLE_EN "EEPROM Settings"
+#define EEPROM_SETTINGS_STORE_EN "Store settings to EEPROM"
+#define EEPROM_SETTINGS_READ_EN "Read settings from EEPROM"
+#define EEPROM_SETTINGS_REVERT_EN "Revert settings to factory defaults"
+
+#define EEPROM_STORE_TIPS_EN "Store settings to EEPROM?"
+#define EEPROM_READ_TIPS_EN "Read settings from EEPROM?"
+#define EEPROM_REVERT_TIPS_EN "Revert settings to factory defaults?"
+
+#define MORE_CUSTOM1_TEXT_EN USER_DESC_1
+#define MORE_CUSTOM2_TEXT_EN USER_DESC_2
+#define MORE_CUSTOM3_TEXT_EN USER_DESC_3
+#define MORE_CUSTOM4_TEXT_EN USER_DESC_4
+#define MORE_CUSTOM5_TEXT_EN USER_DESC_5
+#define MORE_CUSTOM6_TEXT_EN USER_DESC_6
+#define MORE_CUSTOM7_TEXT_EN USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h
new file mode 100644
index 0000000..e65ec43
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_fr.h
@@ -0,0 +1,268 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//*************法文****************************//
+#define TOOL_TEXT_FR "prêt"
+#define PREHEAT_TEXT_FR "Préchauffe"
+#define MOVE_TEXT_FR "Déplace"
+#define HOME_TEXT_FR "Acceuil"
+#define PRINT_TEXT_FR "Impression"
+#define EXTRUDE_TEXT_FR "Extruder"
+#define LEVELING_TEXT_FR "Leveling"
+#define AUTO_LEVELING_TEXT_FR "AutoLevel"
+#define SET_TEXT_FR "Config"
+#define MORE_TEXT_FR "Plus"
+
+#define ADD_TEXT_FR "Ajouter"
+#define DEC_TEXT_FR "Réduire"
+#define EXTRUDER_1_TEXT_FR "Extr1"
+#define EXTRUDER_2_TEXT_FR "Extr2"
+#define HEATBED_TEXT_FR "Hotlit"
+#define TEXT_1C_FR "1℃"
+#define TEXT_5C_FR "5℃"
+#define TEXT_10C_FR "10℃"
+#define CLOSE_TEXT_FR "Off"
+
+#define BACK_TEXT_FR "Arrière"
+
+#define TOOL_PREHEAT_FR "Préchauffe"
+#define TOOL_EXTRUDE_FR "Extruder"
+#define TOOL_MOVE_FR "Déplace"
+#define TOOL_HOME_FR "Acceuil"
+#define TOOL_LEVELING_FR "Leveling"
+#define TOOL_AUTO_LEVELING_FR "AutoLevel"
+#define TOOL_FILAMENT_FR "Filament"
+#define TOOL_MORE_FR "Plus"
+
+#define AXIS_X_ADD_TEXT_FR "X+"
+#define AXIS_X_DEC_TEXT_FR "X-"
+#define AXIS_Y_ADD_TEXT_FR "Y+"
+#define AXIS_Y_DEC_TEXT_FR "Y-"
+#define AXIS_Z_ADD_TEXT_FR "Z+"
+#define AXIS_Z_DEC_TEXT_FR "Z-"
+#define TEXT_01MM_FR "0.1mm"
+#define TEXT_1MM_FR "1mm"
+#define TEXT_10MM_FR "10mm"
+
+#define HOME_X_TEXT_FR "X"
+#define HOME_Y_TEXT_FR "Y"
+#define HOME_Z_TEXT_FR "Z"
+#define HOME_ALL_TEXT_FR "ALL"
+#define HOME_STOPMOVE_FR "Quickstop"
+
+#define PAGE_UP_TEXT_FR "En haut"
+#define PAGE_DOWN_TEXT_FR "En bas"
+
+#define EXTRUDER_IN_TEXT_FR "Insérer"
+#define EXTRUDER_OUT_TEXT_FR "éjecter"
+#define EXTRUDE_1MM_TEXT_FR "1mm"
+#define EXTRUDE_5MM_TEXT_FR "5mm"
+#define EXTRUDE_10MM_TEXT_FR "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_FR "Lente"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_FR "Moyen"
+#define EXTRUDE_HIGH_SPEED_TEXT_FR "Rapide"
+
+#define LEVELING_POINT1_TEXT_FR "Premier"
+#define LEVELING_POINT2_TEXT_FR "Seconde"
+#define LEVELING_POINT3_TEXT_FR "Troisième"
+#define LEVELING_POINT4_TEXT_FR "Quatrième"
+#define LEVELING_POINT5_TEXT_FR "Cinquième"
+
+#define FILESYS_TEXT_FR "Fichier"
+#define WIFI_TEXT_FR "WiFi"
+#define FAN_TEXT_FR "Fan"
+#define ABOUT_TEXT_FR "A propos"
+#define BREAK_POINT_TEXT_FR "Continuer"
+#define FILAMENT_TEXT_FR "Remplacer"
+#define LANGUAGE_TEXT_FR "Langue"
+#define MOTOR_OFF_TEXT_FR "M-hors"
+#define MOTOR_OFF_XY_TEXT_FR "M-hors-XY"
+#define SHUTDOWN_TEXT_FR "Eteindre"
+#define MACHINE_PARA_FR "Config"
+#define EEPROM_SETTINGS_FR "Eeprom Set"
+
+#define U_DISK_TEXT_FR "Clé usb"
+#define SD_CARD_TEXT_FR "Carte SD"
+#define WIFI_NAME_TEXT_FR "WiFi: "
+#define WIFI_KEY_TEXT_FR "Key: "
+#define WIFI_IP_TEXT_FR "IP: "
+#define WIFI_AP_TEXT_FR "Etat: AP"
+#define WIFI_STA_TEXT_FR "Etat: STA"
+#define WIFI_CONNECTED_TEXT_FR "Connecté"
+#define WIFI_DISCONNECTED_TEXT_FR "Déconnecté"
+#define WIFI_EXCEPTION_TEXT_FR "Exception"
+#define WIFI_RECONNECT_TEXT_FR "Reconnect"
+#define CLOUD_TEXT_FR "Cloud"
+#define CLOUD_BIND_FR "Lié"
+#define CLOUD_UNBIND_FR "Délier"
+#define CLOUD_UNBINDING_FR "Délier"
+#define CLOUD_DISCONNECTED_FR "Déconnecté"
+#define CLOUD_UNBINDED_FR "Délier"
+#define CLOUD_BINDED_FR "Lié"
+#define CLOUD_DISABLE_FR "Désactiver"
+
+#define FAN_ADD_TEXT_FR "Ajouter"
+#define FAN_DEC_TEXT_FR "Réduire"
+#define FAN_OPEN_TEXT_FR "100%"
+#define FAN_HALF_TEXT_FR "50%"
+#define FAN_CLOSE_TEXT_FR "0%"
+#define FAN_TIPS1_TEXT_FR "ventilateur"
+#define FAN_TIPS2_TEXT_FR "ventilateur\n0"
+
+#define FILAMENT_IN_TEXT_FR "Insérer"
+#define FILAMENT_OUT_TEXT_FR "éjecter"
+#define FILAMENT_EXT0_TEXT_FR "Extr1"
+#define FILAMENT_EXT1_TEXT_FR "Extr2"
+#define FILAMENT_HEAT_TEXT_FR "Preheat"
+#define FILAMENT_STOP_TEXT_FR "Arrêter"
+#define FILAMENT_TIPS2_TEXT_FR "T:"
+#define FILAMENT_TIPS3_TEXT_FR "Insérer le filament..."
+#define FILAMENT_TIPS4_TEXT_FR "éjecter le filament..."
+#define FILAMENT_TIPS5_TEXT_FR "Température trop basse pour démarrer, chauffez svp"
+#define FILAMENT_TIPS6_TEXT_FR "Terminé"
+
+#define FILAMENT_CHANGE_TEXT_FR "Please click <Load> \nor <unload>,After \npinter pause."
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_FR "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_FR "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_FR "Heat completed,please load filament \nto extruder,and click <confirm> \nfor start loading."
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_FR "Please load filament to extruder,\nand click <confirm> for start loading."
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_FR "Heat completed,please \nclick <confirm> for start unloading.!"
+#define FILAMENT_DIALOG_LOADING_TIPS_FR "Is loading ,please wait!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_FR "Is unloading,please wait!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_FR "Load filament completed,\nclick <confirm> for return!"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_FR "Unload filament completed,\nclick <confirm> for return!"
+
+
+#define PRE_HEAT_EXT_TEXT_FR "E"
+#define PRE_HEAT_BED_TEXT_FR "Bed"
+
+#define FILE_LOADING_FR "Chargement......"
+#define NO_FILE_AND_CHECK_FR "Aucun fichier,vérifiez à nouveau!"
+#define NO_FILE_FR "Pas de fichier!"
+
+#define EXTRUDER_TEMP_TEXT_FR "Temper"
+#define EXTRUDER_E_LENGTH1_TEXT_FR "Extruder1"
+#define EXTRUDER_E_LENGTH2_TEXT_FR "Extruder2"
+#define EXTRUDER_E_LENGTH3_TEXT_FR "Extruder3"
+
+#define ABOUT_TYPE_TEXT_FR "Type: "
+#define ABOUT_VERSION_TEXT_FR "Firmware: "
+#define ABOUT_WIFI_TEXT_FR "Wifi: "
+
+#define PRINTING_OPERATION_FR "Option"
+#define PRINTING_PAUSE_FR "Pause"
+#define PRINTING_TEMP_FR "Temp."
+#define PRINTING_CHANGESPEED_FR "Speed"
+#define PRINTING_RESUME_FR "Reprendre"
+#define PRINTING_STOP_FR "Stop"
+#define PRINTING_MORE_FR "Plus"
+#define PRINTING_EXTRUDER_FR "Extruder"
+#define PRINTING_MOVE_FR "Déplace"
+
+#define EXTRUDER_SPEED_FR "Extruder"
+#define MOVE_SPEED_FR "Déplace"
+#define EXTRUDER_SPEED_STATE_FR "Vitesse d'extrusion"
+#define MOVE_SPEED_STATE_FR "vitesse de déplacement"
+#define STEP_1PERCENT_FR "1%"
+#define STEP_5PERCENT_FR "5%"
+#define STEP_10PERCENT_FR "10%"
+
+#define TITLE_READYPRINT_FR "Prête"
+#define TITLE_PREHEAT_FR "Préchauffe"
+#define TITLE_MOVE_FR "Déplace"
+#define TITLE_HOME_FR "Acceuil"
+#define TITLE_EXTRUDE_FR "Extruder"
+#define TITLE_LEVELING_FR "Leveling"
+#define TITLE_SET_FR "Paramètres"
+#define TITLE_MORE_FR "Plus"
+#define TITLE_CHOOSEFILE_FR "Fichier"
+#define TITLE_PRINTING_FR "Pimpression"
+#define TITLE_OPERATION_FR "Option"
+#define TITLE_ADJUST_FR "Réglage"
+#define TITLE_WIRELESS_FR "Sans fil"
+#define TITLE_FILAMENT_FR "Remplacer"
+#define TITLE_ABOUT_FR "A propos"
+#define TITLE_FAN_FR "Ventilateur"
+#define TITLE_LANGUAGE_FR "Langue"
+#define TITLE_PAUSE_FR "Pause"
+#define TITLE_CHANGESPEED_FR "Speed"
+#define TITLE_CLOUD_TEXT_FR "Cloud"
+#define TITLE_DIALOG_CONFIRM_FR "Confirm"
+#define TITLE_FILESYS_FR "FileSys"
+
+#define DIALOG_CLOSE_MACHINE_FR "Closing machine......"
+
+#define AUTO_SHUTDOWN_FR "Auto"
+#define MANUAL_SHUTDOWN_FR "Manuel"
+
+#define DIALOG_CONFIRM_FR "Confirmer"
+#define DIALOG_CANCLE_FR "Annuler"
+#define DIALOG_OK_FR "OK"
+#define DIALOG_RESET_FR "Réinitialiser"
+#define DIALOG_RETRY_FR "Recommencez"
+#define DIALOG_DISABLE_FR "Disable"
+#define DIALOG_PRINT_MODEL_FR "Imprimer le fichier?"
+#define DIALOG_CANCEL_PRINT_FR "Arrêter?"
+
+#define DIALOG_STOP_FR "Arrêter"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_FR "Continuer?"
+#define DIALOG_ERROR_TIPS1_FR "Erreur:error:Aucun fichier, \nvérifiez à nouveau."
+#define DIALOG_ERROR_TIPS2_FR "Erreur:La opération a échoué. \nVerifiez que le baudrate de l'écran et de \nla carte mère soient identique!"
+#define DIALOG_ERROR_TIPS3_FR "Erreur: le nom du fichier ou le \nchemin d'accès est trop long."
+#define DIALOG_UNBIND_PRINTER_FR "Unbind the printer?"
+#define DIALOG_FILAMENT_NO_PRESS_FR "Filament detection switch is not pressed"
+#define DIALOG_PRINT_FINISH_FR "L'impression est terminée!"
+#define DIALOG_PRINT_TIME_FR "Temps d'impression: "
+#define DIALOG_REPRINT_FR "Print again"
+#define DIALOG_WIFI_ENABLE_TIPS_FR "The wifi module is being configured,\nplease wait a moment....."
+#define DIALOG_PAUSING_TIPS_FR "La machine fait une pause ..."
+
+#define MESSAGE_PAUSING_FR "Parking..."
+#define MESSAGE_CHANGING_FR "Attente filament pour démarrer"
+#define MESSAGE_UNLOAD_FR "Attente retrait du filament"
+#define MESSAGE_WAITING_FR "Presser bouton,pour reprendre"
+#define MESSAGE_INSERT_FR "Insérer filament et app. bouton pour continuer..."
+#define MESSAGE_LOAD_FR "Attente chargement filament"
+#define MESSAGE_PURGE_FR "Attente Purge filament"
+#define MESSAGE_RESUME_FR "Attente reprise impression"
+#define MESSAGE_HEAT_FR "Presser le bouton pour chauffer..."
+#define MESSAGE_HEATING_FR "Buse en chauffe Patienter SVP..."
+#define MESSAGE_OPTION_FR "Purger davantage ou continuer l'impression?"
+#define MESSAGE_PURGE_MORE_FR "Purge"
+#define MESSAGE_CONTINUE_PRINT_FR "Impression"
+#define EEPROM_SETTINGS_TITLE_FR "Paramètres EEPROM"
+#define EEPROM_SETTINGS_STORE_FR "Stocker les paramètres dans l'EEPROM"
+#define EEPROM_SETTINGS_READ_FR "Lire les paramètres de l'EEPROM"
+#define EEPROM_SETTINGS_REVERT_FR "Rétablir les paramètres par défaut d'usine"
+
+#define EEPROM_STORE_TIPS_FR "Stocker les paramètres dans l'EEPROM?"
+#define EEPROM_READ_TIPS_FR "Lire les paramètres de l'EEPROM?"
+#define EEPROM_REVERT_TIPS_FR "Rétablir les paramètres par défaut d'usine?"
+
+#define MORE_CUSTOM1_TEXT_FR USER_DESC_1
+#define MORE_CUSTOM2_TEXT_FR USER_DESC_2
+#define MORE_CUSTOM3_TEXT_FR USER_DESC_3
+#define MORE_CUSTOM4_TEXT_FR USER_DESC_4
+#define MORE_CUSTOM5_TEXT_FR USER_DESC_5
+#define MORE_CUSTOM6_TEXT_FR USER_DESC_6
+#define MORE_CUSTOM7_TEXT_FR USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h
new file mode 100644
index 0000000..2820feb
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_it.h
@@ -0,0 +1,265 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//****************意大利语***************************//
+#define TOOL_TEXT_IT "Strumento"
+#define PREHEAT_TEXT_IT "Prerisc"
+#define MOVE_TEXT_IT "Muovi"
+#define HOME_TEXT_IT "Home"
+#define PRINT_TEXT_IT "Stampa"
+#define EXTRUDE_TEXT_IT "Estrude"
+#define LEVELING_TEXT_IT "Leveling"
+#define AUTO_LEVELING_TEXT_IT "AutoLevel"
+#define SET_TEXT_IT "Imposta"
+#define MORE_TEXT_IT "Di più"
+
+#define ADD_TEXT_IT "Aumentare"
+#define DEC_TEXT_IT "Ridurre"
+#define EXTRUDER_1_TEXT_IT "Estrude1"
+#define EXTRUDER_2_TEXT_IT "Estrude2"
+#define HEATBED_TEXT_IT "Piano"
+#define TEXT_1C_IT "1℃"
+#define TEXT_5C_IT "5℃"
+#define TEXT_10C_IT "10℃"
+#define CLOSE_TEXT_IT "Spento"
+
+#define BACK_TEXT_IT "Indietro"
+
+#define TOOL_PREHEAT_IT "Prerisc"
+#define TOOL_EXTRUDE_IT "Estrude"
+#define TOOL_MOVE_IT "Muovi"
+#define TOOL_HOME_IT "Home"
+#define TOOL_LEVELING_IT "Leveling"
+#define TOOL_AUTO_LEVELING_IT "Autolevel"
+#define TOOL_FILAMENT_IT "Filamento"
+#define TOOL_MORE_IT "Di più"
+
+#define AXIS_X_ADD_TEXT_IT "X+"
+#define AXIS_X_DEC_TEXT_IT "X-"
+#define AXIS_Y_ADD_TEXT_IT "Y+"
+#define AXIS_Y_DEC_TEXT_IT "Y-"
+#define AXIS_Z_ADD_TEXT_IT "Z+"
+#define AXIS_Z_DEC_TEXT_IT "Z-"
+#define TEXT_01MM_IT "0.1mm"
+#define TEXT_1MM_IT "1mm"
+#define TEXT_10MM_IT "10mm"
+
+#define HOME_X_TEXT_IT "X"
+#define HOME_Y_TEXT_IT "Y"
+#define HOME_Z_TEXT_IT "Z"
+#define HOME_ALL_TEXT_IT "All"
+#define HOME_STOPMOVE_IT "Quickstop"
+
+#define PAGE_UP_TEXT_IT "Pagina su"
+#define PAGE_DOWN_TEXT_IT "Pagina giù"
+
+#define EXTRUDER_IN_TEXT_IT "Estru"
+#define EXTRUDER_OUT_TEXT_IT "Ritra"
+#define EXTRUDE_1MM_TEXT_IT "1mm"
+#define EXTRUDE_5MM_TEXT_IT "5mm"
+#define EXTRUDE_10MM_TEXT_IT "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_IT "Bassa"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_IT "Media"
+#define EXTRUDE_HIGH_SPEED_TEXT_IT "Alta"
+
+#define LEVELING_POINT1_TEXT_IT "Primo"
+#define LEVELING_POINT2_TEXT_IT "Secondo"
+#define LEVELING_POINT3_TEXT_IT "Terzo"
+#define LEVELING_POINT4_TEXT_IT "Quarto"
+#define LEVELING_POINT5_TEXT_IT "Quinto"
+
+#define FILESYS_TEXT_IT "FileSys"
+#define WIFI_TEXT_IT "WIFI"
+#define FAN_TEXT_IT "Ventola"
+#define ABOUT_TEXT_IT "Circa"
+#define BREAK_POINT_TEXT_IT "Continua"
+#define FILAMENT_TEXT_IT "Filamento"
+#define LANGUAGE_TEXT_IT "Lingua"
+#define MOTOR_OFF_TEXT_IT "Motor off"
+#define MOTOR_OFF_XY_TEXT_IT "Off-XY"
+#define SHUTDOWN_TEXT_IT "Spento"
+#define MACHINE_PARA_IT "Config"
+#define EEPROM_SETTINGS_IT "Eeprom Set"
+
+#define U_DISK_TEXT_IT "USB"
+#define SD_CARD_TEXT_IT "SD"
+#define WIFI_NAME_TEXT_IT "WIFI: "
+#define WIFI_KEY_TEXT_IT "KEY: "
+#define WIFI_IP_TEXT_IT "IP: "
+#define WIFI_AP_TEXT_IT "Stato: AP"
+#define WIFI_STA_TEXT_IT "Stato: STA"
+#define WIFI_CONNECTED_TEXT_IT "Connesso"
+#define WIFI_DISCONNECTED_TEXT_IT "Disconnesso"
+#define WIFI_EXCEPTION_TEXT_IT "Eccezione"
+#define WIFI_RECONNECT_TEXT_IT "Reconnect"
+#define CLOUD_TEXT_IT "Cloud"
+#define CLOUD_BIND_IT "Legato"
+#define CLOUD_UNBIND_IT "Libero"
+#define CLOUD_DISCONNECTED_IT "Disconnesso"
+#define CLOUD_UNBINDING_IT "Libero"
+#define CLOUD_UNBINDED_IT "Sciolto"
+#define CLOUD_BINDED_IT "Legato"
+#define CLOUD_DISABLE_IT "Disable"
+
+#define FAN_ADD_TEXT_IT "Aumentare"
+#define FAN_DEC_TEXT_IT "Ridurre"
+#define FAN_OPEN_TEXT_IT "100%"
+#define FAN_HALF_TEXT_IT "50%"
+#define FAN_CLOSE_TEXT_IT "Spento"
+#define FAN_TIPS1_TEXT_IT "Ventola"
+#define FAN_TIPS2_TEXT_IT "Ventola\n0"
+
+#define FILAMENT_IN_TEXT_IT "Inser"
+#define FILAMENT_OUT_TEXT_IT "Estra"
+#define FILAMENT_EXT0_TEXT_IT "Estrude1"
+#define FILAMENT_EXT1_TEXT_IT "Estrude2"
+#define FILAMENT_HEAT_TEXT_IT "Preriscaldamento"
+#define FILAMENT_STOP_TEXT_IT "Stop"
+#define FILAMENT_TIPS2_TEXT_IT "T:"
+#define FILAMENT_TIPS3_TEXT_IT "Inserimento del filamento..."
+#define FILAMENT_TIPS4_TEXT_IT "Estrazione del filamento..."
+#define FILAMENT_TIPS5_TEXT_IT "Temp is too low to go,please heat"
+#define FILAMENT_TIPS6_TEXT_IT "Completato"
+
+#define FILAMENT_CHANGE_TEXT_IT "Please click <Load> \nor <unload>,After \npinter pause."
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..."
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_IT "Heating up the nozzle,please wait..."
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_IT "Heat completed,please load filament \nto extruder,and click <confirm> \nfor start loading."
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_IT "Please load filament to extruder,\nand click <confirm> for start loading."
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_IT "Heat completed,please \nclick <confirm> for start unloading.!"
+#define FILAMENT_DIALOG_LOADING_TIPS_IT "Is loading ,please wait!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_IT "Is unloading,please wait!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_IT "Load filament completed,\nclick <confirm> for return!"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_IT "Unload filament completed,\nclick <confirm> for return!"
+
+#define PRE_HEAT_EXT_TEXT_IT "E"
+#define PRE_HEAT_BED_TEXT_IT "Piano"
+
+#define FILE_LOADING_IT "Caricamento......"
+#define NO_FILE_AND_CHECK_IT "Nessun file,\n per favore controllare di nuovo!"
+#define NO_FILE_IT "Nessun file!"
+
+#define EXTRUDER_TEMP_TEXT_IT "Temper"
+#define EXTRUDER_E_LENGTH1_TEXT_IT "Estrude1"
+#define EXTRUDER_E_LENGTH2_TEXT_IT "Estrude2"
+#define EXTRUDER_E_LENGTH3_TEXT_IT "Estrude3"
+
+#define ABOUT_TYPE_TEXT_IT "Type: "
+#define ABOUT_VERSION_TEXT_IT "Firmware: "
+#define ABOUT_WIFI_TEXT_IT "WiFi: "
+
+#define PRINTING_OPERATION_IT "Opzioni"
+#define PRINTING_PAUSE_IT "Pause"
+#define PRINTING_TEMP_IT "Temp."
+#define PRINTING_CHANGESPEED_IT "Velocità"
+#define PRINTING_RESUME_IT "Recupero"
+#define PRINTING_STOP_IT "Stop"
+#define PRINTING_MORE_IT "Di più"
+#define PRINTING_EXTRUDER_IT "Estrude"
+#define PRINTING_MOVE_IT "Muovi"
+
+#define EXTRUDER_SPEED_IT "Estrude"
+#define MOVE_SPEED_IT "Muovi"
+#define EXTRUDER_SPEED_STATE_IT "Estrusione"
+#define MOVE_SPEED_STATE_IT "Movimento"
+#define STEP_1PERCENT_IT "1%"
+#define STEP_5PERCENT_IT "5%"
+#define STEP_10PERCENT_IT "10%"
+
+#define TITLE_READYPRINT_IT "Pronto"
+#define TITLE_PREHEAT_IT "Preris"
+#define TITLE_MOVE_IT "Muovi"
+#define TITLE_HOME_IT "Home"
+#define TITLE_EXTRUDE_IT "Estrude"
+#define TITLE_LEVELING_IT "Livella"
+#define TITLE_SET_IT "Impostare"
+#define TITLE_MORE_IT "Di più"
+#define TITLE_CHOOSEFILE_IT "File"
+#define TITLE_PRINTING_IT "Stampa"
+#define TITLE_OPERATION_IT "Opzioni"
+#define TITLE_ADJUST_IT "Regolare"
+#define TITLE_WIRELESS_IT "Wireless"
+#define TITLE_FILAMENT_IT "Filamento"
+#define TITLE_ABOUT_IT "Circa"
+#define TITLE_FAN_IT "Ventola"
+#define TITLE_LANGUAGE_IT "Lingua"
+#define TITLE_PAUSE_IT "Pausa"
+#define TITLE_CHANGESPEED_IT "Velocità"
+#define TITLE_CLOUD_TEXT_IT "Cloud"
+#define TITLE_DIALOG_CONFIRM_IT "Confirm"
+#define TITLE_FILESYS_IT "FileSys"
+
+#define AUTO_SHUTDOWN_IT "Auto"
+#define MANUAL_SHUTDOWN_IT "Manuale"
+
+#define DIALOG_CONFIRM_IT "Conferma"
+#define DIALOG_CANCLE_IT "Cancella"
+#define DIALOG_OK_IT "OK"
+#define DIALOG_RESET_IT "Resettare"
+#define DIALOG_RETRY_IT "Riprovare"
+#define DIALOG_DISABLE_IT "Disable"
+#define DIALOG_PRINT_MODEL_IT "Gcode stampa?"
+#define DIALOG_CANCEL_PRINT_IT "Stop stampa?"
+#define DIALOG_STOP_IT "Stop"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_IT "Continua a stampare dal \npunto di interruzione?"
+#define DIALOG_ERROR_TIPS1_IT "Errore: nessun file, \nper favore controllare di nuovo."
+#define DIALOG_ERROR_TIPS2_IT "Errore: operazione non riuscita, \nsi prega di controllare se il baudrate del \ndisplay è lo stesso scheda madre"
+#define DIALOG_ERROR_TIPS3_IT "Errore: il nome del file o il \npercorso è troppo lungo!"
+#define DIALOG_CLOSE_MACHINE_IT "Closing machine......"
+#define DIALOG_UNBIND_PRINTER_IT "Unbind the printer?"
+#define DIALOG_FILAMENT_NO_PRESS_IT "Filament detection switch is not pressed"
+#define DIALOG_PRINT_FINISH_IT "La stampa è completa!"
+#define DIALOG_PRINT_TIME_IT "Tempo di stampa: "
+#define DIALOG_REPRINT_IT "Print again"
+#define DIALOG_WIFI_ENABLE_TIPS_IT "The wifi module is being configured,\nplease wait a moment....."
+#define DIALOG_PAUSING_TIPS_IT "La macchina si ferma ..."
+
+#define MESSAGE_PAUSING_IT "Parcheggiando..."
+#define MESSAGE_CHANGING_IT "Attendere avvio del cambio di filamento"
+#define MESSAGE_UNLOAD_IT "Attendere l'espulsione del filamento"
+#define MESSAGE_WAITING_IT "Premi per riprendere la stampa"
+#define MESSAGE_INSERT_IT "Inserisci il filamento e premi per continuare"
+#define MESSAGE_LOAD_IT "Attendere il caricamento del filamento"
+#define MESSAGE_PURGE_IT "Attendere lo spurgo del filamento"
+#define MESSAGE_RESUME_IT "Attendere la ripresa della stampa..."
+#define MESSAGE_HEAT_IT "Premi per riscaldare ugello"
+#define MESSAGE_HEATING_IT "Riscaldam. ugello Attendere prego..."
+#define MESSAGE_OPTION_IT "Eliminare di più o continuare a stampare?"
+#define MESSAGE_PURGE_MORE_IT "Epurazione"
+#define MESSAGE_CONTINUE_PRINT_IT "Stampa"
+#define EEPROM_SETTINGS_TITLE_IT "Impostazioni EEPROM"
+#define EEPROM_SETTINGS_STORE_IT "Memorizzare le impostazioni su EEPROM"
+#define EEPROM_SETTINGS_READ_IT "Leggi le impostazioni dalla EEPROM"
+#define EEPROM_SETTINGS_REVERT_IT "Ripristina le impostazioni predefinite di fabbrica"
+
+#define EEPROM_STORE_TIPS_IT "Memorizzare le impostazioni su EEPROM?"
+#define EEPROM_READ_TIPS_IT "Leggi le impostazioni dalla EEPROM?"
+#define EEPROM_REVERT_TIPS_IT "Ripristinare le impostazioni predefinite?"
+
+#define MORE_CUSTOM1_TEXT_IT USER_DESC_1
+#define MORE_CUSTOM2_TEXT_IT USER_DESC_2
+#define MORE_CUSTOM3_TEXT_IT USER_DESC_3
+#define MORE_CUSTOM4_TEXT_IT USER_DESC_4
+#define MORE_CUSTOM5_TEXT_IT USER_DESC_5
+#define MORE_CUSTOM6_TEXT_IT USER_DESC_6
+#define MORE_CUSTOM7_TEXT_IT USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h
new file mode 100644
index 0000000..04fbf25
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_ru.h
@@ -0,0 +1,384 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//****************俄语***************************//
+#define TOOL_TEXT_RU "инструмент"
+#define PREHEAT_TEXT_RU " нагрев"
+#define MOVE_TEXT_RU "движение"
+#define HOME_TEXT_RU "домой"
+#define PRINT_TEXT_RU " печать"
+#define EXTRUDE_TEXT_RU "экструзия"
+#define LEVELING_TEXT_RU "уровень"
+#define AUTO_LEVELING_TEXT_RU "aвтоуровень"
+#define SET_TEXT_RU "настройки"
+#define MORE_TEXT_RU "больше"
+
+#define ADD_TEXT_RU "добавить"
+#define DEC_TEXT_RU "уменьшить"
+#define EXTRUDER_1_TEXT_RU "экструдер1"
+#define EXTRUDER_2_TEXT_RU "экструдер2"
+#define HEATBED_TEXT_RU "стол"
+#define TEXT_1C_RU "1℃"
+#define TEXT_5C_RU "5℃"
+#define TEXT_10C_RU "10℃"
+#define CLOSE_TEXT_RU "выкл"
+
+#define BACK_TEXT_RU "назад"
+
+#define TOOL_PREHEAT_RU "нагрев"
+#define TOOL_EXTRUDE_RU "экструдер"
+#define TOOL_MOVE_RU "движение"
+#define TOOL_HOME_RU "домой"
+#define TOOL_LEVELING_RU "уровень"
+#define TOOL_AUTO_LEVELING_RU "aвтоуровень"
+#define TOOL_FILAMENT_RU "замена"
+#define TOOL_MORE_RU "больше"
+
+#define AXIS_X_ADD_TEXT_RU "X +"
+#define AXIS_X_DEC_TEXT_RU "X -"
+#define AXIS_Y_ADD_TEXT_RU "Y +"
+#define AXIS_Y_DEC_TEXT_RU "Y -"
+#define AXIS_Z_ADD_TEXT_RU "Z +"
+#define AXIS_Z_DEC_TEXT_RU "Z -"
+#define TEXT_01MM_RU "0.1 mm"
+#define TEXT_1MM_RU "1 mm"
+#define TEXT_10MM_RU "10 mm"
+
+#define HOME_X_TEXT_RU "X"
+#define HOME_Y_TEXT_RU "Y"
+#define HOME_Z_TEXT_RU "Z"
+#define HOME_ALL_TEXT_RU "Home"
+#define HOME_STOPMOVE_RU "Quickstop"
+
+#define PAGE_UP_TEXT_RU "вверх"
+#define PAGE_DOWN_TEXT_RU "вниз"
+
+#define EXTRUDER_IN_TEXT_RU "втянуть"
+#define EXTRUDER_OUT_TEXT_RU "выдавить"
+#define EXTRUDE_1MM_TEXT_RU "1 mm"
+#define EXTRUDE_5MM_TEXT_RU "5 mm"
+#define EXTRUDE_10MM_TEXT_RU "10 mm"
+#define EXTRUDE_LOW_SPEED_TEXT_RU "мин"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_RU "сред"
+#define EXTRUDE_HIGH_SPEED_TEXT_RU "выс"
+
+#define LEVELING_POINT1_TEXT_RU "1 точка"
+#define LEVELING_POINT2_TEXT_RU "2 точка"
+#define LEVELING_POINT3_TEXT_RU "3 точка"
+#define LEVELING_POINT4_TEXT_RU "4 точка"
+#define LEVELING_POINT5_TEXT_RU "5 точка"
+
+#define FILESYS_TEXT_RU "система"
+#define WIFI_TEXT_RU "WiFi"
+#define FAN_TEXT_RU "вентилятор"
+#define ABOUT_TEXT_RU "инфо"
+#define BREAK_POINT_TEXT_RU "продолжить"
+#define FILAMENT_TEXT_RU "замена"
+#define LANGUAGE_TEXT_RU "язык"
+#define MOTOR_OFF_TEXT_RU "откл. мотор"
+#define MOTOR_OFF_XY_TEXT_RU "Off-XY"
+#define SHUTDOWN_TEXT_RU "выключение"
+#define MACHINE_PARA_RU "конфиг"
+
+#define U_DISK_TEXT_RU "U диск"
+#define SD_CARD_TEXT_RU "SD диск"
+#define WIFI_NAME_TEXT_RU "WiFi: "
+#define WIFI_KEY_TEXT_RU "пароль: "
+#define WIFI_IP_TEXT_RU "IP: "
+#define WIFI_AP_TEXT_RU "режим: AP"
+#define WIFI_STA_TEXT_RU "режим: STA"
+#define WIFI_CONNECTED_TEXT_RU "подключен"
+#define WIFI_DISCONNECTED_TEXT_RU "не подключен"
+#define WIFI_EXCEPTION_TEXT_RU "исключение"
+#define WIFI_RECONNECT_TEXT_RU "выбор сети"
+#define CLOUD_TEXT_RU "облако"
+#define CLOUD_BIND_RU "соединён"
+#define CLOUD_UNBIND_RU "отсоед."
+#define CLOUD_UNBINDING_RU "отвязано"
+#define CLOUD_DISCONNECTED_RU "отключено"
+#define CLOUD_UNBINDED_RU "несвяз."
+#define CLOUD_BINDED_RU "связано"
+#define CLOUD_DISABLE_RU "Disable"
+
+#define FAN_ADD_TEXT_RU "добавить"
+#define FAN_DEC_TEXT_RU "уменьшить"
+#define FAN_OPEN_TEXT_RU "100%"
+#define FAN_HALF_TEXT_RU "50%"
+#define FAN_CLOSE_TEXT_RU "откл"
+#define FAN_TIPS1_TEXT_RU "вентилятор"
+#define FAN_TIPS2_TEXT_RU "вентилятор\nоткл"
+
+#define FILAMENT_IN_TEXT_RU "втянуть"
+#define FILAMENT_OUT_TEXT_RU "выдавить"
+#define FILAMENT_EXT0_TEXT_RU "экструдер1"
+#define FILAMENT_EXT1_TEXT_RU "экструдер2"
+#define FILAMENT_HEAT_TEXT_RU "нагрев"
+#define FILAMENT_STOP_TEXT_RU "стоп"
+#define FILAMENT_TIPS2_TEXT_RU "T:"
+#define FILAMENT_TIPS3_TEXT_RU "втянуть..."
+#define FILAMENT_TIPS4_TEXT_RU "вядавить..."
+#define FILAMENT_TIPS5_TEXT_RU "Низкая температура, \nнеобходим нагрев"
+#define FILAMENT_TIPS6_TEXT_RU "завершено"
+
+#define FILAMENT_CHANGE_TEXT_RU "Please click <Load> \nor <unload>,After \npinter pause."
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_RU "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_RU "Heating up the nozzle,\nplease wait..."
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_RU "Heat completed,please load filament \nto extruder,and click <confirm> \nfor start loading."
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_RU "Please load filament to extruder,\nand click <confirm> for start loading."
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_RU "Heat completed,please \nclick <confirm> for start unloading.!"
+#define FILAMENT_DIALOG_LOADING_TIPS_RU "Is loading ,please wait!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_RU "Is unloading,please wait!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_RU "Load filament completed,\nclick <confirm> for return!"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_RU "Unload filament completed,\nclick <confirm> for return!"
+
+#define PRE_HEAT_EXT_TEXT_RU "E"
+#define PRE_HEAT_BED_TEXT_RU "стол"
+
+#define FILE_LOADING_RU "загрузка......"
+#define NO_FILE_AND_CHECK_RU "нет файла,попробуйте ещё раз!"
+
+#define NO_FILE_RU "нет файла!"
+
+#define EXTRUDER_TEMP_TEXT_RU "температура"
+#define EXTRUDER_E_LENGTH1_TEXT_RU "экструзия1"
+#define EXTRUDER_E_LENGTH2_TEXT_RU "экструзия2"
+#define EXTRUDER_E_LENGTH3_TEXT_RU "экструзия3"
+
+#define ABOUT_TYPE_TEXT_RU "Type: "
+#define ABOUT_VERSION_TEXT_RU "Firmware: "
+#define ABOUT_WIFI_TEXT_RU "WiFi: "
+
+#define PRINTING_OPERATION_RU "опции"
+#define PRINTING_PAUSE_RU "пауза"
+#define PRINTING_TEMP_RU "темп"
+#define PRINTING_CHANGESPEED_RU "скорости"
+#define PRINTING_RESUME_RU "возобн. "
+#define PRINTING_STOP_RU "стоп"
+#define PRINTING_MORE_RU "больше"
+#define PRINTING_EXTRUDER_RU "экстр"
+#define PRINTING_MOVE_RU "движение"
+
+#define EXTRUDER_SPEED_RU "экстр"
+#define MOVE_SPEED_RU "движ"
+#define EXTRUDER_SPEED_STATE_RU "скорость экстр"
+#define MOVE_SPEED_STATE_RU "скорость движ"
+#define STEP_1PERCENT_RU "1%"
+#define STEP_5PERCENT_RU "5%"
+#define STEP_10PERCENT_RU "10%"
+
+#define TITLE_READYPRINT_RU "готов к"
+#define TITLE_PREHEAT_RU "движение"
+#define TITLE_MOVE_RU "движение"
+#define TITLE_HOME_RU "Home"
+#define TITLE_EXTRUDE_RU "экструзия"
+#define TITLE_LEVELING_RU "уровень"
+#define TITLE_MLEVELING_RU "углы"
+#define TITLE_SET_RU "настройки"
+#define TITLE_MORE_RU "больше"
+#define TITLE_CHOOSEFILE_RU "файла"
+#define TITLE_PRINTING_RU "печать"
+#define TITLE_OPERATION_RU "управление"
+#define TITLE_ADJUST_RU "регулировать"
+#define TITLE_WIRELESS_RU "Wireless"
+#define TITLE_FILAMENT_RU "замена"
+#define TITLE_ABOUT_RU "инфо"
+#define TITLE_FAN_RU "вентилятор"
+#define TITLE_LANGUAGE_RU "язык"
+#define TITLE_PAUSE_RU "пауза"
+#define TITLE_CHANGESPEED_RU "скорости"
+#define TILE_TOOL_RU "инструмент"
+#define TITLE_CLOUD_TEXT_RU "Cloud"
+#define TITLE_DIALOG_CONFIRM_RU "Confirm"
+#define TITLE_FILESYS_RU "FileSys"
+
+#define AUTO_SHUTDOWN_RU "авто-откл"
+#define MANUAL_SHUTDOWN_RU "ручн-откл"
+
+#define DIALOG_CONFIRM_RU "да"//"подтвердить"
+#define DIALOG_CANCLE_RU "отмена"
+#define DIALOG_OK_RU "да"
+#define DIALOG_RESET_RU "сброс"
+#define DIALOG_RETRY_RU "повтор"
+#define DIALOG_DISABLE_RU "запретить"
+#define DIALOG_PRINT_MODEL_RU "печать модели?"
+#define DIALOG_CANCEL_PRINT_RU "стоп?"
+#define DIALOG_STOP_RU "стоп"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_RU "продолжить?"
+#define DIALOG_ERROR_TIPS1_RU "ошибка:нет файла, попробуйте ещё раз."
+#define DIALOG_ERROR_TIPS2_RU "ошибка:сбой передачи. установите скорость \nпередачи данных как на плате управления!"
+#define DIALOG_ERROR_TIPS3_RU "ошибка: имя файла слишком длинное!"
+#define DIALOG_CLOSE_MACHINE_RU "Closing machine......"
+#define DIALOG_UNBIND_PRINTER_RU "Unbind the printer?"
+#define DIALOG_FILAMENT_NO_PRESS_RU "Filament detection switch is not pressed"
+#define DIALOG_PRINT_FINISH_RU "печать завершена!"
+#define DIALOG_PRINT_TIME_RU "Время печати: "
+#define DIALOG_REPRINT_RU "Print again"
+#define DIALOG_WIFI_ENABLE_TIPS_RU "The wifi module is being configured,\nplease wait a moment....."
+#define DIALOG_PAUSING_TIPS_RU "Машина останавливается ..."
+
+#define MESSAGE_PAUSING_RU "Стоянка..."
+#define MESSAGE_CHANGING_RU "Подождите, пока начнется смена филамента"
+#define MESSAGE_UNLOAD_RU "Дождитесь выгрузки нити"
+#define MESSAGE_WAITING_RU "Нажмите кнопку,чтобы возобновить печать"
+#define MESSAGE_INSERT_RU "Вставьте нить и нажмите кнопку,чтобы продолжить"
+#define MESSAGE_LOAD_RU "Дождитесь загрузки нити"
+#define MESSAGE_PURGE_RU "Дождитесь чистки нити"
+#define MESSAGE_RESUME_RU "Подождите,пока печать возобновится ..."
+#define MESSAGE_HEAT_RU "Нажмите кнопку, чтобы нагреть форсунку"
+#define MESSAGE_HEATING_RU "Подогрев форсунки Пожалуйста, подождите ..."
+#define MESSAGE_OPTION_RU "Очистить больше или продолжить печать?"
+#define MESSAGE_PURGE_MORE_RU "чистка"
+#define MESSAGE_CONTINUE_PRINT_RU "Распечатать"
+#define EEPROM_SETTINGS_TITLE_RU "Настройки EEPROM"
+#define EEPROM_SETTINGS_STORE_RU "Cохранение настроек в EEPROM"
+#define EEPROM_SETTINGS_READ_RU "Чтение настроек из EEPROM"
+#define EEPROM_SETTINGS_REVERT_RU "Bосстановить заводские настройки по умолчанию"
+
+#define MORE_CUSTOM1_TEXT_RU USER_DESC_1
+#define MORE_CUSTOM2_TEXT_RU USER_DESC_2
+#define MORE_CUSTOM3_TEXT_RU USER_DESC_3
+#define MORE_CUSTOM4_TEXT_RU USER_DESC_4
+#define MORE_CUSTOM5_TEXT_RU USER_DESC_5
+#define MORE_CUSTOM6_TEXT_RU USER_DESC_6
+#define MORE_CUSTOM7_TEXT_RU USER_DESC_7
+
+//Malderin translate
+//
+//
+#define EEPROM_STORE_TIPS_RU "Cохранить настройки в EEPROM?"
+#define EEPROM_READ_TIPS_RU "читать настройки из EEPROM?"
+#define EEPROM_REVERT_TIPS_RU "Cбросить настройки к значениям по умолчанию?"
+#define EEPROM_SETTINGS_RU "EEPROM"
+
+
+#define NEXT_RU "след."
+#define PREVIOUS_RU "пред."
+#define ENABLE_RU "да "
+#define DISABLE_RU "нет"
+#define KEY_CONFIRM_RU "OK"
+
+#define MACHINE_PARA_TITLE_RU "настройки"
+#define MACHINE_TYPE_CNOFIG_RU "Hастройки принтера"
+#define MOTOR_CONFIG_RU "Hастройки моторов"
+#define MACHINE_LEVELING_CONFIG_RU "Hастройки уровня"
+#define ADVANCE_CONFIG_RU "Pасширенные настройки"
+#define MACHINE_FILAMENT_CONFIG_RU "Hастройки филамента"
+#define ENCODER_SETTINGS_RU "Hастройки энкодера"
+
+
+#define LEVELING_CONF_TITLE_RU "Hастройки принтера>Hастройки уровня"
+#define LEVELING_PARA_CONF_RU "настройки уровня"
+#define LEVELING_MANUAL_POS_RU "настройки координат для уровня"
+#define LEVELING_AUTO_COMMAND_RU "настройки комманд увтоуровня"
+#define LEVELING_AUTO_ZOFFSET_RU "координаты смещения сопла"
+#define LEVELING_TOUCHMI_RU "Settings-TouchMi-Probe"
+#define TM_INIT_RU "Init"
+#define TM_ZOFFSETPOS_RU "Zoffset+"
+#define TM_ZOFFSETNEG_RU "Zoffset-"
+#define TM_SAVE_RU "Save"
+#define TM_TEST_RU "Test"
+
+#define BLTOUCH_LEVELING_TITTLE_RU "Settings>BL-Touch Probe"
+#define BLTOUCH_LEVELING_RU "BL-Touch Probe"
+#define BLTOUCH_INIT_RU "Init"
+#define BLTOUCH_ZOFFSETPOS_RU "Zoffset+"
+#define BLTOUCH_ZOFFSETNEG_RU "Zoffset-"
+#define BLTOUCH_SAVE_RU "Save"
+#define BLTOUCH_TEST_RU "Test"
+
+#define MACHINE_CONFIG_TITLE_RU "Hастройки принтера>настройки притера"
+#define MAXFEEDRATE_CONF_RU "настройки максимальной скорости"
+#define ACCELERATION_CONF_RU "настройки ускорений"
+#define JERKCONF_RU "настройки рывков"
+
+#define MOTOR_CONF_TITLE_RU "Hастройки принтера>Hастройки моторов"
+#define STEPSCONF_RU "настройки шагов"
+#define TMC_CURRENT_RU "TMC настройки токов"
+#define TMC_STEP_MODE_RU "TMC настрйоки режима шагов"
+
+#define ACCELERATION_CONF_TITLE_RU "Hастройки принтера>ускорения"
+#define PRINT_ACCELERATION_RU "ускорение печати"
+#define RETRACT_ACCELERATION_RU "ускорение ретракта"
+#define TRAVEL_ACCELERATION_RU "ускорение перемещений"
+#define X_ACCELERATION_RU "ускорение оси X"
+#define Y_ACCELERATION_RU "ускорение оси Y"
+#define Z_ACCELERATION_RU "ускорение оси Z"
+#define E0_ACCELERATION_RU "ускорение E0"
+#define E1_ACCELERATION_RU "ускорение E1"
+
+#define MAXFEEDRATE_CONF_TITLE_RU "Hастройки принтера>максимальная скорость"
+#define X_MAXFEEDRATE_RU "максимальная скорость оси X"
+#define Y_MAXFEEDRATE_RU "максимальная скорость оси Y"
+#define Z_MAXFEEDRATE_RU "максимальная скорость оси Z"
+#define E0_MAXFEEDRATE_RU "максимальная скорость E0"
+#define E1_MAXFEEDRATE_RU "максимальная скорость E1"
+
+#define JERK_CONF_TITLE_RU "Hастройки принтера>скорость рывка"
+#define X_JERK_RU "скорость рывка оси X"
+#define Y_JERK_RU "скорость рывка оси Y"
+#define Z_JERK_RU "скорость рывка оси Z"
+#define E_JERK_RU "скорость рывка оси E"
+
+#define STEPS_CONF_TITLE_RU "Hастройки принтера>настройки шагов"
+#define X_STEPS_RU "шаги оси X"
+#define Y_STEPS_RU "шаги оси Y"
+#define Z_STEPS_RU "шаги оси Z"
+#define E0_STEPS_RU "шаги E0"
+#define E1_STEPS_RU "шаги E1"
+
+#define TMC_CURRENT_CONF_TITLE_RU "Hастройки принтера>TMC настройка токов"
+#define X_TMC_CURRENT_RU "ток оси X (mA)"
+#define Y_TMC_CURRENT_RU "ток оси Y (mA)"
+#define Z_TMC_CURRENT_RU "ток оси Z (mA)"
+#define E0_TMC_CURRENT_RU "ток E0 (mA)"
+#define E1_TMC_CURRENT_RU "ток E1 (mA)"
+
+#define TMC_MODE_CONF_TITLE_RU "Hастройки принтера>TMC настройки режима шагов"
+#define X_TMC_MODE_RU "включает ли двигатель X режим StealthChop"
+#define Y_TMC_MODE_RU "включает ли ось Y режим StealthChop"
+#define Z_TMC_MODE_RU "включает ли ось Z режим StealthChop"
+#define E0_TMC_MODE_RU "включает ли E0 режим StealthChop"
+#define E1_TMC_MODE_RU "включает ли E1 режим StealthChop"
+
+#define ADVANCED_CONF_TITLE_RU "Hастройки принтера>Pасширенные"
+#define PAUSE_POSITION_RU "Hастройки позиции паузы печати"
+#define PAUSE_POSITION_X_RU "положение по X (абс. полож., -1 недействит.)"
+#define PAUSE_POSITION_Y_RU "положение по Y (абс. полож., -1 недействит.)"
+#define PAUSE_POSITION_Z_RU "положение по Z (абс. полож., -1 недействит.)"
+
+#define OFFSET_TITLE_RU "Hастройки принтера>отступ"
+#define OFFSET_X_RU "X отступ"
+#define OFFSET_Y_RU "Y отступ"
+#define OFFSET_Z_RU "Z отступ"
+
+#define FILAMENT_CONF_TITLE_RU "Hастройки принтера>Hастройки филамента"
+#define FILAMENT_IN_LENGTH_RU "длинна загрузки"
+#define FILAMENT_IN_SPEED_RU "скорость загрузки"
+#define FILAMENT_TEMPERATURE_RU "температура филамента"
+#define FILAMENT_OUT_LENGTH_RU "длинна извлечения"
+#define FILAMENT_OUT_SPEED_RU "скорость извлечения"
+
+#define ENCODER_CONF_TITLE_RU "Hастройки принтера>Hастройки энкодера"
+#define ENCODER_CONF_TEXT_RU "энкодер используется?"
+
+//end of Malderin translate
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h
new file mode 100644
index 0000000..4623749
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_s_cn.h
@@ -0,0 +1,518 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//*************简体中文***********************//
+#define NEXT_CN "下一页"
+#define PREVIOUS_CN "上一页"
+#define DEFAULT_CN "默认值"
+#define KEY_BACK_CN "退格"
+#define KEY_REST_CN "重置"
+#define KEY_CONFIRM_CN "确定"
+
+#define MACHINE_PARA_TITLE_CN "机器参数"
+#define MACHINE_TYPE_CNOFIG_CN "机器设置"
+#define MOTOR_CONFIG_CN "电机设置"
+#define MACHINE_LEVELING_CONFIG_CN "调平设置"
+#define ADVANCE_CONFIG_CN "高级设置"
+
+#define MACHINE_CONFIG_TITLE_CN "机器参数>机器配置"
+#define MACHINE_TYPE_CN "机型选择"
+#define MACHINE_STROKE_CN "行程设置"
+#define MACHINE_HOMEDIR_CN "归零方向"
+#define MACHINE_ENDSTOP_TYPE_CN "限位开关类型"
+#define MACHINE_FILAMENT_CONFIG_CN "换料设置"
+
+#define MACHINE_TYPE_CONFIG_TITLE_CN "机器参数>机型选择"
+#define MACHINE_TYPE_XYZ_CN "XYZ机型"
+#define MACHINE_TYPE_DELTA_CN "Delta机型"
+#define MACHINE_TYPE_COREXY_CN "Corexy机型"
+
+#define MACHINE_STROKE_CONF_TITLE_CN "机器参数>机器行程"
+#define X_MAX_LENGTH_CN "X轴最大行程"
+#define Y_MAX_LENGTH_CN "Y轴最大行程"
+#define Z_MAX_LENGTH_CN "Z轴最大行程"
+
+#define X_MIN_LENGTH_CN "X轴最小行程"
+#define Y_MIN_LENGTH_CN "Y轴最小行程"
+#define Z_MIN_LENGTH_CN "Z轴最小行程"
+
+#define HOME_DIR_CONF_TITLE_CN "机器参数>归零方向"
+#define HOME_DIR_X_CN "X轴归零方向"
+#define HOME_DIR_Y_CN "Y轴归零方向"
+#define HOME_DIR_Z_CN "Z轴归零方向"
+#define HOME_MIN_CN "MIN"
+#define HOME_MAX_CN "MAX"
+
+#define ENDSTOP_CONF_TITLE_CN "机器参数>限位开关"
+#define MIN_ENDSTOP_X_CN "X轴最小限位"
+#define MIN_ENDSTOP_Y_CN "Y轴最小限位"
+#define MIN_ENDSTOP_Z_CN "Z轴最小限位"
+#define MAX_ENDSTOP_X_CN "X轴最大限位"
+#define MAX_ENDSTOP_Y_CN "Y轴最大限位"
+#define MAX_ENDSTOP_Z_CN "Z轴最大限位"
+#define ENDSTOP_FIL_CN "断料开关类型"
+#define ENDSTOP_LEVEL_CN "调平开关类型"
+#define ENDSTOP_OPENED_CN "常开"
+#define ENDSTOP_CLOSED_CN "常闭"
+
+#define FILAMENT_CONF_TITLE_CN "换料设置"
+#define FILAMENT_IN_LENGTH_CN "进料长度"
+#define FILAMENT_IN_SPEED_CN "进料速度"
+#define FILAMENT_TEMPERATURE_CN "换料温度"
+#define FILAMENT_OUT_LENGTH_CN "退料长度"
+#define FILAMENT_OUT_SPEED_CN "退料速度"
+
+#define LEVELING_CONF_TITLE_CN "机器参数>调平设置"
+#define LEVELING_PARA_CONF_CN "调平设置"
+#define LEVELING_MANUAL_POS_CN "手动调平坐标设置"
+#define LEVELING_AUTO_COMMAND_CN "自动调平指令设置"
+#define LEVELING_AUTO_ZOFFSET_CN "挤出头与调平开关偏移设置"
+
+#define BLTOUCH_LEVELING_TITTLE_CN "机器参数>BL-Touch Probe"
+#define BLTOUCH_LEVELING_CN "BL-Touch Probe"
+#define BLTOUCH_INIT_CN "初始化"
+#define BLTOUCH_ZOFFSETPOS_CN "Zoffset+"
+#define BLTOUCH_ZOFFSETNEG_CN "Zoffset-"
+#define BLTOUCH_SAVE_CN "保存"
+#define BLTOUCH_TEST_CN "测试"
+
+#define LEVELING_TOUCHMI_CN "机器参数>TouchMi-Probe"
+#define TM_INIT_CN "初始化"
+#define TM_ZOFFSETPOS_CN "Zoffset+"
+#define TM_ZOFFSETNEG_CN "Zoffset-"
+#define TM_SAVE_CN "保存"
+#define TM_TEST_CN "测试"
+
+#define LEVELING_PARA_CONF_TITLE_CN "调平参数"
+#define AUTO_LEVELING_ENABLE_CN "自动调平"
+#define BLTOUCH_LEVELING_ENABLE_CN "启动BLtouch"
+#define PROBE_PORT_CN "调平探针接口"
+#define PROBE_X_OFFSET_CN "探针X方向偏移"
+#define PROBE_Y_OFFSET_CN "探针Y方向偏移"
+#define PROBE_Z_OFFSET_CN "探针Z方向偏移"
+#define PROBE_XY_SPEED_CN "探针XY方向移动速度"
+#define PROBE_Z_SPEED_CN "探针Z方向移动速度"
+#define ENABLE_CN "是"
+#define DISABLE_CN "否"
+#define LOCKED_CN "否"
+#define Z_MIN_CN "ZMin"
+#define Z_MAX_CN "ZMax"
+
+#define DELTA_LEVEL_CONF_TITLE_CN "Delta机器参数"
+#define DELTA_LEVEL_CONF_CN "Delta机器调平"
+#define DELTA_MACHINE_RADIUS_CN "机器半径"
+#define DELTA_DIAGONAL_ROD_CN "机器杆长"
+#define DELTA_PRINT_RADIUS_CN "打印半径"
+#define DELTA_HEIGHT_CN "打印高度"
+#define SMOOTH_ROD_OFFSET_CN "滑块偏移"
+#define EFFECTOR_OFFSET_CN "效应器偏移"
+#define CALIBRATION_RADIUS_CN "调平半径"
+
+#define XYZ_LEVEL_CONF_TITLE_CN "XYZ机器参数"
+#define PROBE_REACH_MAX_LEFT_CN "探针达到最左位置"
+#define PROBE_REACH_MAX_RIGHT_CN "探针达到最右位置"
+#define PROBE_REACH_MAX_FRONT_CN "探针达到最前位置"
+#define PROBE_REACH_MAX_BACK_CN "探针达到最后位置"
+
+#define TEMPERATURE_CONF_TITLE_CN "机器参数>温度设置"
+#define NOZZLE_CONF_CN "喷头设置"
+#define HOTBED_CONF_CN "热床设置"
+#define PREHEAT_TEMPER_CN "预设温度"
+
+#define NOZZLE_CONF_TITLE_CN "机器参数>喷头设置"
+#define NOZZLECNT_CN "喷头数量"
+#define NOZZLE_TYPE_CN "E0温感类型"
+#define NOZZLE_ADJUST_TYPE_CN "PID调温"
+#define NOZZLE_MIN_TEMPERATURE_CN "最低温度"
+#define NOZZLE_MAX_TEMPERATURE_CN "最高温度"
+#define EXTRUD_MIN_TEMPER_CN "最低挤出温度"
+
+#define HOTBED_CONF_TITLE_CN "机器参数>热床设置"
+#define HOTBED_ADJUST_CN "PID调温"
+#define HOTBED_MIN_TEMPERATURE_CN "最低温度"
+#define HOTBED_MAX_TEMPERATURE_CN "最高温度"
+
+#define MOTOR_CONF_TITLE_CN "机器参数>电机设置"
+#define MAXFEEDRATE_CONF_CN "最大速度设置"
+#define ACCELERATION_CONF_CN "加速度设置"
+#define JERKCONF_CN "突变速度设置"
+#define STEPSCONF_CN "脉冲设置"
+#define TMC_CURRENT_CN "TMC 驱动电流设置"
+#define TMC_STEP_MODE_CN "TMC 驱动模式设置"
+#define MOTORDIRCONF_CN "电机方向设置"
+#define HOMEFEEDRATECONF_CN "归零速度设置"
+#define HOMING_SENSITIVITY_CONF_CN "无限位回零灵敏度调节"
+
+#define MAXFEEDRATE_CONF_TITLE_CN "机器参数>最大速度"
+#define X_MAXFEEDRATE_CN "X轴最大速度"
+#define Y_MAXFEEDRATE_CN "Y轴最大速度"
+#define Z_MAXFEEDRATE_CN "Z轴最大速度"
+#define E0_MAXFEEDRATE_CN "E0轴最大速度"
+#define E1_MAXFEEDRATE_CN "E1轴最大速度"
+
+#define ACCELERATION_CONF_TITLE_CN "机器参数>加速度"
+#define PRINT_ACCELERATION_CN "打印加速度"
+#define RETRACT_ACCELERATION_CN "回抽加速度"
+#define TRAVEL_ACCELERATION_CN "空载加速度"
+#define X_ACCELERATION_CN "X轴加速度"
+#define Y_ACCELERATION_CN "Y轴加速度"
+#define Z_ACCELERATION_CN "Z轴加速度"
+#define E0_ACCELERATION_CN "E0轴加速度"
+#define E1_ACCELERATION_CN "E1轴加速度"
+
+#define JERK_CONF_TITLE_CN "机器参数>突变速度"
+#define X_JERK_CN "X轴突变速度"
+#define Y_JERK_CN "Y轴突变速度"
+#define Z_JERK_CN "Z轴突变速度"
+#define E_JERK_CN "E轴突变速度"
+
+#define STEPS_CONF_TITLE_CN "机器参数>脉冲设置"
+#define X_STEPS_CN "X轴脉冲"
+#define Y_STEPS_CN "Y轴脉冲"
+#define Z_STEPS_CN "Z轴脉冲"
+#define E0_STEPS_CN "E0轴脉冲"
+#define E1_STEPS_CN "E1轴脉冲"
+
+#define TMC_CURRENT_CONF_TITLE_CN "机器参数>TMC电流设置"
+#define X_TMC_CURRENT_CN "X轴电流(毫安)"
+#define Y_TMC_CURRENT_CN "Y轴电流(毫安)"
+#define Z_TMC_CURRENT_CN "Z轴电流(毫安)"
+#define E0_TMC_CURRENT_CN "E0轴电流(毫安)"
+#define E1_TMC_CURRENT_CN "E1轴电流(毫安)"
+
+#define TMC_MODE_CONF_TITLE_CN "机器参数>TMC模式设置"
+#define X_TMC_MODE_CN "X轴是否使能静音模式"
+#define Y_TMC_MODE_CN "Y轴是否使能静音模式"
+#define Z_TMC_MODE_CN "Z轴是否使能静音模式"
+#define E0_TMC_MODE_CN "E0轴是否使能静音模式"
+#define E1_TMC_MODE_CN "E1轴是否使能静音模式"
+
+#define MOTORDIR_CONF_TITLE_CN "机器参数>电机方向"
+#define X_MOTORDIR_CN "X轴电机方向"
+#define Y_MOTORDIR_CN "Y轴电机方向"
+#define Z_MOTORDIR_CN "Z轴电机方向"
+#define E0_MOTORDIR_CN "E0轴电机方向"
+#define E1_MOTORDIR_CN "E1轴电机方向"
+#define INVERT_P_CN "正向"
+#define INVERT_N_CN "反向"
+
+#define HOMEFEEDRATE_CONF_TITLE_CN "机器参数>归零速度"
+#define X_HOMESPEED_CN "XY轴归零速度"
+#define Y_HOMESPEED_CN "Y轴归零速度"
+#define Z_HOMESPEED_CN "Z轴归零速度"
+
+#define ADVANCED_CONF_TITLE_CN "机器参数>高级设置"
+#define PWROFF_DECTION_CN "断电检测模块"
+#define PWROFF_AFTER_PRINT_CN "启动打完关机功能"
+#define HAVE_UPS_CN "机器配备UPS电源"
+#define Z2_AND_Z2ENDSTOP_CONF_CN "双Z轴双限位功能设置"
+#define ENABLE_PINS_CONF_CN "电机使能脚电平设置"
+#define WIFI_SETTINGS_CN "Wi-Fi参数设置"
+#define ENCODER_SETTINGS_CN "旋钮设置"
+
+#define Z2_AND_Z2ENDSTOP_CONF_TITLE_CN "双z双限位设置"
+#define Z2_ENABLE_CN "启用Z2轴"
+#define Z2_ENDSTOP_CN "启用Z2限位"
+#define Z2_PORT_CN "Z2限位接口"
+
+#define ENABLE_PINS_CONF_TITLE_CN "电机使能脚电平"
+#define X_ENABLE_PINS_INVERT_CN "X轴电机使能电平"
+#define Y_ENABLE_PINS_INVERT_CN "Y轴电机使能电平"
+#define Z_ENABLE_PINS_INVERT_CN "Z轴电机使能电平"
+#define E_ENABLE_PINS_INVERT_CN "E轴电机使能电平"
+
+#define PAUSE_POSITION_CN "打印暂停位置设置"
+#define PAUSE_POSITION_X_CN "X轴暂停位置(绝对位置,-1无效)"
+#define PAUSE_POSITION_Y_CN "Y轴暂停位置(绝对位置,-1无效)"
+#define PAUSE_POSITION_Z_CN "Z轴暂停位置(相对位置,-1无效)"
+#define WIFI_SETTINGS_TITLE_CN "机器参数>Wi-Fi设置"
+#define WIFI_SETTINGS_MODE_CN "Wi-Fi 模式"
+#define WIFI_SETTINGS_NAME_CN "Wi-Fi 名称: "
+#define WIFI_SETTINGS_PASSWORD_CN "Wi-Fi 密码: "
+#define WIFI_SETTINGS_CLOUD_CN "是否使用云服务?"
+#define WIFI_SETTINGS_CONFIG_CN "配置"
+#define WIFI_SETTINGS_EDIT_CN "编辑"
+#define WIFI_CONFIG_TIPS_CN "进行Wi-Fi配置?"
+
+#define OFFSET_TITLE_CN "机器参数>偏移设置"
+#define OFFSET_X_CN "X轴与调平开关偏移"
+#define OFFSET_Y_CN "Y轴与调平开关偏移"
+#define OFFSET_Z_CN "Z轴与调平开关偏移"
+
+#define HOMING_SENSITIVITY_CONF_TITLE_CN "机器参数>灵敏度调节"
+#define X_SENSITIVITY_CN "X轴灵敏度"
+#define Y_SENSITIVITY_CN "Y轴灵敏度"
+#define Z_SENSITIVITY_CN "Z轴灵敏度"
+#define Z2_SENSITIVITY_CN "Z2轴灵敏度"
+
+#define ENCODER_CONF_TITLE_CN "机器参数>旋钮设置"
+#define ENCODER_CONF_TEXT_CN "是否使用旋钮功能?"
+
+#define TOOL_TEXT_CN "工具"
+#define PREHEAT_TEXT_CN "预热"
+#define MOVE_TEXT_CN "移动"
+#define HOME_TEXT_CN "回零"
+#define PRINT_TEXT_CN "打印"
+#define EXTRUDE_TEXT_CN "挤出"
+#define LEVELING_TEXT_CN "调平"
+#define AUTO_LEVELING_TEXT_CN "自动调平"
+#define SET_TEXT_CN "设置"
+#define MORE_TEXT_CN "更多"
+
+#define ADD_TEXT_CN "增加"
+#define DEC_TEXT_CN "减少"
+#define EXTRUDER_1_TEXT_CN "喷头1"
+#define EXTRUDER_2_TEXT_CN "喷头2"
+#define HEATBED_TEXT_CN "热床"
+#define TEXT_1C_CN "1℃"
+#define TEXT_5C_CN "5℃"
+#define TEXT_10C_CN "10℃"
+#define CLOSE_TEXT_CN "关闭"
+
+#define BACK_TEXT_CN "返回"
+
+#define TOOL_PREHEAT_CN "预热"
+#define TOOL_EXTRUDE_CN "挤出"
+#define TOOL_MOVE_CN "移动"
+#define TOOL_HOME_CN "回零"
+#define TOOL_LEVELING_CN "调平"
+#define TOOL_AUTO_LEVELING_CN "自动调平"
+#define TOOL_FILAMENT_CN "换料"
+#define TOOL_MORE_CN "更多"
+
+#define AXIS_X_ADD_TEXT_CN "X+"
+#define AXIS_X_DEC_TEXT_CN "X-"
+#define AXIS_Y_ADD_TEXT_CN "Y+"
+#define AXIS_Y_DEC_TEXT_CN "Y-"
+#define AXIS_Z_ADD_TEXT_CN "Z+"
+#define AXIS_Z_DEC_TEXT_CN "Z-"
+#define TEXT_01MM_CN "0.1mm"
+#define TEXT_1MM_CN "1mm"
+#define TEXT_10MM_CN "10mm"
+
+#define HOME_X_TEXT_CN "X"
+#define HOME_Y_TEXT_CN "Y"
+#define HOME_Z_TEXT_CN "Z"
+#define HOME_ALL_TEXT_CN "回零"
+#define HOME_STOPMOVE_CN "急停"
+
+#define PAGE_UP_TEXT_CN "上一页"
+#define PAGE_DOWN_TEXT_CN "下一页"
+
+#define EXTRUDER_IN_TEXT_CN "进料"
+#define EXTRUDER_OUT_TEXT_CN "退料"
+#define EXTRUDE_1MM_TEXT_CN "1mm"
+#define EXTRUDE_5MM_TEXT_CN "5mm"
+#define EXTRUDE_10MM_TEXT_CN "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_CN "低速"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_CN "常速"
+#define EXTRUDE_HIGH_SPEED_TEXT_CN "高速"
+
+#define LEVELING_POINT1_TEXT_CN "第一点"
+#define LEVELING_POINT2_TEXT_CN "第二点"
+#define LEVELING_POINT3_TEXT_CN "第三点"
+#define LEVELING_POINT4_TEXT_CN "第四点"
+#define LEVELING_POINT5_TEXT_CN "第五点"
+
+#define FILESYS_TEXT_CN "文件系统"
+#define WIFI_TEXT_CN "WIFI"
+#define FAN_TEXT_CN "风扇"
+#define ABOUT_TEXT_CN "关于"
+#define BREAK_POINT_TEXT_CN "断点续打"
+#define FILAMENT_TEXT_CN "换料"
+#define LANGUAGE_TEXT_CN "语言"
+#define MOTOR_OFF_TEXT_CN "关闭电机"
+#define MOTOR_OFF_XY_TEXT_CN "关闭XY"
+#define SHUTDOWN_TEXT_CN "关机"
+#define MACHINE_PARA_CN "机器参数"
+#define EEPROM_SETTINGS_CN "Eeprom设置"
+
+#define U_DISK_TEXT_CN "U盘"
+#define SD_CARD_TEXT_CN "SD卡"
+#define WIFI_NAME_TEXT_CN "无线网络:"
+#define WIFI_KEY_TEXT_CN "密码: "
+#define WIFI_IP_TEXT_CN "IP: "
+#define WIFI_AP_TEXT_CN "状态: AP"
+#define WIFI_STA_TEXT_CN "状态: STA"
+#define WIFI_CONNECTED_TEXT_CN "已连接"
+#define WIFI_DISCONNECTED_TEXT_CN "未连接"
+#define WIFI_EXCEPTION_TEXT_CN "模块异常"
+#define CLOUD_TEXT_CN "云服务"
+#define CLOUD_BIND_CN "已绑定"
+#define CLOUD_UNBIND_CN "解绑"
+#define CLOUD_UNBINDING_CN "解绑中"
+#define CLOUD_DISCONNECTED_CN "未连接"
+#define CLOUD_UNBINDED_CN "未绑定"
+#define CLOUD_BINDED_CN "已绑定"
+#define CLOUD_DISABLE_CN "已禁用"
+
+#define FAN_ADD_TEXT_CN "增加"
+#define FAN_DEC_TEXT_CN "减少"
+#define FAN_OPEN_TEXT_CN "100%"
+#define FAN_HALF_TEXT_CN "50%"
+#define FAN_CLOSE_TEXT_CN "关闭"
+#define FAN_TIPS1_TEXT_CN "风扇"
+#define FAN_TIPS2_TEXT_CN "FAN\nClose"
+
+#define FILAMENT_IN_TEXT_CN "进料"
+#define FILAMENT_OUT_TEXT_CN "退料"
+#define FILAMENT_EXT0_TEXT_CN "喷头1"
+#define FILAMENT_EXT1_TEXT_CN "喷头2"
+#define FILAMENT_HEAT_TEXT_CN "预热"
+#define FILAMENT_STOP_TEXT_CN "停止"
+#define FILAMENT_CHANGE_TEXT_CN "待打印机暂停后,\n请按<进料>或<退料>"
+
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_CN "准备进料,正在加热,请稍等!"
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_CN "准备退料,正在加热,请稍等!"
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_CN "加热完成,请装载耗材后,按<确定>开始进料!"
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_CN "请装载耗材,按<确定>开始进料!"
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_CN "加热完成,请按<确定>开始退料!"
+#define FILAMENT_DIALOG_LOADING_TIPS_CN "正在进料,请等待耗材加载完成!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_CN "正在退料,请等待耗材卸载完成!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_CN "进料完成,请按<确定>返回"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_CN "退料完成,请按<确定>返回"
+
+#define FILAMENT_TIPS3_TEXT_CN "正在进料"
+#define FILAMENT_TIPS4_TEXT_CN "正在退料"
+#define FILAMENT_TIPS5_TEXT_CN "温度太低,请先预热"
+#define FILAMENT_TIPS6_TEXT_CN "换料完成"
+
+#define PRE_HEAT_EXT_TEXT_CN "喷头"
+#define PRE_HEAT_BED_TEXT_CN "热床"
+
+#define FILE_LOADING_CN "正在载入......"
+#define NO_FILE_AND_CHECK_CN "无文件!请插入sd卡或u盘!"
+#define NO_FILE_CN "无文件!"
+
+#define EXTRUDER_TEMP_TEXT_CN "温度"
+#define EXTRUDER_E_LENGTH1_TEXT_CN "喷头"
+#define EXTRUDER_E_LENGTH2_TEXT_CN "喷头"
+#define EXTRUDER_E_LENGTH3_TEXT_CN "喷头"
+
+#define ABOUT_TYPE_TEXT_CN "Type: "
+#define ABOUT_VERSION_TEXT_CN "Firmware: "
+#define ABOUT_WIFI_TEXT_CN "Wifi: "
+
+#define PRINTING_OPERATION_CN "操作"
+#define PRINTING_PAUSE_CN "暂停"
+#define PRINTING_TEMP_CN "温度"
+#define PRINTING_CHANGESPEED_CN "变速"
+#define PRINTING_RESUME_CN "恢复"
+#define PRINTING_STOP_CN "停止"
+#define PRINTING_MORE_CN "更多"
+#define PRINTING_EXTRUDER_CN "挤出"
+#define PRINTING_MOVE_CN "移动"
+
+#define EXTRUDER_SPEED_CN "挤出"
+#define MOVE_SPEED_CN "移动"
+#define EXTRUDER_SPEED_STATE_CN "挤出速度"
+#define MOVE_SPEED_STATE_CN "移动速度"
+#define STEP_1PERCENT_CN "1%"
+#define STEP_5PERCENT_CN "5%"
+#define STEP_10PERCENT_CN "10%"
+
+#define TITLE_READYPRINT_CN "准备打印"
+#define TITLE_PREHEAT_CN "预热"
+#define TITLE_MOVE_CN "移动"
+#define TITLE_HOME_CN "回零"
+#define TITLE_EXTRUDE_CN "挤出"
+#define TITLE_LEVELING_CN "调平"
+#define TITLE_SET_CN "设置"
+#define TITLE_MORE_CN "更多"
+#define TITLE_CHOOSEFILE_CN "选择文件"
+#define TITLE_PRINTING_CN "正在打印"
+#define TITLE_OPERATION_CN "操作"
+#define TITLE_ADJUST_CN "调整"
+#define TITLE_WIRELESS_CN "无线网络"
+#define TITLE_FILAMENT_CN "换料"
+#define TITLE_ABOUT_CN "关于"
+#define TITLE_FAN_CN "风扇"
+#define TITLE_LANGUAGE_CN "语言"
+#define TITLE_PAUSE_CN "暂停"
+#define TITLE_CHANGESPEED_CN "变速"
+#define TITLE_CLOUD_TEXT_CN "云服务"
+#define TITLE_DIALOG_CONFIRM_CN "确认"
+#define TITLE_FILESYS_CN "文件系统"
+
+#define AUTO_SHUTDOWN_CN "自动关机"
+#define MANUAL_SHUTDOWN_CN "手动关机"
+
+#define DIALOG_CONFIRM_CN "确定"
+#define DIALOG_CANCLE_CN "取消"
+#define DIALOG_OK_CN "确认"
+#define DIALOG_RESET_CN "重置"
+#define DIALOG_DISABLE_CN "禁用"
+#define DIALOG_PRINT_MODEL_CN "打印模型?"
+#define DIALOG_CANCEL_PRINT_CN "停止打印?"
+#define DIALOG_RETRY_CN "重试"
+#define DIALOG_STOP_CN "停止"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_CN "从断点续打?"
+#define DIALOG_ERROR_TIPS1_CN "错误:找不到文件,请插入sd卡/u盘!"
+#define DIALOG_ERROR_TIPS2_CN "错误:通信失败,请检查波特率或主板硬件!"
+#define DIALOG_ERROR_TIPS3_CN "错误:文件名或文件路径太长 !"
+#define DIALOG_CLOSE_MACHINE_CN "正在关机......"
+#define DIALOG_UNBIND_PRINTER_CN "解除绑定?"
+#define DIALOG_FILAMENT_NO_PRESS_CN "请先装载耗材!"
+#define DIALOG_PRINT_FINISH_CN "打印完成!"
+#define DIALOG_PRINT_TIME_CN "打印时间: "
+#define DIALOG_REPRINT_CN "再打印一次"
+#define DIALOG_WIFI_ENABLE_TIPS_CN "wifi模块正在配置中,请稍等......"
+#define DIALOG_PAUSING_TIPS_CN "机器暂停中..."
+
+#define TEXT_VALUE_CN "%d℃/%d℃"
+#define EXTRUDE_TEXT_VALUE_T_CN ": %d℃"
+#define WIFI_RECONNECT_TEXT_CN "重新连接"
+
+#define PRINTING_GBK "正在打印"
+#define PRINTING_OPERATION_GBK "操作"
+#define PRINTING_PAUSE_GBK "暂停"
+
+#define MESSAGE_PAUSING_CN "暂停中..."
+#define MESSAGE_CHANGING_CN "等待换料开始..."
+#define MESSAGE_UNLOAD_CN "退料中,请稍等..."
+#define MESSAGE_WAITING_CN "点击按钮恢复打印"
+#define MESSAGE_INSERT_CN "装载耗材后,点击按钮开始打印"
+#define MESSAGE_LOAD_CN "进料中,请稍等..."
+#define MESSAGE_PURGE_CN "等待挤出..."
+#define MESSAGE_RESUME_CN "等待恢复打印..."
+#define MESSAGE_HEAT_CN "按下按钮,加热喷头"
+#define MESSAGE_HEATING_CN "喷头加热中,请等待..."
+#define MESSAGE_OPTION_CN "挤出更多还是继续打印?"
+#define MESSAGE_PURGE_MORE_CN "挤出"
+#define MESSAGE_CONTINUE_PRINT_CN "打印"
+#define EEPROM_SETTINGS_TITLE_CN "EEPROM 设置"
+#define EEPROM_SETTINGS_STORE_CN "保存参数至EEPROM"
+#define EEPROM_SETTINGS_READ_CN "读取EEPROM参数"
+#define EEPROM_SETTINGS_REVERT_CN "恢复默认参数"
+
+#define EEPROM_STORE_TIPS_CN "是否保存参数到EEPROM?"
+#define EEPROM_READ_TIPS_CN "是否使用EEPROM参数?"
+#define EEPROM_REVERT_TIPS_CN "是否恢复默认参数?"
+
+#define MORE_CUSTOM1_TEXT_CN USER_DESC_1
+#define MORE_CUSTOM2_TEXT_CN USER_DESC_2
+#define MORE_CUSTOM3_TEXT_CN USER_DESC_3
+#define MORE_CUSTOM4_TEXT_CN USER_DESC_4
+#define MORE_CUSTOM5_TEXT_CN USER_DESC_5
+#define MORE_CUSTOM6_TEXT_CN USER_DESC_6
+#define MORE_CUSTOM7_TEXT_CN USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h
new file mode 100644
index 0000000..675af55
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_sp.h
@@ -0,0 +1,274 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//****************西班牙语***************************
+#define TOOL_TEXT_SP "Ajustes"
+#define PREHEAT_TEXT_SP "Precalentar"
+#define MOVE_TEXT_SP "Mover"
+#define HOME_TEXT_SP "Origen"
+#define PRINT_TEXT_SP "Imprimir"
+#define EXTRUDE_TEXT_SP "Extrusor"
+#define LEVELING_TEXT_SP "Leveling"
+#define MLEVELING_TEXT_SP "Leveling"
+#define AUTO_LEVELING_TEXT_SP "Autolevel"
+#define SET_TEXT_SP "Config"
+#define MORE_TEXT_SP "Más"
+
+#define ADD_TEXT_SP "Más"
+#define DEC_TEXT_SP "Menos"
+#define EXTRUDER_1_TEXT_SP "Extrusor1: "
+#define EXTRUDER_2_TEXT_SP "Extrusor2: "
+#define HEATBED_TEXT_SP "Cama: "
+#define TEXT_1C_SP "1℃"
+#define TEXT_5C_SP "5℃"
+#define TEXT_10C_SP "10℃"
+#define CLOSE_TEXT_SP "Apagar"
+
+#define BACK_TEXT_SP "Atrás"
+
+#define TOOL_PREHEAT_SP "Precalentar"
+#define TOOL_EXTRUDE_SP "Extrusor"
+#define TOOL_MOVE_SP "Mover"
+#define TOOL_HOME_SP "Origen"
+#define TOOL_LEVELING_SP "Leveling"
+#define TOOL_MLEVELING_SP "Leveling"
+#define TOOL_AUTO_LEVELING_SP "Autolevel"
+#define TOOL_FILAMENT_SP "Filamento"
+#define TOOL_MORE_SP "Más"
+
+#define AXIS_X_ADD_TEXT_SP "X+"
+#define AXIS_X_DEC_TEXT_SP "X-"
+#define AXIS_Y_ADD_TEXT_SP "Y+"
+#define AXIS_Y_DEC_TEXT_SP "Y-"
+#define AXIS_Z_ADD_TEXT_SP "Z+"
+#define AXIS_Z_DEC_TEXT_SP "Z-"
+#define TEXT_01MM_SP "0.1mm"
+#define TEXT_1MM_SP "1mm"
+#define TEXT_10MM_SP "10mm"
+
+#define HOME_X_TEXT_SP "EJE X"
+#define HOME_Y_TEXT_SP "EJE Y"
+#define HOME_Z_TEXT_SP "EJE Z"
+#define HOME_ALL_TEXT_SP "TODOS"
+#define HOME_STOPMOVE_SP "Quickstop"
+
+#define PAGE_UP_TEXT_SP "Arriba"
+#define PAGE_DOWN_TEXT_SP "Abajo"
+
+#define EXTRUDER_IN_TEXT_SP "Dentro"
+#define EXTRUDER_OUT_TEXT_SP "Fuera"
+#define EXTRUDE_1MM_TEXT_SP "1mm"
+#define EXTRUDE_5MM_TEXT_SP "5mm"
+#define EXTRUDE_10MM_TEXT_SP "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_SP "Baja"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_SP "Media"
+#define EXTRUDE_HIGH_SPEED_TEXT_SP "Alta"
+
+#define LEVELING_POINT1_TEXT_SP "Primero"
+#define LEVELING_POINT2_TEXT_SP "Segundo"
+#define LEVELING_POINT3_TEXT_SP "Tercero"
+#define LEVELING_POINT4_TEXT_SP "Cuarto"
+#define LEVELING_POINT5_TEXT_SP "Quinto"
+
+#define FILESYS_TEXT_SP "Puerto"
+#define WIFI_TEXT_SP "WiFi"
+#define FAN_TEXT_SP "Ventilador"
+#define ABOUT_TEXT_SP "Acerca"
+#define BREAK_POINT_TEXT_SP "Continuar"
+#define FILAMENT_TEXT_SP "Filamento"
+#define LANGUAGE_TEXT_SP "Language"
+#define MOTOR_OFF_TEXT_SP "Apagar motor"
+#define MOTOR_OFF_XY_TEXT_SP "Off-XY"
+#define SHUTDOWN_TEXT_SP "Apagar"
+#define MACHINE_PARA_SP "Config"
+#define EEPROM_SETTINGS_SP "Eeprom Set"
+
+#define U_DISK_TEXT_SP "PENDRIVE"
+#define SD_CARD_TEXT_SP "SD"
+#define WIFI_NAME_TEXT_SP "WIFI: "
+#define WIFI_KEY_TEXT_SP "Contraseña: "
+#define WIFI_IP_TEXT_SP "IP: "
+#define WIFI_AP_TEXT_SP "Estado: AP"
+#define WIFI_STA_TEXT_SP "Estado: STA"
+#define WIFI_CONNECTED_TEXT_SP "Conectado"
+#define WIFI_DISCONNECTED_TEXT_SP "Desconectado"
+#define WIFI_EXCEPTION_TEXT_SP "Excepción"
+#define WIFI_RECONNECT_TEXT_SP "Reconnect"
+#define CLOUD_TEXT_SP "Nube"
+#define CLOUD_BIND_SP "Atado"
+#define CLOUD_UNBIND_SP "Sin atar"
+#define CLOUD_UNBINDING_SP "Unbinding"
+#define CLOUD_DISCONNECTED_SP "Disconnected"
+#define CLOUD_UNBINDED_SP "Unbinded"
+#define CLOUD_BINDED_SP "Binded"
+#define CLOUD_DISABLE_SP "Disable"
+
+#define FAN_ADD_TEXT_SP "Más"
+#define FAN_DEC_TEXT_SP "Menos"
+#define FAN_OPEN_TEXT_SP "100%"
+#define FAN_HALF_TEXT_SP "50%"
+#define FAN_CLOSE_TEXT_SP "0%"
+#define FAN_TIPS1_TEXT_SP "ventilador"
+#define FAN_TIPS2_TEXT_SP "ventilador\n0"
+
+#define FILAMENT_IN_TEXT_SP "Dentro"
+#define FILAMENT_OUT_TEXT_SP "Fuera"
+#define FILAMENT_EXT0_TEXT_SP "Extrusor1"
+#define FILAMENT_EXT1_TEXT_SP "Extrusor2"
+#define FILAMENT_HEAT_TEXT_SP "Precalentar"
+#define FILAMENT_STOP_TEXT_SP "Parar"
+#define FILAMENT_TIPS2_TEXT_SP "T:"
+#define FILAMENT_TIPS3_TEXT_SP "Dentro..."
+#define FILAMENT_TIPS4_TEXT_SP "Fuera..."
+#define FILAMENT_TIPS5_TEXT_SP "Temperatura demasiado baja, por favor calentar"
+#define FILAMENT_TIPS6_TEXT_SP "Completado"
+
+#define FILAMENT_CHANGE_TEXT_SP "Please click <Load> \nor <unload>,After \npinter pause."
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_SP "Calentando el extrusor,\npor favor espere..."
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_SP "Calentando el extrusor,\npor favor espere..."
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_SP "Temperatura alcanzada.Inserte el \nfilamento y luego presione\"Confirmar\"\npara comenzar la carga."
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_SP "Inserte el filamento y \nluego presione\"Confirmar\"para \ncomenzar la carga."
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_SP "Temperatura alcanzada.\nPresione\"Confirmar\"para retirar \nel filamento."
+#define FILAMENT_DIALOG_LOADING_TIPS_SP "Cargando filamento,\npor favor espere."
+#define FILAMENT_DIALOG_UNLOADING_TIPS_SP "Retirando filamento,\npor favor espere."
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_SP "Filamento cargado,\npresione\"Confirmar\"."
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_SP "Filamento retirado,\npresione\"Confirmar\"."
+
+#define PRE_HEAT_EXT_TEXT_SP "Extrusor"
+#define PRE_HEAT_BED_TEXT_SP "cama"
+
+#define FILE_LOADING_SP "Cargando......"
+#define NO_FILE_AND_CHECK_SP "Archivo no encontrado,\n por favor insertar SD o disco USB!"
+#define NO_FILE_SP "Sin archivo!"
+
+#define EXTRUDER_TEMP_TEXT_SP "Temper"
+#define EXTRUDER_E_LENGTH1_TEXT_SP "Extrusor1"
+#define EXTRUDER_E_LENGTH2_TEXT_SP "Extrusor2"
+#define EXTRUDER_E_LENGTH3_TEXT_SP "Extrusor3"
+
+#define ABOUT_TYPE_TEXT_SP "Pantalla: "
+#define ABOUT_VERSION_TEXT_SP "Firmware: "
+#define ABOUT_WIFI_TEXT_SP "WiFi: "
+
+#define PRINTING_OPERATION_SP "Ajustes"
+#define PRINTING_PAUSE_SP "Pausar"
+#define PRINTING_TEMP_SP "Temp."
+#define PRINTING_CHANGESPEED_SP "Velocidad"
+#define PRINTING_RESUME_SP "Resumir"
+#define PRINTING_STOP_SP "Detener"
+#define PRINTING_MORE_SP "Más"
+#define PRINTING_EXTRUDER_SP "Extrusor"
+#define PRINTING_MOVE_SP "Mover"
+
+#define EXTRUDER_SPEED_SP "Extrusor"
+#define MOVE_SPEED_SP "Mover"
+#define EXTRUDER_SPEED_STATE_SP "Extrusión"
+#define MOVE_SPEED_STATE_SP "Movimiento"
+#define STEP_1PERCENT_SP "1%"
+#define STEP_5PERCENT_SP "5%"
+#define STEP_10PERCENT_SP "10%"
+
+#define TITLE_READYPRINT_SP "Inicio"
+#define TITLE_PREHEAT_SP "Precalentar"
+#define TITLE_MOVE_SP "Mover"
+#define TITLE_HOME_SP "Origen"
+#define TITLE_EXTRUDE_SP "Extrusor"
+#define TITLE_LEVELING_SP "Leveling"
+#define TITLE_SET_SP "Config"
+#define TITLE_MORE_SP "Más"
+#define TITLE_CHOOSEFILE_SP "Imprimir"
+#define TITLE_PRINTING_SP "Imprimir"
+#define TITLE_OPERATION_SP "Ajustes"
+#define TITLE_ADJUST_SP "Temp."
+#define TITLE_WIRELESS_SP "Wireless"
+#define TITLE_FILAMENT_SP "Filamento"
+#define TITLE_ABOUT_SP "Acerca"
+#define TITLE_FAN_SP "Ventilador"
+#define TITLE_LANGUAGE_SP "Language"
+#define TITLE_PAUSE_SP "Pausar"
+#define TITLE_CHANGESPEED_SP "Velocidad"
+#define TILE_TOOL_SP "Ajustes"
+#define TITLE_CLOUD_TEXT_SP "Cloud"
+#define TITLE_DIALOG_CONFIRM_SP "Confirmar"
+#define TITLE_FILESYS_SP "Puerto"
+
+#define AUTO_SHUTDOWN_SP "Auto"
+#define MANUAL_SHUTDOWN_SP "manual"
+
+#define DIALOG_CONFIRM_SP "Confirmar"
+#define DIALOG_CANCLE_SP "Cancelar"
+#define DIALOG_OK_SP "OK"
+#define DIALOG_RESET_SP "Resetear"
+#define DIALOG_RETRY_SP "Reintentar"
+#define DIALOG_DISABLE_SP "Desactivar"
+#define DIALOG_PRINT_MODEL_SP "¿Está seguro?"
+#define DIALOG_CANCEL_PRINT_SP "¿Está seguro que desea detener la impresión?"
+
+#define DIALOG_RETRY_SP "Reintentar"
+#define DIALOG_STOP_SP "Stop"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_SP "Reprint from breakpoint?"
+#define DIALOG_ERROR_TIPS1_SP "Error:archivo no encontrado, \npor favor insertar SD o disco USB."
+#define DIALOG_ERROR_TIPS2_SP "error:transacción fallida, \nconfigurar baudrate del \ndisplay para la placa base!"
+#define DIALOG_ERROR_TIPS3_SP "Error : nombre de archivo o \nruta demasiado largo!"
+#define DIALOG_CLOSE_MACHINE_SP "Closing machine......"
+#define DIALOG_UNBIND_PRINTER_SP "Unbind the printer?"
+#define DIALOG_FILAMENT_NO_PRESS_SP "Filament detection switch is not pressed"
+#define DIALOG_PRINT_FINISH_SP "¡La impresión está completa!"
+#define DIALOG_PRINT_TIME_SP "Tiempo de impresión: "
+#define DIALOG_REPRINT_SP "Print again"
+#define DIALOG_WIFI_ENABLE_TIPS_SP "The wifi module is being configured,\nplease wait a moment....."
+#define DIALOG_PAUSING_TIPS_SP "La máquina se detiene ..."
+
+#define PRINTING_SP "Imprimiendo"
+#define PRINTING_AJUSTES_SP "Ajustes"
+#define PRINTING_PAUSAR_SP "Pausar"
+
+#define MESSAGE_PAUSING_SP "Aparcando..."
+#define MESSAGE_CHANGING_SP "Esperando para iniciar el cambio de filamento"
+#define MESSAGE_UNLOAD_SP "Espere para liberar el filamento"
+#define MESSAGE_WAITING_SP "Pulsar el botón para reanudar impresión"
+#define MESSAGE_INSERT_SP "Inserte el filamento y pulse el botón para continuar..."
+#define MESSAGE_LOAD_SP "Espere para purgar el filamento"
+#define MESSAGE_PURGE_SP "Espere para purgar el filamento"
+#define MESSAGE_RESUME_SP "Esperando impresora para reanudar..."
+#define MESSAGE_HEAT_SP "Pulse el botón para calentar la boquilla"
+#define MESSAGE_HEATING_SP "Calentando boquilla Espere por favor..."
+#define MESSAGE_OPTION_SP "¿Purgar más o continuar con la impresión?"
+#define MESSAGE_PURGE_MORE_SP "Purga"
+#define MESSAGE_CONTINUE_PRINT_SP "Impresión"
+#define EEPROM_SETTINGS_TITLE_SP "Configuraciones EEPROM"
+#define EEPROM_SETTINGS_STORE_SP "Guardar configuración en EEPROM"
+#define EEPROM_SETTINGS_READ_SP "Leer la configuración de EEPROM"
+#define EEPROM_SETTINGS_REVERT_SP "Revert settings to factory defaults"
+
+#define EEPROM_STORE_TIPS_SP "¿Guardar ajustes en EEPROM?"
+#define EEPROM_READ_TIPS_SP "Leer la configuración de EEPROM?"
+#define EEPROM_REVERT_TIPS_SP "Revert settings to factory defaults?"
+
+#define MORE_CUSTOM1_TEXT_SP USER_DESC_1
+#define MORE_CUSTOM2_TEXT_SP USER_DESC_2
+#define MORE_CUSTOM3_TEXT_SP USER_DESC_3
+#define MORE_CUSTOM4_TEXT_SP USER_DESC_4
+#define MORE_CUSTOM5_TEXT_SP USER_DESC_5
+#define MORE_CUSTOM6_TEXT_SP USER_DESC_6
+#define MORE_CUSTOM7_TEXT_SP USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h
new file mode 100644
index 0000000..e97c63c
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_Language_t_cn.h
@@ -0,0 +1,515 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+//***************繁体中文**********************//
+#define NEXT_T_CN "下一頁"
+#define PREVIOUS_T_CN "上一頁"
+#define DEFAULT_T_CN "默認值"
+#define KEY_BACK_T_CN "退格"
+#define KEY_REST_T_CN "重置"
+#define KEY_CONFIRM_T_CN "確定"
+
+#define MACHINE_PARA_TITLE_T_CN "機器參數"
+#define MACHINE_TYPE_CNOFIG_T_CN "機器設置"
+#define MOTOR_CONFIG_T_CN "電機設置"
+#define MACHINE_LEVELING_CONFIG_T_CN "調平設置"
+#define ADVANCE_CONFIG_T_CN "高級設置"
+
+#define MACHINE_CONFIG_TITLE_T_CN "機器參數>機器配置"
+#define MACHINE_TYPE_T_CN "機型選擇"
+#define MACHINE_STROKE_T_CN "行程設置"
+#define MACHINE_HOMEDIR_T_CN "歸零方向"
+#define MACHINE_ENDSTOP_TYPE_T_CN "限位開關類型"
+#define MACHINE_FILAMENT_CONFIG_T_CN "換料設置"
+
+#define MACHINE_TYPE_CONFIG_TITLE_T_CN "機器參數>機型選擇"
+#define MACHINE_TYPE_XYZ_T_CN "XYZ機型"
+#define MACHINE_TYPE_DELTA_T_CN "Delta機型"
+#define MACHINE_TYPE_COREXY_T_CN "Corexy機型"
+
+#define MACHINE_STROKE_CONF_TITLE_T_CN "機器參數>機器行程"
+#define X_MAX_LENGTH_T_CN "X軸最大行程"
+#define Y_MAX_LENGTH_T_CN "Y軸最大行程"
+#define Z_MAX_LENGTH_T_CN "Z軸最大行程"
+
+#define X_MIN_LENGTH_T_CN "X軸最小行程"
+#define Y_MIN_LENGTH_T_CN "Y軸最小行程"
+#define Z_MIN_LENGTH_T_CN "Z軸最小行程"
+
+#define HOME_DIR_CONF_TITLE_T_CN "機器參數>歸零方向"
+#define HOME_DIR_X_T_CN "X軸歸零方向"
+#define HOME_DIR_Y_T_CN "Y軸歸零方向"
+#define HOME_DIR_Z_T_CN "Z軸歸零方向"
+#define HOME_MIN_T_CN "MIN"
+#define HOME_MAX_T_CN "MAX"
+
+#define ENDSTOP_CONF_TITLE_T_CN "機器參數>限位開關"
+#define MIN_ENDSTOP_X_T_CN "X軸最小限位"
+#define MIN_ENDSTOP_Y_T_CN "Y軸最小限位"
+#define MIN_ENDSTOP_Z_T_CN "Z軸最小限位"
+#define MAX_ENDSTOP_X_T_CN "X軸最大限位"
+#define MAX_ENDSTOP_Y_T_CN "Y軸最大限位"
+#define MAX_ENDSTOP_Z_T_CN "Z軸最大限位"
+#define ENDSTOP_FIL_T_CN "斷料開關類型"
+#define ENDSTOP_LEVEL_T_CN "調平開關類型"
+#define ENDSTOP_OPENED_T_CN "常開"
+#define ENDSTOP_CLOSED_T_CN "常閉"
+
+#define FILAMENT_CONF_TITLE_T_CN "換料設置"
+#define FILAMENT_IN_LENGTH_T_CN "進料長度"
+#define FILAMENT_IN_SPEED_T_CN "進料速度"
+#define FILAMENT_TEMPERATURE_T_CN "換料溫度"
+#define FILAMENT_OUT_LENGTH_T_CN "退料長度"
+#define FILAMENT_OUT_SPEED_T_CN "退料速度"
+
+#define LEVELING_CONF_TITLE_T_CN "機器參數>調平設置"
+#define LEVELING_PARA_CONF_T_CN "調平設置"
+#define LEVELING_MANUAL_POS_T_CN "手動調平坐標設置"
+#define LEVELING_AUTO_COMMAND_T_CN "自動調平指令設置"
+#define LEVELING_AUTO_ZOFFSET_T_CN "擠出頭與調平開關偏移設置"
+#define LEVELING_TOUCHMI_T_CN "機器參數>TouchMi-Probe"
+#define TM_INIT_T_CN "初始化"
+#define TM_ZOFFSETPOS_T_CN "Zoffset+"
+#define TM_ZOFFSETNEG_T_CN "Zoffset-"
+#define TM_SAVE_T_CN "保存"
+#define TM_TEST_T_CN "測試"
+
+#define BLTOUCH_LEVELING_TITTLE_T_CN "機器參數>BL-Touch Probe"
+#define BLTOUCH_LEVELING_T_CN "BL-Touch Probe"
+#define BLTOUCH_INIT_T_CN "初始化"
+#define BLTOUCH_ZOFFSETPOS_T_CN "Zoffset+"
+#define BLTOUCH_ZOFFSETNEG_T_CN "Zoffset-"
+#define BLTOUCH_SAVE_T_CN "保存"
+#define BLTOUCH_TEST_T_CN "測試"
+
+#define LEVELING_PARA_CONF_TITLE_T_CN "調平參數"
+#define AUTO_LEVELING_ENABLE_T_CN "自動調平"
+#define BLTOUCH_LEVELING_ENABLE_T_CN "啟動BLtouch"
+#define PROBE_PORT_T_CN "調平探針接口"
+#define PROBE_X_OFFSET_T_CN "探針X方向偏移"
+#define PROBE_Y_OFFSET_T_CN "探针Y方向偏移"
+#define PROBE_Z_OFFSET_T_CN "探针Z方向偏移"
+#define PROBE_XY_SPEED_T_CN "探针XY方向移動速度"
+#define PROBE_Z_SPEED_T_CN "探针Z方向移動速度"
+#define ENABLE_T_CN "是"
+#define DISABLE_T_CN "否"
+#define LOCKED_T_CN "否"
+#define Z_MIN_T_CN "ZMin"
+#define Z_MAX_T_CN "ZMax"
+
+#define DELTA_LEVEL_CONF_TITLE_T_CN "Delta機器參數"
+#define DELTA_LEVEL_CONF_T_CN "Delta機器調平"
+#define DELTA_MACHINE_RADIUS_T_CN "機器半徑"
+#define DELTA_DIAGONAL_ROD_T_CN "機器桿長"
+#define DELTA_PRINT_RADIUS_T_CN "打印半徑"
+#define DELTA_HEIGHT_T_CN "打印高度"
+#define SMOOTH_ROD_OFFSET_T_CN "滑塊偏移"
+#define EFFECTOR_OFFSET_T_CN "效應器偏移"
+#define CALIBRATION_RADIUS_T_CN "調平半徑"
+
+#define XYZ_LEVEL_CONF_TITLE_T_CN "XYZ機器參數"
+#define PROBE_REACH_MAX_LEFT_T_CN "探针達到最左位置"
+#define PROBE_REACH_MAX_RIGHT_T_CN "探针達到最右位置"
+#define PROBE_REACH_MAX_FRONT_T_CN "探针達到最前位置"
+#define PROBE_REACH_MAX_BACK_T_CN "探针達到最後位置"
+
+#define TEMPERATURE_CONF_TITLE_T_CN "機器參數>溫度設置"
+#define NOZZLE_CONF_T_CN "噴頭設置"
+#define HOTBED_CONF_T_CN "熱床設置"
+#define PREHEAT_TEMPER_T_CN "預設溫度"
+
+#define NOZZLE_CONF_TITLE_T_CN "機器參數>噴頭設置"
+#define NOZZLECNT_T_CN "噴頭數量"
+#define NOZZLE_TYPE_T_CN "E0溫感類型"
+#define NOZZLE_ADJUST_TYPE_T_CN "PID調溫"
+#define NOZZLE_MIN_TEMPERATURE_T_CN "最低溫度"
+#define NOZZLE_MAX_TEMPERATURE_T_CN "最高溫度"
+#define EXTRUD_MIN_TEMPER_T_CN "最低擠出溫度"
+
+#define HOTBED_CONF_TITLE_T_CN "機器參數>熱床設置"
+#define HOTBED_ADJUST_T_CN "PID調溫"
+#define HOTBED_MIN_TEMPERATURE_T_CN "最低溫度"
+#define HOTBED_MAX_TEMPERATURE_T_CN "最高溫度"
+
+#define MOTOR_CONF_TITLE_T_CN "機器參數>電機設置"
+#define MAXFEEDRATE_CONF_T_CN "最大速度設置"
+#define ACCELERATION_CONF_T_CN "加速度設置"
+#define JERKCONF_T_CN "突變速度設置"
+#define STEPSCONF_T_CN "脈沖設置"
+#define TMC_CURRENT_T_CN "TMC 驅動電流設置"
+#define TMC_STEP_MODE_T_CN "TMC 驅動模式設置"
+#define MOTORDIRCONF_T_CN "電機方向設置"
+#define HOMEFEEDRATECONF_T_CN "歸零速度設置"
+#define HOMING_SENSITIVITY_CONF_T_CN "無限位回零靈敏度調節"
+
+#define MAXFEEDRATE_CONF_TITLE_T_CN "機器參數>最大速度"
+#define X_MAXFEEDRATE_T_CN "X軸最大速度"
+#define Y_MAXFEEDRATE_T_CN "Y軸最大速度"
+#define Z_MAXFEEDRATE_T_CN "Z軸最大速度"
+#define E0_MAXFEEDRATE_T_CN "E0軸最大速度"
+#define E1_MAXFEEDRATE_T_CN "E1軸最大速度"
+
+#define ACCELERATION_CONF_TITLE_T_CN "機器參數>加速度"
+#define PRINT_ACCELERATION_T_CN "打印加速度"
+#define RETRACT_ACCELERATION_T_CN "回抽加速度"
+#define TRAVEL_ACCELERATION_T_CN "空載加速度"
+#define X_ACCELERATION_T_CN "X軸加速度"
+#define Y_ACCELERATION_T_CN "Y軸加速度"
+#define Z_ACCELERATION_T_CN "Z軸加速度"
+#define E0_ACCELERATION_T_CN "E0軸加速度"
+#define E1_ACCELERATION_T_CN "E1軸加速度"
+
+#define JERK_CONF_TITLE_T_CN "機器參數>突變速度"
+#define X_JERK_T_CN "X軸突變速度"
+#define Y_JERK_T_CN "Y軸突變速度"
+#define Z_JERK_T_CN "Z軸突變速度"
+#define E_JERK_T_CN "E軸突變速度"
+
+#define STEPS_CONF_TITLE_T_CN "機器參數>脈衝設置"
+#define X_STEPS_T_CN "X軸脈沖"
+#define Y_STEPS_T_CN "Y軸脈沖"
+#define Z_STEPS_T_CN "Z軸脈沖"
+#define E0_STEPS_T_CN "E0軸脈沖"
+#define E1_STEPS_T_CN "E1軸脈沖"
+
+#define TMC_CURRENT_CONF_TITLE_T_CN "機器參數>TMC電流設置"
+#define X_TMC_CURRENT_T_CN "X軸電流(毫安)"
+#define Y_TMC_CURRENT_T_CN "Y軸電流(毫安)"
+#define Z_TMC_CURRENT_T_CN "Z軸電流(毫安)"
+#define E0_TMC_CURRENT_T_CN "E0軸電流(毫安)"
+#define E1_TMC_CURRENT_T_CN "E1軸電流(毫安)"
+
+#define TMC_MODE_CONF_TITLE_T_CN "機器參數>TMC模式設置"
+#define X_TMC_MODE_T_CN "X軸是否使能靜音模式"
+#define Y_TMC_MODE_T_CN "Y軸是否使能靜音模式"
+#define Z_TMC_MODE_T_CN "Z軸是否使能靜音模式"
+#define E0_TMC_MODE_T_CN "E0軸是否使能靜音模式"
+#define E1_TMC_MODE_T_CN "E1軸是否使能靜音模式"
+
+#define MOTORDIR_CONF_TITLE_T_CN "機器參數>電機方向"
+#define X_MOTORDIR_T_CN "X軸電機方向"
+#define Y_MOTORDIR_T_CN "Y軸電機方向"
+#define Z_MOTORDIR_T_CN "Z軸電機方向"
+#define E0_MOTORDIR_T_CN "E0軸電機方向"
+#define E1_MOTORDIR_T_CN "E1軸電機方向"
+#define INVERT_P_T_CN "正向"
+#define INVERT_N_T_CN "反向"
+
+#define HOMEFEEDRATE_CONF_TITLE_T_CN "機器參數>歸零速度"
+#define X_HOMESPEED_T_CN "XY軸歸零速度"
+#define Y_HOMESPEED_T_CN "Y軸歸零速度"
+#define Z_HOMESPEED_T_CN "Z軸歸零速度"
+
+#define ADVANCED_CONF_TITLE_T_CN "機器參數>高級設置"
+#define PWROFF_DECTION_T_CN "斷電檢測模塊"
+#define PWROFF_AFTER_PRINT_T_CN "啟動打完關機功能"
+#define HAVE_UPS_T_CN "機器配備UPS電壓"
+#define Z2_AND_Z2ENDSTOP_CONF_T_CN "雙z軸雙限位功能設置"
+#define ENABLE_PINS_CONF_T_CN "電機使能腳電平設置"
+#define WIFI_SETTINGS_T_CN "Wi-Fi參數設置"
+#define ENCODER_SETTINGS_T_CN "旋鈕設置"
+
+#define Z2_AND_Z2ENDSTOP_CONF_TITLE_T_CN "雙z軸雙限位設置"
+#define Z2_ENABLE_T_CN "啟用Z2軸"
+#define Z2_ENDSTOP_T_CN "啟用Z2限位"
+#define Z2_PORT_T_CN "Z2限位接口"
+
+#define ENABLE_PINS_CONF_TITLE_T_CN "電機使能腳電平"
+#define X_ENABLE_PINS_INVERT_T_CN "X軸電機使能電平"
+#define Y_ENABLE_PINS_INVERT_T_CN "Y軸電機使能電平"
+#define Z_ENABLE_PINS_INVERT_T_CN "Z軸電機使能電平"
+#define E_ENABLE_PINS_INVERT_T_CN "E軸電機使能電平"
+
+#define PAUSE_POSITION_T_CN "打印暫停位置設置"
+#define PAUSE_POSITION_X_T_CN "X軸暫停位置(絕對位置,-1無效)"
+#define PAUSE_POSITION_Y_T_CN "Y軸暫停位置(絕對位置,-1無效)"
+#define PAUSE_POSITION_Z_T_CN "Z軸暫停位置(相對位置,-1無效)"
+#define WIFI_SETTINGS_TITLE_T_CN "機器參數>Wi-Fi設置"
+#define WIFI_SETTINGS_MODE_T_CN "Wi-Fi 模式"
+#define WIFI_SETTINGS_NAME_T_CN "Wi-Fi 名稱: "
+#define WIFI_SETTINGS_PASSWORD_T_CN "Wi-Fi 密碼: "
+#define WIFI_SETTINGS_CLOUD_T_CN "是否使用雲服務?"
+#define WIFI_SETTINGS_CONFIG_T_CN "配置"
+#define WIFI_SETTINGS_EDIT_T_CN "編輯"
+#define WIFI_CONFIG_TIPS_T_CN "進行Wi-Fi配置?"
+
+#define OFFSET_TITLE_T_CN "機器參數>偏移設置"
+#define OFFSET_X_T_CN "X軸與調平開關偏移"
+#define OFFSET_Y_T_CN "Y軸與調平開關偏移"
+#define OFFSET_Z_T_CN "Z軸與調平開關偏移"
+
+#define HOMING_SENSITIVITY_CONF_TITLE_T_CN "機器參數>靈敏度調節"
+#define X_SENSITIVITY_T_CN "X軸靈敏度"
+#define Y_SENSITIVITY_T_CN "Y軸靈敏度"
+#define Z_SENSITIVITY_T_CN "Z軸靈敏度"
+#define Z2_SENSITIVITY_T_CN "Z2軸靈敏度"
+
+#define ENCODER_CONF_TITLE_T_CN "機器參數>旋鈕設置"
+#define ENCODER_CONF_TEXT_T_CN "是否使用旋鈕功能?"
+
+#define TOOL_TEXT_T_CN "工具"
+#define PREHEAT_TEXT_T_CN "預熱"
+#define MOVE_TEXT_T_CN "移動"
+#define HOME_TEXT_T_CN "回零"
+#define PRINT_TEXT_T_CN "打印"
+#define EXTRUDE_TEXT_T_CN "擠出"
+#define LEVELING_TEXT_T_CN "調平"
+#define AUTO_LEVELING_TEXT_T_CN "自動調平"
+#define SET_TEXT_T_CN "設置"
+#define MORE_TEXT_T_CN "更多"
+
+#define ADD_TEXT_T_CN "增加"
+#define DEC_TEXT_T_CN "減少"
+#define EXTRUDER_1_TEXT_T_CN "噴頭1"
+#define EXTRUDER_2_TEXT_T_CN "噴頭2"
+#define HEATBED_TEXT_T_CN "熱床"
+#define TEXT_1C_T_CN "1℃"
+#define TEXT_5C_T_CN "5℃"
+#define TEXT_10C_T_CN "10℃"
+#define CLOSE_TEXT_T_CN "關閉"
+
+#define BACK_TEXT_T_CN "返回"
+
+#define TOOL_PREHEAT_T_CN "預熱"
+#define TOOL_EXTRUDE_T_CN "擠出"
+#define TOOL_MOVE_T_CN "移動"
+#define TOOL_HOME_T_CN "回零"
+#define TOOL_LEVELING_T_CN "調平"
+#define TOOL_AUTO_LEVELING_T_CN "自動調平"
+#define TOOL_FILAMENT_T_CN "換料"
+#define TOOL_MORE_T_CN "更多"
+
+#define AXIS_X_ADD_TEXT_T_CN "X+"
+#define AXIS_X_DEC_TEXT_T_CN "X-"
+#define AXIS_Y_ADD_TEXT_T_CN "Y+"
+#define AXIS_Y_DEC_TEXT_T_CN "Y-"
+#define AXIS_Z_ADD_TEXT_T_CN "Z+"
+#define AXIS_Z_DEC_TEXT_T_CN "Z-"
+#define TEXT_01MM_T_CN "0.1mm"
+#define TEXT_1MM_T_CN "1mm"
+#define TEXT_10MM_T_CN "10mm"
+
+#define HOME_X_TEXT_T_CN "X"
+#define HOME_Y_TEXT_T_CN "Y"
+#define HOME_Z_TEXT_T_CN "Z"
+#define HOME_ALL_TEXT_T_CN "回零"
+#define HOME_STOPMOVE_T_CN "急停"
+
+#define PAGE_UP_TEXT_T_CN "上一頁"
+#define PAGE_DOWN_TEXT_T_CN "下一頁"
+
+#define EXTRUDER_IN_TEXT_T_CN "進料"
+#define EXTRUDER_OUT_TEXT_T_CN "退料"
+#define EXTRUDE_1MM_TEXT_T_CN "1mm"
+#define EXTRUDE_5MM_TEXT_T_CN "5mm"
+#define EXTRUDE_10MM_TEXT_T_CN "10mm"
+#define EXTRUDE_LOW_SPEED_TEXT_T_CN "低速"
+#define EXTRUDE_MEDIUM_SPEED_TEXT_T_CN "常速"
+#define EXTRUDE_HIGH_SPEED_TEXT_T_CN "高速"
+
+#define LEVELING_POINT1_TEXT_T_CN "第一點"
+#define LEVELING_POINT2_TEXT_T_CN "第二點"
+#define LEVELING_POINT3_TEXT_T_CN "第三點"
+#define LEVELING_POINT4_TEXT_T_CN "第四點"
+#define LEVELING_POINT5_TEXT_T_CN "第五點"
+
+#define FILESYS_TEXT_T_CN "文件系統"
+#define WIFI_TEXT_T_CN "WIFI"
+#define FAN_TEXT_T_CN "風扇"
+#define ABOUT_TEXT_T_CN "關於"
+#define BREAK_POINT_TEXT_T_CN "斷點續打"
+#define FILAMENT_TEXT_T_CN "換料"
+#define LANGUAGE_TEXT_T_CN "語言"
+#define MOTOR_OFF_TEXT_T_CN "關閉電機"
+#define MOTOR_OFF_XY_TEXT_T_CN "關閉XY"
+#define SHUTDOWN_TEXT_T_CN "關機"
+#define MACHINE_PARA_T_CN "機器參數"
+#define EEPROM_SETTINGS_T_CN "Eeprom設置"
+
+#define U_DISK_TEXT_T_CN "U盤"
+#define SD_CARD_TEXT_T_CN "SD卡"
+#define WIFI_NAME_TEXT_T_CN "無線網絡:"
+#define WIFI_KEY_TEXT_T_CN "密碼: "
+#define WIFI_IP_TEXT_T_CN "IP: "
+#define WIFI_AP_TEXT_T_CN "狀態: AP"
+#define WIFI_STA_TEXT_T_CN "狀態: STA"
+#define WIFI_CONNECTED_TEXT_T_CN "已連接"
+#define WIFI_DISCONNECTED_TEXT_T_CN "未連接"
+#define WIFI_EXCEPTION_TEXT_T_CN "模塊異常"
+#define CLOUD_TEXT_T_CN "雲服務"
+#define CLOUD_BIND_T_CN "已綁定"
+#define CLOUD_UNBIND_T_CN "解綁"
+#define CLOUD_UNBINDING_T_CN "解绑中"
+#define CLOUD_DISCONNECTED_T_CN "未連接"
+#define CLOUD_UNBINDED_T_CN "未綁定"
+#define CLOUD_BINDED_T_CN "已綁定"
+#define CLOUD_DISABLE_T_CN "已禁用"
+
+#define FAN_ADD_TEXT_T_CN "增加"
+#define FAN_DEC_TEXT_T_CN "減少"
+#define FAN_OPEN_TEXT_T_CN "100%"
+#define FAN_HALF_TEXT_T_CN "50%"
+#define FAN_CLOSE_TEXT_T_CN "關閉"
+#define FAN_TIPS1_TEXT_T_CN "風扇"
+#define FAN_TIPS2_TEXT_T_CN "FAN\nClose"
+
+#define FILAMENT_IN_TEXT_T_CN "進料"
+#define FILAMENT_OUT_TEXT_T_CN "退料"
+#define FILAMENT_EXT0_TEXT_T_CN "噴頭1"
+#define FILAMENT_EXT1_TEXT_T_CN "噴頭2"
+#define FILAMENT_HEAT_TEXT_T_CN "預熱"
+#define FILAMENT_STOP_TEXT_T_CN "停止"
+#define FILAMENT_TIPS2_TEXT_T_CN "T:"
+#define FILAMENT_TIPS3_TEXT_T_CN "正在進料"
+#define FILAMENT_TIPS4_TEXT_T_CN "正在退料"
+#define FILAMENT_TIPS5_TEXT_T_CN "溫度太低,請先預熱"
+#define FILAMENT_TIPS6_TEXT_T_CN "換料完成"
+#define FILAMENT_CHANGE_TEXT_T_CN "待打印機暫停后,\n請按<進料>或<退料>"
+
+#define FILAMENT_DIALOG_LOAD_HEAT_TIPS_T_CN "準備進料,正在加熱,請稍等"
+#define FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_T_CN "準備退料,正在加熱,請稍等"
+#define FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_T_CN "加熱完成,請裝載耗材后,按<確定>開始進料"
+#define FILAMENT_DIALOG_LOAD_CONFIRM2_TIPS_T_CN "請裝載耗,按<確定>開始進料!"
+#define FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_T_CN "加熱完成,请按<確定>開始退料!"
+#define FILAMENT_DIALOG_LOADING_TIPS_T_CN "正在進料,请等待耗材加載完成!"
+#define FILAMENT_DIALOG_UNLOADING_TIPS_T_CN "正在退料,请等待耗材卸載完成!"
+#define FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_T_CN "進料完成,请按<確定>返回"
+#define FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_T_CN "退料完成,请按<確定>返回"
+
+#define PRE_HEAT_EXT_TEXT_T_CN "噴頭"
+#define PRE_HEAT_BED_TEXT_T_CN "熱床"
+
+#define FILE_LOADING_T_CN "正在載入......"
+#define NO_FILE_AND_CHECK_T_CN "無文件!請插入sd卡/u盤!"
+#define NO_FILE_T_CN "無文件!"
+
+#define EXTRUDER_TEMP_TEXT_T_CN "溫度"
+#define EXTRUDER_E_LENGTH1_TEXT_T_CN "噴頭"
+#define EXTRUDER_E_LENGTH2_TEXT_T_CN "噴頭"
+#define EXTRUDER_E_LENGTH3_TEXT_T_CN "噴頭"
+
+#define ABOUT_TYPE_TEXT_T_CN "Type: "
+#define ABOUT_VERSION_TEXT_T_CN "Firmware: "
+#define ABOUT_WIFI_TEXT_T_CN "Wifi: "
+
+#define PRINTING_OPERATION_T_CN "操作"
+#define PRINTING_PAUSE_T_CN "暫停"
+#define PRINTING_TEMP_T_CN "溫度"
+#define PRINTING_CHANGESPEED_T_CN "變速"
+#define PRINTING_RESUME_T_CN "恢復"
+#define PRINTING_STOP_T_CN "停止"
+#define PRINTING_MORE_T_CN "更多"
+#define PRINTING_EXTRUDER_T_CN "擠出"
+#define PRINTING_MOVE_T_CN "移動"
+
+#define EXTRUDER_SPEED_T_CN "擠出"
+#define MOVE_SPEED_T_CN "移動"
+#define EXTRUDER_SPEED_STATE_T_CN "擠出速度"
+#define MOVE_SPEED_STATE_T_CN "移動速度"
+#define STEP_1PERCENT_T_CN "1%%"
+#define STEP_5PERCENT_T_CN "5%%"
+#define STEP_10PERCENT_T_CN "10%%"
+
+#define TITLE_READYPRINT_T_CN "準備打印"
+#define TITLE_PREHEAT_T_CN "預熱"
+#define TITLE_MOVE_T_CN "移動"
+#define TITLE_HOME_T_CN "回零"
+#define TITLE_EXTRUDE_T_CN "擠出"
+#define TITLE_LEVELING_T_CN "調平"
+#define TITLE_SET_T_CN "設置"
+#define TITLE_MORE_T_CN "更多"
+#define TITLE_CHOOSEFILE_T_CN "選擇文件"
+#define TITLE_PRINTING_T_CN "正在打印"
+#define TITLE_OPERATION_T_CN "操作"
+#define TITLE_ADJUST_T_CN "調整"
+#define TITLE_WIRELESS_T_CN "無線網絡"
+#define TITLE_FILAMENT_T_CN "換料"
+#define TITLE_ABOUT_T_CN "關於"
+#define TITLE_FAN_T_CN "風扇"
+#define TITLE_LANGUAGE_T_CN "語言"
+#define TITLE_PAUSE_T_CN "暫停"
+#define TITLE_CHANGESPEED_T_CN "變速"
+#define TITLE_CLOUD_TEXT_T_CN "雲服務"
+#define TITLE_DIALOG_CONFIRM_T_CN "確認"
+#define TITLE_FILESYS_T_CN "文件系統"
+
+#define AUTO_SHUTDOWN_T_CN "自動關機"
+#define MANUAL_SHUTDOWN_T_CN "手動關機"
+
+#define DIALOG_CONFIRM_T_CN "確定"
+#define DIALOG_CANCLE_T_CN "取消"
+#define DIALOG_OK_T_CN "確認"
+#define DIALOG_RESET_T_CN "重設"
+#define DIALOG_RETRY_T_CN "重試"
+#define DIALOG_DISABLE_T_CN "禁用"
+#define DIALOG_PRINT_MODEL_T_CN "打印模型?"
+#define DIALOG_CANCEL_PRINT_T_CN "停止打印?"
+#define DIALOG_RETRY_T_CN "重試"
+#define DIALOG_STOP_T_CN "停止"
+#define DIALOG_REPRINT_FROM_BREAKPOINT_T_CN "從斷點續打?"
+#define DIALOG_ERROR_TIPS1_T_CN "錯誤:找不到文件,請插入sd卡/u盤!"
+#define DIALOG_ERROR_TIPS2_T_CN "錯誤:通信失敗,請檢查波特率或主板硬件!"
+#define DIALOG_ERROR_TIPS3_T_CN "錯誤:文件名或文件路徑太長!"
+#define DIALOG_CLOSE_MACHINE_T_CN "正在關機......"
+#define DIALOG_UNBIND_PRINTER_T_CN "解除綁定?"
+#define DIALOG_FILAMENT_NO_PRESS_T_CN "請先裝載耗材!"
+#define DIALOG_PRINT_FINISH_T_CN "打印完成!"
+#define DIALOG_PRINT_TIME_T_CN "打印時間: "
+#define DIALOG_REPRINT_T_CN "再打印壹次"
+#define DIALOG_WIFI_ENABLE_TIPS_T_CN "wifi模塊正在配置中,請稍等......"
+#define DIALOG_PAUSING_TIPS_T_CN "機器暫停中..."
+
+#define TEXT_VALUE_T_CN "%d℃/%d℃"
+#define EXTRUDE_TEXT_VALUE_T_T_CN ": %d℃"
+#define WIFI_RECONNECT_TEXT_T_CN "重新連接"
+
+#define MESSAGE_PAUSING_T_CN "暫停中..."
+#define MESSAGE_CHANGING_T_CN "等待換料開始..."
+#define MESSAGE_UNLOAD_T_CN "退料中,請稍等..."
+#define MESSAGE_WAITING_T_CN "點擊按鈕恢復打印"
+#define MESSAGE_INSERT_T_CN "裝載耗材後,點擊按鈕開始打印"
+#define MESSAGE_LOAD_T_CN "進料中,請稍等..."
+#define MESSAGE_PURGE_T_CN "等待擠出..."
+#define MESSAGE_RESUME_T_CN "等待恢復打印..."
+#define MESSAGE_HEAT_T_CN "按下按鈕,加熱噴頭"
+#define MESSAGE_HEATING_T_CN "噴頭加熱中,請等待..."
+#define MESSAGE_OPTION_T_CN "擠出更多還是繼續打印"
+#define MESSAGE_PURGE_MORE_T_CN "擠出"
+#define MESSAGE_CONTINUE_PRINT_T_CN "打印"
+
+#define EEPROM_SETTINGS_TITLE_T_CN "EEPROM 設置"
+#define EEPROM_SETTINGS_STORE_T_CN "保存參數至EEPROM"
+#define EEPROM_SETTINGS_READ_T_CN "讀取EEPROM參數"
+#define EEPROM_SETTINGS_REVERT_T_CN "恢復默認參數"
+
+#define EEPROM_STORE_TIPS_T_CN "是否保存參數到EEPROM?"
+#define EEPROM_READ_TIPS_T_CN "是否使用EEPROM參數?"
+#define EEPROM_REVERT_TIPS_T_CN "是否恢復默認參數?"
+
+#define MORE_CUSTOM1_TEXT_T_CN USER_DESC_1
+#define MORE_CUSTOM2_TEXT_T_CN USER_DESC_2
+#define MORE_CUSTOM3_TEXT_T_CN USER_DESC_3
+#define MORE_CUSTOM4_TEXT_T_CN USER_DESC_4
+#define MORE_CUSTOM5_TEXT_T_CN USER_DESC_5
+#define MORE_CUSTOM6_TEXT_T_CN USER_DESC_6
+#define MORE_CUSTOM7_TEXT_T_CN USER_DESC_7
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp
new file mode 100644
index 0000000..d7b08fe
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.cpp
@@ -0,0 +1,584 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "SPI_TFT.h"
+
+#include "tft_lvgl_configuration.h"
+#include "draw_ready_print.h"
+
+#include "pic_manager.h"
+#include "mks_hardware_test.h"
+#include "draw_ui.h"
+#include "SPIFlashStorage.h"
+#include <lvgl.h>
+
+#include "../../../../MarlinCore.h"
+#include "../../../../inc/MarlinConfig.h"
+
+#include HAL_PATH(../../../../HAL, tft/xpt2046.h)
+#include "../../../marlinui.h"
+XPT2046 touch;
+
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+
+#if HAS_SERVOS
+ #include "../../../../module/servo.h"
+#endif
+
+#if EITHER(PROBE_TARE, HAS_Z_SERVO_PROBE)
+ #include "../../../../module/probe.h"
+#endif
+
+#if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ #include "../../../tft_io/touch_calibration.h"
+ #include "draw_touch_calibration.h"
+#endif
+
+#if ENABLED(MKS_WIFI_MODULE)
+ #include "wifi_module.h"
+#endif
+
+#include <SPI.h>
+
+#ifndef TFT_WIDTH
+ #define TFT_WIDTH 480
+#endif
+#ifndef TFT_HEIGHT
+ #define TFT_HEIGHT 320
+#endif
+
+#if HAS_SPI_FLASH_FONT
+ extern void init_gb2312_font();
+#endif
+
+static lv_disp_buf_t disp_buf;
+lv_group_t* g;
+#if ENABLED(SDSUPPORT)
+ extern void UpdateAssets();
+#endif
+uint16_t DeviceCode = 0x9488;
+extern uint8_t sel_id;
+
+uint8_t bmp_public_buf[14 * 1024];
+uint8_t public_buf[513];
+
+extern bool flash_preview_begin, default_preview_flg, gcode_preview_over;
+
+void SysTick_Callback() {
+ lv_tick_inc(1);
+ print_time_count();
+ #if ENABLED(MKS_WIFI_MODULE)
+ if (tips_disp.timer == TIPS_TIMER_START)
+ tips_disp.timer_count++;
+ #endif
+ if (uiCfg.filament_loading_time_flg == 1) {
+ uiCfg.filament_loading_time_cnt++;
+ uiCfg.filament_rate = (uint32_t)(((uiCfg.filament_loading_time_cnt / (uiCfg.filament_loading_time * 1000.0)) * 100.0) + 0.5);
+ if (uiCfg.filament_loading_time_cnt >= (uiCfg.filament_loading_time * 1000)) {
+ uiCfg.filament_loading_time_cnt = 0;
+ uiCfg.filament_loading_time_flg = 0;
+ uiCfg.filament_loading_completed = 1;
+ }
+ }
+ if (uiCfg.filament_unloading_time_flg == 1) {
+ uiCfg.filament_unloading_time_cnt++;
+ uiCfg.filament_rate = (uint32_t)(((uiCfg.filament_unloading_time_cnt / (uiCfg.filament_unloading_time * 1000.0)) * 100.0) + 0.5);
+ if (uiCfg.filament_unloading_time_cnt >= (uiCfg.filament_unloading_time * 1000)) {
+ uiCfg.filament_unloading_time_cnt = 0;
+ uiCfg.filament_unloading_time_flg = 0;
+ uiCfg.filament_unloading_completed = 1;
+ uiCfg.filament_rate = 100;
+ }
+ }
+}
+
+void tft_lvgl_init() {
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+
+ gCfgItems_init();
+ ui_cfg_init();
+ disp_language_init();
+
+ watchdog_refresh(); // LVGL init takes time
+
+ #if MB(MKS_ROBIN_NANO)
+ OUT_WRITE(PB0, LOW); // HE1
+ #endif
+
+ // Init TFT first!
+ SPI_TFT.spi_init(SPI_FULL_SPEED);
+ SPI_TFT.LCD_init();
+
+ #if ENABLED(USB_FLASH_DRIVE_SUPPORT)
+ uint16_t usb_flash_loop = 1000;
+ do {
+ Sd2Card::idle();
+ watchdog_refresh();
+ delay(2);
+ } while((!Sd2Card::isInserted()) && (usb_flash_loop--));
+ card.mount();
+ #elif HAS_LOGO_IN_FLASH
+ delay(2000);
+ #endif
+
+ watchdog_refresh(); // LVGL init takes time
+
+ #if ENABLED(SDSUPPORT)
+ UpdateAssets();
+ watchdog_refresh(); // LVGL init takes time
+ #endif
+
+ mks_test_get();
+
+ touch.Init();
+
+ lv_init();
+
+ lv_disp_buf_init(&disp_buf, bmp_public_buf, nullptr, LV_HOR_RES_MAX * 14); /*Initialize the display buffer*/
+
+ lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
+ lv_disp_drv_init(&disp_drv); /*Basic initialization*/
+ disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
+ disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/
+ lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
+
+ lv_indev_drv_t indev_drv;
+ lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
+ indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
+ indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
+ lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
+
+ #if HAS_ROTARY_ENCODER
+ g = lv_group_create();
+ lv_indev_drv_t enc_drv;
+ lv_indev_drv_init(&enc_drv);
+ enc_drv.type = LV_INDEV_TYPE_ENCODER;
+ enc_drv.read_cb = my_mousewheel_read;
+ lv_indev_t * enc_indev = lv_indev_drv_register(&enc_drv);
+ lv_indev_set_group(enc_indev, g);
+ #endif
+
+ lv_fs_drv_t spi_flash_drv;
+ lv_fs_drv_init(&spi_flash_drv);
+ spi_flash_drv.letter = 'F';
+ spi_flash_drv.open_cb = spi_flash_open_cb;
+ spi_flash_drv.close_cb = spi_flash_close_cb;
+ spi_flash_drv.read_cb = spi_flash_read_cb;
+ spi_flash_drv.seek_cb = spi_flash_seek_cb;
+ spi_flash_drv.tell_cb = spi_flash_tell_cb;
+ lv_fs_drv_register(&spi_flash_drv);
+
+ lv_fs_drv_t sd_drv;
+ lv_fs_drv_init(&sd_drv);
+ sd_drv.letter = 'S';
+ sd_drv.open_cb = sd_open_cb;
+ sd_drv.close_cb = sd_close_cb;
+ sd_drv.read_cb = sd_read_cb;
+ sd_drv.seek_cb = sd_seek_cb;
+ sd_drv.tell_cb = sd_tell_cb;
+ lv_fs_drv_register(&sd_drv);
+
+ systick_attach_callback(SysTick_Callback);
+
+ #if HAS_SPI_FLASH_FONT
+ init_gb2312_font();
+ #endif
+
+ tft_style_init();
+
+ filament_pin_setup();
+
+ lv_encoder_pin_init();
+
+ #if ENABLED(MKS_WIFI_MODULE)
+ mks_esp_wifi_init();
+ //WIFISERIAL.begin(WIFI_BAUDRATE);
+ //uint32_t serial_connect_timeout = millis() + 1000UL;
+ //while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+ mks_wifi_firmware_upddate();
+ #endif
+ TERN_(HAS_SERVOS, servo_init());
+ TERN_(HAS_Z_SERVO_PROBE, probe.servo_probe_init());
+ bool ready = true;
+ #if ENABLED(POWER_LOSS_RECOVERY)
+ recovery.load();
+ if (recovery.valid()) {
+ ready = false;
+ if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+
+ uiCfg.print_state = REPRINTING;
+
+ #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
+ strncpy(public_buf_m, recovery.info.sd_filename, sizeof(public_buf_m));
+ card.printLongPath(public_buf_m);
+ strncpy(list_file.long_name[sel_id], card.longFilename, sizeof(list_file.long_name[sel_id]));
+ #else
+ strncpy(list_file.long_name[sel_id], recovery.info.sd_filename, sizeof(list_file.long_name[sel_id]));
+ #endif
+ lv_draw_printing();
+ }
+ #endif
+
+ if (ready) {
+ lv_draw_ready_print();
+ }
+
+ if (mks_test_flag == 0x1E)
+ mks_gpio_test();
+}
+
+void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) {
+ uint16_t width = area->x2 - area->x1 + 1,
+ height = area->y2 - area->y1 + 1;
+
+ SPI_TFT.setWindow((uint16_t)area->x1, (uint16_t)area->y1, width, height);
+
+ for (uint16_t i = 0; i < height; i++)
+ SPI_TFT.tftio.WriteSequence((uint16_t*)(color_p + width * i), width);
+
+ lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+}
+
+void lv_fill_rect(lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2, lv_color_t bk_color) {
+ uint16_t width, height;
+ width = x2 - x1 + 1;
+ height = y2 - y1 + 1;
+
+ SPI_TFT.setWindow((uint16_t)x1, (uint16_t)y1, width, height);
+ #if ENABLED(TFT_LVGL_UI_FSMC)
+ SPI_TFT.tftio.WriteReg(0x002C);
+ #endif
+
+ #ifdef LCD_USE_DMA_FSMC
+ SPI_TFT.tftio.WriteMultiple(bk_color.full, width * height);
+ #else
+ for (uint32_t i = 0; i < width * height; i++)
+ SPI_TFT.tftio.WriteData(bk_color.full);
+ #endif
+
+ #if ENABLED(TFT_LVGL_UI_SPI)
+ W25QXX.init(SPI_QUARTER_SPEED);
+ #endif
+}
+
+#define TICK_CYCLE 1
+
+unsigned int getTickDiff(unsigned int curTick, unsigned int lastTick) {
+ return TICK_CYCLE * (lastTick <= curTick ? (curTick - lastTick) : (0xFFFFFFFF - lastTick + curTick));
+}
+
+static bool get_point(int16_t *x, int16_t *y) {
+ bool is_touched = touch.getRawPoint(x, y);
+
+ if (!is_touched) return false;
+
+ #if ENABLED(TOUCH_SCREEN_CALIBRATION)
+ const calibrationState state = touch_calibration.get_calibration_state();
+ if (state >= CALIBRATION_TOP_LEFT && state <= CALIBRATION_BOTTOM_RIGHT) {
+ if (touch_calibration.handleTouch(*x, *y)) lv_update_touch_calibration_screen();
+ return false;
+ }
+ *x = int16_t((int32_t(*x) * touch_calibration.calibration.x) >> 16) + touch_calibration.calibration.offset_x;
+ *y = int16_t((int32_t(*y) * touch_calibration.calibration.y) >> 16) + touch_calibration.calibration.offset_y;
+ #else
+ *x = int16_t((int32_t(*x) * TOUCH_CALIBRATION_X) >> 16) + TOUCH_OFFSET_X;
+ *y = int16_t((int32_t(*y) * TOUCH_CALIBRATION_Y) >> 16) + TOUCH_OFFSET_Y;
+ #endif
+
+ return true;
+}
+
+bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
+ static int16_t last_x = 0, last_y = 0;
+ static uint8_t last_touch_state = LV_INDEV_STATE_REL;
+ static int32_t touch_time1 = 0;
+ uint32_t tmpTime, diffTime = 0;
+
+ tmpTime = millis();
+ diffTime = getTickDiff(tmpTime, touch_time1);
+ if (diffTime > 20) {
+ if (get_point(&last_x, &last_y)) {
+
+ if (last_touch_state == LV_INDEV_STATE_PR) return false;
+ data->state = LV_INDEV_STATE_PR;
+
+ // Set the coordinates (if released use the last-pressed coordinates)
+ #if TFT_ROTATION == TFT_ROTATE_180
+ data->point.x = TFT_WIDTH - last_x;
+ data->point.y = TFT_HEIGHT -last_y;
+ #else
+ data->point.x = last_x;
+ data->point.y = last_y;
+ #endif
+
+ last_x = last_y = 0;
+ last_touch_state = LV_INDEV_STATE_PR;
+ }
+ else {
+ if (last_touch_state == LV_INDEV_STATE_PR)
+ data->state = LV_INDEV_STATE_REL;
+ last_touch_state = LV_INDEV_STATE_REL;
+ }
+
+ touch_time1 = tmpTime;
+ }
+
+ return false; // Return `false` since no data is buffering or left to read
+}
+
+int16_t enc_diff = 0;
+lv_indev_state_t state = LV_INDEV_STATE_REL;
+
+bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
+ (void) indev_drv; /*Unused*/
+
+ data->state = state;
+ data->enc_diff = enc_diff;
+ enc_diff = 0;
+
+ return false; /*No more data to read so return false*/
+}
+
+extern uint8_t currentFlashPage;
+
+//spi_flash
+uint32_t pic_read_base_addr = 0, pic_read_addr_offset = 0;
+lv_fs_res_t spi_flash_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) {
+ static char last_path_name[30];
+ if (strcasecmp(last_path_name, path) != 0) {
+ pic_read_base_addr = lv_get_pic_addr((uint8_t *)path);
+ strcpy(last_path_name, path);
+ }
+ else {
+ W25QXX.init(SPI_QUARTER_SPEED);
+ currentFlashPage = 0;
+ }
+ pic_read_addr_offset = pic_read_base_addr;
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t spi_flash_close_cb (lv_fs_drv_t * drv, void * file_p) {
+ lv_fs_res_t res = LV_FS_RES_OK;
+ /* Add your code here*/
+ pic_read_addr_offset = pic_read_base_addr;
+ return res;
+}
+
+lv_fs_res_t spi_flash_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) {
+ lv_pic_test((uint8_t *)buf, pic_read_addr_offset, btr);
+ *br = btr;
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t spi_flash_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos) {
+ #if HAS_SPI_FLASH_COMPRESSION
+ if (pos == 4) {
+ uint8_t bmp_header[4];
+ SPIFlash.beginRead(pic_read_base_addr);
+ SPIFlash.readData(bmp_header, 4);
+ currentFlashPage = 1;
+ }
+ pic_read_addr_offset = pic_read_base_addr;
+ #else
+ pic_read_addr_offset = pic_read_base_addr + pos;
+ #endif
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t spi_flash_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) {
+ *pos_p = pic_read_addr_offset - pic_read_base_addr;
+ return LV_FS_RES_OK;
+}
+
+//sd
+char *cur_namefff;
+uint32_t sd_read_base_addr = 0, sd_read_addr_offset = 0, small_image_size = 409;
+char last_path[(SHORT_NAME_LEN + 1) * MAX_DIR_LEVEL + strlen("S:/") + 1];
+lv_fs_res_t sd_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) {
+ if (path != nullptr && card.isFileOpen() && strcmp((const char*)path, (const char*)last_path) == 0) return LV_FS_RES_OK;
+ strcpy(last_path, path);
+ lv_close_gcode_file();
+ char name_buf[100];
+ *name_buf = '/';
+ strcpy(name_buf + 1, path);
+ char *temp = strstr(name_buf, ".bin");
+ if (temp) strcpy(temp, ".GCO");
+ sd_read_base_addr = lv_open_gcode_file((char *)name_buf);
+ sd_read_addr_offset = sd_read_base_addr;
+ if (sd_read_addr_offset == UINT32_MAX) return LV_FS_RES_NOT_EX;
+ // find small image size
+ card.read(public_buf, 512);
+ public_buf[511] = '\0';
+ char* eol = strpbrk((const char*)public_buf, "\n\r");
+ small_image_size = (uintptr_t)eol - (uintptr_t)((uint32_t *)(&public_buf[0])) + 1;
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t sd_close_cb (lv_fs_drv_t * drv, void * file_p) {
+ /* Add your code here*/
+ //lv_close_gcode_file();
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t sd_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) {
+ if (btr == 200) {
+ lv_gcode_file_read((uint8_t *)buf);
+ //pic_read_addr_offset += 208;
+ *br = 200;
+ }
+ else if (btr == 4) {
+ uint8_t header_pic[4] = { 0x04, 0x90, 0x81, 0x0C };
+ memcpy(buf, header_pic, 4);
+ *br = 4;
+ }
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t sd_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos) {
+ sd_read_addr_offset = sd_read_base_addr + (pos - 4) / 200 * small_image_size;
+ lv_gcode_file_seek(sd_read_addr_offset);
+ return LV_FS_RES_OK;
+}
+
+lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) {
+ if (sd_read_addr_offset) *pos_p = 0;
+ else *pos_p = (sd_read_addr_offset - sd_read_base_addr) / small_image_size * 200 + 4;
+ return LV_FS_RES_OK;
+}
+
+void lv_encoder_pin_init() {
+ #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 BUTTON_EXISTS(BACK)
+ SET_INPUT_PULLUP(BTN_BACK);
+ #endif
+
+ #if BUTTON_EXISTS(UP)
+ SET_INPUT(BTN_UP);
+ #endif
+ #if BUTTON_EXISTS(DWN)
+ SET_INPUT(BTN_DWN);
+ #endif
+ #if BUTTON_EXISTS(LFT)
+ SET_INPUT(BTN_LFT);
+ #endif
+ #if BUTTON_EXISTS(RT)
+ SET_INPUT(BTN_RT);
+ #endif
+}
+
+#if 1 // HAS_ENCODER_ACTION
+ void lv_update_encoder() {
+ static uint32_t encoder_time1;
+ uint32_t tmpTime, diffTime = 0;
+ tmpTime = millis();
+ diffTime = getTickDiff(tmpTime, encoder_time1);
+ if (diffTime > 50) {
+
+ #if HAS_ENCODER_WHEEL
+
+ #if ANY_BUTTON(EN1, EN2, ENC, BACK)
+
+ uint8_t newbutton = 0;
+
+ #if BUTTON_EXISTS(EN1)
+ if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
+ #endif
+ #if BUTTON_EXISTS(EN2)
+ if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
+ #endif
+ #if BUTTON_EXISTS(ENC)
+ if (BUTTON_PRESSED(ENC)) newbutton |= EN_C;
+ #endif
+ #if BUTTON_EXISTS(BACK)
+ if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
+ #endif
+
+ #else
+
+ constexpr uint8_t newbutton = 0;
+
+ #endif
+
+
+ static uint8_t buttons = 0;
+ buttons = newbutton;
+ static uint8_t lastEncoderBits;
+
+ #define encrot0 0
+ #define encrot1 1
+ #define encrot2 2
+
+ uint8_t enc = 0;
+ if (buttons & EN_A) enc |= B01;
+ if (buttons & EN_B) enc |= B10;
+ if (enc != lastEncoderBits) {
+ switch (enc) {
+ case encrot1:
+ if (lastEncoderBits == encrot0) {
+ enc_diff--;
+ encoder_time1 = tmpTime;
+ }
+ break;
+ case encrot2:
+ if (lastEncoderBits == encrot0) {
+ enc_diff++;
+ encoder_time1 = tmpTime;
+ }
+ break;
+ }
+ lastEncoderBits = enc;
+ }
+ static uint8_t last_button_state = LV_INDEV_STATE_REL;
+ const uint8_t enc_c = (buttons & EN_C) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+ if (enc_c != last_button_state) {
+ state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
+ last_button_state = enc_c;
+ }
+
+ #endif // HAS_ENCODER_WHEEL
+
+ } // next_button_update_ms
+ }
+
+#endif // HAS_ENCODER_ACTION
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h
new file mode 100644
index 0000000..018f737
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_lvgl_configuration.h
@@ -0,0 +1,69 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+/**
+ * @file lcd/extui/lib/mks_ui/tft_lvgl_configuration.h
+ * @date 2020-02-21
+ */
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#include <lvgl.h>
+
+//#define TFT_ROTATION TFT_ROTATE_180
+
+extern uint8_t bmp_public_buf[14 * 1024];
+extern uint8_t public_buf[513];
+
+extern void tft_lvgl_init();
+extern void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p);
+extern bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
+extern bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
+
+extern void LCD_Clear(uint16_t Color);
+extern void tft_set_point(uint16_t x, uint16_t y, uint16_t point);
+extern void LCD_setWindowArea(uint16_t StartX, uint16_t StartY, uint16_t width, uint16_t heigh);
+extern void LCD_WriteRAM_Prepare(void);
+extern void lcd_draw_logo();
+extern void lv_encoder_pin_init();
+extern void lv_update_encoder();
+
+extern lv_fs_res_t spi_flash_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
+extern lv_fs_res_t spi_flash_close_cb (lv_fs_drv_t * drv, void * file_p);
+extern lv_fs_res_t spi_flash_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
+extern lv_fs_res_t spi_flash_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos);
+extern lv_fs_res_t spi_flash_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
+
+extern lv_fs_res_t sd_open_cb (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
+extern lv_fs_res_t sd_close_cb (lv_fs_drv_t * drv, void * file_p);
+extern lv_fs_res_t sd_read_cb (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
+extern lv_fs_res_t sd_seek_cb(lv_fs_drv_t * drv, void * file_p, uint32_t pos);
+extern lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
+
+extern void lv_fill_rect(lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2, lv_color_t bk_color);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp
new file mode 100644
index 0000000..f05874a
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp
@@ -0,0 +1,2920 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "../../../../MarlinCore.h"
+
+#include "draw_ui.h"
+#include "tft_multi_language.h"
+
+// ********************************************* //
+
+common_menu_def common_menu;
+main_menu_def main_menu;
+preheat_menu_def preheat_menu;
+move_menu_def move_menu;
+home_menu_def home_menu;
+file_menu_def file_menu;
+extrude_menu_def extrude_menu;
+leveling_menu_def leveling_menu;
+set_menu_def set_menu;
+more_menu_def more_menu;
+wifi_menu_def wifi_menu;
+cloud_menu_def cloud_menu;
+about_menu_def about_menu;
+fan_menu_def fan_menu;
+filament_menu_def filament_menu;
+printing_menu_def printing_menu;
+operation_menu_def operation_menu;
+pause_menu_def pause_menu;
+speed_menu_def speed_menu;
+printing_more_menu_def printing_more_menu;
+dialog_menu_def dialog_menu;
+language_menu_def language_menu;
+print_file_dialog_menu_def print_file_dialog_menu;
+filesys_menu_def filesys_menu;
+tool_menu_def tool_menu;
+MachinePara_menu_def MachinePara_menu;
+pause_msg_def pause_msg_menu;
+eeprom_def eeprom_menu;
+touchmi_menu_def touchmi_menu;
+
+machine_common_def machine_menu;
+void machine_setting_disp() {
+ if (gCfgItems.language == LANG_SIMPLE_CHINESE) {
+ MachinePara_menu.title = MACHINE_PARA_TITLE_CN;
+ MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_CN;
+ MachinePara_menu.MotorSetting = MOTOR_CONFIG_CN;
+ MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_CN;
+ MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_CN;
+
+ machine_menu.default_value = DEFAULT_CN;
+ machine_menu.next = NEXT_CN;
+ machine_menu.previous = PREVIOUS_CN;
+
+ machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_CN;
+ machine_menu.MachineType = MACHINE_TYPE_CN;
+ machine_menu.Stroke = MACHINE_STROKE_CN;
+ machine_menu.HomeDir = MACHINE_HOMEDIR_CN;
+ machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_CN;
+ machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_CN;
+
+ machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_CN;
+ machine_menu.xyz = MACHINE_TYPE_XYZ_CN;
+ machine_menu.delta = MACHINE_TYPE_DELTA_CN;
+ machine_menu.corexy = MACHINE_TYPE_COREXY_CN;
+
+ machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_CN;
+ machine_menu.xStroke = X_MAX_LENGTH_CN;
+ machine_menu.yStroke = Y_MAX_LENGTH_CN;
+ machine_menu.zStroke = Z_MAX_LENGTH_CN;
+
+ machine_menu.xmin = X_MIN_LENGTH_CN;
+ machine_menu.ymin = Y_MIN_LENGTH_CN;
+ machine_menu.zmin = Z_MIN_LENGTH_CN;
+
+ machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_CN;
+ machine_menu.xHomeDir = HOME_DIR_X_CN;
+ machine_menu.yHomeDir = HOME_DIR_Y_CN;
+ machine_menu.zHomeDir = HOME_DIR_Z_CN;
+ machine_menu.min = HOME_MIN_CN;
+ machine_menu.max = HOME_MAX_CN;
+
+ machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_CN;
+ machine_menu.xEndstop_min = MIN_ENDSTOP_X_CN;
+ machine_menu.yEndstop_min = MIN_ENDSTOP_Y_CN;
+ machine_menu.zEndstop_min = MIN_ENDSTOP_Z_CN;
+ machine_menu.xEndstop_max = MAX_ENDSTOP_X_CN;
+ machine_menu.yEndstop_max = MAX_ENDSTOP_Y_CN;
+ machine_menu.zEndstop_max = MAX_ENDSTOP_Z_CN;
+ machine_menu.FilamentEndstop = ENDSTOP_FIL_CN;
+ machine_menu.LevelingEndstop = ENDSTOP_LEVEL_CN;
+ machine_menu.opened = ENDSTOP_OPENED_CN;
+ machine_menu.closed = ENDSTOP_CLOSED_CN;
+
+ machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_CN;
+ machine_menu.InLength = FILAMENT_IN_LENGTH_CN;
+ machine_menu.InSpeed = FILAMENT_IN_SPEED_CN;
+ machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_CN;
+ machine_menu.OutLength = FILAMENT_OUT_LENGTH_CN;
+ machine_menu.OutSpeed = FILAMENT_OUT_SPEED_CN;
+
+ machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_CN;
+ machine_menu.LevelingParaConf = LEVELING_PARA_CONF_CN;
+ machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_CN;
+ machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_CN;
+ machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_CN;
+
+ machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_CN;
+ machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_CN;
+ machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_CN;
+ machine_menu.ProbePort = PROBE_PORT_CN;
+ machine_menu.ProbeXoffset = PROBE_X_OFFSET_CN;
+ machine_menu.ProbeYoffset = PROBE_Y_OFFSET_CN;
+ machine_menu.ProbeZoffset = PROBE_Z_OFFSET_CN;
+ machine_menu.ProbeXYspeed = PROBE_XY_SPEED_CN;
+ machine_menu.ProbeZspeed = PROBE_Z_SPEED_CN;
+ machine_menu.enable = ENABLE_CN;
+ machine_menu.disable = DISABLE_CN;
+ machine_menu.locked = LOCKED_CN;
+ machine_menu.z_min = Z_MIN_CN;
+ machine_menu.z_max = Z_MAX_CN;
+
+ machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_CN;
+ machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_CN;
+ machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_CN;
+ machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_CN;
+ machine_menu.DeltaHeight = DELTA_HEIGHT_CN;
+ machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_CN;
+ machine_menu.EffectorOffset = EFFECTOR_OFFSET_CN;
+ machine_menu.CalibrationRadius = CALIBRATION_RADIUS_CN;
+
+ machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_CN;
+
+ machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_CN;
+ machine_menu.NozzleConf = NOZZLE_CONF_CN;
+ machine_menu.HotBedConf = HOTBED_CONF_CN;
+ machine_menu.PreheatTemperConf = PREHEAT_TEMPER_CN;
+
+ machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_CN;
+ machine_menu.NozzleCnt = NOZZLECNT_CN;
+ machine_menu.NozzleType = NOZZLE_TYPE_CN;
+ machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_CN;
+ machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_CN;
+ machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_CN;
+ machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_CN;
+
+ machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_CN;
+ machine_menu.HotbedAjustType = HOTBED_ADJUST_CN;
+ machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_CN;
+ machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_CN;
+
+ machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_CN;
+ machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_CN;
+ machine_menu.AccelerationConf = ACCELERATION_CONF_CN;
+ machine_menu.JerkConf = JERKCONF_CN;
+ machine_menu.StepsConf = STEPSCONF_CN;
+ machine_menu.TMCcurrentConf = TMC_CURRENT_CN;
+ machine_menu.TMCStepModeConf = TMC_STEP_MODE_CN;
+ machine_menu.MotorDirConf = MOTORDIRCONF_CN;
+ machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_CN;
+ machine_menu.PausePosition = PAUSE_POSITION_CN;
+ machine_menu.WifiSettings = WIFI_SETTINGS_CN;
+ machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_CN;
+ machine_menu.EncoderSettings = ENCODER_SETTINGS_CN;
+
+ machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_CN;
+ machine_menu.XMaxFeedRate = X_MAXFEEDRATE_CN;
+ machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_CN;
+ machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_CN;
+ machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_CN;
+ machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_CN;
+
+ machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_CN;
+ machine_menu.PrintAcceleration = PRINT_ACCELERATION_CN;
+ machine_menu.RetractAcceleration = RETRACT_ACCELERATION_CN;
+ machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_CN;
+ machine_menu.X_Acceleration = X_ACCELERATION_CN;
+ machine_menu.Y_Acceleration = Y_ACCELERATION_CN;
+ machine_menu.Z_Acceleration = Z_ACCELERATION_CN;
+ machine_menu.E0_Acceleration = E0_ACCELERATION_CN;
+ machine_menu.E1_Acceleration = E1_ACCELERATION_CN;
+
+ machine_menu.JerkConfTitle = JERK_CONF_TITLE_CN;
+ machine_menu.X_Jerk = X_JERK_CN;
+ machine_menu.Y_Jerk = Y_JERK_CN;
+ machine_menu.Z_Jerk = Z_JERK_CN;
+ machine_menu.E_Jerk = E_JERK_CN;
+
+ machine_menu.StepsConfTitle = STEPS_CONF_TITLE_CN;
+ machine_menu.X_Steps = X_STEPS_CN;
+ machine_menu.Y_Steps = Y_STEPS_CN;
+ machine_menu.Z_Steps = Z_STEPS_CN;
+ machine_menu.E0_Steps = E0_STEPS_CN;
+ machine_menu.E1_Steps = E1_STEPS_CN;
+
+ machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_CN;
+ machine_menu.X_Current = X_TMC_CURRENT_CN;
+ machine_menu.Y_Current = Y_TMC_CURRENT_CN;
+ machine_menu.Z_Current = Z_TMC_CURRENT_CN;
+ machine_menu.E0_Current = E0_TMC_CURRENT_CN;
+ machine_menu.E1_Current = E1_TMC_CURRENT_CN;
+
+ machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_CN;
+ machine_menu.X_StepMode = X_TMC_MODE_CN;
+ machine_menu.Y_StepMode = Y_TMC_MODE_CN;
+ machine_menu.Z_StepMode = Z_TMC_MODE_CN;
+ machine_menu.E0_StepMode = E0_TMC_MODE_CN;
+ machine_menu.E1_StepMode = E1_TMC_MODE_CN;
+
+ machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_CN;
+ machine_menu.X_MotorDir = X_MOTORDIR_CN;
+ machine_menu.Y_MotorDir = Y_MOTORDIR_CN;
+ machine_menu.Z_MotorDir = Z_MOTORDIR_CN;
+ machine_menu.E0_MotorDir = E0_MOTORDIR_CN;
+ machine_menu.E1_MotorDir = E1_MOTORDIR_CN;
+ machine_menu.Invert_0 = INVERT_P_CN;
+ machine_menu.Invert_1 = INVERT_N_CN;
+
+ machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_CN;
+ machine_menu.XY_HomeFeedRate = X_HOMESPEED_CN;
+ machine_menu.Z_HomeFeedRate = Z_HOMESPEED_CN;
+
+ machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_CN;
+ machine_menu.PwrOffDection = PWROFF_DECTION_CN;
+ machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_CN;
+ machine_menu.HaveUps = HAVE_UPS_CN;
+ machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_CN;
+ machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_CN;
+
+ machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_CN;
+ machine_menu.Z2Enable = Z2_ENABLE_CN;
+ machine_menu.Z2EndstopEnable = Z2_ENDSTOP_CN;
+ machine_menu.Z2Port = Z2_PORT_CN;
+
+ machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_CN;
+ machine_menu.XInvert = X_ENABLE_PINS_INVERT_CN;
+ machine_menu.YInvert = Y_ENABLE_PINS_INVERT_CN;
+ machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_CN;
+ machine_menu.EInvert = E_ENABLE_PINS_INVERT_CN;
+
+ machine_menu.key_back = KEY_BACK_CN;
+ machine_menu.key_reset = KEY_REST_CN;
+ machine_menu.key_confirm = KEY_CONFIRM_CN;
+
+ machine_menu.PausePosText = PAUSE_POSITION_CN;
+ machine_menu.xPos = PAUSE_POSITION_X_CN;
+ machine_menu.yPos = PAUSE_POSITION_Y_CN;
+ machine_menu.zPos = PAUSE_POSITION_Z_CN;
+ machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_CN;
+ machine_menu.wifiMode = WIFI_SETTINGS_MODE_CN;
+ machine_menu.wifiName = WIFI_SETTINGS_NAME_CN;
+ machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_CN;
+ machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_CN;
+ machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_CN;
+ machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_CN;
+ machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_CN;
+
+ machine_menu.OffsetConfTitle = OFFSET_TITLE_CN;
+ machine_menu.Xoffset = OFFSET_X_CN;
+ machine_menu.Yoffset = OFFSET_Y_CN;
+ machine_menu.Zoffset = OFFSET_Z_CN;
+
+ machine_menu.LevelingTouchmiConf = LEVELING_TOUCHMI_CN;
+ machine_menu.TouchmiInit = TM_INIT_CN;
+ machine_menu.TouchmiOffsetpos = TM_ZOFFSETPOS_CN;
+ machine_menu.TouchmiOffsetneg = TM_ZOFFSETNEG_CN;
+ machine_menu.TouchmiSave = TM_SAVE_CN;
+ machine_menu.TouchmiTest = TM_TEST_CN;
+
+ machine_menu.BLTouchLevelingConfTitle = BLTOUCH_LEVELING_TITTLE_CN;
+ machine_menu.BLTouchLevelingConf = BLTOUCH_LEVELING_CN;
+ machine_menu.BLTouchInit = BLTOUCH_INIT_CN;
+ machine_menu.BLTouchOffsetpos = BLTOUCH_ZOFFSETPOS_CN;
+ machine_menu.BLTouchOffsetneg = BLTOUCH_ZOFFSETNEG_CN;
+ machine_menu.BLTouchSave = BLTOUCH_SAVE_CN;
+ machine_menu.BLTouchTest = BLTOUCH_TEST_CN;
+
+ machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_CN;
+ machine_menu.X_Sensitivity = X_SENSITIVITY_CN;
+ machine_menu.Y_Sensitivity = Y_SENSITIVITY_CN;
+ machine_menu.Z_Sensitivity = Z_SENSITIVITY_CN;
+ machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_CN;
+
+ machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_CN;
+ machine_menu.EncoderConfText = ENCODER_CONF_TEXT_CN;
+ }
+ else if (gCfgItems.language == LANG_COMPLEX_CHINESE) {
+ MachinePara_menu.title = MACHINE_PARA_TITLE_T_CN;
+ MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_T_CN;
+ MachinePara_menu.MotorSetting = MOTOR_CONFIG_T_CN;
+ MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_T_CN;
+ MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_T_CN;
+
+ machine_menu.default_value = DEFAULT_T_CN;
+ machine_menu.next = NEXT_T_CN;
+ machine_menu.previous = PREVIOUS_T_CN;
+
+ machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_T_CN;
+ machine_menu.MachineType = MACHINE_TYPE_T_CN;
+ machine_menu.Stroke = MACHINE_STROKE_T_CN;
+ machine_menu.HomeDir = MACHINE_HOMEDIR_T_CN;
+ machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_T_CN;
+ machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_T_CN;
+
+ machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_T_CN;
+ machine_menu.xyz = MACHINE_TYPE_XYZ_T_CN;
+ machine_menu.delta = MACHINE_TYPE_DELTA_T_CN;
+ machine_menu.corexy = MACHINE_TYPE_COREXY_T_CN;
+
+ machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_T_CN;
+ machine_menu.xStroke = X_MAX_LENGTH_T_CN;
+ machine_menu.yStroke = Y_MAX_LENGTH_T_CN;
+ machine_menu.zStroke = Z_MAX_LENGTH_T_CN;
+
+ machine_menu.xmin = X_MIN_LENGTH_T_CN;
+ machine_menu.ymin = Y_MIN_LENGTH_T_CN;
+ machine_menu.zmin = Z_MIN_LENGTH_T_CN;
+
+ machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_T_CN;
+ machine_menu.xHomeDir = HOME_DIR_X_T_CN;
+ machine_menu.yHomeDir = HOME_DIR_Y_T_CN;
+ machine_menu.zHomeDir = HOME_DIR_Z_T_CN;
+ machine_menu.min = HOME_MIN_T_CN;
+ machine_menu.max = HOME_MAX_T_CN;
+
+ machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_T_CN;
+ machine_menu.xEndstop_min = MIN_ENDSTOP_X_T_CN;
+ machine_menu.yEndstop_min = MIN_ENDSTOP_Y_T_CN;
+ machine_menu.zEndstop_min = MIN_ENDSTOP_Z_T_CN;
+ machine_menu.xEndstop_max = MAX_ENDSTOP_X_T_CN;
+ machine_menu.yEndstop_max = MAX_ENDSTOP_Y_T_CN;
+ machine_menu.zEndstop_max = MAX_ENDSTOP_Z_T_CN;
+ machine_menu.FilamentEndstop = ENDSTOP_FIL_T_CN;
+ machine_menu.LevelingEndstop = ENDSTOP_LEVEL_T_CN;
+ machine_menu.opened = ENDSTOP_OPENED_T_CN;
+ machine_menu.closed = ENDSTOP_CLOSED_T_CN;
+
+ machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_T_CN;
+ machine_menu.InLength = FILAMENT_IN_LENGTH_T_CN;
+ machine_menu.InSpeed = FILAMENT_IN_SPEED_T_CN;
+ machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_T_CN;
+ machine_menu.OutLength = FILAMENT_OUT_LENGTH_T_CN;
+ machine_menu.OutSpeed = FILAMENT_OUT_SPEED_T_CN;
+
+ machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_T_CN;
+ machine_menu.LevelingParaConf = LEVELING_PARA_CONF_T_CN;
+ machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_T_CN;
+ machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_T_CN;
+ machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_T_CN;
+
+ machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_T_CN;
+ machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_T_CN;
+ machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_T_CN;
+ machine_menu.ProbePort = PROBE_PORT_T_CN;
+ machine_menu.ProbeXoffset = PROBE_X_OFFSET_T_CN;
+ machine_menu.ProbeYoffset = PROBE_Y_OFFSET_T_CN;
+ machine_menu.ProbeZoffset = PROBE_Z_OFFSET_T_CN;
+ machine_menu.ProbeXYspeed = PROBE_XY_SPEED_T_CN;
+ machine_menu.ProbeZspeed = PROBE_Z_SPEED_T_CN;
+ machine_menu.enable = ENABLE_T_CN;
+ machine_menu.disable = DISABLE_T_CN;
+ machine_menu.locked = LOCKED_T_CN;
+ machine_menu.z_min = Z_MIN_T_CN;
+ machine_menu.z_max = Z_MAX_T_CN;
+
+ machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_T_CN;
+ machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_T_CN;
+ machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_T_CN;
+ machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_T_CN;
+ machine_menu.DeltaHeight = DELTA_HEIGHT_T_CN;
+ machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_T_CN;
+ machine_menu.EffectorOffset = EFFECTOR_OFFSET_T_CN;
+ machine_menu.CalibrationRadius = CALIBRATION_RADIUS_T_CN;
+
+ machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_T_CN;
+
+ machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_T_CN;
+ machine_menu.NozzleConf = NOZZLE_CONF_T_CN;
+ machine_menu.HotBedConf = HOTBED_CONF_T_CN;
+ machine_menu.PreheatTemperConf = PREHEAT_TEMPER_T_CN;
+
+ machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_T_CN;
+ machine_menu.NozzleCnt = NOZZLECNT_T_CN;
+ machine_menu.NozzleType = NOZZLE_TYPE_T_CN;
+ machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_T_CN;
+ machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_T_CN;
+ machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_T_CN;
+ machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_T_CN;
+
+ machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_T_CN;
+ machine_menu.HotbedAjustType = HOTBED_ADJUST_T_CN;
+ machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_T_CN;
+ machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_T_CN;
+
+ machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_T_CN;
+ machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_T_CN;
+ machine_menu.AccelerationConf = ACCELERATION_CONF_T_CN;
+ machine_menu.JerkConf = JERKCONF_T_CN;
+ machine_menu.StepsConf = STEPSCONF_T_CN;
+ machine_menu.TMCcurrentConf = TMC_CURRENT_T_CN;
+ machine_menu.TMCStepModeConf = TMC_STEP_MODE_T_CN;
+ machine_menu.MotorDirConf = MOTORDIRCONF_T_CN;
+ machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_T_CN;
+ machine_menu.PausePosition = PAUSE_POSITION_T_CN;
+ machine_menu.WifiSettings = WIFI_SETTINGS_T_CN;
+ machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_T_CN;
+ machine_menu.EncoderSettings = ENCODER_SETTINGS_T_CN;
+
+ machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_T_CN;
+ machine_menu.XMaxFeedRate = X_MAXFEEDRATE_T_CN;
+ machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_T_CN;
+ machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_T_CN;
+ machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_T_CN;
+ machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_T_CN;
+
+ machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_T_CN;
+ machine_menu.PrintAcceleration = PRINT_ACCELERATION_T_CN;
+ machine_menu.RetractAcceleration = RETRACT_ACCELERATION_T_CN;
+ machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_T_CN;
+ machine_menu.X_Acceleration = X_ACCELERATION_T_CN;
+ machine_menu.Y_Acceleration = Y_ACCELERATION_T_CN;
+ machine_menu.Z_Acceleration = Z_ACCELERATION_T_CN;
+ machine_menu.E0_Acceleration = E0_ACCELERATION_T_CN;
+ machine_menu.E1_Acceleration = E1_ACCELERATION_T_CN;
+
+ machine_menu.JerkConfTitle = JERK_CONF_TITLE_T_CN;
+ machine_menu.X_Jerk = X_JERK_T_CN;
+ machine_menu.Y_Jerk = Y_JERK_T_CN;
+ machine_menu.Z_Jerk = Z_JERK_T_CN;
+ machine_menu.E_Jerk = E_JERK_T_CN;
+
+ machine_menu.StepsConfTitle = STEPS_CONF_TITLE_T_CN;
+ machine_menu.X_Steps = X_STEPS_T_CN;
+ machine_menu.Y_Steps = Y_STEPS_T_CN;
+ machine_menu.Z_Steps = Z_STEPS_T_CN;
+ machine_menu.E0_Steps = E0_STEPS_T_CN;
+ machine_menu.E1_Steps = E1_STEPS_T_CN;
+
+ machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_T_CN;
+ machine_menu.X_Current = X_TMC_CURRENT_T_CN;
+ machine_menu.Y_Current = Y_TMC_CURRENT_T_CN;
+ machine_menu.Z_Current = Z_TMC_CURRENT_T_CN;
+ machine_menu.E0_Current = E0_TMC_CURRENT_T_CN;
+ machine_menu.E1_Current = E1_TMC_CURRENT_T_CN;
+
+ machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_T_CN;
+ machine_menu.X_StepMode = X_TMC_MODE_T_CN;
+ machine_menu.Y_StepMode = Y_TMC_MODE_T_CN;
+ machine_menu.Z_StepMode = Z_TMC_MODE_T_CN;
+ machine_menu.E0_StepMode = E0_TMC_MODE_T_CN;
+ machine_menu.E1_StepMode = E1_TMC_MODE_T_CN;
+
+ machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_T_CN;
+ machine_menu.X_MotorDir = X_MOTORDIR_T_CN;
+ machine_menu.Y_MotorDir = Y_MOTORDIR_T_CN;
+ machine_menu.Z_MotorDir = Z_MOTORDIR_T_CN;
+ machine_menu.E0_MotorDir = E0_MOTORDIR_T_CN;
+ machine_menu.E1_MotorDir = E1_MOTORDIR_T_CN;
+ machine_menu.Invert_0 = INVERT_P_T_CN;
+ machine_menu.Invert_1 = INVERT_N_T_CN;
+
+ machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_T_CN;
+ machine_menu.XY_HomeFeedRate = X_HOMESPEED_T_CN;
+ machine_menu.Z_HomeFeedRate = Z_HOMESPEED_T_CN;
+
+ machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_T_CN;
+ machine_menu.PwrOffDection = PWROFF_DECTION_T_CN;
+ machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_T_CN;
+ machine_menu.HaveUps = HAVE_UPS_T_CN;
+ machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_T_CN;
+ machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_T_CN;
+
+ machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_T_CN;
+ machine_menu.Z2Enable = Z2_ENABLE_T_CN;
+ machine_menu.Z2EndstopEnable = Z2_ENDSTOP_T_CN;
+ machine_menu.Z2Port = Z2_PORT_T_CN;
+
+ machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_T_CN;
+ machine_menu.XInvert = X_ENABLE_PINS_INVERT_T_CN;
+ machine_menu.YInvert = Y_ENABLE_PINS_INVERT_T_CN;
+ machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_T_CN;
+ machine_menu.EInvert = E_ENABLE_PINS_INVERT_T_CN;
+
+ machine_menu.key_back = KEY_BACK_T_CN;
+ machine_menu.key_reset = KEY_REST_T_CN;
+ machine_menu.key_confirm = KEY_CONFIRM_T_CN;
+
+ machine_menu.PausePosText = PAUSE_POSITION_T_CN;
+ machine_menu.xPos = PAUSE_POSITION_X_T_CN;
+ machine_menu.yPos = PAUSE_POSITION_Y_T_CN;
+ machine_menu.zPos = PAUSE_POSITION_Z_T_CN;
+
+ machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_T_CN;
+ machine_menu.wifiMode = WIFI_SETTINGS_MODE_T_CN;
+ machine_menu.wifiName = WIFI_SETTINGS_NAME_T_CN;
+ machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_T_CN;
+ machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_T_CN;
+ machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_T_CN;
+ machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_T_CN;
+ machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_T_CN;
+
+ machine_menu.OffsetConfTitle = OFFSET_TITLE_T_CN;
+ machine_menu.Xoffset = OFFSET_X_T_CN;
+ machine_menu.Yoffset = OFFSET_Y_T_CN;
+ machine_menu.Zoffset = OFFSET_Z_T_CN;
+
+ machine_menu.LevelingTouchmiConf = LEVELING_TOUCHMI_T_CN;
+ machine_menu.TouchmiInit = TM_INIT_T_CN;
+ machine_menu.TouchmiOffsetpos = TM_ZOFFSETPOS_T_CN;
+ machine_menu.TouchmiOffsetneg = TM_ZOFFSETNEG_T_CN;
+ machine_menu.TouchmiSave = TM_SAVE_T_CN;
+ machine_menu.TouchmiTest = TM_TEST_T_CN;
+
+ machine_menu.BLTouchLevelingConfTitle = BLTOUCH_LEVELING_TITTLE_T_CN;
+ machine_menu.BLTouchLevelingConf = BLTOUCH_LEVELING_T_CN;
+ machine_menu.BLTouchInit = BLTOUCH_INIT_T_CN;
+ machine_menu.BLTouchOffsetpos = BLTOUCH_ZOFFSETPOS_T_CN;
+ machine_menu.BLTouchOffsetneg = BLTOUCH_ZOFFSETNEG_T_CN;
+ machine_menu.BLTouchSave = BLTOUCH_SAVE_T_CN;
+ machine_menu.BLTouchTest = BLTOUCH_TEST_T_CN;
+
+ machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_T_CN;
+ machine_menu.X_Sensitivity = X_SENSITIVITY_T_CN;
+ machine_menu.Y_Sensitivity = Y_SENSITIVITY_T_CN;
+ machine_menu.Z_Sensitivity = Z_SENSITIVITY_T_CN;
+ machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_T_CN;
+
+ machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_T_CN;
+ machine_menu.EncoderConfText = ENCODER_CONF_TEXT_T_CN;
+ }
+ else {
+ MachinePara_menu.title = MACHINE_PARA_TITLE_EN;
+ MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_EN;
+ MachinePara_menu.MotorSetting = MOTOR_CONFIG_EN;
+ MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_EN;
+ MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_EN;
+
+ machine_menu.default_value = DEFAULT_EN;
+ machine_menu.next = NEXT_EN;
+ machine_menu.previous = PREVIOUS_EN;
+
+ machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_EN;
+ machine_menu.MachineType = MACHINE_TYPE_EN;
+ machine_menu.Stroke = MACHINE_STROKE_EN;
+ machine_menu.HomeDir = MACHINE_HOMEDIR_EN;
+ machine_menu.EndStopType = MACHINE_ENDSTOP_TYPE_EN;
+ machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_EN;
+
+ machine_menu.MachineTypeConfTitle = MACHINE_TYPE_CONFIG_TITLE_EN;
+ machine_menu.xyz = MACHINE_TYPE_XYZ_EN;
+ machine_menu.delta = MACHINE_TYPE_DELTA_EN;
+ machine_menu.corexy = MACHINE_TYPE_COREXY_EN;
+
+ machine_menu.StrokeConfTitle = MACHINE_STROKE_CONF_TITLE_EN;
+ machine_menu.xStroke = X_MAX_LENGTH_EN;
+ machine_menu.yStroke = Y_MAX_LENGTH_EN;
+ machine_menu.zStroke = Z_MAX_LENGTH_EN;
+
+ machine_menu.xmin = X_MIN_LENGTH_EN;
+ machine_menu.ymin = Y_MIN_LENGTH_EN;
+ machine_menu.zmin = Z_MIN_LENGTH_EN;
+
+ machine_menu.HomeDirConfTitle = HOME_DIR_CONF_TITLE_EN;
+ machine_menu.xHomeDir = HOME_DIR_X_EN;
+ machine_menu.yHomeDir = HOME_DIR_Y_EN;
+ machine_menu.zHomeDir = HOME_DIR_Z_EN;
+ machine_menu.min = HOME_MIN_EN;
+ machine_menu.max = HOME_MAX_EN;
+
+ machine_menu.EndstopConfTitle = ENDSTOP_CONF_TITLE_EN;
+ machine_menu.xEndstop_min = MIN_ENDSTOP_X_EN;
+ machine_menu.yEndstop_min = MIN_ENDSTOP_Y_EN;
+ machine_menu.zEndstop_min = MIN_ENDSTOP_Z_EN;
+ machine_menu.xEndstop_max = MAX_ENDSTOP_X_EN;
+ machine_menu.yEndstop_max = MAX_ENDSTOP_Y_EN;
+ machine_menu.zEndstop_max = MAX_ENDSTOP_Z_EN;
+ machine_menu.FilamentEndstop = ENDSTOP_FIL_EN;
+ machine_menu.LevelingEndstop = ENDSTOP_LEVEL_EN;
+ machine_menu.opened = ENDSTOP_OPENED_EN;
+ machine_menu.closed = ENDSTOP_CLOSED_EN;
+
+ machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_EN;
+ machine_menu.InLength = FILAMENT_IN_LENGTH_EN;
+ machine_menu.InSpeed = FILAMENT_IN_SPEED_EN;
+ machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_EN;
+ machine_menu.OutLength = FILAMENT_OUT_LENGTH_EN;
+ machine_menu.OutSpeed = FILAMENT_OUT_SPEED_EN;
+
+ machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_EN;
+ machine_menu.LevelingParaConf = LEVELING_PARA_CONF_EN;
+ machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_EN;
+ machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_EN;
+ machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_EN;
+
+ machine_menu.LevelingSubConfTitle = LEVELING_PARA_CONF_TITLE_EN;
+ machine_menu.AutoLevelEnable = AUTO_LEVELING_ENABLE_EN;
+ machine_menu.BLtouchEnable = BLTOUCH_LEVELING_ENABLE_EN;
+ machine_menu.ProbePort = PROBE_PORT_EN;
+ machine_menu.ProbeXoffset = PROBE_X_OFFSET_EN;
+ machine_menu.ProbeYoffset = PROBE_Y_OFFSET_EN;
+ machine_menu.ProbeZoffset = PROBE_Z_OFFSET_EN;
+ machine_menu.ProbeXYspeed = PROBE_XY_SPEED_EN;
+ machine_menu.ProbeZspeed = PROBE_Z_SPEED_EN;
+ machine_menu.enable = ENABLE_EN;
+ machine_menu.disable = DISABLE_EN;
+ machine_menu.locked = LOCKED_EN;
+ machine_menu.z_min = Z_MIN_EN;
+ machine_menu.z_max = Z_MAX_EN;
+
+ machine_menu.LevelingSubDeltaConfTitle = DELTA_LEVEL_CONF_TITLE_EN;
+ machine_menu.MachineRadius = DELTA_MACHINE_RADIUS_EN;
+ machine_menu.DiagonalRod = DELTA_DIAGONAL_ROD_EN;
+ machine_menu.PrintableRadius = DELTA_PRINT_RADIUS_EN;
+ machine_menu.DeltaHeight = DELTA_HEIGHT_EN;
+ machine_menu.SmoothRodOffset = SMOOTH_ROD_OFFSET_EN;
+ machine_menu.EffectorOffset = EFFECTOR_OFFSET_EN;
+ machine_menu.CalibrationRadius = CALIBRATION_RADIUS_EN;
+
+ machine_menu.LevelingSubXYZConfTitle = XYZ_LEVEL_CONF_TITLE_EN;
+
+ machine_menu.TemperatureConfTitle = TEMPERATURE_CONF_TITLE_EN;
+ machine_menu.NozzleConf = NOZZLE_CONF_EN;
+ machine_menu.HotBedConf = HOTBED_CONF_EN;
+ machine_menu.PreheatTemperConf = PREHEAT_TEMPER_EN;
+
+ machine_menu.NozzleConfTitle = NOZZLE_CONF_TITLE_EN;
+ machine_menu.NozzleCnt = NOZZLECNT_EN;
+ machine_menu.NozzleType = NOZZLE_TYPE_EN;
+ machine_menu.NozzleAdjustType = NOZZLE_ADJUST_TYPE_EN;
+ machine_menu.NozzleMinTemperature = NOZZLE_MIN_TEMPERATURE_EN;
+ machine_menu.NozzleMaxTemperature = NOZZLE_MAX_TEMPERATURE_EN;
+ machine_menu.Extrude_Min_Temper = EXTRUD_MIN_TEMPER_EN;
+
+ machine_menu.HotbedEnable = HOTBED_ENABLE_EN;
+ machine_menu.HotbedConfTitle = HOTBED_CONF_TITLE_EN;
+ machine_menu.HotbedAjustType = HOTBED_ADJUST_EN;
+ machine_menu.HotbedMinTemperature = HOTBED_MIN_TEMPERATURE_EN;
+ machine_menu.HotbedMaxTemperature = HOTBED_MAX_TEMPERATURE_EN;
+
+ machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_EN;
+ machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_EN;
+ machine_menu.AccelerationConf = ACCELERATION_CONF_EN;
+ machine_menu.JerkConf = JERKCONF_EN;
+ machine_menu.StepsConf = STEPSCONF_EN;
+ machine_menu.TMCcurrentConf = TMC_CURRENT_EN;
+ machine_menu.TMCStepModeConf = TMC_STEP_MODE_EN;
+ machine_menu.MotorDirConf = MOTORDIRCONF_EN;
+ machine_menu.HomeFeedRateConf = HOMEFEEDRATECONF_EN;
+ machine_menu.PausePosition = PAUSE_POSITION_EN;
+ machine_menu.WifiSettings = WIFI_SETTINGS_EN;
+ machine_menu.HomingSensitivityConf = HOMING_SENSITIVITY_CONF_EN;
+ machine_menu.EncoderSettings = ENCODER_SETTINGS_EN;
+
+ machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_EN;
+ machine_menu.XMaxFeedRate = X_MAXFEEDRATE_EN;
+ machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_EN;
+ machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_EN;
+ machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_EN;
+ machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_EN;
+
+ machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_EN;
+ machine_menu.PrintAcceleration = PRINT_ACCELERATION_EN;
+ machine_menu.RetractAcceleration = RETRACT_ACCELERATION_EN;
+ machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_EN;
+ machine_menu.X_Acceleration = X_ACCELERATION_EN;
+ machine_menu.Y_Acceleration = Y_ACCELERATION_EN;
+ machine_menu.Z_Acceleration = Z_ACCELERATION_EN;
+ machine_menu.E0_Acceleration = E0_ACCELERATION_EN;
+ machine_menu.E1_Acceleration = E1_ACCELERATION_EN;
+
+ machine_menu.JerkConfTitle = JERK_CONF_TITLE_EN;
+ machine_menu.X_Jerk = X_JERK_EN;
+ machine_menu.Y_Jerk = Y_JERK_EN;
+ machine_menu.Z_Jerk = Z_JERK_EN;
+ machine_menu.E_Jerk = E_JERK_EN;
+
+ machine_menu.StepsConfTitle = STEPS_CONF_TITLE_EN;
+ machine_menu.X_Steps = X_STEPS_EN;
+ machine_menu.Y_Steps = Y_STEPS_EN;
+ machine_menu.Z_Steps = Z_STEPS_EN;
+ machine_menu.E0_Steps = E0_STEPS_EN;
+ machine_menu.E1_Steps = E1_STEPS_EN;
+
+ machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_EN;
+ machine_menu.X_Current = X_TMC_CURRENT_EN;
+ machine_menu.Y_Current = Y_TMC_CURRENT_EN;
+ machine_menu.Z_Current = Z_TMC_CURRENT_EN;
+ machine_menu.E0_Current = E0_TMC_CURRENT_EN;
+ machine_menu.E1_Current = E1_TMC_CURRENT_EN;
+
+ machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_EN;
+ machine_menu.X_StepMode = X_TMC_MODE_EN;
+ machine_menu.Y_StepMode = Y_TMC_MODE_EN;
+ machine_menu.Z_StepMode = Z_TMC_MODE_EN;
+ machine_menu.E0_StepMode = E0_TMC_MODE_EN;
+ machine_menu.E1_StepMode = E1_TMC_MODE_EN;
+
+ machine_menu.MotorDirConfTitle = MOTORDIR_CONF_TITLE_EN;
+ machine_menu.X_MotorDir = X_MOTORDIR_EN;
+ machine_menu.Y_MotorDir = Y_MOTORDIR_EN;
+ machine_menu.Z_MotorDir = Z_MOTORDIR_EN;
+ machine_menu.E0_MotorDir = E0_MOTORDIR_EN;
+ machine_menu.E1_MotorDir = E1_MOTORDIR_EN;
+ machine_menu.Invert_0 = INVERT_P_EN;
+ machine_menu.Invert_1 = INVERT_N_EN;
+
+ machine_menu.HomeFeedRateConfTitle = HOMEFEEDRATE_CONF_TITLE_EN;
+ machine_menu.XY_HomeFeedRate = X_HOMESPEED_EN;
+ machine_menu.Z_HomeFeedRate = Z_HOMESPEED_EN;
+
+ machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_EN;
+ machine_menu.PwrOffDection = PWROFF_DECTION_EN;
+ machine_menu.PwrOffAfterPrint = PWROFF_AFTER_PRINT_EN;
+ machine_menu.HaveUps = HAVE_UPS_EN;
+ machine_menu.Z2andZ2Endstop = Z2_AND_Z2ENDSTOP_CONF_EN;
+ machine_menu.EnablePinsInvert = ENABLE_PINS_CONF_EN;
+
+ machine_menu.Z2ConfTitle = Z2_AND_Z2ENDSTOP_CONF_TITLE_EN;
+ machine_menu.Z2Enable = Z2_ENABLE_EN;
+ machine_menu.Z2EndstopEnable = Z2_ENDSTOP_EN;
+ machine_menu.Z2Port = Z2_PORT_EN;
+
+ machine_menu.EnablePinsInvertTitle = ENABLE_PINS_CONF_TITLE_EN;
+ machine_menu.XInvert = X_ENABLE_PINS_INVERT_EN;
+ machine_menu.YInvert = Y_ENABLE_PINS_INVERT_EN;
+ machine_menu.ZInvert = Z_ENABLE_PINS_INVERT_EN;
+ machine_menu.EInvert = E_ENABLE_PINS_INVERT_EN;
+
+ machine_menu.key_back = KEY_BACK_EN;
+ machine_menu.key_reset = KEY_REST_EN;
+ machine_menu.key_confirm = KEY_CONFIRM_EN;
+ //
+ machine_menu.high_level = MOTOR_EN_HIGH_LEVEL_EN;
+ machine_menu.low_level = MOTOR_EN_LOW_LEVEL_EN;
+
+ machine_menu.PausePosText = PAUSE_POSITION_EN;
+ machine_menu.xPos = PAUSE_POSITION_X_EN;
+ machine_menu.yPos = PAUSE_POSITION_Y_EN;
+ machine_menu.zPos = PAUSE_POSITION_Z_EN;
+ machine_menu.WifiConfTitle = WIFI_SETTINGS_TITLE_EN;
+ machine_menu.wifiMode = WIFI_SETTINGS_MODE_EN;
+ machine_menu.wifiName = WIFI_SETTINGS_NAME_EN;
+ machine_menu.wifiPassWord = WIFI_SETTINGS_PASSWORD_EN;
+ machine_menu.wifiCloud = WIFI_SETTINGS_CLOUD_EN;
+ machine_menu.wifiConfig = WIFI_SETTINGS_CONFIG_EN;
+ machine_menu.wifiEdit = WIFI_SETTINGS_EDIT_EN;
+ machine_menu.wifiConfigTips = WIFI_CONFIG_TIPS_EN;
+
+ machine_menu.OffsetConfTitle = OFFSET_TITLE_EN;
+ machine_menu.Xoffset = OFFSET_X_EN;
+ machine_menu.Yoffset = OFFSET_Y_EN;
+ machine_menu.Zoffset = OFFSET_Z_EN;
+
+ machine_menu.LevelingTouchmiConf = LEVELING_TOUCHMI_EN;
+ machine_menu.TouchmiInit = TM_INIT_EN;
+ machine_menu.TouchmiOffsetpos = TM_ZOFFSETPOS_EN;
+ machine_menu.TouchmiOffsetneg = TM_ZOFFSETNEG_EN;
+ machine_menu.TouchmiSave = TM_SAVE_EN;
+ machine_menu.TouchmiTest = TM_TEST_EN;
+
+ machine_menu.BLTouchLevelingConfTitle = BLTOUCH_LEVELING_TITTLE_EN;
+ machine_menu.BLTouchLevelingConf = BLTOUCH_LEVELING_EN;
+ machine_menu.BLTouchInit = BLTOUCH_INIT_EN;
+ machine_menu.BLTouchOffsetpos = BLTOUCH_ZOFFSETPOS_EN;
+ machine_menu.BLTouchOffsetneg = BLTOUCH_ZOFFSETNEG_EN;
+ machine_menu.BLTouchSave = BLTOUCH_SAVE_EN;
+ machine_menu.BLTouchTest = BLTOUCH_TEST_EN;
+
+ machine_menu.HomingSensitivityConfTitle = HOMING_SENSITIVITY_CONF_TITLE_EN;
+ machine_menu.X_Sensitivity = X_SENSITIVITY_EN;
+ machine_menu.Y_Sensitivity = Y_SENSITIVITY_EN;
+ machine_menu.Z_Sensitivity = Z_SENSITIVITY_EN;
+ machine_menu.Z2_Sensitivity = Z2_SENSITIVITY_EN;
+
+ machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_EN;
+ machine_menu.EncoderConfText = ENCODER_CONF_TEXT_EN;
+ }
+}
+
+void disp_language_init() {
+ preheat_menu.value_state = TEXT_VALUE;
+ preheat_menu.step_1c = TEXT_1C;
+ preheat_menu.step_5c = TEXT_5C;
+ preheat_menu.step_10c = TEXT_10C;
+
+ move_menu.x_add = AXIS_X_ADD_TEXT;
+ move_menu.x_dec = AXIS_X_DEC_TEXT;
+ move_menu.y_add = AXIS_Y_ADD_TEXT;
+ move_menu.y_dec = AXIS_Y_DEC_TEXT;
+ move_menu.z_add = AXIS_Z_ADD_TEXT;
+ move_menu.z_dec = AXIS_Z_DEC_TEXT;
+
+ move_menu.step_001mm = TEXT_001MM;
+ move_menu.step_005mm = TEXT_005MM;
+ move_menu.step_01mm = TEXT_01MM;
+ move_menu.step_1mm = TEXT_1MM;
+ move_menu.step_10mm = TEXT_10MM;
+
+ home_menu.home_x = HOME_X_TEXT;
+ home_menu.home_y = HOME_Y_TEXT;
+ home_menu.home_z = HOME_Z_TEXT;
+ home_menu.home_all = HOME_ALL_TEXT;
+
+ extrude_menu.temp_value = TEXT_VALUE_T;
+ extrude_menu.count_value_mm = TEXT_VALUE_mm;
+ extrude_menu.count_value_cm = TEXT_VALUE_cm;
+ extrude_menu.count_value_m = TEXT_VALUE_m;
+ extrude_menu.step_1mm = EXTRUDE_1MM_TEXT;
+ extrude_menu.step_5mm = EXTRUDE_5MM_TEXT;
+ extrude_menu.step_10mm = EXTRUDE_10MM_TEXT;
+
+ fan_menu.full = FAN_OPEN_TEXT;
+ fan_menu.half = FAN_HALF_TEXT;
+ fan_menu.off = FAN_CLOSE_TEXT;
+
+ speed_menu.step_1percent = STEP_1PERCENT;
+ speed_menu.step_5percent = STEP_5PERCENT;
+ speed_menu.step_10percent = STEP_10PERCENT;
+
+ language_menu.chinese_s = LANGUAGE_S_CN;
+ language_menu.chinese_t = LANGUAGE_T_CN;
+ language_menu.english = LANGUAGE_EN;
+ language_menu.russian = LANGUAGE_RU;
+ language_menu.spanish = LANGUAGE_SP;
+ language_menu.german = LANGUAGE_GE;
+ language_menu.japan = LANGUAGE_JP;
+ language_menu.korean = LANGUAGE_KR;
+ language_menu.portuguese = LANGUAGE_PR;
+ language_menu.italy = LANGUAGE_IT;
+ language_menu.brazil = LANGUAGE_BR;
+ language_menu.french = LANGUAGE_FR;
+
+ about_menu.type_name = ABOUT_TYPE_TEXT;
+ about_menu.firmware_v = ABOUT_VERSION_TEXT;
+
+ wifi_menu.ip = WIFI_IP_TEXT;
+ wifi_menu.wifi = WIFI_NAME_TEXT;
+ wifi_menu.key = WIFI_KEY_TEXT;
+ wifi_menu.state_ap = WIFI_STATE_AP_TEXT;
+ wifi_menu.state_sta = WIFI_STATE_STA_TEXT;
+ wifi_menu.connected = WIFI_CONNECTED_TEXT;
+ wifi_menu.disconnected = WIFI_DISCONNECTED_TEXT;
+ wifi_menu.exception = WIFI_EXCEPTION_TEXT;
+
+ printing_menu.temp1 = TEXT_VALUE;
+ printing_menu.temp2 = TEXT_VALUE;
+ printing_menu.bed_temp = TEXT_VALUE;
+
+ filament_menu.stat_temp = TEXT_VALUE;
+
+ machine_menu.key_0 = KEYBOARD_KEY0_EN;
+ machine_menu.key_1 = KEYBOARD_KEY1_EN;
+ machine_menu.key_2 = KEYBOARD_KEY2_EN;
+ machine_menu.key_3 = KEYBOARD_KEY3_EN;
+ machine_menu.key_4 = KEYBOARD_KEY4_EN;
+ machine_menu.key_5 = KEYBOARD_KEY5_EN;
+ machine_menu.key_6 = KEYBOARD_KEY6_EN;
+ machine_menu.key_7 = KEYBOARD_KEY7_EN;
+ machine_menu.key_8 = KEYBOARD_KEY8_EN;
+ machine_menu.key_9 = KEYBOARD_KEY9_EN;
+ machine_menu.key_point = KEYBOARD_KEY_POINT_EN;
+ machine_menu.negative = KEYBOARD_KEY_NEGATIVE_EN;
+ // wifi-list
+ #if ENABLED(MKS_WIFI_MODULE)
+ list_menu.title = TEXT_WIFI_MENU_TITLE_EN;
+ list_menu.file_pages = FILE_PAGES_EN;
+
+ // tips
+ tips_menu.joining = TEXT_WIFI_JOINING_EN;
+ tips_menu.failedJoin = TEXT_WIFI_FAILED_JOIN_EN;
+ tips_menu.wifiConected = TEXT_WIFI_WIFI_CONECTED_EN;
+ #endif
+ machine_setting_disp();
+
+ operation_menu.babystep = TEXT_BABY_STEP_EN;
+
+ switch (gCfgItems.language) {
+ case LANG_SIMPLE_CHINESE:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_CN;
+ common_menu.text_back = BACK_TEXT_CN;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_CN;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_CN;
+ common_menu.print_special_title = PRINTING_GBK;
+ common_menu.pause_special_title = PRINTING_PAUSE_GBK;
+ common_menu.operate_special_title = PRINTING_OPERATION_GBK;
+ //
+ main_menu.title = TITLE_READYPRINT_CN;
+ main_menu.preheat = PREHEAT_TEXT_CN;
+ main_menu.move = MOVE_TEXT_CN;
+ main_menu.home = HOME_TEXT_CN;
+ main_menu.print = PRINT_TEXT_CN;
+ main_menu.extrude = EXTRUDE_TEXT_CN;
+ main_menu.leveling = LEVELING_TEXT_CN;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_CN;
+ main_menu.fan = FAN_TEXT_CN;
+ main_menu.set = SET_TEXT_CN;
+ main_menu.more = MORE_TEXT_CN;
+ main_menu.tool = TOOL_TEXT_CN;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_CN;
+ tool_menu.preheat = TOOL_PREHEAT_CN;
+ tool_menu.extrude = TOOL_EXTRUDE_CN;
+ tool_menu.move = TOOL_MOVE_CN;
+ tool_menu.home = TOOL_HOME_CN;
+ tool_menu.leveling = TOOL_LEVELING_CN;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_CN;
+ tool_menu.filament = TOOL_FILAMENT_CN;
+ tool_menu.more = TOOL_MORE_CN;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_CN;
+ preheat_menu.title = TITLE_PREHEAT_CN;
+ preheat_menu.add = ADD_TEXT_CN;
+ preheat_menu.dec = DEC_TEXT_CN;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_CN;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_CN;
+ preheat_menu.hotbed = HEATBED_TEXT_CN;
+ preheat_menu.off = CLOSE_TEXT_CN;
+
+ preheat_menu.value_state = TEXT_VALUE_CN;
+ preheat_menu.step_1c = TEXT_1C_CN;
+ preheat_menu.step_5c = TEXT_5C_CN;
+ preheat_menu.step_10c = TEXT_10C_CN;
+ //
+ move_menu.title = MOVE_TEXT_CN;
+ //
+ home_menu.title = TITLE_HOME_CN;
+ home_menu.stopmove = HOME_STOPMOVE_CN;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_CN;
+ file_menu.page_up = PAGE_UP_TEXT_CN;
+ file_menu.page_down = PAGE_DOWN_TEXT_CN;
+ file_menu.file_loading = FILE_LOADING_CN;
+ file_menu.no_file = NO_FILE_CN;
+ file_menu.no_file_and_check = NO_FILE_CN;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_CN;
+ extrude_menu.in = EXTRUDER_IN_TEXT_CN;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_CN;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_CN;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_CN;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_CN;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_CN;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_CN;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_CN;
+ extrude_menu.temp_value = EXTRUDE_TEXT_VALUE_T_CN;
+ //
+ leveling_menu.title = TITLE_LEVELING_CN;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_CN;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_CN;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_CN;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_CN;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_CN;
+ //
+ set_menu.title = TITLE_SET_CN;
+ set_menu.filesys = FILESYS_TEXT_CN;
+ set_menu.wifi = WIFI_TEXT_CN;
+ set_menu.about = ABOUT_TEXT_CN;
+ set_menu.fan = FAN_TEXT_CN;
+ set_menu.filament = FILAMENT_TEXT_CN;
+ set_menu.breakpoint = BREAK_POINT_TEXT_CN;
+ set_menu.motoroff = MOTOR_OFF_TEXT_CN;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_CN;
+ set_menu.language = LANGUAGE_TEXT_CN;
+ set_menu.shutdown = SHUTDOWN_TEXT_CN;
+ set_menu.machine_para = MACHINE_PARA_CN;
+ set_menu.eepromSet = EEPROM_SETTINGS_CN;
+ //
+ filesys_menu.title = TITLE_FILESYS_CN;
+ filesys_menu.sd_sys = SD_CARD_TEXT_CN;
+ filesys_menu.usb_sys = U_DISK_TEXT_CN;
+ //
+ more_menu.title = TITLE_MORE_CN;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_CN;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_CN;
+ #endif
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_CN;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_CN;
+ // CLOUD
+ cloud_menu.title = TITLE_CLOUD_TEXT_CN;
+ cloud_menu.bind = CLOUD_BINDED_CN;
+ cloud_menu.binded = CLOUD_BINDED_CN;
+ cloud_menu.unbind = CLOUD_UNBIND_CN;
+ cloud_menu.unbinding = CLOUD_UNBINDED_CN;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_CN;
+ cloud_menu.unbinded = CLOUD_UNBINDED_CN;
+ cloud_menu.disable = CLOUD_DISABLE_CN;
+ //
+ about_menu.title = ABOUT_TEXT_CN;
+ about_menu.type = ABOUT_TYPE_TEXT_CN;
+ about_menu.version = ABOUT_VERSION_TEXT_CN;
+ about_menu.wifi = ABOUT_WIFI_TEXT_CN;
+
+ //
+ fan_menu.title = FAN_TEXT_CN;
+ fan_menu.add = FAN_ADD_TEXT_CN;
+ fan_menu.dec = FAN_DEC_TEXT_CN;
+ fan_menu.state = FAN_TIPS1_TEXT_CN;
+ //
+ filament_menu.title = TITLE_FILAMENT_CN;
+ filament_menu.in = FILAMENT_IN_TEXT_CN;
+ filament_menu.out = FILAMENT_OUT_TEXT_CN;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_CN;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_CN;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_CN;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_CN;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_CN;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_CN;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_CN;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_CN;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_CN;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_CN;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_CN;
+
+
+ //
+ language_menu.title = TITLE_LANGUAGE_CN;
+ language_menu.next = PAGE_DOWN_TEXT_CN;
+ language_menu.up = PAGE_UP_TEXT_CN;
+
+ //
+ printing_menu.title = TITLE_PRINTING_CN;
+ printing_menu.option = PRINTING_OPERATION_CN;
+ printing_menu.stop = PRINTING_STOP_CN;
+ printing_menu.pause = PRINTING_PAUSE_CN;
+ printing_menu.resume = PRINTING_RESUME_CN;
+
+ //
+ operation_menu.title = TITLE_OPERATION_CN;
+ operation_menu.pause = PRINTING_PAUSE_CN;
+ operation_menu.stop = PRINTING_STOP_CN;
+ operation_menu.temp = PRINTING_TEMP_CN;
+ operation_menu.fan = FAN_TEXT_CN;
+ operation_menu.filament = FILAMENT_TEXT_CN;
+ operation_menu.extr = PRINTING_EXTRUDER_CN;
+ operation_menu.speed = PRINTING_CHANGESPEED_CN;
+ operation_menu.more = PRINTING_MORE_CN;
+ operation_menu.move = PRINTING_MOVE_CN;
+ operation_menu.auto_off = AUTO_SHUTDOWN_CN;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_CN;
+ //
+ pause_menu.title = TITLE_PAUSE_CN;
+ pause_menu.resume = PRINTING_RESUME_CN;
+ pause_menu.stop = PRINTING_STOP_CN;
+ pause_menu.extrude = PRINTING_EXTRUDER_CN;
+ pause_menu.move = PRINTING_MOVE_CN;
+ pause_menu.filament = FILAMENT_TEXT_CN;
+ pause_menu.more = PRINTING_MORE_CN;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_CN;
+ speed_menu.add = ADD_TEXT_CN;
+ speed_menu.dec = DEC_TEXT_CN;
+ speed_menu.move = MOVE_SPEED_CN;
+ speed_menu.extrude = EXTRUDER_SPEED_CN;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_CN;
+ speed_menu.move_speed = MOVE_SPEED_STATE_CN;
+ //
+ printing_more_menu.title = TITLE_MORE_CN;
+ printing_more_menu.fan = FAN_TEXT_CN;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_CN;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_CN;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_CN;
+ printing_more_menu.temp = PRINTING_TEMP_CN;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_CN;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_CN;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_CN;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_CN;
+ print_file_dialog_menu.retry = DIALOG_RETRY_CN;
+ print_file_dialog_menu.stop = DIALOG_STOP_CN;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_CN;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_CN;
+
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_CN;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_CN;
+
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_CN;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_CN;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_CN;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_CN;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_CN;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_CN;
+ pause_msg_menu.changing = MESSAGE_CHANGING_CN;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_CN;
+ pause_msg_menu.waiting = MESSAGE_WAITING_CN;
+ pause_msg_menu.insert = MESSAGE_INSERT_CN;
+ pause_msg_menu.load = MESSAGE_LOAD_CN;
+ pause_msg_menu.purge = MESSAGE_PURGE_CN;
+ pause_msg_menu.resume = MESSAGE_RESUME_CN;
+ pause_msg_menu.heat = MESSAGE_HEAT_CN;
+ pause_msg_menu.heating = MESSAGE_HEATING_CN;
+ pause_msg_menu.option = MESSAGE_OPTION_CN;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_CN;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_CN;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_CN;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_CN;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_CN;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_CN;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_CN;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_CN;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_CN;
+ break;
+
+ #if 1
+ #if 1
+
+ case LANG_COMPLEX_CHINESE:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_T_CN;
+ common_menu.text_back = BACK_TEXT_T_CN;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_T_CN;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_T_CN;
+ common_menu.print_special_title = PRINTING_GBK;
+ common_menu.pause_special_title = PRINTING_PAUSE_GBK;
+ common_menu.operate_special_title = PRINTING_OPERATION_GBK;
+ //
+ main_menu.title = TITLE_READYPRINT_T_CN;
+ main_menu.preheat = PREHEAT_TEXT_T_CN;
+ main_menu.move = MOVE_TEXT_T_CN;
+ main_menu.home = HOME_TEXT_T_CN;
+ main_menu.print = PRINT_TEXT_T_CN;
+ main_menu.extrude = EXTRUDE_TEXT_T_CN;
+ main_menu.leveling = LEVELING_TEXT_T_CN;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_T_CN;
+ main_menu.fan = FAN_TEXT_T_CN;
+ main_menu.set = SET_TEXT_T_CN;
+ main_menu.more = MORE_TEXT_T_CN;
+ main_menu.tool = TOOL_TEXT_T_CN;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_T_CN;
+ tool_menu.preheat = TOOL_PREHEAT_T_CN;
+ tool_menu.extrude = TOOL_EXTRUDE_T_CN;
+ tool_menu.move = TOOL_MOVE_T_CN;
+ tool_menu.home = TOOL_HOME_T_CN;
+ tool_menu.leveling = TOOL_LEVELING_T_CN;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_T_CN;
+ tool_menu.filament = TOOL_FILAMENT_T_CN;
+ tool_menu.more = TOOL_MORE_T_CN;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_T_CN;
+ preheat_menu.title = TITLE_PREHEAT_T_CN;
+ preheat_menu.add = ADD_TEXT_T_CN;
+ preheat_menu.dec = DEC_TEXT_T_CN;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_T_CN;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_T_CN;
+ preheat_menu.hotbed = HEATBED_TEXT_T_CN;
+ preheat_menu.off = CLOSE_TEXT_T_CN;
+ preheat_menu.value_state = TEXT_VALUE_T_CN;
+ preheat_menu.step_1c = TEXT_1C_T_CN;
+ preheat_menu.step_5c = TEXT_5C_T_CN;
+ preheat_menu.step_10c = TEXT_10C_T_CN;
+ //
+ move_menu.title = MOVE_TEXT_T_CN;
+ //
+ home_menu.title = TITLE_HOME_T_CN;
+ home_menu.stopmove = HOME_STOPMOVE_T_CN;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_T_CN;
+ file_menu.page_up = PAGE_UP_TEXT_T_CN;
+ file_menu.page_down = PAGE_DOWN_TEXT_T_CN;
+ file_menu.file_loading = FILE_LOADING_T_CN;
+ file_menu.no_file = NO_FILE_T_CN;
+ file_menu.no_file_and_check = NO_FILE_T_CN;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_T_CN;
+ extrude_menu.in = EXTRUDER_IN_TEXT_T_CN;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_T_CN;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_T_CN;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_T_CN;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_T_CN;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_T_CN;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_T_CN;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_T_CN;
+ extrude_menu.temp_value = EXTRUDE_TEXT_VALUE_T_T_CN;
+ //
+ leveling_menu.title = TITLE_LEVELING_CN;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_T_CN;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_T_CN;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_T_CN;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_T_CN;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_T_CN;
+ //
+ set_menu.title = TITLE_SET_T_CN;
+ set_menu.filesys = FILESYS_TEXT_T_CN;
+ set_menu.wifi = WIFI_TEXT_T_CN;
+ set_menu.about = ABOUT_TEXT_T_CN;
+ set_menu.fan = FAN_TEXT_T_CN;
+ set_menu.filament = FILAMENT_TEXT_T_CN;
+ set_menu.breakpoint = BREAK_POINT_TEXT_T_CN;
+ set_menu.motoroff = MOTOR_OFF_TEXT_T_CN;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_T_CN;
+ set_menu.language = LANGUAGE_TEXT_T_CN;
+ set_menu.shutdown = SHUTDOWN_TEXT_T_CN;
+ set_menu.machine_para = MACHINE_PARA_T_CN;
+ set_menu.eepromSet = EEPROM_SETTINGS_T_CN;
+ filesys_menu.title = TITLE_FILESYS_T_CN;
+ filesys_menu.sd_sys = SD_CARD_TEXT_T_CN;
+ filesys_menu.usb_sys = U_DISK_TEXT_T_CN;
+ //
+ more_menu.title = TITLE_MORE_T_CN;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_T_CN;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_T_CN;
+ #endif
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_T_CN;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_T_CN;
+ // CLOUD
+ cloud_menu.title = TITLE_CLOUD_TEXT_T_CN;
+ cloud_menu.bind = CLOUD_BINDED_T_CN;
+ cloud_menu.binded = CLOUD_BINDED_T_CN;
+ cloud_menu.unbind = CLOUD_UNBIND_T_CN;
+ cloud_menu.unbinding = CLOUD_UNBINDED_T_CN;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_T_CN;
+ cloud_menu.unbinded = CLOUD_UNBINDED_T_CN;
+ cloud_menu.disable = CLOUD_DISABLE_T_CN;
+ //
+ about_menu.title = ABOUT_TEXT_T_CN;
+ about_menu.type = ABOUT_TYPE_TEXT_T_CN;
+ about_menu.version = ABOUT_VERSION_TEXT_T_CN;
+ about_menu.wifi = ABOUT_WIFI_TEXT_T_CN;
+
+ //
+ fan_menu.title = FAN_TEXT_T_CN;
+ fan_menu.add = FAN_ADD_TEXT_T_CN;
+ fan_menu.dec = FAN_DEC_TEXT_T_CN;
+ fan_menu.state = FAN_TIPS1_TEXT_T_CN;
+ //
+ filament_menu.title = TITLE_FILAMENT_T_CN;
+ filament_menu.in = FILAMENT_IN_TEXT_T_CN;
+ filament_menu.out = FILAMENT_OUT_TEXT_T_CN;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_T_CN;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_T_CN;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_T_CN;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_T_CN;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_T_CN;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_T_CN;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_T_CN;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_T_CN;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_T_CN;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_T_CN;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_T_CN;
+
+ //
+ language_menu.title = TITLE_LANGUAGE_T_CN;
+ language_menu.next = PAGE_DOWN_TEXT_T_CN;
+ language_menu.up = PAGE_UP_TEXT_T_CN;
+
+ //
+ printing_menu.title = TITLE_PRINTING_T_CN;
+ printing_menu.option = PRINTING_OPERATION_T_CN;
+ printing_menu.stop = PRINTING_STOP_T_CN;
+ printing_menu.pause = PRINTING_PAUSE_T_CN;
+ printing_menu.resume = PRINTING_RESUME_T_CN;
+
+ //
+ operation_menu.title = TITLE_OPERATION_T_CN;
+ operation_menu.pause = PRINTING_PAUSE_T_CN;
+ operation_menu.stop = PRINTING_STOP_T_CN;
+ operation_menu.temp = PRINTING_TEMP_T_CN;
+ operation_menu.fan = FAN_TEXT_T_CN;
+ operation_menu.extr = PRINTING_EXTRUDER_T_CN;
+ operation_menu.speed = PRINTING_CHANGESPEED_T_CN;
+ operation_menu.filament = FILAMENT_TEXT_T_CN;
+ operation_menu.more = PRINTING_MORE_T_CN;
+ operation_menu.move = PRINTING_MOVE_T_CN;
+ operation_menu.auto_off = AUTO_SHUTDOWN_T_CN;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_T_CN;
+ //
+ pause_menu.title = TITLE_PAUSE_T_CN;
+ pause_menu.resume = PRINTING_RESUME_T_CN;
+ pause_menu.stop = PRINTING_STOP_T_CN;
+ pause_menu.extrude = PRINTING_EXTRUDER_T_CN;
+ pause_menu.move = PRINTING_MOVE_T_CN;
+ pause_menu.filament = FILAMENT_TEXT_T_CN;
+ pause_menu.more = PRINTING_MORE_T_CN;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_T_CN;
+ speed_menu.add = ADD_TEXT_T_CN;
+ speed_menu.dec = DEC_TEXT_T_CN;
+ speed_menu.move = MOVE_SPEED_T_CN;
+ speed_menu.extrude = EXTRUDER_SPEED_T_CN;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_T_CN;
+ speed_menu.move_speed = MOVE_SPEED_STATE_T_CN;
+ //
+ printing_more_menu.title = TITLE_MORE_T_CN;
+ printing_more_menu.fan = FAN_TEXT_T_CN;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_T_CN;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_T_CN;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_T_CN;
+ printing_more_menu.temp = PRINTING_TEMP_T_CN;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_T_CN;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_T_CN;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_T_CN;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_T_CN;
+ print_file_dialog_menu.retry = DIALOG_RETRY_T_CN;
+ print_file_dialog_menu.stop = DIALOG_STOP_T_CN;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_T_CN;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_T_CN;
+
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_T_CN;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_T_CN;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_T_CN;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_T_CN;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_T_CN;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_T_CN;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_T_CN;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_T_CN;
+ pause_msg_menu.changing = MESSAGE_CHANGING_T_CN;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_T_CN;
+ pause_msg_menu.waiting = MESSAGE_WAITING_T_CN;
+ pause_msg_menu.insert = MESSAGE_INSERT_T_CN;
+ pause_msg_menu.load = MESSAGE_LOAD_T_CN;
+ pause_msg_menu.purge = MESSAGE_PURGE_T_CN;
+ pause_msg_menu.resume = MESSAGE_RESUME_T_CN;
+ pause_msg_menu.heat = MESSAGE_HEAT_T_CN;
+ pause_msg_menu.heating = MESSAGE_HEATING_T_CN;
+ pause_msg_menu.option = MESSAGE_OPTION_T_CN;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_T_CN;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_T_CN;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_T_CN;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_T_CN;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_T_CN;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_T_CN;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_T_CN;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_T_CN;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_T_CN;
+ break;
+ case LANG_ENGLISH:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_EN;
+ common_menu.text_back = BACK_TEXT_EN;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_EN;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_EN;
+ common_menu.print_special_title = PRINTING_OTHER_LANGUGE;
+ common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE;
+ common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE;
+ //
+ main_menu.title = TITLE_READYPRINT_EN;
+ main_menu.preheat = PREHEAT_TEXT_EN;
+ main_menu.move = MOVE_TEXT_EN;
+ main_menu.home = HOME_TEXT_EN;
+ main_menu.print = PRINT_TEXT_EN;
+ main_menu.extrude = EXTRUDE_TEXT_EN;
+ main_menu.leveling = LEVELING_TEXT_EN;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_EN;
+ main_menu.fan = FAN_TEXT_EN;
+ main_menu.set = SET_TEXT_EN;
+ main_menu.more = MORE_TEXT_EN;
+ main_menu.tool = TOOL_TEXT_EN;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_EN;
+ tool_menu.preheat = TOOL_PREHEAT_EN;
+ tool_menu.extrude = TOOL_EXTRUDE_EN;
+ tool_menu.move = TOOL_MOVE_EN;
+ tool_menu.home = TOOL_HOME_EN;
+ tool_menu.leveling = TOOL_LEVELING_EN;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_EN;
+ tool_menu.filament = TOOL_FILAMENT_EN;
+ tool_menu.more = TOOL_MORE_EN;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_EN;
+ preheat_menu.title = TITLE_PREHEAT_EN;
+ preheat_menu.add = ADD_TEXT_EN;
+ preheat_menu.dec = DEC_TEXT_EN;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_EN;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_EN;
+ preheat_menu.hotbed = HEATBED_TEXT_EN;
+ preheat_menu.off = CLOSE_TEXT_EN;
+ //
+ move_menu.title = TITLE_MOVE_EN;
+ //
+ home_menu.title = TITLE_HOME_EN;
+ home_menu.stopmove = HOME_STOPMOVE_EN;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_EN;
+ file_menu.page_up = PAGE_UP_TEXT_EN;
+ file_menu.page_down = PAGE_DOWN_TEXT_EN;
+ file_menu.file_loading = FILE_LOADING_EN;
+ file_menu.no_file = NO_FILE_EN;
+ file_menu.no_file_and_check = NO_FILE_EN;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_EN;
+ extrude_menu.in = EXTRUDER_IN_TEXT_EN;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_EN;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_EN;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_EN;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_EN;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_EN;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_EN;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_EN;
+ //
+ leveling_menu.title = TITLE_LEVELING_EN;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_EN;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_EN;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_EN;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_EN;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_EN;
+ //
+ set_menu.title = TITLE_SET_EN;
+ set_menu.filesys = FILESYS_TEXT_EN;
+ set_menu.wifi = WIFI_TEXT_EN;
+ set_menu.about = ABOUT_TEXT_EN;
+ set_menu.fan = FAN_TEXT_EN;
+ set_menu.filament = FILAMENT_TEXT_EN;
+ set_menu.breakpoint = BREAK_POINT_TEXT_EN;
+ set_menu.motoroff = MOTOR_OFF_TEXT_EN;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_EN;
+ set_menu.language = LANGUAGE_TEXT_EN;
+ set_menu.shutdown = SHUTDOWN_TEXT_EN;
+ set_menu.machine_para = MACHINE_PARA_EN;
+ set_menu.eepromSet = EEPROM_SETTINGS_EN;
+ more_menu.title = TITLE_MORE_EN;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_EN;
+ #endif
+
+ //
+ filesys_menu.title = TITLE_FILESYS_EN;
+ filesys_menu.sd_sys = SD_CARD_TEXT_EN;
+ filesys_menu.usb_sys = U_DISK_TEXT_EN;
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_EN;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_EN;
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_EN;
+ cloud_menu.bind = CLOUD_BINDED_EN;
+ cloud_menu.binded = CLOUD_BINDED_EN;
+ cloud_menu.unbind = CLOUD_UNBIND_EN;
+ cloud_menu.unbinding = CLOUD_UNBINDED_EN;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_EN;
+ cloud_menu.unbinded = CLOUD_UNBINDED_EN;
+ cloud_menu.disable = CLOUD_DISABLE_EN;
+ //
+ about_menu.title = TITLE_ABOUT_EN;
+ about_menu.type = ABOUT_TYPE_TEXT_EN;
+ about_menu.version = ABOUT_VERSION_TEXT_EN;
+ about_menu.wifi = ABOUT_WIFI_TEXT_EN;
+ //
+ fan_menu.title = TITLE_FAN_EN;
+ fan_menu.add = FAN_ADD_TEXT_EN;
+ fan_menu.dec = FAN_DEC_TEXT_EN;
+ fan_menu.state = FAN_TIPS1_TEXT_EN;
+ //
+ filament_menu.title = TITLE_FILAMENT_EN;
+ filament_menu.in = FILAMENT_IN_TEXT_EN;
+ filament_menu.out = FILAMENT_OUT_TEXT_EN;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_EN;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_EN;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_EN;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_EN;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_EN;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN;
+
+ //
+ language_menu.title = TITLE_LANGUAGE_EN;
+ language_menu.next = PAGE_DOWN_TEXT_EN;
+ language_menu.up = PAGE_UP_TEXT_EN;
+ //
+ printing_menu.title = TITLE_PRINTING_EN;
+ printing_menu.option = PRINTING_OPERATION_EN;
+ printing_menu.stop = PRINTING_STOP_EN;
+ printing_menu.pause = PRINTING_PAUSE_EN;
+ printing_menu.resume = PRINTING_RESUME_EN;
+
+ //
+ operation_menu.title = TITLE_OPERATION_EN;
+ operation_menu.pause = PRINTING_PAUSE_EN;
+ operation_menu.stop = PRINTING_STOP_EN;
+ operation_menu.temp = PRINTING_TEMP_EN;
+ operation_menu.fan = FAN_TEXT_EN;
+ operation_menu.extr = PRINTING_EXTRUDER_EN;
+ operation_menu.speed = PRINTING_CHANGESPEED_EN;
+ operation_menu.filament = FILAMENT_TEXT_EN;
+ operation_menu.more = PRINTING_MORE_EN;
+ operation_menu.move = PRINTING_MOVE_EN;
+ operation_menu.auto_off = AUTO_SHUTDOWN_EN;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_EN;
+ //
+ pause_menu.title = TITLE_PAUSE_EN;
+ pause_menu.resume = PRINTING_RESUME_EN;
+ pause_menu.stop = PRINTING_STOP_EN;
+ pause_menu.extrude = PRINTING_EXTRUDER_EN;
+ pause_menu.move = PRINTING_MOVE_EN;
+ pause_menu.filament = FILAMENT_TEXT_EN;
+ pause_menu.more = PRINTING_MORE_EN;
+
+ //
+ speed_menu.title = TITLE_CHANGESPEED_EN;
+ speed_menu.add = ADD_TEXT_EN;
+ speed_menu.dec = DEC_TEXT_EN;
+ speed_menu.move = MOVE_SPEED_EN;
+ speed_menu.extrude = EXTRUDER_SPEED_EN;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_EN;
+ speed_menu.move_speed = MOVE_SPEED_STATE_EN;
+ //
+ printing_more_menu.title = TITLE_MORE_EN;
+ printing_more_menu.fan = FAN_TEXT_EN;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_EN;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_EN;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_EN;
+ printing_more_menu.temp = PRINTING_TEMP_EN;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_EN;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_EN;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_EN;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_EN;
+ print_file_dialog_menu.retry = DIALOG_RETRY_EN;
+ print_file_dialog_menu.stop = DIALOG_STOP_EN;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_EN;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_EN;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_EN;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_EN;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_EN;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_EN;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_EN;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_EN;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_EN;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_EN;
+ pause_msg_menu.changing = MESSAGE_CHANGING_EN;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_EN;
+ pause_msg_menu.waiting = MESSAGE_WAITING_EN;
+ pause_msg_menu.insert = MESSAGE_INSERT_EN;
+ pause_msg_menu.load = MESSAGE_LOAD_EN;
+ pause_msg_menu.purge = MESSAGE_PURGE_EN;
+ pause_msg_menu.resume = MESSAGE_RESUME_EN;
+ pause_msg_menu.heat = MESSAGE_HEAT_EN;
+ pause_msg_menu.heating = MESSAGE_HEATING_EN;
+ pause_msg_menu.option = MESSAGE_OPTION_EN;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_EN;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_EN;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_EN;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_EN;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_EN;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_EN;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_EN;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_EN;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_EN;
+ break;
+ case LANG_RUSSIAN:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_RU;
+ common_menu.text_back = BACK_TEXT_RU;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_RU;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_RU;
+ common_menu.print_special_title = PRINTING_OTHER_LANGUGE;
+ common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE;
+ common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE;
+ //
+ main_menu.title = TITLE_READYPRINT_RU;
+ main_menu.preheat = PREHEAT_TEXT_RU;
+ main_menu.move = MOVE_TEXT_RU;
+ main_menu.home = HOME_TEXT_RU;
+ main_menu.print = PRINT_TEXT_RU;
+ main_menu.extrude = EXTRUDE_TEXT_RU;
+ main_menu.leveling = LEVELING_TEXT_RU;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_RU;
+ main_menu.fan = FAN_TEXT_RU;
+ main_menu.set = SET_TEXT_RU;
+ main_menu.more = MORE_TEXT_RU;
+ main_menu.tool = TOOL_TEXT_RU;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_RU;
+ tool_menu.preheat = TOOL_PREHEAT_RU;
+ tool_menu.extrude = TOOL_EXTRUDE_RU;
+ tool_menu.move = TOOL_MOVE_RU;
+ tool_menu.home = TOOL_HOME_RU;
+ tool_menu.leveling = TOOL_LEVELING_RU;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_RU;
+ tool_menu.filament = TOOL_FILAMENT_RU;
+ tool_menu.more = TOOL_MORE_RU;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_RU;
+ preheat_menu.title = TITLE_PREHEAT_RU;
+ preheat_menu.add = ADD_TEXT_RU;
+ preheat_menu.dec = DEC_TEXT_RU;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_RU;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_RU;
+ preheat_menu.hotbed = HEATBED_TEXT_RU;
+ preheat_menu.off = CLOSE_TEXT_RU;
+ //
+ move_menu.title = MOVE_TEXT_RU;
+ //
+ home_menu.title = TITLE_HOME_RU;
+ home_menu.stopmove = HOME_STOPMOVE_RU;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_RU;
+ file_menu.page_up = PAGE_UP_TEXT_RU;
+ file_menu.page_down = PAGE_DOWN_TEXT_RU;
+ file_menu.file_loading = FILE_LOADING_RU;
+ file_menu.no_file = NO_FILE_RU;
+ file_menu.no_file_and_check = NO_FILE_RU;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_RU;
+ extrude_menu.in = EXTRUDER_IN_TEXT_RU;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_RU;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_RU;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_RU;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_RU;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_RU;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_RU;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_RU;
+ //
+ leveling_menu.title = TITLE_LEVELING_RU;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_RU;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_RU;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_RU;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_RU;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_RU;
+ //
+ set_menu.title = TITLE_SET_RU;
+ set_menu.filesys = FILESYS_TEXT_RU;
+ set_menu.wifi = WIFI_TEXT_RU;
+ set_menu.about = ABOUT_TEXT_RU;
+ set_menu.fan = FAN_TEXT_RU;
+ set_menu.filament = FILAMENT_TEXT_RU;
+ set_menu.breakpoint = BREAK_POINT_TEXT_RU;
+ set_menu.motoroff = MOTOR_OFF_TEXT_RU;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_RU;
+ set_menu.language = LANGUAGE_TEXT_RU;
+ set_menu.shutdown = SHUTDOWN_TEXT_RU;
+ set_menu.machine_para = MACHINE_PARA_RU;
+ set_menu.eepromSet = EEPROM_SETTINGS_RU;
+ more_menu.title = TITLE_MORE_RU;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_RU;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_RU;
+ #endif
+ //
+ filesys_menu.title = TITLE_FILESYS_RU;
+ filesys_menu.sd_sys = SD_CARD_TEXT_RU;
+ filesys_menu.usb_sys = U_DISK_TEXT_RU;
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_RU;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_RU;
+
+ machine_menu.next = NEXT_RU;
+ machine_menu.previous = PREVIOUS_RU;
+ machine_menu.enable = ENABLE_RU;
+ machine_menu.disable = DISABLE_RU;
+ machine_menu.key_confirm = KEY_CONFIRM_RU;
+
+ MachinePara_menu.MachineSetting = MACHINE_TYPE_CNOFIG_RU;
+ MachinePara_menu.title = MACHINE_PARA_TITLE_RU;
+ machine_menu.MachineConfigTitle = MACHINE_CONFIG_TITLE_RU;
+ MachinePara_menu.MotorSetting = MOTOR_CONFIG_RU;
+ MachinePara_menu.leveling = MACHINE_LEVELING_CONFIG_RU;
+ MachinePara_menu.AdvanceSetting = ADVANCE_CONFIG_RU;
+ machine_menu.MotorConfTitle = MOTOR_CONF_TITLE_RU;
+ machine_menu.MaxFeedRateConf = MAXFEEDRATE_CONF_RU;
+ machine_menu.AccelerationConf = ACCELERATION_CONF_RU;
+ machine_menu.JerkConf = JERKCONF_RU;
+ machine_menu.StepsConf = STEPSCONF_RU;
+ machine_menu.TMCcurrentConf = TMC_CURRENT_RU;
+ machine_menu.TMCStepModeConf = TMC_STEP_MODE_RU;
+ machine_menu.PausePosition = PAUSE_POSITION_RU;
+ machine_menu.FilamentConf = MACHINE_FILAMENT_CONFIG_RU;
+ machine_menu.EncoderSettings = ENCODER_SETTINGS_RU;
+ machine_menu.AdvancedConfTitle = ADVANCED_CONF_TITLE_RU;
+
+ machine_menu.LevelingParaConfTitle = LEVELING_CONF_TITLE_RU;
+ machine_menu.LevelingParaConf = LEVELING_PARA_CONF_RU;
+ machine_menu.LevelingManuPosConf = LEVELING_MANUAL_POS_RU;
+ machine_menu.LevelingAutoCommandConf = LEVELING_AUTO_COMMAND_RU;
+ machine_menu.LevelingAutoZoffsetConf = LEVELING_AUTO_ZOFFSET_RU;
+
+ machine_menu.AccelerationConfTitle = ACCELERATION_CONF_TITLE_RU;
+ machine_menu.PrintAcceleration = PRINT_ACCELERATION_RU;
+ machine_menu.RetractAcceleration = RETRACT_ACCELERATION_RU;
+ machine_menu.TravelAcceleration = TRAVEL_ACCELERATION_RU;
+ machine_menu.X_Acceleration = X_ACCELERATION_RU;
+ machine_menu.Y_Acceleration = Y_ACCELERATION_RU;
+ machine_menu.Z_Acceleration = Z_ACCELERATION_RU;
+ machine_menu.E0_Acceleration = E0_ACCELERATION_RU;
+ machine_menu.E1_Acceleration = E1_ACCELERATION_RU;
+
+ machine_menu.MaxFeedRateConfTitle = MAXFEEDRATE_CONF_TITLE_RU;
+ machine_menu.XMaxFeedRate = X_MAXFEEDRATE_RU;
+ machine_menu.YMaxFeedRate = Y_MAXFEEDRATE_RU;
+ machine_menu.ZMaxFeedRate = Z_MAXFEEDRATE_RU;
+ machine_menu.E0MaxFeedRate = E0_MAXFEEDRATE_RU;
+ machine_menu.E1MaxFeedRate = E1_MAXFEEDRATE_RU;
+
+ machine_menu.JerkConfTitle = JERK_CONF_TITLE_RU;
+ machine_menu.X_Jerk = X_JERK_RU;
+ machine_menu.Y_Jerk = Y_JERK_RU;
+ machine_menu.Z_Jerk = Z_JERK_RU;
+ machine_menu.E_Jerk = E_JERK_RU;
+
+ machine_menu.StepsConfTitle = STEPS_CONF_TITLE_RU;
+ machine_menu.X_Steps = X_STEPS_RU;
+ machine_menu.Y_Steps = Y_STEPS_RU;
+ machine_menu.Z_Steps = Z_STEPS_RU;
+ machine_menu.E0_Steps = E0_STEPS_RU;
+ machine_menu.E1_Steps = E1_STEPS_RU;
+
+ machine_menu.TmcCurrentConfTitle = TMC_CURRENT_CONF_TITLE_RU;
+ machine_menu.X_Current = X_TMC_CURRENT_RU;
+ machine_menu.Y_Current = Y_TMC_CURRENT_RU;
+ machine_menu.Z_Current = Z_TMC_CURRENT_RU;
+ machine_menu.E0_Current = E0_TMC_CURRENT_RU;
+ machine_menu.E1_Current = E1_TMC_CURRENT_RU;
+
+ machine_menu.TmcStepModeConfTitle = TMC_MODE_CONF_TITLE_RU;
+ machine_menu.X_StepMode = X_TMC_MODE_RU;
+ machine_menu.Y_StepMode = Y_TMC_MODE_RU;
+ machine_menu.Z_StepMode = Z_TMC_MODE_RU;
+ machine_menu.E0_StepMode = E0_TMC_MODE_RU;
+ machine_menu.E1_StepMode = E1_TMC_MODE_RU;
+
+ machine_menu.PausePosText = PAUSE_POSITION_RU;
+ machine_menu.xPos = PAUSE_POSITION_X_RU;
+ machine_menu.yPos = PAUSE_POSITION_Y_RU;
+ machine_menu.zPos = PAUSE_POSITION_Z_RU;
+
+ machine_menu.OffsetConfTitle = OFFSET_TITLE_RU;
+ machine_menu.Xoffset = OFFSET_X_RU;
+ machine_menu.Yoffset = OFFSET_Y_RU;
+ machine_menu.Zoffset = OFFSET_Z_RU;
+
+ machine_menu.LevelingTouchmiConf = LEVELING_TOUCHMI_RU;
+ machine_menu.TouchmiInit = TM_INIT_RU;
+ machine_menu.TouchmiOffsetpos = TM_ZOFFSETPOS_RU;
+ machine_menu.TouchmiOffsetneg = TM_ZOFFSETNEG_RU;
+ machine_menu.TouchmiSave = TM_SAVE_RU;
+ machine_menu.TouchmiTest = TM_TEST_RU;
+
+ machine_menu.BLTouchLevelingConfTitle = BLTOUCH_LEVELING_TITTLE_RU;
+ machine_menu.BLTouchLevelingConf = BLTOUCH_LEVELING_RU;
+ machine_menu.BLTouchInit = BLTOUCH_INIT_RU;
+ machine_menu.BLTouchOffsetpos = BLTOUCH_ZOFFSETPOS_RU;
+ machine_menu.BLTouchOffsetneg = BLTOUCH_ZOFFSETNEG_RU;
+ machine_menu.BLTouchSave = BLTOUCH_SAVE_RU;
+ machine_menu.BLTouchTest = BLTOUCH_TEST_RU;
+
+ machine_menu.FilamentConfTitle = FILAMENT_CONF_TITLE_RU;
+ machine_menu.InLength = FILAMENT_IN_LENGTH_RU;
+ machine_menu.InSpeed = FILAMENT_IN_SPEED_RU;
+ machine_menu.FilamentTemperature = FILAMENT_TEMPERATURE_RU;
+ machine_menu.OutLength = FILAMENT_OUT_LENGTH_RU;
+ machine_menu.OutSpeed = FILAMENT_OUT_SPEED_RU;
+
+ machine_menu.EncoderConfTitle = ENCODER_CONF_TITLE_RU;
+ machine_menu.EncoderConfText = ENCODER_CONF_TEXT_RU;
+
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_RU;
+ cloud_menu.bind = CLOUD_BINDED_RU;
+ cloud_menu.binded = CLOUD_BINDED_RU;
+ cloud_menu.unbind = CLOUD_UNBIND_RU;
+ cloud_menu.unbinding = CLOUD_UNBINDED_RU;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_RU;
+ cloud_menu.unbinded = CLOUD_UNBINDED_RU;
+ cloud_menu.disable = CLOUD_DISABLE_RU;
+ //
+ about_menu.title = ABOUT_TEXT_RU;
+ about_menu.type = ABOUT_TYPE_TEXT_RU;
+ about_menu.version = ABOUT_VERSION_TEXT_RU;
+ about_menu.wifi = ABOUT_WIFI_TEXT_RU;
+ //
+ fan_menu.title = FAN_TEXT_RU;
+ fan_menu.add = FAN_ADD_TEXT_RU;
+ fan_menu.dec = FAN_DEC_TEXT_RU;
+ fan_menu.state = FAN_TIPS1_TEXT_RU;
+ //
+ filament_menu.title = TITLE_FILAMENT_RU;
+ filament_menu.in = FILAMENT_IN_TEXT_RU;
+ filament_menu.out = FILAMENT_OUT_TEXT_RU;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_RU;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_RU;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_RU;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_RU;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_RU;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_RU;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_RU;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_RU;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_RU;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_RU;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_RU;
+
+ //
+ language_menu.title = LANGUAGE_TEXT_RU;
+ language_menu.next = PAGE_DOWN_TEXT_RU;
+ language_menu.up = PAGE_UP_TEXT_RU;
+ //
+ printing_menu.title = TITLE_PRINTING_RU;
+ printing_menu.option = PRINTING_OPERATION_RU;
+ printing_menu.stop = PRINTING_STOP_RU;
+ printing_menu.pause = PRINTING_PAUSE_RU;
+ printing_menu.resume = PRINTING_RESUME_RU;
+
+ //
+ operation_menu.title = TITLE_OPERATION_RU;
+ operation_menu.pause = PRINTING_PAUSE_RU;
+ operation_menu.stop = PRINTING_STOP_RU;
+ operation_menu.temp = PRINTING_TEMP_RU;
+ operation_menu.fan = FAN_TEXT_RU;
+ operation_menu.extr = PRINTING_EXTRUDER_RU;
+ operation_menu.speed = PRINTING_CHANGESPEED_RU;
+ operation_menu.filament = FILAMENT_TEXT_RU;
+ operation_menu.more = PRINTING_MORE_RU;
+ operation_menu.move = PRINTING_MOVE_RU;
+ operation_menu.auto_off = AUTO_SHUTDOWN_RU;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_RU;
+ //
+ pause_menu.title = TITLE_PAUSE_RU;
+ pause_menu.resume = PRINTING_RESUME_RU;
+ pause_menu.stop = PRINTING_STOP_RU;
+ pause_menu.extrude = PRINTING_EXTRUDER_RU;
+ pause_menu.move = PRINTING_MOVE_RU;
+ pause_menu.filament = FILAMENT_TEXT_RU;
+ pause_menu.more = PRINTING_MORE_RU;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_RU;
+ speed_menu.add = ADD_TEXT_RU;
+ speed_menu.dec = DEC_TEXT_RU;
+ speed_menu.move = MOVE_SPEED_RU;
+ speed_menu.extrude = EXTRUDER_SPEED_RU;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_RU;
+ speed_menu.move_speed = MOVE_SPEED_STATE_RU;
+ //
+ printing_more_menu.title = TITLE_MORE_RU;
+ printing_more_menu.fan = FAN_TEXT_RU;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_RU;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_RU;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_RU;
+ printing_more_menu.temp = PRINTING_TEMP_RU;
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_RU;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_RU;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_RU;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_RU;
+ print_file_dialog_menu.retry = DIALOG_RETRY_RU;
+ print_file_dialog_menu.stop = DIALOG_STOP_RU;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_RU;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_RU;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_RU;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_RU;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_RU;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_RU;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_RU;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_RU;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_RU;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_RU;
+ pause_msg_menu.changing = MESSAGE_CHANGING_RU;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_RU;
+ pause_msg_menu.waiting = MESSAGE_WAITING_RU;
+ pause_msg_menu.insert = MESSAGE_INSERT_RU;
+ pause_msg_menu.load = MESSAGE_LOAD_RU;
+ pause_msg_menu.purge = MESSAGE_PURGE_RU;
+ pause_msg_menu.resume = MESSAGE_RESUME_RU;
+ pause_msg_menu.heat = MESSAGE_HEAT_RU;
+ pause_msg_menu.heating = MESSAGE_HEATING_RU;
+ pause_msg_menu.option = MESSAGE_OPTION_RU;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_RU;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_RU;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_RU;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_RU;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_RU;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_RU;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_RU;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_RU;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_RU;
+ break;
+ case LANG_SPANISH:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_SP;
+ common_menu.text_back = BACK_TEXT_SP;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_SP;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_SP;
+ common_menu.print_special_title = PRINTING_SP;
+ common_menu.pause_special_title = PRINTING_PAUSAR_SP;
+ common_menu.operate_special_title = PRINTING_AJUSTES_SP;
+ //
+ main_menu.title = TITLE_READYPRINT_SP;
+ main_menu.preheat = PREHEAT_TEXT_SP;
+ main_menu.move = MOVE_TEXT_SP;
+ main_menu.home = HOME_TEXT_SP;
+ main_menu.print = PRINT_TEXT_SP;
+ main_menu.extrude = EXTRUDE_TEXT_SP;
+ main_menu.leveling = LEVELING_TEXT_SP;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_SP;
+ main_menu.fan = FAN_TEXT_SP;
+ main_menu.set = SET_TEXT_SP;
+ main_menu.more = MORE_TEXT_SP;
+ main_menu.tool = TOOL_TEXT_SP;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_SP;
+ tool_menu.preheat = TOOL_PREHEAT_SP;
+ tool_menu.extrude = TOOL_EXTRUDE_SP;
+ tool_menu.move = TOOL_MOVE_SP;
+ tool_menu.home = TOOL_HOME_SP;
+ tool_menu.leveling = TOOL_LEVELING_SP;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_SP;
+ tool_menu.filament = TOOL_FILAMENT_SP;
+ tool_menu.more = TOOL_MORE_SP;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_SP;
+ preheat_menu.title = TITLE_PREHEAT_SP;
+ preheat_menu.add = ADD_TEXT_SP;
+ preheat_menu.dec = DEC_TEXT_SP;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_SP;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_SP;
+ preheat_menu.hotbed = HEATBED_TEXT_SP;
+ preheat_menu.off = CLOSE_TEXT_SP;
+ //
+ move_menu.title = MOVE_TEXT_SP;
+ //
+ home_menu.title = TITLE_HOME_SP;
+ home_menu.home_x = HOME_X_TEXT_SP;
+ home_menu.home_y = HOME_Y_TEXT_SP;
+ home_menu.home_z = HOME_Z_TEXT_SP;
+ home_menu.home_all = HOME_ALL_TEXT_SP;
+ home_menu.stopmove = HOME_STOPMOVE_SP;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_SP;
+ file_menu.page_up = PAGE_UP_TEXT_SP;
+ file_menu.page_down = PAGE_DOWN_TEXT_SP;
+ file_menu.file_loading = FILE_LOADING_SP;
+ file_menu.no_file = NO_FILE_SP;
+ file_menu.no_file_and_check = NO_FILE_SP;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_SP;
+ extrude_menu.in = EXTRUDER_IN_TEXT_SP;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_SP;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_SP;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_SP;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_SP;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_SP;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_SP;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_SP;
+ //
+ leveling_menu.title = TITLE_LEVELING_SP;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_SP;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_SP;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_SP;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_SP;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_SP;
+ //
+ set_menu.title = TITLE_SET_SP;
+ set_menu.filesys = FILESYS_TEXT_SP;
+ set_menu.wifi = WIFI_TEXT_SP;
+ set_menu.about = ABOUT_TEXT_SP;
+ set_menu.fan = FAN_TEXT_SP;
+ set_menu.filament = FILAMENT_TEXT_SP;
+ set_menu.breakpoint = BREAK_POINT_TEXT_SP;
+ set_menu.motoroff = MOTOR_OFF_TEXT_SP;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_SP;
+ set_menu.language = LANGUAGE_TEXT_SP;
+ set_menu.shutdown = SHUTDOWN_TEXT_SP;
+ set_menu.machine_para = MACHINE_PARA_SP;
+ set_menu.eepromSet = EEPROM_SETTINGS_SP;
+ more_menu.title = TITLE_MORE_SP;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_SP;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_SP;
+ #endif
+ //
+ filesys_menu.title = TITLE_FILESYS_SP;
+ filesys_menu.sd_sys = SD_CARD_TEXT_SP;
+ filesys_menu.usb_sys = U_DISK_TEXT_SP;
+
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_SP;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_SP;
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_SP;
+ cloud_menu.bind = CLOUD_BINDED_SP;
+ cloud_menu.binded = CLOUD_BINDED_SP;
+ cloud_menu.unbind = CLOUD_UNBIND_SP;
+ cloud_menu.unbinding = CLOUD_UNBINDED_SP;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_SP;
+ cloud_menu.unbinded = CLOUD_UNBINDED_SP;
+ cloud_menu.disable = CLOUD_DISABLE_SP;
+ //
+ about_menu.title = ABOUT_TEXT_SP;
+ about_menu.type = ABOUT_TYPE_TEXT_SP;
+ about_menu.version = ABOUT_VERSION_TEXT_SP;
+ about_menu.wifi = ABOUT_WIFI_TEXT_SP;
+ //
+ fan_menu.title = FAN_TEXT_SP;
+ fan_menu.add = FAN_ADD_TEXT_SP;
+ fan_menu.dec = FAN_DEC_TEXT_SP;
+ fan_menu.state = FAN_TIPS1_TEXT_SP;
+ //
+ filament_menu.title = TITLE_FILAMENT_SP;
+ filament_menu.in = FILAMENT_IN_TEXT_SP;
+ filament_menu.out = FILAMENT_OUT_TEXT_SP;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_SP;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_SP;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_SP;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_SP;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_SP;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_SP;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_SP;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_SP;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_SP;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_SP;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_SP;
+
+ //
+ language_menu.title = LANGUAGE_TEXT_SP;
+ language_menu.next = PAGE_DOWN_TEXT_SP;
+ language_menu.up = PAGE_UP_TEXT_SP;
+ //
+ printing_menu.title = TITLE_PRINTING_SP;
+ printing_menu.option = PRINTING_OPERATION_SP;
+ printing_menu.stop = PRINTING_STOP_SP;
+ printing_menu.pause = PRINTING_PAUSE_SP;
+ printing_menu.resume = PRINTING_RESUME_SP;
+
+ //
+ operation_menu.title = TITLE_OPERATION_SP;
+ operation_menu.pause = PRINTING_PAUSE_SP;
+ operation_menu.stop = PRINTING_STOP_SP;
+ operation_menu.temp = PRINTING_TEMP_SP;
+ operation_menu.fan = FAN_TEXT_SP;
+ operation_menu.extr = PRINTING_EXTRUDER_SP;
+ operation_menu.speed = PRINTING_CHANGESPEED_SP;
+ operation_menu.filament = FILAMENT_TEXT_SP;
+ operation_menu.more = PRINTING_MORE_SP;
+ operation_menu.move = PRINTING_MOVE_SP;
+ operation_menu.auto_off = AUTO_SHUTDOWN_SP;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_SP;
+ //
+ pause_menu.title = TITLE_PAUSE_RU;
+ pause_menu.resume = PRINTING_RESUME_SP;
+ pause_menu.stop = PRINTING_STOP_SP;
+ pause_menu.extrude = PRINTING_EXTRUDER_SP;
+ pause_menu.move = PRINTING_MOVE_SP;
+ pause_menu.filament = FILAMENT_TEXT_SP;
+ pause_menu.more = PRINTING_MORE_SP;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_SP;
+ speed_menu.add = ADD_TEXT_SP;
+ speed_menu.dec = DEC_TEXT_SP;
+ speed_menu.move = MOVE_SPEED_SP;
+ speed_menu.extrude = EXTRUDER_SPEED_SP;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_SP;
+ speed_menu.move_speed = MOVE_SPEED_STATE_SP;
+ //
+ printing_more_menu.title = TITLE_MORE_SP;
+ printing_more_menu.fan = FAN_TEXT_SP;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_SP;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_SP;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_SP;
+ printing_more_menu.temp = PRINTING_TEMP_SP;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_SP;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_SP;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_SP;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_SP;
+ print_file_dialog_menu.retry = DIALOG_RETRY_SP;
+ print_file_dialog_menu.stop = DIALOG_STOP_SP;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_SP;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_SP;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_SP;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_SP;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_SP;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_SP;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_SP;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_SP;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_SP;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_SP;
+ pause_msg_menu.changing = MESSAGE_CHANGING_SP;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_SP;
+ pause_msg_menu.waiting = MESSAGE_WAITING_SP;
+ pause_msg_menu.insert = MESSAGE_INSERT_SP;
+ pause_msg_menu.load = MESSAGE_LOAD_SP;
+ pause_msg_menu.purge = MESSAGE_PURGE_SP;
+ pause_msg_menu.resume = MESSAGE_RESUME_SP;
+ pause_msg_menu.heat = MESSAGE_HEAT_SP;
+ pause_msg_menu.heating = MESSAGE_HEATING_SP;
+ pause_msg_menu.option = MESSAGE_OPTION_SP;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_SP;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_SP;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_SP;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_SP;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_SP;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_SP;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_SP;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_SP;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_SP;
+ break;
+
+ #endif // if 1
+
+ case LANG_FRENCH:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_FR;
+ common_menu.text_back = BACK_TEXT_FR;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_FR;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_FR;
+ common_menu.print_special_title = PRINTING_OTHER_LANGUGE;
+ common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE;
+ common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE;
+
+ //
+ main_menu.title = TITLE_READYPRINT_FR;
+ main_menu.preheat = PREHEAT_TEXT_FR;
+ main_menu.move = MOVE_TEXT_FR;
+ main_menu.home = HOME_TEXT_FR;
+ main_menu.print = PRINT_TEXT_FR;
+ main_menu.extrude = EXTRUDE_TEXT_FR;
+ main_menu.leveling = LEVELING_TEXT_FR;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_FR;
+ main_menu.fan = FAN_TEXT_FR;
+ main_menu.set = SET_TEXT_FR;
+ main_menu.more = MORE_TEXT_FR;
+ main_menu.tool = TOOL_TEXT_FR;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_FR;
+ tool_menu.preheat = TOOL_PREHEAT_FR;
+ tool_menu.extrude = TOOL_EXTRUDE_FR;
+ tool_menu.move = TOOL_MOVE_FR;
+ tool_menu.home = TOOL_HOME_FR;
+ tool_menu.leveling = TOOL_LEVELING_FR;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_FR;
+ tool_menu.filament = TOOL_FILAMENT_FR;
+ tool_menu.more = TOOL_MORE_FR;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_FR;
+ preheat_menu.title = TITLE_PREHEAT_FR;
+ preheat_menu.add = ADD_TEXT_FR;
+ preheat_menu.dec = DEC_TEXT_FR;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_FR;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_FR;
+ preheat_menu.hotbed = HEATBED_TEXT_FR;
+ preheat_menu.off = CLOSE_TEXT_FR;
+ //
+ move_menu.title = MOVE_TEXT_FR;
+ //
+ home_menu.title = TITLE_HOME_FR;
+ home_menu.stopmove = HOME_STOPMOVE_FR;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_FR;
+ file_menu.page_up = PAGE_UP_TEXT_FR;
+ file_menu.page_down = PAGE_DOWN_TEXT_FR;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_FR;
+ extrude_menu.in = EXTRUDER_IN_TEXT_FR;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_FR;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_FR;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_FR;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_FR;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_FR;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_FR;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_FR;
+ //
+ leveling_menu.title = TITLE_LEVELING_FR;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_FR;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_FR;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_FR;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_FR;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_FR;
+ //
+ set_menu.title = TITLE_SET_FR;
+ set_menu.filesys = FILESYS_TEXT_FR;
+ set_menu.wifi = WIFI_TEXT_FR;
+ set_menu.about = ABOUT_TEXT_FR;
+ set_menu.fan = FAN_TEXT_FR;
+ set_menu.filament = FILAMENT_TEXT_FR;
+ set_menu.breakpoint = BREAK_POINT_TEXT_FR;
+ set_menu.motoroff = MOTOR_OFF_TEXT_FR;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_FR;
+ set_menu.language = LANGUAGE_TEXT_FR;
+ set_menu.shutdown = SHUTDOWN_TEXT_FR;
+ set_menu.machine_para = MACHINE_PARA_FR;
+ set_menu.eepromSet = EEPROM_SETTINGS_FR;
+ more_menu.title = TITLE_MORE_FR;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_FR;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_FR;
+ #endif
+ //
+ filesys_menu.title = TITLE_FILESYS_FR;
+ filesys_menu.sd_sys = SD_CARD_TEXT_FR;
+ filesys_menu.usb_sys = U_DISK_TEXT_FR;
+ file_menu.file_loading = FILE_LOADING_FR;
+ file_menu.no_file = NO_FILE_FR;
+ file_menu.no_file_and_check = NO_FILE_FR;
+ // WIFI
+ wifi_menu.title = WIFI_NAME_TEXT_FR;
+ wifi_menu.cloud = CLOUD_TEXT_FR;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_FR;
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_FR;
+ cloud_menu.bind = CLOUD_BINDED_FR;
+ cloud_menu.binded = CLOUD_BINDED_FR;
+ cloud_menu.unbind = CLOUD_UNBIND_FR;
+ cloud_menu.unbinding = CLOUD_UNBINDED_FR;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_FR;
+ cloud_menu.unbinded = CLOUD_UNBINDED_FR;
+ cloud_menu.disable = CLOUD_DISABLE_FR;
+ //
+ about_menu.title = ABOUT_TEXT_FR;
+ about_menu.type = ABOUT_TYPE_TEXT_FR;
+ about_menu.version = ABOUT_VERSION_TEXT_FR;
+ about_menu.wifi = ABOUT_WIFI_TEXT_FR;
+ //
+ fan_menu.title = FAN_TEXT_FR;
+ fan_menu.add = FAN_ADD_TEXT_FR;
+ fan_menu.dec = FAN_DEC_TEXT_FR;
+ fan_menu.state = FAN_TIPS1_TEXT_FR;
+ //
+ filament_menu.title = TITLE_FILAMENT_FR;
+ filament_menu.in = FILAMENT_IN_TEXT_FR;
+ filament_menu.out = FILAMENT_OUT_TEXT_FR;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_FR;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_FR;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_FR;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_FR;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_FR;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_FR;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_FR;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_FR;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_FR;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_FR;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_FR;
+
+ //
+ language_menu.title = LANGUAGE_TEXT_FR;
+
+ //
+ printing_menu.title = TITLE_PRINTING_FR;
+ printing_menu.option = PRINTING_OPERATION_FR;
+ printing_menu.stop = PRINTING_STOP_FR;
+ printing_menu.pause = PRINTING_PAUSE_FR;
+ printing_menu.resume = PRINTING_RESUME_FR;
+
+ //
+ operation_menu.title = TITLE_OPERATION_FR;
+ operation_menu.pause = PRINTING_PAUSE_FR;
+ operation_menu.stop = PRINTING_STOP_FR;
+ operation_menu.temp = PRINTING_TEMP_FR;
+ operation_menu.fan = FAN_TEXT_FR;
+ operation_menu.extr = PRINTING_EXTRUDER_FR;
+ operation_menu.speed = PRINTING_CHANGESPEED_FR;
+ operation_menu.filament = FILAMENT_TEXT_FR;
+ operation_menu.more = PRINTING_MORE_FR;
+ operation_menu.move = PRINTING_MOVE_FR;
+ operation_menu.auto_off = AUTO_SHUTDOWN_FR;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_FR;
+ //
+ pause_menu.title = TITLE_PAUSE_FR;
+ pause_menu.resume = PRINTING_RESUME_FR;
+ pause_menu.stop = PRINTING_STOP_FR;
+ pause_menu.extrude = PRINTING_EXTRUDER_FR;
+ pause_menu.move = PRINTING_MOVE_FR;
+ pause_menu.filament = FILAMENT_TEXT_FR;
+ pause_menu.more = PRINTING_MORE_FR;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_FR;
+ speed_menu.add = ADD_TEXT_FR;
+ speed_menu.dec = DEC_TEXT_FR;
+ speed_menu.move = MOVE_SPEED_FR;
+ speed_menu.extrude = EXTRUDER_SPEED_FR;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_FR;
+ speed_menu.move_speed = MOVE_SPEED_STATE_FR;
+ //
+ printing_more_menu.fan = FAN_TEXT_FR;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_FR;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_FR;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_FR;
+ printing_more_menu.temp = PRINTING_TEMP_FR;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_FR;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_FR;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_FR;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_FR;
+ print_file_dialog_menu.retry = DIALOG_RETRY_FR;
+ print_file_dialog_menu.stop = DIALOG_STOP_FR;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_FR;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_FR;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_FR;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_FR;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_FR;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_FR;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_FR;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_FR;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_FR;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_FR;
+ pause_msg_menu.changing = MESSAGE_CHANGING_FR;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_FR;
+ pause_msg_menu.waiting = MESSAGE_WAITING_FR;
+ pause_msg_menu.insert = MESSAGE_INSERT_FR;
+ pause_msg_menu.load = MESSAGE_LOAD_FR;
+ pause_msg_menu.purge = MESSAGE_PURGE_FR;
+ pause_msg_menu.resume = MESSAGE_RESUME_FR;
+ pause_msg_menu.heat = MESSAGE_HEAT_FR;
+ pause_msg_menu.heating = MESSAGE_HEATING_FR;
+ pause_msg_menu.option = MESSAGE_OPTION_FR;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_FR;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_FR;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_FR;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_FR;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_FR;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_FR;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_FR;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_FR;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_FR;
+ break;
+
+ case LANG_ITALY:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_IT;
+ common_menu.text_back = BACK_TEXT_IT;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_IT;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_IT;
+ common_menu.print_special_title = PRINTING_OTHER_LANGUGE;
+ common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE;
+ common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE;
+
+ //
+ main_menu.title = TITLE_READYPRINT_IT;
+ main_menu.preheat = PREHEAT_TEXT_IT;
+ main_menu.move = MOVE_TEXT_IT;
+ main_menu.home = HOME_TEXT_IT;
+ main_menu.print = PRINT_TEXT_IT;
+ main_menu.extrude = EXTRUDE_TEXT_IT;
+ main_menu.leveling = LEVELING_TEXT_IT;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_IT;
+ main_menu.fan = FAN_TEXT_IT;
+ main_menu.set = SET_TEXT_IT;
+ main_menu.more = MORE_TEXT_IT;
+ main_menu.tool = TOOL_TEXT_IT;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_IT;
+ tool_menu.preheat = TOOL_PREHEAT_IT;
+ tool_menu.extrude = TOOL_EXTRUDE_IT;
+ tool_menu.move = TOOL_MOVE_IT;
+ tool_menu.home = TOOL_HOME_IT;
+ tool_menu.leveling = TOOL_LEVELING_IT;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_IT;
+ tool_menu.filament = TOOL_FILAMENT_IT;
+ tool_menu.more = TOOL_MORE_IT;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_IT;
+ preheat_menu.title = TITLE_PREHEAT_IT;
+ preheat_menu.add = ADD_TEXT_IT;
+ preheat_menu.dec = DEC_TEXT_IT;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_IT;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_IT;
+ preheat_menu.hotbed = HEATBED_TEXT_IT;
+ preheat_menu.off = CLOSE_TEXT_IT;
+ //
+ move_menu.title = MOVE_TEXT_IT;
+ //
+ home_menu.title = TITLE_HOME_IT;
+ home_menu.stopmove = HOME_STOPMOVE_IT;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_IT;
+ file_menu.page_up = PAGE_UP_TEXT_IT;
+ file_menu.page_down = PAGE_DOWN_TEXT_IT;
+ file_menu.file_loading = FILE_LOADING_IT;
+ file_menu.no_file = NO_FILE_IT;
+ file_menu.no_file_and_check = NO_FILE_IT;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_IT;
+ extrude_menu.in = EXTRUDER_IN_TEXT_IT;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_IT;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_IT;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_IT;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_IT;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_IT;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_IT;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_IT;
+ //
+ leveling_menu.title = TITLE_LEVELING_IT;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_IT;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_IT;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_IT;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_IT;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_IT;
+ //
+ set_menu.title = TITLE_SET_IT;
+ set_menu.filesys = FILESYS_TEXT_IT;
+ set_menu.wifi = WIFI_TEXT_IT;
+ set_menu.about = ABOUT_TEXT_IT;
+ set_menu.fan = FAN_TEXT_IT;
+ set_menu.filament = FILAMENT_TEXT_IT;
+ set_menu.breakpoint = BREAK_POINT_TEXT_IT;
+ set_menu.motoroff = MOTOR_OFF_TEXT_IT;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_IT;
+ set_menu.language = LANGUAGE_TEXT_IT;
+ set_menu.shutdown = SHUTDOWN_TEXT_IT;
+ set_menu.machine_para = MACHINE_PARA_IT;
+ set_menu.eepromSet = EEPROM_SETTINGS_IT;
+ more_menu.title = TITLE_MORE_IT;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_IT;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_IT;
+ #endif
+ //
+ filesys_menu.title = TITLE_FILESYS_IT;
+ filesys_menu.sd_sys = SD_CARD_TEXT_IT;
+ filesys_menu.usb_sys = U_DISK_TEXT_IT;
+
+ // WIFI
+ wifi_menu.title = WIFI_NAME_TEXT_IT;
+ wifi_menu.cloud = CLOSE_TEXT_IT;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_IT;
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_IT;
+ cloud_menu.bind = CLOUD_BINDED_IT;
+ cloud_menu.binded = CLOUD_BINDED_IT;
+ cloud_menu.unbind = CLOUD_UNBIND_IT;
+ cloud_menu.unbinding = CLOUD_UNBINDED_IT;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_IT;
+ cloud_menu.unbinded = CLOUD_UNBINDED_IT;
+ cloud_menu.disable = CLOUD_DISABLE_IT;
+ //
+ about_menu.title = ABOUT_TEXT_IT;
+ about_menu.type = ABOUT_TYPE_TEXT_IT;
+ about_menu.version = ABOUT_VERSION_TEXT_IT;
+ about_menu.wifi = ABOUT_WIFI_TEXT_IT;
+ //
+ fan_menu.title = FAN_TEXT_IT;
+ fan_menu.add = FAN_ADD_TEXT_IT;
+ fan_menu.dec = FAN_DEC_TEXT_IT;
+ fan_menu.state = FAN_TIPS1_TEXT_IT;
+ //
+ filament_menu.title = TITLE_FILAMENT_IT;
+ filament_menu.in = FILAMENT_IN_TEXT_IT;
+ filament_menu.out = FILAMENT_OUT_TEXT_IT;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_IT;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_IT;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_IT;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_IT;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_IT;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_IT;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_IT;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_IT;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_IT;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_IT;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_IT;
+
+ //
+ language_menu.title = LANGUAGE_TEXT_IT;
+
+ //
+ printing_menu.title = TITLE_PRINTING_IT;
+ printing_menu.option = PRINTING_OPERATION_IT;
+ printing_menu.stop = PRINTING_STOP_IT;
+ printing_menu.pause = PRINTING_PAUSE_IT;
+ printing_menu.resume = PRINTING_RESUME_IT;
+
+ //
+ operation_menu.title = TITLE_OPERATION_IT;
+ operation_menu.pause = PRINTING_PAUSE_IT;
+ operation_menu.stop = PRINTING_STOP_IT;
+ operation_menu.temp = PRINTING_TEMP_IT;
+ operation_menu.fan = FAN_TEXT_IT;
+ operation_menu.extr = PRINTING_EXTRUDER_IT;
+ operation_menu.speed = PRINTING_CHANGESPEED_IT;
+ operation_menu.filament = FILAMENT_TEXT_IT;
+ operation_menu.more = PRINTING_MORE_IT;
+ operation_menu.move = PRINTING_MOVE_IT;
+ operation_menu.auto_off = AUTO_SHUTDOWN_IT;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_IT;
+ //
+ pause_menu.title = TITLE_PAUSE_IT;
+ pause_menu.resume = PRINTING_RESUME_IT;
+ pause_menu.stop = PRINTING_STOP_IT;
+ pause_menu.extrude = PRINTING_EXTRUDER_IT;
+ pause_menu.move = PRINTING_MOVE_IT;
+ pause_menu.filament = FILAMENT_TEXT_IT;
+ pause_menu.more = PRINTING_MORE_IT;
+
+ //
+ speed_menu.title = PRINTING_CHANGESPEED_IT;
+ speed_menu.add = ADD_TEXT_IT;
+ speed_menu.dec = DEC_TEXT_IT;
+ speed_menu.move = MOVE_SPEED_IT;
+ speed_menu.extrude = EXTRUDER_SPEED_IT;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_IT;
+ speed_menu.move_speed = MOVE_SPEED_STATE_IT;
+ //
+ printing_more_menu.fan = FAN_TEXT_IT;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_IT;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_IT;
+ printing_more_menu.temp = PRINTING_TEMP_IT;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_IT;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_IT;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_IT;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_IT;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_IT;
+ print_file_dialog_menu.retry = DIALOG_RETRY_IT;
+ print_file_dialog_menu.stop = DIALOG_STOP_IT;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_IT;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_IT;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_IT;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_IT;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_IT;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_IT;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_IT;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_IT;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_IT;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_IT;
+ pause_msg_menu.changing = MESSAGE_CHANGING_IT;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_IT;
+ pause_msg_menu.waiting = MESSAGE_WAITING_IT;
+ pause_msg_menu.insert = MESSAGE_INSERT_IT;
+ pause_msg_menu.load = MESSAGE_LOAD_IT;
+ pause_msg_menu.purge = MESSAGE_PURGE_IT;
+ pause_msg_menu.resume = MESSAGE_RESUME_IT;
+ pause_msg_menu.heat = MESSAGE_HEAT_IT;
+ pause_msg_menu.heating = MESSAGE_HEATING_IT;
+ pause_msg_menu.option = MESSAGE_OPTION_IT;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_IT;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_IT;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_IT;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_IT;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_IT;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_IT;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_IT;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_IT;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_IT;
+ break;
+
+ #endif // if 1
+
+ default:
+ common_menu.dialog_confirm_title = TITLE_DIALOG_CONFIRM_EN;
+ common_menu.text_back = BACK_TEXT_EN;
+ common_menu.close_machine_tips = DIALOG_CLOSE_MACHINE_EN;
+ common_menu.unbind_printer_tips = DIALOG_UNBIND_PRINTER_EN;
+ common_menu.print_special_title = PRINTING_OTHER_LANGUGE;
+ common_menu.pause_special_title = PRINTING_PAUSE_OTHER_LANGUGE;
+ common_menu.operate_special_title = PRINTING_OPERATION_OTHER_LANGUGE;
+ //
+ main_menu.title = TITLE_READYPRINT_EN;
+ main_menu.preheat = PREHEAT_TEXT_EN;
+ main_menu.move = MOVE_TEXT_EN;
+ main_menu.home = HOME_TEXT_EN;
+ main_menu.print = PRINT_TEXT_EN;
+ main_menu.extrude = EXTRUDE_TEXT_EN;
+ main_menu.leveling = LEVELING_TEXT_EN;
+ main_menu.autoleveling = AUTO_LEVELING_TEXT_EN;
+ main_menu.fan = FAN_TEXT_EN;
+ main_menu.set = SET_TEXT_EN;
+ main_menu.more = MORE_TEXT_EN;
+ main_menu.tool = TOOL_TEXT_EN;
+ // TOOL
+ tool_menu.title = TOOL_TEXT_EN;
+ tool_menu.preheat = TOOL_PREHEAT_EN;
+ tool_menu.extrude = TOOL_EXTRUDE_EN;
+ tool_menu.move = TOOL_MOVE_EN;
+ tool_menu.home = TOOL_HOME_EN;
+ tool_menu.leveling = TOOL_LEVELING_EN;
+ tool_menu.autoleveling = TOOL_AUTO_LEVELING_EN;
+ tool_menu.filament = TOOL_FILAMENT_EN;
+ tool_menu.more = TOOL_MORE_EN;
+ //
+ preheat_menu.adjust_title = TITLE_ADJUST_EN;
+ preheat_menu.title = TITLE_PREHEAT_EN;
+ preheat_menu.add = ADD_TEXT_EN;
+ preheat_menu.dec = DEC_TEXT_EN;
+ preheat_menu.ext1 = EXTRUDER_1_TEXT_EN;
+ preheat_menu.ext2 = EXTRUDER_2_TEXT_EN;
+ preheat_menu.hotbed = HEATBED_TEXT_EN;
+ preheat_menu.off = CLOSE_TEXT_EN;
+ //
+ move_menu.title = TITLE_MOVE_EN;
+ //
+ home_menu.title = TITLE_HOME_EN;
+ home_menu.stopmove = HOME_STOPMOVE_EN;
+ //
+ file_menu.title = TITLE_CHOOSEFILE_EN;
+ file_menu.page_up = PAGE_UP_TEXT_EN;
+ file_menu.page_down = PAGE_DOWN_TEXT_EN;
+ file_menu.file_loading = FILE_LOADING_EN;
+ file_menu.no_file = NO_FILE_EN;
+ file_menu.no_file_and_check = NO_FILE_EN;
+ //
+ extrude_menu.title = TITLE_EXTRUDE_EN;
+ extrude_menu.in = EXTRUDER_IN_TEXT_EN;
+ extrude_menu.out = EXTRUDER_OUT_TEXT_EN;
+ extrude_menu.ext1 = EXTRUDER_1_TEXT_EN;
+ extrude_menu.ext2 = EXTRUDER_2_TEXT_EN;
+ extrude_menu.low = EXTRUDE_LOW_SPEED_TEXT_EN;
+ extrude_menu.normal = EXTRUDE_MEDIUM_SPEED_TEXT_EN;
+ extrude_menu.high = EXTRUDE_HIGH_SPEED_TEXT_EN;
+ extrude_menu.temper_text = EXTRUDER_TEMP_TEXT_EN;
+ //
+ leveling_menu.title = TITLE_LEVELING_EN;
+ leveling_menu.position1 = LEVELING_POINT1_TEXT_EN;
+ leveling_menu.position2 = LEVELING_POINT2_TEXT_EN;
+ leveling_menu.position3 = LEVELING_POINT3_TEXT_EN;
+ leveling_menu.position4 = LEVELING_POINT4_TEXT_EN;
+ leveling_menu.position5 = LEVELING_POINT5_TEXT_EN;
+ //
+ set_menu.title = TITLE_SET_EN;
+ set_menu.filesys = FILESYS_TEXT_EN;
+ set_menu.wifi = WIFI_TEXT_EN;
+ set_menu.about = ABOUT_TEXT_EN;
+ set_menu.fan = FAN_TEXT_EN;
+ set_menu.filament = FILAMENT_TEXT_EN;
+ set_menu.breakpoint = BREAK_POINT_TEXT_EN;
+ set_menu.motoroff = MOTOR_OFF_TEXT_EN;
+ set_menu.motoroffXY = MOTOR_OFF_XY_TEXT_EN;
+ set_menu.language = LANGUAGE_TEXT_EN;
+ set_menu.shutdown = SHUTDOWN_TEXT_EN;
+ set_menu.machine_para = MACHINE_PARA_EN;
+ set_menu.eepromSet = EEPROM_SETTINGS_EN;
+ //
+ more_menu.title = TITLE_MORE_EN;
+ #if ENABLED(USER_CMD_1_ENABLE)
+ more_menu.custom1 = MORE_CUSTOM1_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_2_ENABLE)
+ more_menu.custom2 = MORE_CUSTOM2_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_3_ENABLE)
+ more_menu.custom3 = MORE_CUSTOM3_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_4_ENABLE)
+ more_menu.custom4 = MORE_CUSTOM4_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_5_ENABLE)
+ more_menu.custom5 = MORE_CUSTOM5_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_6_ENABLE)
+ more_menu.custom6 = MORE_CUSTOM6_TEXT_EN;
+ #endif
+ #if ENABLED(USER_CMD_7_ENABLE)
+ more_menu.custom7 = MORE_CUSTOM7_TEXT_EN;
+ #endif
+ //
+ filesys_menu.title = TITLE_FILESYS_EN;
+ filesys_menu.sd_sys = SD_CARD_TEXT_EN;
+ filesys_menu.usb_sys = U_DISK_TEXT_EN;
+ // WIFI
+ wifi_menu.title = WIFI_TEXT;
+ wifi_menu.cloud = CLOUD_TEXT_EN;
+ wifi_menu.reconnect = WIFI_RECONNECT_TEXT_EN;
+
+ cloud_menu.title = TITLE_CLOUD_TEXT_EN;
+ cloud_menu.bind = CLOUD_BINDED_EN;
+ cloud_menu.binded = CLOUD_BINDED_EN;
+ cloud_menu.unbind = CLOUD_UNBIND_EN;
+ cloud_menu.unbinding = CLOUD_UNBINDED_EN;
+ cloud_menu.disconnected = CLOUD_DISCONNECTED_EN;
+ cloud_menu.unbinded = CLOUD_UNBINDED_EN;
+ cloud_menu.disable = CLOUD_DISABLE_EN;
+ //
+ about_menu.title = TITLE_ABOUT_EN;
+ about_menu.type = ABOUT_TYPE_TEXT_EN;
+ about_menu.version = ABOUT_VERSION_TEXT_EN;
+ about_menu.wifi = ABOUT_WIFI_TEXT_EN;
+ //
+ fan_menu.title = TITLE_FAN_EN;
+ fan_menu.add = FAN_ADD_TEXT_EN;
+ fan_menu.dec = FAN_DEC_TEXT_EN;
+ fan_menu.state = FAN_TIPS1_TEXT_EN;
+ //
+ filament_menu.title = TITLE_FILAMENT_EN;
+ filament_menu.in = FILAMENT_IN_TEXT_EN;
+ filament_menu.out = FILAMENT_OUT_TEXT_EN;
+ filament_menu.ext1 = FILAMENT_EXT0_TEXT_EN;
+ filament_menu.ext2 = FILAMENT_EXT1_TEXT_EN;
+ filament_menu.ready_replace = FILAMENT_CHANGE_TEXT_EN;
+ filament_menu.filament_dialog_load_heat = FILAMENT_DIALOG_LOAD_HEAT_TIPS_EN;
+ filament_menu.filament_dialog_load_heat_confirm = FILAMENT_DIALOG_LOAD_CONFIRM1_TIPS_EN;
+ filament_menu.filament_dialog_loading = FILAMENT_DIALOG_LOADING_TIPS_EN;
+ filament_menu.filament_dialog_load_completed = FILAMENT_DIALOG_LOAD_COMPLETE_TIPS_EN;
+ filament_menu.filament_dialog_unload_heat = FILAMENT_DIALOG_UNLOAD_HEAT_TIPS_EN;
+ filament_menu.filament_dialog_unload_heat_confirm = FILAMENT_DIALOG_UNLOAD_CONFIRM_TIPS_EN;
+ filament_menu.filament_dialog_unloading = FILAMENT_DIALOG_UNLOADING_TIPS_EN;
+ filament_menu.filament_dialog_unload_completed = FILAMENT_DIALOG_UNLOAD_COMPLETE_TIPS_EN;
+
+ //
+ language_menu.title = TITLE_LANGUAGE_EN;
+ language_menu.next = PAGE_DOWN_TEXT_EN;
+ language_menu.up = PAGE_UP_TEXT_EN;
+ //
+ printing_menu.title = TITLE_PRINTING_EN;
+ printing_menu.option = PRINTING_OPERATION_EN;
+ printing_menu.stop = PRINTING_STOP_EN;
+ printing_menu.pause = PRINTING_PAUSE_EN;
+ printing_menu.resume = PRINTING_RESUME_EN;
+
+ //
+ operation_menu.title = TITLE_OPERATION_EN;
+ operation_menu.pause = PRINTING_PAUSE_EN;
+ operation_menu.stop = PRINTING_STOP_EN;
+ operation_menu.temp = PRINTING_TEMP_EN;
+ operation_menu.fan = FAN_TEXT_EN;
+ operation_menu.extr = PRINTING_EXTRUDER_EN;
+ operation_menu.speed = PRINTING_CHANGESPEED_EN;
+ operation_menu.filament = FILAMENT_TEXT_EN;
+ operation_menu.more = PRINTING_MORE_EN;
+ operation_menu.move = PRINTING_MOVE_EN;
+ operation_menu.auto_off = AUTO_SHUTDOWN_EN;
+ operation_menu.manual_off = MANUAL_SHUTDOWN_EN;
+ //
+ pause_menu.title = TITLE_PAUSE_EN;
+ pause_menu.resume = PRINTING_RESUME_EN;
+ pause_menu.stop = PRINTING_STOP_EN;
+ pause_menu.extrude = PRINTING_EXTRUDER_EN;
+ pause_menu.move = PRINTING_MOVE_EN;
+ pause_menu.filament = FILAMENT_TEXT_EN;
+ pause_menu.more = PRINTING_MORE_EN;
+
+ //
+ speed_menu.title = TITLE_CHANGESPEED_EN;
+ speed_menu.add = ADD_TEXT_EN;
+ speed_menu.dec = DEC_TEXT_EN;
+ speed_menu.move = MOVE_SPEED_EN;
+ speed_menu.extrude = EXTRUDER_SPEED_EN;
+ speed_menu.extrude_speed = EXTRUDER_SPEED_STATE_EN;
+ speed_menu.move_speed = MOVE_SPEED_STATE_EN;
+ //
+ printing_more_menu.title = TITLE_MORE_EN;
+ printing_more_menu.fan = FAN_TEXT_EN;
+ printing_more_menu.auto_close = AUTO_SHUTDOWN_EN;
+ printing_more_menu.manual = MANUAL_SHUTDOWN_EN;
+ printing_more_menu.speed = PRINTING_CHANGESPEED_EN;
+ printing_more_menu.temp = PRINTING_TEMP_EN;
+
+ print_file_dialog_menu.confirm = DIALOG_CONFIRM_EN;
+ print_file_dialog_menu.cancel = DIALOG_CANCLE_EN;
+ print_file_dialog_menu.print_file = DIALOG_PRINT_MODEL_EN;
+ print_file_dialog_menu.cancel_print = DIALOG_CANCEL_PRINT_EN;
+ print_file_dialog_menu.retry = DIALOG_RETRY_EN;
+ print_file_dialog_menu.stop = DIALOG_STOP_EN;
+ print_file_dialog_menu.no_file_print_tips = DIALOG_ERROR_TIPS1_EN;
+ print_file_dialog_menu.print_from_breakpoint = DIALOG_REPRINT_FROM_BREAKPOINT_EN;
+ print_file_dialog_menu.close_machine_error = DIALOG_ERROR_TIPS2_EN;
+ print_file_dialog_menu.filament_no_press = DIALOG_FILAMENT_NO_PRESS_EN;
+ print_file_dialog_menu.print_finish = DIALOG_PRINT_FINISH_EN;
+ print_file_dialog_menu.print_time = DIALOG_PRINT_TIME_EN;
+ print_file_dialog_menu.reprint = DIALOG_REPRINT_EN;
+ print_file_dialog_menu.wifi_enable_tips = DIALOG_WIFI_ENABLE_TIPS_EN;
+ print_file_dialog_menu.machinePausingTips = DIALOG_PAUSING_TIPS_EN;
+
+ pause_msg_menu.pausing = MESSAGE_PAUSING_EN;
+ pause_msg_menu.changing = MESSAGE_CHANGING_EN;
+ pause_msg_menu.unload = MESSAGE_UNLOAD_EN;
+ pause_msg_menu.waiting = MESSAGE_WAITING_EN;
+ pause_msg_menu.insert = MESSAGE_INSERT_EN;
+ pause_msg_menu.load = MESSAGE_LOAD_EN;
+ pause_msg_menu.purge = MESSAGE_PURGE_EN;
+ pause_msg_menu.resume = MESSAGE_RESUME_EN;
+ pause_msg_menu.heat = MESSAGE_HEAT_EN;
+ pause_msg_menu.heating = MESSAGE_HEATING_EN;
+ pause_msg_menu.option = MESSAGE_OPTION_EN;
+ pause_msg_menu.purgeMore = MESSAGE_PURGE_MORE_EN;
+ pause_msg_menu.continuePrint = MESSAGE_CONTINUE_PRINT_EN;
+ eeprom_menu.title = EEPROM_SETTINGS_TITLE_EN;
+ eeprom_menu.store = EEPROM_SETTINGS_STORE_EN;
+ eeprom_menu.read = EEPROM_SETTINGS_READ_EN;
+ eeprom_menu.revert = EEPROM_SETTINGS_REVERT_EN;
+ eeprom_menu.storeTips = EEPROM_STORE_TIPS_EN;
+ eeprom_menu.readTips = EEPROM_READ_TIPS_EN;
+ eeprom_menu.revertTips = EEPROM_REVERT_TIPS_EN;
+ break;
+ }
+}
+
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h
new file mode 100644
index 0000000..7314da4
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.h
@@ -0,0 +1,865 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "tft_Language_en.h"
+#include "tft_Language_s_cn.h"
+#include "tft_Language_t_cn.h"
+#include "tft_Language_ru.h"
+#include "tft_Language_fr.h"
+#include "tft_Language_sp.h"
+#include "tft_Language_it.h"
+
+extern void disp_language_init();
+
+#define LANG_SIMPLE_CHINESE 1
+#define LANG_COMPLEX_CHINESE 2
+#define LANG_ENGLISH 3
+#define LANG_JAPAN 4
+#define LANG_GERMAN 5
+#define LANG_FRENCH 6
+#define LANG_RUSSIAN 7
+#define LANG_KOREAN 8
+#define LANG_TURKISH 9
+#define LANG_SPANISH 10
+#define LANG_GREEK 11
+#define LANG_ITALY 12
+#define LANG_PORTUGUESE 13
+
+#define MULTI_LANGUAGE_ENABLE 1
+#define MULTI_LANGUAGE_DISABLE 0
+
+typedef struct machine_common_disp{
+ const char *default_value;
+
+ const char *next;
+ const char *previous;
+
+ const char *MachineConfigTitle;
+ const char *MachineType;
+ const char *Stroke;
+ const char *HomeDir;
+ const char *EndStopType;
+ const char *FilamentConf;
+
+ const char *MachineTypeConfTitle;
+ const char *xyz;
+ const char *delta;
+ const char *corexy;
+
+ const char *StrokeConfTitle;
+ const char *xStroke;
+ const char *yStroke;
+ const char *zStroke;
+
+ const char *xmin;
+ const char *ymin;
+ const char *zmin;
+
+ const char *HomeDirConfTitle;
+ const char *xHomeDir;
+ const char *yHomeDir;
+ const char *zHomeDir;
+ const char *min;
+ const char *max;
+
+ const char *EndstopConfTitle;
+ const char *xEndstop_min;
+ const char *yEndstop_min;
+ const char *zEndstop_min;
+ const char *xEndstop_max;
+ const char *yEndstop_max;
+ const char *zEndstop_max;
+ const char *FilamentEndstop;
+ const char *LevelingEndstop;
+ const char *opened;
+ const char *closed;
+
+ const char *FilamentConfTitle;
+ const char *InLength;
+ const char *InSpeed;
+ const char *FilamentTemperature;
+ const char *OutLength;
+ const char *OutSpeed;
+
+ const char *LevelingParaConfTitle;
+ const char *LevelingParaConf;
+ const char *LevelingManuPosConf;
+ const char *LevelingAutoCommandConf;
+ const char *LevelingAutoZoffsetConf;
+ const char *LevelingTouchmiConf;
+ const char *TouchmiInit;
+ const char *TouchmiOffsetpos;
+ const char *TouchmiOffsetneg;
+ const char *TouchmiSave;
+ const char *TouchmiTest;
+
+ const char *BLTouchLevelingConfTitle;
+ const char *BLTouchLevelingConf;
+ const char *BLTouchInit;
+ const char *BLTouchOffsetpos;
+ const char *BLTouchOffsetneg;
+ const char *BLTouchSave;
+ const char *BLTouchTest;
+
+ const char *LevelingSubConfTitle;
+ const char *AutoLevelEnable;
+ const char *BLtouchEnable;
+ const char *ProbePort;
+ const char *ProbeXoffset;
+ const char *ProbeYoffset;
+ const char *ProbeZoffset;
+ const char *ProbeXYspeed;
+ const char *ProbeZspeed;
+ const char *enable;
+ const char *disable;
+ const char *locked;
+ const char *z_min;
+ const char *z_max;
+
+ const char *LevelingSubDeltaConfTitle;
+ const char *MachineRadius;
+ const char *DiagonalRod;
+ const char *PrintableRadius;
+ const char *DeltaHeight;
+ const char *SmoothRodOffset;
+ const char *EffectorOffset;
+ const char *CalibrationRadius;
+
+ const char *LevelingSubXYZConfTitle;
+
+ const char *TemperatureConfTitle;
+ const char *NozzleConf;
+ const char *HotBedConf;
+ const char *PreheatTemperConf;
+
+ const char *NozzleCnt;
+ const char *NozzleConfTitle;
+ const char *NozzleType;
+ const char *NozzleAdjustType;
+ const char *NozzleMinTemperature;
+ const char *NozzleMaxTemperature;
+ const char *Extrude_Min_Temper;
+
+ const char *HotbedEnable;
+ const char *HotbedConfTitle;
+ const char *HotbedAjustType;
+ const char *HotbedMinTemperature;
+ const char *HotbedMaxTemperature;
+
+ const char *MotorConfTitle;
+ const char *MaxFeedRateConf;
+ const char *AccelerationConf;
+ const char *JerkConf;
+ const char *StepsConf;
+ const char *MotorDirConf;
+ const char *HomeFeedRateConf;
+ const char *TMCcurrentConf;
+ const char *TMCStepModeConf;
+ const char *HomingSensitivityConf;
+
+ const char *MaxFeedRateConfTitle;
+ const char *XMaxFeedRate;
+ const char *YMaxFeedRate;
+ const char *ZMaxFeedRate;
+ const char *E0MaxFeedRate;
+ const char *E1MaxFeedRate;
+
+ const char *AccelerationConfTitle;
+ const char *PrintAcceleration;
+ const char *RetractAcceleration;
+ const char *TravelAcceleration;
+ const char *X_Acceleration;
+ const char *Y_Acceleration;
+ const char *Z_Acceleration;
+ const char *E0_Acceleration;
+ const char *E1_Acceleration;
+
+ const char *JerkConfTitle;
+ const char *X_Jerk;
+ const char *Y_Jerk;
+ const char *Z_Jerk;
+ const char *E_Jerk;
+
+ const char *StepsConfTitle;
+ const char *X_Steps;
+ const char *Y_Steps;
+ const char *Z_Steps;
+ const char *E0_Steps;
+ const char *E1_Steps;
+
+ const char *TmcCurrentConfTitle;
+ const char *X_Current;
+ const char *Y_Current;
+ const char *Z_Current;
+ const char *E0_Current;
+ const char *E1_Current;
+
+ const char *TmcStepModeConfTitle;
+ const char *X_StepMode;
+ const char *Y_StepMode;
+ const char *Z_StepMode;
+ const char *E0_StepMode;
+ const char *E1_StepMode;
+
+ const char *HomingSensitivityConfTitle;
+ const char *X_Sensitivity;
+ const char *Y_Sensitivity;
+ const char *Z_Sensitivity;
+ const char *Z2_Sensitivity;
+
+ const char *MotorDirConfTitle;
+ const char *X_MotorDir;
+ const char *Y_MotorDir;
+ const char *Z_MotorDir;
+ const char *E0_MotorDir;
+ const char *E1_MotorDir;
+ const char *Invert_1;
+ const char *Invert_0;
+
+ const char *HomeFeedRateConfTitle;
+ const char *XY_HomeFeedRate;
+ const char *Y_HomeFeedRate;
+ const char *Z_HomeFeedRate;
+
+ const char *AdvancedConfTitle;
+ const char *PwrOffDection;
+ const char *PwrOffAfterPrint;
+ const char *HaveUps;
+ const char *Z2andZ2Endstop;
+ const char *EnablePinsInvert;
+ const char *PausePosition;
+ const char *WifiSettings;
+ const char *EncoderSettings;
+
+ const char *Z2ConfTitle;
+ const char *Z2Enable;
+ const char *Z2EndstopEnable;
+ const char *Z2Port;
+
+ const char *EnablePinsInvertTitle;
+ const char *XInvert;
+ const char *YInvert;
+ const char *ZInvert;
+ const char *EInvert;
+
+ const char *key_1;
+ const char *key_2;
+ const char *key_3;
+ const char *key_4;
+ const char *key_5;
+ const char *key_6;
+ const char *key_7;
+ const char *key_8;
+ const char *key_9;
+ const char *key_0;
+ const char *key_point;
+ const char *key_back;
+ const char *key_reset;
+ const char *key_confirm;
+ const char *negative;
+ const char *low_level;
+ const char *high_level;
+
+ const char *PausePosText;
+ const char *xPos;
+ const char *yPos;
+ const char *zPos;
+
+ const char *WifiConfTitle;
+ const char *wifiMode;
+ const char *wifiName;
+ const char *wifiPassWord;
+ const char *wifiCloud;
+ const char *wifiConfig;
+ const char *wifiEdit;
+ const char *wifiConfigTips;
+
+ const char *OffsetConfTitle;
+ const char *Xoffset;
+ const char *Yoffset;
+ const char *Zoffset;
+
+ const char *EncoderConfTitle;
+ const char *EncoderConfText;
+
+} machine_common_def;
+
+extern machine_common_def machine_menu;
+
+typedef struct common_menu_disp {
+ const char *text_back;
+ const char *dialog_confirm_title;
+ const char *close_machine_tips;
+ const char *unbind_printer_tips;
+ const char *print_special_title;
+ const char *pause_special_title;
+ const char *operate_special_title;
+ const char *next;
+ const char *previous;
+} common_menu_def;
+
+extern common_menu_def common_menu;
+
+typedef struct main_menu_disp {
+ const char *title;
+ const char *preheat;
+ const char *move;
+ const char *home;
+ const char *print;
+ const char *extrude;
+ const char *leveling;
+ const char *autoleveling;
+ const char *fan;
+ const char *set;
+ const char *tool;
+ const char *more;
+ const char *machine_para;
+} main_menu_def;
+
+extern main_menu_def main_menu;
+
+typedef struct preheat_menu_disp {
+ const char *adjust_title;
+ const char *title;
+ const char *add;
+ const char *dec;
+ const char *ext1;
+ const char *ext2;
+ const char *hotbed;
+ const char *off;
+ const char *step_1c;
+ const char *step_5c;
+ const char *step_10c;
+ const char *back;
+
+ const char *value_state;
+
+ const char *dialog_tips;
+
+} preheat_menu_def;
+
+extern preheat_menu_def preheat_menu;
+
+typedef struct move_menu_disp {
+ const char *title;
+ const char *x_add;
+ const char *x_dec;
+ const char *y_add;
+ const char *y_dec;
+ const char *z_add;
+ const char *z_dec;
+ const char *step_001mm;
+ const char *step_005mm;
+ const char *step_01mm;
+ const char *step_1mm;
+ const char *step_10mm;
+ const char *back;
+} move_menu_def;
+
+extern move_menu_def move_menu;
+
+typedef struct home_menu_disp {
+ const char *title;
+ const char *home_all;
+ const char *home_x;
+ const char *home_y;
+ const char *home_z;
+ const char *stopmove;
+ const char *back;
+} home_menu_def;
+
+extern home_menu_def home_menu;
+
+typedef struct touchmi_menu_disp {
+ const char *title;
+ const char *init;
+ const char *zoffsetpos;
+ const char *zoffsetneg;
+ const char *test;
+ const char *save;
+} touchmi_menu_def;
+
+extern touchmi_menu_def touchmi_menu;
+
+typedef struct file_menu_disp {
+ const char *title;
+ const char *page_up;
+ const char *page_down;
+ const char *back;
+
+ const char *file_loading;
+ const char *no_file;
+ const char *no_file_and_check;
+
+} file_menu_def;
+
+extern file_menu_def file_menu;
+
+typedef struct extrude_menu_disp {
+ const char *title;
+ const char *in;
+ const char *out;
+ const char *ext1;
+ const char *ext2;
+ const char *step_1mm;
+ const char *step_5mm;
+ const char *step_10mm;
+ const char *low;
+ const char *normal;
+ const char *high;
+ const char *back;
+
+ const char *count_value_mm;
+ const char *count_value_cm;
+ const char *count_value_m;
+ const char *temp_value;
+ const char *temper_text;
+} extrude_menu_def;
+
+extern extrude_menu_def extrude_menu;
+
+typedef struct leveling_menu_disp {
+ const char *title;
+ const char *position1;
+ const char *position2;
+ const char *position3;
+ const char *position4;
+ const char *position5;
+
+ char *back;
+} leveling_menu_def;
+
+extern leveling_menu_def leveling_menu;
+
+typedef struct set_menu_disp {
+ const char *title;
+ const char *filesys;
+ const char *wifi;
+ const char *about;
+ const char *fan;
+ const char *filament;
+ const char *breakpoint;
+ const char *motoroff;
+ const char *motoroffXY;
+ const char *shutdown;
+ const char *language;
+ const char *machine_para;
+ const char *eepromSet;
+ const char *back;
+} set_menu_def;
+
+extern set_menu_def set_menu;
+
+typedef struct filesys_menu_disp {
+ const char *title;
+ const char *filesys;
+ const char *sd_sys;
+ const char *usb_sys;
+ const char *back;
+} filesys_menu_def;
+
+extern filesys_menu_def filesys_menu;
+
+typedef struct more_menu_disp {
+ const char *title;
+ const char *custom1;
+ const char *custom2;
+ const char *custom3;
+ const char *custom4;
+ const char *custom5;
+ const char *custom6;
+ const char *custom7;
+ const char *back;
+} more_menu_def;
+
+extern more_menu_def more_menu;
+
+typedef struct wifi_menu_disp {
+ const char *title;
+ const char *ip;
+ const char *wifi;
+ const char *key;
+ const char *state_ap;
+ const char *state_sta;
+ const char *cloud;
+ const char *connected;
+ const char *disconnected;
+ const char *exception;
+ const char *back;
+ const char *reconnect;
+} wifi_menu_def;
+
+extern wifi_menu_def wifi_menu;
+
+typedef struct cloud_menu_disp {
+ const char *title;
+ const char *unbind;
+ const char *unbinding;
+ const char *unbinded;
+ const char *bind;
+ const char *binding;
+ const char *binded;
+ const char *disable;
+ const char *disconnected;
+ const char *back;
+ const char *unbind_printer_tips;
+} cloud_menu_def;
+
+extern cloud_menu_def cloud_menu;
+
+typedef struct about_menu_disp {
+ const char *title;
+ const char *type_name;
+ const char *firmware_v;
+ const char *type;
+ const char *version;
+ const char *wifi;
+ const char *type_robin;
+ const char *type_robin_mini;
+ const char *back;
+} about_menu_def;
+
+extern about_menu_def about_menu;
+
+typedef struct fan_menu_disp {
+ const char *title;
+ const char *add;
+ const char *dec;
+ const char *full;
+ const char *half;
+ const char *off;
+ const char *back;
+
+ const char *state;
+ const char *state_value;
+} fan_menu_def;
+
+extern fan_menu_def fan_menu;
+
+typedef struct filament_menu_disp {
+ const char *title;
+ const char *in;
+ const char *out;
+ const char *ext1;
+ const char *ext2;
+ const char *back;
+ const char *stat_temp;
+ const char *ready_replace;
+ const char *replacing;
+ const char *loading;
+ const char *unloading;
+ const char *heating;
+ const char *complete_and_back;
+ const char *filament_dialog_load_heat;
+ const char *filament_dialog_unload_heat;
+ const char *filament_dialog_load_heat_confirm;
+ const char *filament_dialog_unload_heat_confirm;
+ const char *filament_dialog_loading;
+ const char *filament_dialog_unloading;
+ const char *filament_dialog_load_completed;
+ const char *filament_dialog_unload_completed;
+ const char *filament_dialog_ok;
+ const char *filament_dialog_back;
+} filament_menu_def;
+
+extern filament_menu_def filament_menu;
+
+typedef struct language_menu {
+ const char *title;
+ const char *chinese_s;
+ const char *chinese_t;
+ const char *english;
+ const char *russian;
+ const char *japan;
+ const char *italy;
+ const char *german;
+ const char *spanish;
+ const char *korean;
+ const char *french;
+ const char *brazil;
+ const char *portuguese;
+ const char *next;
+ const char *up;
+ const char *back;
+} language_menu_def;
+
+extern language_menu_def language_menu;
+
+typedef struct printing_menu_disp {
+ const char *title;
+ const char *option;
+ const char *temp1;
+ const char *temp2;
+ const char *bed_temp;
+ const char *fan_speed;
+ const char *pause;
+ const char *resume;
+ const char *stop;
+} printing_menu_def;
+
+extern printing_menu_def printing_menu;
+
+typedef struct operation_menu_disp {
+ const char *title;
+ const char *pause;
+ const char *stop;
+ const char *temp;
+ const char *fan;
+ const char *filament;
+ const char *extr;
+ const char *speed;
+ const char *move;
+ const char *more;
+ const char *auto_off;
+ const char *manual_off;
+ const char *back;
+ const char *babystep;
+} operation_menu_def;
+
+extern operation_menu_def operation_menu;
+
+typedef struct pause_menu_disp {
+ const char *title;
+ const char *resume;
+ const char *stop;
+ const char *extrude;
+ const char *move;
+ const char *filament;
+ const char *more;
+} pause_menu_def;
+
+extern pause_menu_def pause_menu;
+
+typedef struct speed_menu_disp {
+ const char *title;
+ const char *add;
+ const char *dec;
+ const char *extrude;
+ const char *move;
+ const char *step_1percent;
+ const char *step_5percent;
+ const char *step_10percent;
+ const char *back;
+ const char *move_speed;
+ const char *extrude_speed;
+} speed_menu_def;
+
+extern speed_menu_def speed_menu;
+
+typedef struct printing_more_menu_disp {
+ const char *title;
+ const char *fan;
+ const char *auto_close;
+ const char *manual;
+ const char *temp;
+ const char *speed;
+ const char *back;
+} printing_more_menu_def;
+
+extern printing_more_menu_def printing_more_menu;
+
+typedef struct dialog_menu_disp {
+ const char *confirm_title;
+
+ const char *error1_repint_no_file;
+ const char *error2_communication_fail;
+ const char *error3_filename_too_long;
+ const char *error4_no_file;
+ const char *error5_check_filesys;
+
+ const char *tip1_print_file;
+ const char *tip2_stop_file;
+} dialog_menu_def;
+
+extern dialog_menu_def dialog_menu;
+
+typedef struct print_file_dialog_disp {
+ const char *title;
+ const char *confirm;
+ const char *cancel;
+ const char *print_file;
+ const char *cancel_print;
+ const char *retry;
+ const char *stop;
+ const char *no_file_print_tips;
+ const char *print_from_breakpoint;
+ const char *file_name_too_long_error;
+ const char *close_machine_error;
+ const char *filament_no_press;
+ const char *print_finish;
+ const char *print_time;
+ const char *reprint;
+ const char *wifi_enable_tips;
+ const char *machinePausingTips;
+} print_file_dialog_menu_def;
+
+extern print_file_dialog_menu_def print_file_dialog_menu;
+
+typedef struct tool_menu_disp {
+ const char *title;
+ const char *preheat;
+ const char *extrude;
+ const char *move;
+ const char *home;
+ const char *leveling;
+ const char *autoleveling;
+ const char *filament;
+ const char *more;
+ const char *back;
+} tool_menu_def;
+
+extern tool_menu_def tool_menu;
+
+typedef struct MachinePara_menu_disp {
+ const char *title;
+ const char *MachineSetting;
+ const char *MotorSetting;
+ const char *leveling;
+ const char *AdvanceSetting;
+} MachinePara_menu_def;
+
+extern MachinePara_menu_def MachinePara_menu;
+
+typedef struct pause_msg_disp {
+ const char *pausing;
+ const char *changing;
+ const char *unload;
+ const char *waiting;
+ const char *insert;
+ const char *load;
+ const char *purge;
+ const char *resume;
+ const char *heat;
+ const char *heating;
+ const char *option;
+ const char *purgeMore;
+ const char *continuePrint;
+} pause_msg_def;
+
+extern pause_msg_def pause_msg_menu;
+
+typedef struct eeprom_disp{
+ const char *title;
+ const char *store;
+ const char *read;
+ const char *revert;
+ const char *storeTips;
+ const char *readTips;
+ const char *revertTips;
+} eeprom_def;
+
+extern eeprom_def eeprom_menu;
+/*****************************************/
+//
+#define TEXT_VALUE "%d/%d"
+
+#define TEXT_VALUE_T ": %d℃"
+#define TEXT_VALUE_mm ": %dmm"
+#define TEXT_VALUE_cm ": %dcm"
+#define TEXT_VALUE_m ": %dm"
+
+#define TEMP_UNIT_SYBOL "%d℃"
+#define FLOAT_TEMP_UNIT_SYBOL "%.1f℃"
+
+#define TEXT_1C "1℃"
+#define TEXT_5C "5℃"
+#define TEXT_10C "10℃"
+
+#define AXIS_X_ADD_TEXT "X+"
+#define AXIS_X_DEC_TEXT "X-"
+#define AXIS_Y_ADD_TEXT "Y+"
+#define AXIS_Y_DEC_TEXT "Y-"
+#define AXIS_Z_ADD_TEXT "Z+"
+#define AXIS_Z_DEC_TEXT "Z-"
+#define TEXT_001MM "0.01 mm"
+#define TEXT_005MM "0.05 mm"
+#define TEXT_01MM "0.1 mm"
+#define TEXT_1MM "1 mm"
+#define TEXT_10MM "10 mm"
+
+#define EXTRUDE_1MM_TEXT "1 mm"
+#define EXTRUDE_5MM_TEXT "5 mm"
+#define EXTRUDE_10MM_TEXT "10 mm"
+
+#define STEP_1PERCENT "1%"
+#define STEP_5PERCENT "5%"
+#define STEP_10PERCENT "10%"
+
+#define LANGUAGE_S_CN "简体"
+#define LANGUAGE_T_CN "繁体"
+#define LANGUAGE_EN "English"
+#define LANGUAGE_JP "日本語"
+#define LANGUAGE_GE "Deutsch"
+#define LANGUAGE_FR "français"
+#define LANGUAGE_IT "Italiano"
+#define LANGUAGE_PR "português"
+#define LANGUAGE_KR "Korean"
+#define LANGUAGE_BR "Brazil"
+#define LANGUAGE_RU "русский"
+#define LANGUAGE_SP "español"
+
+#define HOME_X_TEXT "X"
+#define HOME_Y_TEXT "Y"
+#define HOME_Z_TEXT "Z"
+#define HOME_ALL_TEXT "All"
+
+#define TM_INIT "Init"
+#define TM_ZOFFSETPOS "Offset +"
+#define TM_ZOFFSETNEG "Offset -"
+#define TM_SAVE "Save"
+#define TM_TEST "Test"
+
+//#if defined(MKS_ROBIN_NANO)
+#define ABOUT_TYPE_TEXT "MKS Robin Pro"
+
+#define ABOUT_VERSION_TEXT "1.0.0"
+
+#define FAN_OPEN_TEXT "100%"
+#define FAN_HALF_TEXT "50%"
+#define FAN_CLOSE_TEXT "0%"
+
+#define WIFI_TEXT "WIFI"
+#define WIFI_IP_TEXT "IP: "
+#define WIFI_NAME_TEXT "WiFi: "
+#define WIFI_KEY_TEXT "Key: "
+#define WIFI_STATE_AP_TEXT "State: AP"
+#define WIFI_STATE_STA_TEXT "State: STA"
+#define WIFI_CONNECTED_TEXT "Connected"
+#define WIFI_DISCONNECTED_TEXT "Disconnected"
+#define WIFI_EXCEPTION_TEXT "Exception"
+
+#define FILAMENT_TIPS2_TEXT "T:"
+
+#define DIALOG_UPLOAD_ING_EN "Uploading......"
+#define DIALOG_UPLOAD_ERROR_EN "Upload error"
+#define DIALOG_UPLOAD_FINISH_EN "Upload finished"
+#define DIALOG_UPLOAD_SIZE_EN "Size"
+#define DIALOG_UPLOAD_TIME_EN "Time"
+#define DIALOG_UPLOAD_SPEED_EN "Speed"
+#define DIALOG_UPDATE_WIFI_FIRMWARE_EN "Updating wifi model firmware"
+#define DIALOG_UPDATE_WIFI_WEB_EN "Updating wifi model web data"
+#define DIALOG_UPDATE_NO_DEVICE_EN "Please check\nwether memory device insert!"
+
+#define ZOFFSET_STEP001 "0.01 mm"
+#define ZOFFSET_STEP01 "0.1 mm"
+#define ZOFFSET_STEP1 "1 mm"
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp
new file mode 100644
index 0000000..d10d10e
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.cpp
@@ -0,0 +1,526 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+#include "wifiSerial.h"
+
+#ifdef __STM32F1__
+
+ #include <libmaple/libmaple.h>
+ #include <libmaple/gpio.h>
+ #include <libmaple/timer.h>
+ #include <libmaple/usart.h>
+ #include <libmaple/ring_buffer.h>
+
+ #include "../../../../MarlinCore.h"
+
+ DEFINE_WFSERIAL(WifiSerial1, 1);
+
+ WifiSerial::WifiSerial(usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) {
+ this->usart_device = usart_device;
+ this->tx_pin = tx_pin;
+ this->rx_pin = rx_pin;
+ }
+
+ /**
+ * Set up / tear down
+ */
+ #if STM32_MCU_SERIES == STM32_SERIES_F1
+ /* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict
+ * on this GPIO bit. */
+ static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) {
+ if (dev) timer_set_mode(dev, ch, TIMER_DISABLED);
+ }
+ static void usart_enable_no_irq(usart_dev *usart_device, bool with_irq) {
+ if (with_irq) usart_enable(usart_device);
+ else {
+ usart_reg_map *regs = usart_device->regs;
+ regs->CR1 |= (USART_CR1_TE | USART_CR1_RE);// don't change the word length etc, and 'or' in the patten not overwrite |USART_CR1_M_8N1);
+ regs->CR1 |= USART_CR1_UE;
+ }
+ }
+
+ #elif STM32_MCU_SERIES == STM32_SERIES_F2 || STM32_MCU_SERIES == STM32_SERIES_F4
+ #define disable_timer_if_necessary(dev, ch) ((void)0)
+
+ static void usart_enable_no_irq(usart_dev *usart_device, bool with_irq) {
+ if (with_irq) usart_enable(usart_device);
+ else {
+ usart_reg_map *regs = usart_device->regs;
+ regs->CR1 |= (USART_CR1_TE | USART_CR1_RE);// don't change the word length etc, and 'or' in the patten not overwrite |USART_CR1_M_8N1);
+ regs->CR1 |= USART_CR1_UE;
+ }
+ }
+ #else
+ #warning "Unsupported STM32 series; timer conflicts are possible"
+ #define usart_enable_no_irq(X, Y) usart_enable(X)
+ #endif
+
+ void WifiSerial::begin(uint32 baud) { begin(baud, SERIAL_8N1); }
+
+ /**
+ * Roger Clark.
+ * Note. The config parameter is not currently used. This is a work in progress.
+ * Code needs to be written to set the config of the hardware serial control register in question.
+ */
+
+ void WifiSerial::begin(uint32 baud, uint8_t config) {
+ //ASSERT(baud <= this->usart_device->max_baud); // Roger Clark. Assert doesn't do anything useful, we may as well save the space in flash and ram etc
+
+ if (baud > this->usart_device->max_baud) return;
+
+ const stm32_pin_info *txi = &PIN_MAP[this->tx_pin],
+ *rxi = &PIN_MAP[this->rx_pin];
+
+ disable_timer_if_necessary(txi->timer_device, txi->timer_channel);
+
+ usart_init(this->usart_device);
+
+ // Reinitialize the receive buffer, mks_esp8266 fixed data frame length is 1k bytes
+ rb_init(this->usart_device->rb, WIFI_RX_BUF_SIZE, wifiRxBuf);
+
+ usart_config_gpios_async(this->usart_device,
+ rxi->gpio_device, rxi->gpio_bit,
+ txi->gpio_device, txi->gpio_bit,
+ config);
+ usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud);
+ usart_enable_no_irq(this->usart_device, baud == WIFI_BAUDRATE);
+ }
+
+ void WifiSerial::end(void) {
+ usart_disable(this->usart_device);
+ }
+
+ int WifiSerial::available(void) {
+ return usart_data_available(this->usart_device);
+ }
+
+ //
+ // I/O
+ //
+
+ int WifiSerial::read(void) {
+ if (usart_data_available(usart_device) <= 0) return -1;
+ return usart_getc(usart_device);
+ }
+
+ int WifiSerial::write(unsigned char ch) {
+ usart_putc(this->usart_device, ch);
+ return 1;
+ }
+
+ int WifiSerial::wifi_rb_is_full(void) {
+ return rb_is_full(this->usart_device->rb);
+ }
+
+#else
+
+ WifiSerial WifiSerial1(USART1);
+
+ void WifiSerial::setRx(uint32_t _rx)
+ {
+ _serial.pin_rx = digitalPinToPinName(_rx);
+ }
+
+ void WifiSerial::setTx(uint32_t _tx)
+ {
+ _serial.pin_tx = digitalPinToPinName(_tx);
+ }
+
+ void WifiSerial::setRx(PinName _rx)
+ {
+ _serial.pin_rx = _rx;
+ }
+
+ void WifiSerial::setTx(PinName _tx)
+ {
+ _serial.pin_tx = _tx;
+ }
+
+ void WifiSerial::init(PinName _rx, PinName _tx)
+ {
+ if (_rx == _tx) {
+ _serial.pin_rx = NC;
+ } else {
+ _serial.pin_rx = _rx;
+ }
+ _serial.pin_tx = _tx;
+ _serial.rx_buff = wifiRxBuf;
+ _serial.rx_head = 0;
+ _serial.rx_tail = 0;
+ _serial.tx_buff = wifiTxBuf;
+ _serial.tx_head = 0;
+ _serial.tx_tail = 0;
+ }
+
+ WifiSerial::WifiSerial(void *peripheral)
+ {
+ // If PIN_SERIALy_RX is not defined assume half-duplex
+ _serial.pin_rx = NC;
+ // If Serial is defined in variant set
+ // the Rx/Tx pins for com port if defined
+ #if defined(Serial) && defined(PIN_SERIAL_TX)
+ if ((void *)this == (void *)&Serial) {
+ #if defined(PIN_SERIAL_RX)
+ setRx(PIN_SERIAL_RX);
+ #endif
+ setTx(PIN_SERIAL_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL1_TX) && defined(USART1_BASE)
+ if (peripheral == USART1) {
+ #if defined(PIN_SERIAL1_RX)
+ setRx(PIN_SERIAL1_RX);
+ #endif
+ setTx(PIN_SERIAL1_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL2_TX) && defined(USART2_BASE)
+ if (peripheral == USART2) {
+ #if defined(PIN_SERIAL2_RX)
+ setRx(PIN_SERIAL2_RX);
+ #endif
+ setTx(PIN_SERIAL2_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL3_TX) && defined(USART3_BASE)
+ if (peripheral == USART3) {
+ #if defined(PIN_SERIAL3_RX)
+ setRx(PIN_SERIAL3_RX);
+ #endif
+ setTx(PIN_SERIAL3_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL4_TX) &&\
+ (defined(USART4_BASE) || defined(UART4_BASE))
+ #if defined(USART4_BASE)
+ if (peripheral == USART4)
+ #elif defined(UART4_BASE)
+ if (peripheral == UART4)
+ #endif
+ {
+ #if defined(PIN_SERIAL4_RX)
+ setRx(PIN_SERIAL4_RX);
+ #endif
+ setTx(PIN_SERIAL4_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL5_TX) &&\
+ (defined(USART5_BASE) || defined(UART5_BASE))
+ #if defined(USART5_BASE)
+ if (peripheral == USART5)
+ #elif defined(UART5_BASE)
+ if (peripheral == UART5)
+ #endif
+ {
+ #if defined(PIN_SERIAL5_RX)
+ setRx(PIN_SERIAL5_RX);
+ #endif
+ setTx(PIN_SERIAL5_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL6_TX) && defined(USART6_BASE)
+ if (peripheral == USART6) {
+ #if defined(PIN_SERIAL6_RX)
+ setRx(PIN_SERIAL6_RX);
+ #endif
+ setTx(PIN_SERIAL6_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL7_TX) &&\
+ (defined(USART7_BASE) || defined(UART7_BASE))
+ #if defined(USART7_BASE)
+ if (peripheral == USART7)
+ #elif defined(UART7_BASE)
+ if (peripheral == UART7)
+ #endif
+ {
+ #if defined(PIN_SERIAL7_RX)
+ setRx(PIN_SERIAL7_RX);
+ #endif
+ setTx(PIN_SERIAL7_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL8_TX) &&\
+ (defined(USART8_BASE) || defined(UART8_BASE))
+ #if defined(USART8_BASE)
+ if (peripheral == USART8)
+ #elif defined(UART8_BASE)
+ if (peripheral == UART8)
+ #endif
+ {
+ #if defined(PIN_SERIAL8_RX)
+ setRx(PIN_SERIAL8_RX);
+ #endif
+ setTx(PIN_SERIAL8_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL9_TX) && defined(UART9_BASE)
+ if (peripheral == UART9) {
+ #if defined(PIN_SERIAL9_RX)
+ setRx(PIN_SERIAL9_RX);
+ #endif
+ setTx(PIN_SERIAL9_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIAL10_TX) &&\
+ (defined(USART10_BASE) || defined(UART10_BASE))
+ #if defined(USART10_BASE)
+ if (peripheral == USART10)
+ #elif defined(UART10_BASE)
+ if (peripheral == UART10)
+ #endif
+ {
+ #if defined(PIN_SERIAL10_RX)
+ setRx(PIN_SERIAL10_RX);
+ #endif
+ setTx(PIN_SERIAL10_TX);
+ } else
+ #endif
+ #if defined(PIN_SERIALLP1_TX) && defined(LPUART1_BASE)
+ if (peripheral == LPUART1) {
+ #if defined(PIN_SERIALLP1_RX)
+ setRx(PIN_SERIALLP1_RX);
+ #endif
+ setTx(PIN_SERIALLP1_TX);
+ } else
+ #endif
+ // else get the pins of the first peripheral occurence in PinMap
+ {
+ _serial.pin_rx = pinmap_pin(peripheral, PinMap_UART_RX);
+ _serial.pin_tx = pinmap_pin(peripheral, PinMap_UART_TX);
+ }
+ // if (halfDuplex == HALF_DUPLEX_ENABLED) {
+ // _serial.pin_rx = NC;
+ // }
+ init(_serial.pin_rx, _serial.pin_tx);
+ }
+
+ void WifiSerial::flush()
+ {
+ // If we have never written a byte, no need to flush. This special
+ // case is needed since there is no way to force the TXC (transmit
+ // complete) bit to 1 during initialization
+ if (!_written) {
+ return;
+ }
+
+ while ((_serial.tx_head != _serial.tx_tail)) {
+ // nop, the interrupt handler will free up space for us
+ }
+ // If we get here, nothing is queued anymore (DRIE is disabled) and
+ // the hardware finished tranmission (TXC is set).
+ }
+
+ bool WifiSerial::isHalfDuplex(void) const
+ {
+ return _serial.pin_rx == NC;
+ }
+
+ void WifiSerial::enableHalfDuplexRx(void)
+ {
+ if (isHalfDuplex()) {
+ // In half-duplex mode we have to wait for all TX characters to
+ // be transmitted before we can receive data.
+ flush();
+ if (!_rx_enabled) {
+ _rx_enabled = true;
+ uart_enable_rx(&_serial);
+ }
+ }
+ }
+
+ // Actual interrupt handlers //////////////////////////////////////////////////////////////
+
+ void WifiSerial::_rx_complete_irq(serial_t *obj)
+ {
+ // No Parity error, read byte and store it in the buffer if there is room
+ unsigned char c;
+
+ if (uart_getc(obj, &c) == 0) {
+
+ WRITE(WIFI_IO1_PIN, HIGH);
+
+ rx_buffer_index_t i = (unsigned int)(obj->rx_head + 1) % WIFI_RX_BUF_SIZE;
+
+ // if we should be storing the received character into the location
+ // just before the tail (meaning that the head would advance to the
+ // current location of the tail), we're about to overflow the buffer
+ // and so we don't write the character or advance the head.
+ if (i != obj->rx_tail) {
+ obj->rx_buff[obj->rx_head] = c;
+ obj->rx_head = i;
+ }
+ }
+ }
+
+ // Actual interrupt handlers //////////////////////////////////////////////////////////////
+
+ int WifiSerial::_tx_complete_irq(serial_t *obj)
+ {
+ // If interrupts are enabled, there must be more data in the output
+ // buffer. Send the next byte
+ obj->tx_tail = (obj->tx_tail + 1) % WIFI_TX_BUF_SIZE;
+
+ if (obj->tx_head == obj->tx_tail) {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ void WifiSerial::begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
+
+ void WifiSerial::begin(unsigned long baud, byte config) {
+ uint32_t databits = 0;
+ uint32_t stopbits = 0;
+ uint32_t parity = 0;
+
+ _baud = baud;
+ _config = config;
+
+ // Manage databits
+ switch (config & 0x07) {
+ case 0x02:
+ databits = 6;
+ break;
+ case 0x04:
+ databits = 7;
+ break;
+ case 0x06:
+ databits = 8;
+ break;
+ default:
+ databits = 0;
+ break;
+ }
+
+ if ((config & 0x30) == 0x30) {
+ parity = UART_PARITY_ODD;
+ databits++;
+ } else if ((config & 0x20) == 0x20) {
+ parity = UART_PARITY_EVEN;
+ databits++;
+ } else {
+ parity = UART_PARITY_NONE;
+ }
+
+ if ((config & 0x08) == 0x08) {
+ stopbits = UART_STOPBITS_2;
+ } else {
+ stopbits = UART_STOPBITS_1;
+ }
+
+ switch (databits) {
+ #ifdef UART_WORDLENGTH_7B
+ case 7:
+ databits = UART_WORDLENGTH_7B;
+ break;
+ #endif
+ case 8:
+ databits = UART_WORDLENGTH_8B;
+ break;
+ case 9:
+ databits = UART_WORDLENGTH_9B;
+ break;
+ default:
+ case 0:
+ Error_Handler();
+ break;
+ }
+
+ uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits);
+ enableHalfDuplexRx();
+ if (baud == WIFI_BAUDRATE) uart_attach_rx_callback(&_serial, _rx_complete_irq);
+ else {
+ USART1->CR1 |= (USART_CR1_RE);// don't change the word length etc, and 'or' in the patten not overwrite |USART_CR1_M_8N1);
+ }
+ }
+
+ void WifiSerial::end(void)
+ {
+ // wait for transmission of outgoing data
+ flush();
+
+ uart_deinit(&_serial);
+
+ // clear any received data
+ _serial.rx_head = _serial.rx_tail;
+ }
+
+ int WifiSerial::available(void) {
+ return ((unsigned int)(WIFI_RX_BUF_SIZE + _serial.rx_head - _serial.rx_tail)) % WIFI_RX_BUF_SIZE;
+ }
+
+ //
+ // I/O
+ //
+ int WifiSerial::read(void)
+ {
+ enableHalfDuplexRx();
+ // if the head isn't ahead of the tail, we don't have any characters
+ if (_serial.rx_head == _serial.rx_tail) {
+ return -1;
+ } else {
+ unsigned char c = _serial.rx_buff[_serial.rx_tail];
+ _serial.rx_tail = (rx_buffer_index_t)(_serial.rx_tail + 1) % WIFI_RX_BUF_SIZE;
+ return c;
+ }
+ }
+
+ int WifiSerial::write(uint8_t c)
+ {
+ _written = true;
+ if (isHalfDuplex()) {
+ if (_rx_enabled) {
+ _rx_enabled = false;
+ uart_enable_tx(&_serial);
+ }
+ }
+
+ tx_buffer_index_t i = (_serial.tx_head + 1) % WIFI_TX_BUF_SIZE;
+
+ // If the output buffer is full, there's nothing for it other than to
+ // wait for the interrupt handler to empty it a bit
+ while (i == _serial.tx_tail) {
+ // nop, the interrupt handler will free up space for us
+ }
+
+ _serial.tx_buff[_serial.tx_head] = c;
+ _serial.tx_head = i;
+
+ if (!serial_tx_active(&_serial)) {
+ uart_attach_tx_callback(&_serial, _tx_complete_irq);
+ }
+
+ return 1;
+ }
+#endif // __STM32F1__
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h
new file mode 100644
index 0000000..cd11d6b
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifiSerial.h
@@ -0,0 +1,145 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "tft_lvgl_configuration.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#ifdef SERIAL_PORT_2
+ #error "SERIAL_PORT_2 must be disabled with TFT_LVGL_UI* and MKS_WIFI_MODULE."
+#endif
+
+#define WIFI_BAUDRATE 115200
+#define WIFI_UPLOAD_BAUDRATE 1958400
+#define USART_SAFE_INSERT
+
+#define WIFI_RX_BUF_SIZE (1024)
+#define WIFI_TX_BUF_SIZE (64)
+
+#ifdef __STM32F1__
+
+ #include <libmaple/libmaple_types.h>
+ #include <libmaple/usart.h>
+ #include <libmaple/libmaple.h>
+ #include <libmaple/gpio.h>
+ #include <libmaple/timer.h>
+ #include <libmaple/ring_buffer.h>
+
+ #define DEFINE_WFSERIAL(name, n)\
+ WifiSerial name(USART##n, \
+ BOARD_USART##n##_TX_PIN, \
+ BOARD_USART##n##_RX_PIN)
+
+ class WifiSerial {
+ public:
+ uint8 wifiRxBuf[WIFI_RX_BUF_SIZE];
+
+ public:
+ WifiSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin);
+
+ /* Set up/tear down */
+ void begin(uint32 baud);
+ void begin(uint32 baud,uint8_t config);
+ void end();
+ int available(void);
+ int read(void);
+ int write(uint8_t);
+ inline void wifi_usart_irq(usart_reg_map *regs) {
+ /* Handling RXNEIE and TXEIE interrupts.
+ * RXNE signifies availability of a byte in DR.
+ *
+ * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15.
+ * We enable RXNEIE.
+ */
+ if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) {
+ #ifdef USART_SAFE_INSERT
+ /* If the buffer is full and the user defines USART_SAFE_INSERT,
+ * ignore new bytes. */
+ rb_safe_insert(this->usart_device->rb, (uint8)regs->DR);
+ #else
+ /* By default, push bytes around in the ring buffer. */
+ rb_push_insert(this->usart_device->rb, (uint8)regs->DR);
+ #endif
+ }
+ /* TXE signifies readiness to send a byte to DR. */
+ if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) {
+ if (!rb_is_empty(this->usart_device->wb))
+ regs->DR=rb_remove(this->usart_device->wb);
+ else
+ regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE
+ }
+ }
+ int wifi_rb_is_full(void);
+ struct usart_dev *usart_device;
+ private:
+ uint8 tx_pin;
+ uint8 rx_pin;
+ };
+ extern WifiSerial WifiSerial1;
+ #define WIFISERIAL WifiSerial1
+#else
+
+ #include <inttypes.h>
+ #include "Stream.h"
+ #include "uart.h"
+
+ class WifiSerial {
+ protected:
+ // Has any byte been written to the UART since begin()
+ bool _written;
+ serial_t _serial;
+ public:
+ uint8_t wifiRxBuf[WIFI_RX_BUF_SIZE];
+ uint8_t wifiTxBuf[WIFI_TX_BUF_SIZE];
+ WifiSerial(void *peripheral);
+
+ /* Set up/tear down */
+ void begin(uint32_t baud);
+ void begin(uint32_t baud,uint8_t config);
+ void end();
+ int available(void);
+ int read(void);
+ int write(uint8_t);
+
+ // Interrupt handlers
+ static int _tx_complete_irq(serial_t *obj);
+ static void _rx_complete_irq(serial_t *obj);
+
+ void flush(void);
+ bool isHalfDuplex(void) const;
+ void enableHalfDuplexRx(void);
+
+ private:
+ void setRx(uint32_t _rx);
+ void setTx(uint32_t _tx);
+ void setRx(PinName _rx);
+ void setTx(PinName _tx);
+ void init(PinName _rx, PinName _tx);
+ bool _rx_enabled;
+ uint8_t _config;
+ unsigned long _baud;
+ };
+ extern WifiSerial WifiSerial1;
+ #define WIFISERIAL WifiSerial1
+#endif // __STM32F1__
+#endif // MKS_WIFI_MODULE
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp
new file mode 100644
index 0000000..0e4163c
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp
@@ -0,0 +1,2231 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if HAS_TFT_LVGL_UI
+
+#include "draw_ui.h"
+#include "wifi_module.h"
+#include "wifi_upload.h"
+#include "SPI_TFT.h"
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+#include "../../../../MarlinCore.h"
+#include "../../../../module/temperature.h"
+#include "../../../../gcode/queue.h"
+#include "../../../../gcode/gcode.h"
+#include "../../../../lcd/marlinui.h"
+#include "../../../../sd/cardreader.h"
+#include "../../../../module/planner.h"
+#include "../../../../module/servo.h"
+#include "../../../../module/probe.h"
+#if ENABLED(POWER_LOSS_RECOVERY)
+ #include "../../../../feature/powerloss.h"
+#endif
+#if ENABLED(PARK_HEAD_ON_PAUSE)
+ #include "../../../../feature/pause.h"
+#endif
+
+#define WIFI_SET() WRITE(WIFI_RESET_PIN, HIGH);
+#define WIFI_RESET() WRITE(WIFI_RESET_PIN, LOW);
+#define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH);
+#define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW);
+
+extern uint8_t Explore_Disk (char* path , uint8_t recu_level);
+
+extern uint8_t commands_in_queue;
+extern uint8_t sel_id;
+extern unsigned int getTickDiff(unsigned int curTick, unsigned int lastTick);
+
+SZ_USART_FIFO WifiRxFifo;
+
+#define WAIT_ESP_TRANS_TIMEOUT_TICK 10500
+
+int cfg_cloud_flag = 0;
+
+extern PRINT_TIME print_time;
+
+char wifi_firm_ver[20] = { 0 };
+WIFI_GCODE_BUFFER espGcodeFifo;
+extern uint8_t pause_resum;
+
+uint8_t wifi_connect_flg = 0;
+extern volatile uint8_t get_temp_flag;
+
+#define WIFI_MODE 2
+#define WIFI_AP_MODE 3
+
+int upload_result = 0;
+
+uint32_t upload_time = 0;
+uint32_t upload_size = 0;
+
+volatile WIFI_STATE wifi_link_state;
+WIFI_PARA wifiPara;
+IP_PARA ipPara;
+CLOUD_PARA cloud_para;
+
+char wifi_check_time = 0;
+
+extern uint8_t gCurDir[100];
+
+extern uint32_t wifi_loop_cycle;
+
+volatile TRANSFER_STATE esp_state;
+
+uint8_t left_to_send = 0;
+uint8_t left_to_save[96] = { 0 };
+
+volatile WIFI_DMA_RCV_FIFO wifiDmaRcvFifo;
+
+volatile WIFI_TRANS_ERROR wifiTransError;
+
+static bool need_ok_later = false;
+
+extern volatile WIFI_STATE wifi_link_state;
+extern WIFI_PARA wifiPara;
+extern IP_PARA ipPara;
+extern CLOUD_PARA cloud_para;
+
+extern bool once_flag, flash_preview_begin, default_preview_flg, gcode_preview_over;
+extern char flash_dma_mode;
+
+uint32_t getWifiTick() {
+ return millis();
+}
+
+uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick) {
+ if (lastTick <= curTick)
+ return (curTick - lastTick) * TICK_CYCLE;
+ else
+ return (0xFFFFFFFF - lastTick + curTick) * TICK_CYCLE;
+}
+
+void wifi_delay(int n) {
+ uint32_t begin = getWifiTick();
+ uint32_t end = begin;
+ while (getWifiTickDiff(begin, end) < (uint32_t)n) {
+ end = getWifiTick();
+ }
+}
+
+void wifi_reset() {
+ uint32_t start, now;
+ start = getWifiTick();
+ now = start;
+ WIFI_RESET();
+ while (getWifiTickDiff(start, now) < 500)
+ now = getWifiTick();
+
+ WIFI_SET();
+}
+
+void mount_file_sys(uint8_t disk_type) {
+ if (disk_type == FILE_SYS_SD) {
+ TERN_(SDSUPPORT, card.mount());
+ }
+ else if (disk_type == FILE_SYS_USB) {
+ }
+}
+
+static bool longName2DosName(const char *longName, uint8_t *dosName) {
+ uint8_t i = FILENAME_LENGTH;
+ while (i)
+ dosName[--i] = '\0';
+ while (*longName) {
+ uint8_t c = *longName++;
+ if (c == '.') { // For a dot...
+ if (i == 0) {
+ return false;
+ }
+ else {
+ strcat((char *)dosName, ".GCO");
+ return dosName[0] != '\0';
+ }
+ }
+ else {
+ // Fail for illegal characters
+ PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
+ while (uint8_t b = pgm_read_byte(p++))
+ if (b == c)
+ return false;
+ if (c < 0x21 || c == 0x7F)
+ return false; // Check size, non-printable characters
+ dosName[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); // Uppercase required for 8.3 name
+ }
+ if (i >= 5) {
+ strcat((char *)dosName, "~1.GCO");
+ return dosName[0] != '\0';
+ }
+ }
+ return dosName[0] != '\0'; // Return true if any name was set
+}
+
+#ifdef __STM32F1__
+
+ #include <libmaple/timer.h>
+ #include <libmaple/util.h>
+ #include <libmaple/rcc.h>
+
+ #include <boards.h>
+ #include <wirish.h>
+
+ #include <libmaple/dma.h>
+ #include <libmaple/bitband.h>
+
+ #include <libmaple/libmaple.h>
+ #include <libmaple/gpio.h>
+ #include <libmaple/usart.h>
+ #include <libmaple/ring_buffer.h>
+
+ void exchangeFlashMode(char dmaMode) {
+ if (flash_dma_mode != dmaMode) {
+ flash_dma_mode = dmaMode;
+ if (flash_dma_mode == 1) {
+ }
+ else {
+ dma_disable(DMA1, DMA_CH5);
+ dma_clear_isr_bits(DMA1, DMA_CH4);
+ }
+ }
+ }
+
+ static int storeRcvData(volatile uint8_t *bufToCpy, int32_t len) {
+ unsigned char tmpW = wifiDmaRcvFifo.write_cur;
+ if (len > UDISKBUFLEN) return 0;
+ if (wifiDmaRcvFifo.state[tmpW] == udisk_buf_empty) {
+ memcpy((unsigned char *) wifiDmaRcvFifo.bufferAddr[tmpW], (uint8_t *)bufToCpy, len);
+ wifiDmaRcvFifo.state[tmpW] = udisk_buf_full;
+ wifiDmaRcvFifo.write_cur = (tmpW + 1) % TRANS_RCV_FIFO_BLOCK_NUM;
+ return 1;
+ }
+ return 0;
+ }
+
+ static void esp_dma_pre() {
+ dma_channel_reg_map *channel_regs = dma_tube_regs(DMA1, DMA_CH5);
+
+ CBI32(channel_regs->CCR, 0);
+ channel_regs->CMAR = (uint32_t)WIFISERIAL.usart_device->rb->buf;
+ channel_regs->CNDTR = 0x0000;
+ channel_regs->CNDTR = UART_RX_BUFFER_SIZE;
+ DMA1->regs->IFCR = 0xF0000;
+ SBI32(channel_regs->CCR, 0);
+ }
+
+ static void dma_ch5_irq_handle() {
+ uint8 status_bits = dma_get_isr_bits(DMA1, DMA_CH5);
+ dma_clear_isr_bits(DMA1, DMA_CH5);
+ if (status_bits & 0x8) {
+ // DMA transmit Error
+ }
+ else if (status_bits & 0x2) {
+ // DMA transmit complete
+ if (esp_state == TRANSFER_IDLE)
+ esp_state = TRANSFERING;
+
+ if (storeRcvData(WIFISERIAL.usart_device->rb->buf, UART_RX_BUFFER_SIZE)) {
+ esp_dma_pre();
+ if (wifiTransError.flag != 0x1)
+ WIFI_IO1_RESET();
+ }
+ else {
+ WIFI_IO1_SET();
+ esp_state = TRANSFER_STORE;
+ }
+ }
+ else if (status_bits & 0x4) {
+ // DMA transmit half
+ WIFI_IO1_SET();
+ }
+ }
+ static void wifi_usart_dma_init() {
+ dma_init(DMA1);
+ uint32_t flags = ( DMA_MINC_MODE | DMA_TRNS_CMPLT | DMA_HALF_TRNS | DMA_TRNS_ERR);
+ dma_xfer_size dma_bit_size = DMA_SIZE_8BITS;
+ dma_setup_transfer(DMA1, DMA_CH5, &USART1_BASE->DR, dma_bit_size,
+ (volatile void*)WIFISERIAL.usart_device->rb->buf, dma_bit_size, flags);// Transmit buffer DMA
+ dma_set_priority(DMA1, DMA_CH5, DMA_PRIORITY_LOW);
+ dma_attach_interrupt(DMA1, DMA_CH5, &dma_ch5_irq_handle);
+
+ dma_clear_isr_bits(DMA1, DMA_CH5);
+ dma_set_num_transfers(DMA1, DMA_CH5, UART_RX_BUFFER_SIZE);
+
+ bb_peri_set_bit(&USART1_BASE->CR3, USART_CR3_DMAR_BIT, 1);
+ dma_enable(DMA1, DMA_CH5); // enable transmit
+
+ for (uint8_t i = 0; i < TRANS_RCV_FIFO_BLOCK_NUM; i++) {
+ wifiDmaRcvFifo.bufferAddr[i] = &bmp_public_buf[1024 * i];
+ wifiDmaRcvFifo.state[i] = udisk_buf_empty;
+ }
+
+ memset(wifiDmaRcvFifo.bufferAddr[0], 0, 1024 * TRANS_RCV_FIFO_BLOCK_NUM);
+ wifiDmaRcvFifo.read_cur = 0;
+ wifiDmaRcvFifo.write_cur = 0;
+ }
+
+ void esp_port_begin(uint8_t interrupt) {
+ WifiRxFifo.uart_read_point = 0;
+ WifiRxFifo.uart_write_point = 0;
+ if (interrupt) {
+ #if ENABLED(MKS_WIFI_MODULE)
+ WIFISERIAL.end();
+ for (uint16_t i = 0; i < 65535; i++) { /*nada*/ }
+ WIFISERIAL.begin(WIFI_BAUDRATE);
+ uint32_t serial_connect_timeout = millis() + 1000UL;
+ while (PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+ #endif
+ }
+ else {
+ #if ENABLED(MKS_WIFI_MODULE)
+ WIFISERIAL.end();
+ WIFISERIAL.usart_device->regs->CR1 &= ~USART_CR1_RXNEIE;
+ WIFISERIAL.begin(WIFI_UPLOAD_BAUDRATE);
+ wifi_usart_dma_init();
+ #endif
+ }
+ }
+#else
+
+ DMA_HandleTypeDef wifiUsartDMArx;
+
+ void exchangeFlashMode(char dmaMode) {
+ if (flash_dma_mode != dmaMode) {
+ flash_dma_mode = dmaMode;
+ if (flash_dma_mode == 1) {
+ }
+ else {
+ }
+ }
+ }
+
+ #ifdef STM32F1xx
+
+ HAL_StatusTypeDef HAL_DMA_PollForTransferCustomize(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
+ {
+ uint32_t temp;
+ uint32_t tickstart = 0U;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* no transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+ __HAL_UNLOCK(hdma);
+ return HAL_ERROR;
+ }
+
+ /* Polling mode not supported in circular mode */
+ if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
+ {
+ hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+ return HAL_ERROR;
+ }
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Transfer Complete flag */
+ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
+ }
+ else
+ {
+ /* Half Transfer Complete flag */
+ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
+ {
+ if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET))
+ {
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+ WIFI_IO1_SET();
+ }
+
+ if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
+ {
+ /* When a DMA transfer error occurs */
+ /* A hardware clear of its EN bits is performed */
+ /* Clear all flags */
+ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
+
+ /* Change the DMA state */
+ hdma->State= HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ }
+ }
+
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* The selected Channelx EN bit is cleared (DMA is disabled and
+ all transfers are complete) */
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ else
+ {
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+ }
+ #else
+
+ typedef struct
+ {
+ __IO uint32_t ISR; /*!< DMA interrupt status register */
+ __IO uint32_t Reserved0;
+ __IO uint32_t IFCR; /*!< DMA interrupt flag clear register */
+ } MYDMA_Base_Registers;
+
+ HAL_StatusTypeDef HAL_DMA_PollForTransferCustomize(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
+ {
+ HAL_StatusTypeDef status = HAL_OK;
+ uint32_t mask_cpltlevel;
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t tmpisr;
+
+ /* calculate DMA base and stream number */
+ MYDMA_Base_Registers *regs;
+
+ if(HAL_DMA_STATE_BUSY != hdma->State)
+ {
+ /* No transfer ongoing */
+ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+ __HAL_UNLOCK(hdma);
+ return HAL_ERROR;
+ }
+
+ /* Polling mode not supported in circular mode and double buffering mode */
+ if ((hdma->Instance->CR & DMA_SxCR_CIRC) != RESET)
+ {
+ hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+ return HAL_ERROR;
+ }
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Transfer Complete flag */
+ mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;
+ }
+ else
+ {
+ /* Half Transfer Complete flag */
+ mask_cpltlevel = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
+ }
+
+ regs = (MYDMA_Base_Registers *)hdma->StreamBaseAddress;
+ tmpisr = regs->ISR;
+
+ while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
+ {
+ /* Check for the Timeout (Not applicable in circular mode)*/
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Update error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Get the ISR register value */
+ tmpisr = regs->ISR;
+
+ if((tmpisr & (DMA_FLAG_HTIF0_4 << hdma->StreamIndex)) != RESET)
+ {
+ /* Clear the Direct Mode error flag */
+ regs->IFCR = DMA_FLAG_HTIF0_4 << hdma->StreamIndex;
+ WIFI_IO1_SET();
+ }
+
+ if((tmpisr & (DMA_FLAG_TEIF0_4 << hdma->StreamIndex)) != RESET)
+ {
+ /* Update error code */
+ hdma->ErrorCode |= HAL_DMA_ERROR_TE;
+
+ /* Clear the transfer error flag */
+ regs->IFCR = DMA_FLAG_TEIF0_4 << hdma->StreamIndex;
+ }
+
+ if((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
+ {
+ /* Update error code */
+ hdma->ErrorCode |= HAL_DMA_ERROR_FE;
+
+ /* Clear the FIFO error flag */
+ regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;
+ }
+
+ if((tmpisr & (DMA_FLAG_DMEIF0_4 << hdma->StreamIndex)) != RESET)
+ {
+ /* Update error code */
+ hdma->ErrorCode |= HAL_DMA_ERROR_DME;
+
+ /* Clear the Direct Mode error flag */
+ regs->IFCR = DMA_FLAG_DMEIF0_4 << hdma->StreamIndex;
+ }
+ }
+
+ if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
+ {
+ if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != RESET)
+ {
+ HAL_DMA_Abort(hdma);
+
+ /* Clear the half transfer and transfer complete flags */
+ regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ /* Change the DMA state */
+ hdma->State= HAL_DMA_STATE_READY;
+
+ return HAL_ERROR;
+ }
+ }
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Clear the half transfer and transfer complete flags */
+ regs->IFCR = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << hdma->StreamIndex;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ hdma->State = HAL_DMA_STATE_READY;
+ }
+ else
+ {
+ /* Clear the half transfer and transfer complete flags */
+ regs->IFCR = (DMA_FLAG_HTIF0_4) << hdma->StreamIndex;
+ }
+
+ return status;
+ }
+ #endif
+
+ static void dmaTransmitBegin() {
+ wifiUsartDMArx.Init.MemInc = DMA_MINC_ENABLE;
+ if (HAL_DMA_Init((DMA_HandleTypeDef *)&wifiUsartDMArx) != HAL_OK) {
+ Error_Handler();
+ }
+ if (HAL_DMA_Start(&wifiUsartDMArx, (uint32_t)&(USART1->DR), (uint32_t)WIFISERIAL.wifiRxBuf, UART_RX_BUFFER_SIZE)) {
+ Error_Handler();
+ }
+ USART1->CR1 |= USART_CR1_UE;
+
+ SET_BIT(USART1->CR3, USART_CR3_DMAR);
+ WIFI_IO1_RESET();
+ }
+
+ static int storeRcvData(volatile uint8_t *bufToCpy, int32_t len) {
+ unsigned char tmpW = wifiDmaRcvFifo.write_cur;
+
+ if (len > UDISKBUFLEN) return 0;
+
+ if (wifiDmaRcvFifo.state[tmpW] == udisk_buf_empty) {
+ const int timeOut = 2000; //millisecond
+ dmaTransmitBegin();
+ if(HAL_DMA_PollForTransferCustomize(&wifiUsartDMArx, HAL_DMA_FULL_TRANSFER, timeOut) == HAL_OK) {
+ memcpy((unsigned char *) wifiDmaRcvFifo.bufferAddr[tmpW], (uint8_t *)bufToCpy, len);
+ wifiDmaRcvFifo.state[tmpW] = udisk_buf_full;
+ wifiDmaRcvFifo.write_cur = (tmpW + 1) % TRANS_RCV_FIFO_BLOCK_NUM;
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ static void wifi_usart_dma_init() {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ wifiUsartDMArx.Instance = DMA1_Channel5;
+ #else
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ wifiUsartDMArx.Instance = DMA2_Stream2;
+ wifiUsartDMArx.Init.Channel = DMA_CHANNEL_4;
+ #endif
+ wifiUsartDMArx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ wifiUsartDMArx.Init.PeriphInc = DMA_PINC_DISABLE;
+ wifiUsartDMArx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ wifiUsartDMArx.Init.MemDataAlignment = DMA_PDATAALIGN_BYTE;
+ wifiUsartDMArx.Init.Mode = DMA_NORMAL;
+ #ifdef STM32F4xx
+ wifiUsartDMArx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ #endif
+ wifiUsartDMArx.Init.MemInc = DMA_MINC_ENABLE;
+ if (HAL_DMA_Init((DMA_HandleTypeDef *)&wifiUsartDMArx) != HAL_OK) {
+ Error_Handler();
+ }
+ if (HAL_DMA_Start(&wifiUsartDMArx, (uint32_t)&(USART1->DR), (uint32_t)WIFISERIAL.wifiRxBuf, UART_RX_BUFFER_SIZE)) {
+ Error_Handler();
+ }
+ USART1->CR1 |= USART_CR1_UE;
+
+ SET_BIT(USART1->CR3, USART_CR3_DMAR); /* Enable Rx DMA Request */
+
+ for (uint8_t i = 0; i < TRANS_RCV_FIFO_BLOCK_NUM; i++) {
+ wifiDmaRcvFifo.bufferAddr[i] = &bmp_public_buf[1024 * i];
+ wifiDmaRcvFifo.state[i] = udisk_buf_empty;
+ }
+
+ memset(wifiDmaRcvFifo.bufferAddr[0], 0, 1024 * TRANS_RCV_FIFO_BLOCK_NUM);
+ wifiDmaRcvFifo.read_cur = 0;
+ wifiDmaRcvFifo.write_cur = 0;
+ }
+
+
+ void esp_port_begin(uint8_t interrupt) {
+ WifiRxFifo.uart_read_point = 0;
+ WifiRxFifo.uart_write_point = 0;
+
+ if (interrupt) {
+ #if ENABLED(MKS_WIFI_MODULE)
+ WIFISERIAL.end();
+ for (uint16_t i = 0; i < 65535; i++) { /*nada*/ }
+ WIFISERIAL.begin(WIFI_BAUDRATE);
+ uint32_t serial_connect_timeout = millis() + 1000UL;
+ while (PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
+ #endif
+ }
+ else {
+ #if ENABLED(MKS_WIFI_MODULE)
+ WIFISERIAL.end();
+ USART1->CR1 &= ~USART_CR1_RXNEIE;
+ WIFISERIAL.begin(WIFI_UPLOAD_BAUDRATE);
+ wifi_usart_dma_init();
+ #endif
+ }
+ }
+#endif //
+
+#if ENABLED(MKS_WIFI_MODULE)
+
+ int raw_send_to_wifi(uint8_t *buf, int len) {
+ if (buf == 0 || len <= 0) return 0;
+ for (int i = 0; i < len; i++)
+ WIFISERIAL.write(*(buf + i));
+ return len;
+ }
+
+#endif
+
+void wifi_ret_ack() {}
+
+uint8_t buf_to_wifi[256];
+int index_to_wifi = 0;
+int package_to_wifi(WIFI_RET_TYPE type, uint8_t *buf, int len) {
+ uint8_t wifi_ret_head = 0xA5;
+ uint8_t wifi_ret_tail = 0xFC;
+
+ if (type == WIFI_PARA_SET) {
+ int data_offset = 4;
+ int apLen = strlen((const char *)uiCfg.wifi_name);
+ int keyLen = strlen((const char *)uiCfg.wifi_key);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+
+ buf_to_wifi[data_offset] = gCfgItems.wifi_mode_sel;
+ buf_to_wifi[data_offset + 1] = apLen;
+ memcpy(&buf_to_wifi[data_offset + 2], (const char *)uiCfg.wifi_name, apLen);
+ buf_to_wifi[data_offset + apLen + 2] = keyLen;
+ memcpy(&buf_to_wifi[data_offset + apLen + 3], (const char *)uiCfg.wifi_key, keyLen);
+ buf_to_wifi[data_offset + apLen + keyLen + 3] = wifi_ret_tail;
+
+ index_to_wifi = apLen + keyLen + 3;
+
+ buf_to_wifi[0] = wifi_ret_head;
+ buf_to_wifi[1] = type;
+ buf_to_wifi[2] = index_to_wifi & 0xFF;
+ buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF;
+
+ raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ }
+ else if (type == WIFI_TRANS_INF) {
+ if (len > (int)(sizeof(buf_to_wifi) - index_to_wifi - 5)) {
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ return 0;
+ }
+
+ if (len > 0) {
+ memcpy(&buf_to_wifi[4 + index_to_wifi], buf, len);
+ index_to_wifi += len;
+
+ if (index_to_wifi < 1)
+ return 0;
+
+ if (buf_to_wifi[index_to_wifi + 3] == '\n') {
+ // mask "wait" "busy" "X:"
+ if (((buf_to_wifi[4] == 'w') && (buf_to_wifi[5] == 'a') && (buf_to_wifi[6] == 'i') && (buf_to_wifi[7] == 't') )
+ || ((buf_to_wifi[4] == 'b') && (buf_to_wifi[5] == 'u') && (buf_to_wifi[6] == 's') && (buf_to_wifi[7] == 'y') )
+ || ((buf_to_wifi[4] == 'X') && (buf_to_wifi[5] == ':') )
+ ) {
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ return 0;
+ }
+
+ buf_to_wifi[0] = wifi_ret_head;
+ buf_to_wifi[1] = type;
+ buf_to_wifi[2] = index_to_wifi & 0xFF;
+ buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF;
+ buf_to_wifi[4 + index_to_wifi] = wifi_ret_tail;
+
+ raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ }
+ }
+ }
+ else if (type == WIFI_EXCEP_INF) {
+ ZERO(buf_to_wifi);
+
+ buf_to_wifi[0] = wifi_ret_head;
+ buf_to_wifi[1] = type;
+ buf_to_wifi[2] = 1;
+ buf_to_wifi[3] = 0;
+ buf_to_wifi[4] = *buf;
+ buf_to_wifi[5] = wifi_ret_tail;
+
+ raw_send_to_wifi(buf_to_wifi, 6);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ }
+ else if (type == WIFI_CLOUD_CFG) {
+ int data_offset = 4;
+ int urlLen = strlen((const char *)uiCfg.cloud_hostUrl);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+
+ buf_to_wifi[data_offset] = gCfgItems.cloud_enable ? 0x0A : 0x05;
+ buf_to_wifi[data_offset + 1] = urlLen;
+ memcpy(&buf_to_wifi[data_offset + 2], (const char *)uiCfg.cloud_hostUrl, urlLen);
+ buf_to_wifi[data_offset + urlLen + 2] = uiCfg.cloud_port & 0xFF;
+ buf_to_wifi[data_offset + urlLen + 3] = (uiCfg.cloud_port >> 8) & 0xFF;
+ buf_to_wifi[data_offset + urlLen + 4] = wifi_ret_tail;
+
+ index_to_wifi = urlLen + 4;
+
+ buf_to_wifi[0] = wifi_ret_head;
+ buf_to_wifi[1] = type;
+ buf_to_wifi[2] = index_to_wifi & 0xFF;
+ buf_to_wifi[3] = (index_to_wifi >> 8) & 0xFF;
+
+ raw_send_to_wifi(buf_to_wifi, 5 + index_to_wifi);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ }
+ else if (type == WIFI_CLOUD_UNBIND) {
+ ZERO(buf_to_wifi);
+
+ buf_to_wifi[0] = wifi_ret_head;
+ buf_to_wifi[1] = type;
+ buf_to_wifi[2] = 0;
+ buf_to_wifi[3] = 0;
+ buf_to_wifi[4] = wifi_ret_tail;
+
+ raw_send_to_wifi(buf_to_wifi, 5);
+
+ ZERO(buf_to_wifi);
+ index_to_wifi = 0;
+ }
+ return 1;
+}
+
+
+#define SEND_OK_TO_WIFI send_to_wifi((uint8_t *)"ok\r\n", strlen("ok\r\n"))
+int send_to_wifi(uint8_t *buf, int len) { return package_to_wifi(WIFI_TRANS_INF, buf, len); }
+
+void set_cur_file_sys(int fileType) { gCfgItems.fileSysType = fileType; }
+
+void get_file_list(char *path) {
+ if (!path) return;
+
+ if (gCfgItems.fileSysType == FILE_SYS_SD) {
+ TERN_(SDSUPPORT, card.mount());
+ }
+ else if (gCfgItems.fileSysType == FILE_SYS_USB) {
+ // udisk
+ }
+ Explore_Disk(path, 0);
+}
+
+char wait_ip_back_flag = 0;
+
+typedef struct {
+ int write_index;
+ uint8_t saveFileName[30];
+ uint8_t fileTransfer;
+ uint32_t fileLen;
+ uint32_t tick_begin;
+ uint32_t tick_end;
+} FILE_WRITER;
+
+FILE_WRITER file_writer;
+
+int32_t lastFragment = 0;
+
+char saveFilePath[50];
+
+static SdFile upload_file, *upload_curDir;
+static filepos_t pos;
+
+int write_to_file(char *buf, int len) {
+ int i;
+ int res = 0;
+
+ for (i = 0; i < len; i++) {
+ public_buf[file_writer.write_index++] = buf[i];
+ if (file_writer.write_index >= 512) {
+ res = upload_file.write(public_buf, file_writer.write_index);
+
+ if (res == -1) {
+ upload_file.close();
+ const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+
+ if (upload_file.open(upload_curDir, fname, O_WRITE)) {
+ upload_file.setpos(&pos);
+ res = upload_file.write(public_buf, file_writer.write_index);
+ }
+ }
+ if (res == -1) {
+ return -1;
+ }
+ upload_file.getpos(&pos);
+ file_writer.write_index = 0;
+ }
+ }
+
+ if (res == -1) {
+ memset(public_buf, 0, sizeof(public_buf));
+ file_writer.write_index = 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+#define ESP_PROTOC_HEAD (uint8_t)0xA5
+#define ESP_PROTOC_TAIL (uint8_t)0xFC
+
+#define ESP_TYPE_NET (uint8_t)0x0
+#define ESP_TYPE_GCODE (uint8_t)0x1
+#define ESP_TYPE_FILE_FIRST (uint8_t)0x2
+#define ESP_TYPE_FILE_FRAGMENT (uint8_t)0x3
+
+#define ESP_TYPE_WIFI_LIST (uint8_t)0x4
+
+uint8_t esp_msg_buf[UART_RX_BUFFER_SIZE] = { 0 };
+uint16_t esp_msg_index = 0;
+
+typedef struct {
+ uint8_t head;
+ uint8_t type;
+ uint16_t dataLen;
+ uint8_t *data;
+ uint8_t tail;
+} ESP_PROTOC_FRAME;
+
+
+static int cut_msg_head(uint8_t *msg, uint16_t msgLen, uint16_t cutLen) {
+ if (msgLen < cutLen) return 0;
+
+ else if (msgLen == cutLen) {
+ memset(msg, 0, msgLen);
+ return 0;
+ }
+
+ for (int i = 0; i < (msgLen - cutLen); i++)
+ msg[i] = msg[cutLen + i];
+
+ memset(&msg[msgLen - cutLen], 0, cutLen);
+
+ return msgLen - cutLen;
+}
+
+uint8_t Explore_Disk(char* path , uint8_t recu_level) {
+ char tmp[200];
+ char Fstream[200];
+
+ if (!path) return 0;
+
+ const uint8_t fileCnt = card.get_num_Files();
+
+ for (uint8_t i = 0; i < fileCnt; i++) {
+ const uint16_t nr =
+ #if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA)
+ fileCnt - 1 -
+ #endif
+ i;
+
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ card.getfilename_sorted(nr);
+ #else
+ card.getfilename_sorted(nr);
+ #endif
+ memset(tmp, 0, sizeof(tmp));
+ strcpy(tmp, card.filename);
+
+ ZERO(Fstream);
+ strcpy(Fstream, tmp);
+
+ if (card.flag.filenameIsDir && recu_level <= 10)
+ strcat(Fstream, ".DIR");
+
+ strcat(Fstream, "\r\n");
+ send_to_wifi((uint8_t*)Fstream, strlen(Fstream));
+ }
+
+ return fileCnt;
+}
+
+static void wifi_gcode_exec(uint8_t *cmd_line) {
+ int8_t tempBuf[100] = { 0 };
+ uint8_t *tmpStr = 0;
+ int cmd_value;
+ volatile int print_rate;
+ if (strchr((char *)cmd_line, '\n') && (strchr((char *)cmd_line, 'G') || strchr((char *)cmd_line, 'M') || strchr((char *)cmd_line, 'T'))) {
+ tmpStr = (uint8_t *)strchr((char *)cmd_line, '\n');
+ if (tmpStr) *tmpStr = '\0';
+
+ tmpStr = (uint8_t *)strchr((char *)cmd_line, '\r');
+ if (tmpStr) *tmpStr = '\0';
+
+ tmpStr = (uint8_t *)strchr((char *)cmd_line, '*');
+ if (tmpStr) *tmpStr = '\0';
+
+ tmpStr = (uint8_t *)strchr((char *)cmd_line, 'M');
+ if (tmpStr) {
+ cmd_value = atoi((char *)(tmpStr + 1));
+ tmpStr = (uint8_t *)strchr((char *)tmpStr, ' ');
+
+ switch (cmd_value) {
+
+ case 20: // M20: Print SD / µdisk file
+ file_writer.fileTransfer = 0;
+ if (uiCfg.print_state == IDLE) {
+ int index = 0;
+
+ if (tmpStr == 0) {
+ gCfgItems.fileSysType = FILE_SYS_SD;
+ send_to_wifi((uint8_t *)"Begin file list\r\n", strlen("Begin file list\r\n"));
+ get_file_list((char *)"0:/");
+ send_to_wifi((uint8_t *)"End file list\r\n", strlen("End file list\r\n"));
+ SEND_OK_TO_WIFI;
+ break;
+ }
+
+ while (tmpStr[index] == ' ') index++;
+
+ if (gCfgItems.wifi_type == ESP_WIFI) {
+ char *path = (char *)tempBuf;
+
+ if (strlen((char *)&tmpStr[index]) < 80) {
+ send_to_wifi((uint8_t *)"Begin file list\r\n", strlen("Begin file list\r\n"));
+
+ if (strncmp((char *)&tmpStr[index], "1:", 2) == 0)
+ gCfgItems.fileSysType = FILE_SYS_SD;
+ else if (strncmp((char *)&tmpStr[index], "0:", 2) == 0)
+ gCfgItems.fileSysType = FILE_SYS_USB;
+
+ strcpy((char *)path, (char *)&tmpStr[index]);
+ get_file_list(path);
+ send_to_wifi((uint8_t *)"End file list\r\n", strlen("End file list\r\n"));
+ }
+ SEND_OK_TO_WIFI;
+ }
+ }
+ break;
+
+ case 21:
+ /*init sd card*/
+ SEND_OK_TO_WIFI;
+ break;
+
+ case 23:
+ /*select the file*/
+ if (uiCfg.print_state == IDLE) {
+ int index = 0;
+ while (tmpStr[index] == ' ') index++;
+
+ if (strstr((char *)&tmpStr[index], ".g") || strstr((char *)&tmpStr[index], ".G")) {
+ if (strlen((char *)&tmpStr[index]) < 80) {
+ ZERO(list_file.file_name[sel_id]);
+ ZERO(list_file.long_name[sel_id]);
+ uint8_t has_path_selected = 0;
+
+ if (gCfgItems.wifi_type == ESP_WIFI) {
+ if (strncmp((char *)&tmpStr[index], "1:", 2) == 0) {
+ gCfgItems.fileSysType = FILE_SYS_SD;
+ has_path_selected = 1;
+ }
+ else if (strncmp((char *)&tmpStr[index], "0:", 2) == 0) {
+ gCfgItems.fileSysType = FILE_SYS_USB;
+ has_path_selected = 1;
+ }
+ else if (tmpStr[index] != '/')
+ strcat((char *)list_file.file_name[sel_id], "/");
+
+ if (file_writer.fileTransfer == 1) {
+ uint8_t dosName[FILENAME_LENGTH];
+ uint8_t fileName[sizeof(list_file.file_name[sel_id])];
+ fileName[0] = '\0';
+ if (has_path_selected == 1) {
+ strcat((char *)fileName, (char *)&tmpStr[index + 3]);
+ strcat((char *)list_file.file_name[sel_id], "/");
+ }
+ else strcat((char *)fileName, (char *)&tmpStr[index]);
+ if (!longName2DosName((const char *)fileName, dosName)) {
+ strcpy(list_file.file_name[sel_id], "notValid");
+ }
+ strcat((char *)list_file.file_name[sel_id], (char *)dosName);
+ strcat((char *)list_file.long_name[sel_id], (char *)dosName);
+ }
+ else {
+ strcat((char *)list_file.file_name[sel_id], (char *)&tmpStr[index]);
+ strcat((char *)list_file.long_name[sel_id], (char *)&tmpStr[index]);
+ }
+
+ }
+ else
+ strcpy(list_file.file_name[sel_id], (char *)&tmpStr[index]);
+
+ char *cur_name=strrchr(list_file.file_name[sel_id],'/');
+
+ card.openFileRead(cur_name);
+
+ if (card.isFileOpen())
+ send_to_wifi((uint8_t *)"File selected\r\n", strlen("File selected\r\n"));
+ else {
+ send_to_wifi((uint8_t *)"file.open failed\r\n", strlen("file.open failed\r\n"));
+ strcpy(list_file.file_name[sel_id], "notValid");
+ }
+ SEND_OK_TO_WIFI;
+ }
+ }
+ }
+ break;
+
+ case 24:
+ if (strcmp(list_file.file_name[sel_id], "notValid") != 0) {
+ if (uiCfg.print_state == IDLE) {
+ lv_clear_cur_ui();
+ reset_print_time();
+ start_print_time();
+ preview_gcode_prehandle(list_file.file_name[sel_id]);
+ uiCfg.print_state = WORKING;
+ lv_draw_printing();
+
+ #if ENABLED(SDSUPPORT)
+ if (!gcode_preview_over) {
+ char *cur_name = strrchr(list_file.file_name[sel_id], '/');
+
+ card.endFilePrint();
+
+ SdFile file;
+ SdFile *curDir;
+ card.endFilePrint();
+ const char * const fname = card.diveToFile(true, curDir, cur_name);
+ if (!fname) return;
+ if (file.open(curDir, fname, O_READ)) {
+ gCfgItems.curFilesize = file.fileSize();
+ file.close();
+ update_spi_flash();
+ }
+ card.openFileRead(cur_name);
+ if (card.isFileOpen()) {
+ //saved_feedrate_percentage = feedrate_percentage;
+ feedrate_percentage = 100;
+ planner.flow_percentage[0] = 100;
+ planner.e_factor[0] = planner.flow_percentage[0] * 0.01f;
+ #if EXTRUDERS == 2
+ planner.flow_percentage[1] = 100;
+ planner.e_factor[1] = planner.flow_percentage[1] * 0.01f;
+ #endif
+ card.startFileprint();
+ TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
+ once_flag = false;
+ }
+ }
+ #endif
+ }
+ else if (uiCfg.print_state == PAUSED) {
+ uiCfg.print_state = RESUMING;
+ lv_clear_cur_ui();
+ start_print_time();
+
+ if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+ lv_draw_printing();
+ }
+ else if (uiCfg.print_state == REPRINTING) {
+ uiCfg.print_state = REPRINTED;
+ lv_clear_cur_ui();
+ start_print_time();
+ if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+ lv_draw_printing();
+ }
+ }
+ SEND_OK_TO_WIFI;
+ break;
+
+ case 25:
+ /*pause print file*/
+ if (uiCfg.print_state == WORKING) {
+ stop_print_time();
+
+ lv_clear_cur_ui();
+
+ #if ENABLED(SDSUPPORT)
+ card.pauseSDPrint();
+ uiCfg.print_state = PAUSING;
+ #endif
+ if (gCfgItems.from_flash_pic)
+ flash_preview_begin = true;
+ else
+ default_preview_flg = true;
+ lv_draw_printing();
+ SEND_OK_TO_WIFI;
+ }
+ break;
+
+ case 26:
+ /*stop print file*/
+ if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED) || (uiCfg.print_state == REPRINTING)) {
+ stop_print_time();
+
+ lv_clear_cur_ui();
+ #if ENABLED(SDSUPPORT)
+ uiCfg.print_state = IDLE;
+ card.flag.abort_sd_printing = true;
+ #endif
+
+ lv_draw_ready_print();
+
+ SEND_OK_TO_WIFI;
+ }
+ break;
+
+ case 27:
+ /*report print rate*/
+ if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)|| (uiCfg.print_state == REPRINTING)) {
+ print_rate = uiCfg.totalSend;
+ ZERO(tempBuf);
+ sprintf((char *)tempBuf, "M27 %d\r\n", print_rate);
+ send_to_wifi((uint8_t *)tempBuf, strlen((char *)tempBuf));
+ }
+ break;
+
+ case 28:
+ /*begin to transfer file to filesys*/
+ if (uiCfg.print_state == IDLE) {
+
+ int index = 0;
+ while (tmpStr[index] == ' ') index++;
+
+ if (strstr((char *)&tmpStr[index], ".g") || strstr((char *)&tmpStr[index], ".G")) {
+ strcpy((char *)file_writer.saveFileName, (char *)&tmpStr[index]);
+
+ if (gCfgItems.fileSysType == FILE_SYS_SD) {
+ ZERO(tempBuf);
+ sprintf((char *)tempBuf, "%s", file_writer.saveFileName);
+ }
+ else if (gCfgItems.fileSysType == FILE_SYS_USB) {
+ ZERO(tempBuf);
+ sprintf((char *)tempBuf, "%s", (char *)file_writer.saveFileName);
+ }
+ mount_file_sys(gCfgItems.fileSysType);
+
+ #if ENABLED(SDSUPPORT)
+ char *cur_name = strrchr(list_file.file_name[sel_id], '/');
+ card.openFileWrite(cur_name);
+ if (card.isFileOpen()) {
+ ZERO(file_writer.saveFileName);
+ strcpy((char *)file_writer.saveFileName, (char *)&tmpStr[index]);
+ ZERO(tempBuf);
+ sprintf((char *)tempBuf, "Writing to file: %s\r\n", (char *)file_writer.saveFileName);
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)tempBuf, strlen((char *)tempBuf));
+ wifi_link_state = WIFI_WAIT_TRANS_START;
+ }
+ else {
+ wifi_link_state = WIFI_CONNECTED;
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TRANSFER_NO_DEVICE);
+ }
+ #endif
+ }
+ }
+ break;
+ case 105:
+ case 991:
+ ZERO(tempBuf);
+ if (cmd_value == 105) {
+ SEND_OK_TO_WIFI;
+ sprintf((char *)tempBuf,"T:%.1f /%.1f B:%.1f /%.1f T0:%.1f /%.1f T1:%.1f /%.1f @:0 B@:0\r\n",
+
+ (float)thermalManager.temp_hotend[0].celsius, (float)thermalManager.temp_hotend[0].target,
+ #if HAS_HEATED_BED
+ (float)thermalManager.temp_bed.celsius, (float)thermalManager.temp_bed.target,
+ #else
+ 0.0f, 0.0f,
+ #endif
+ (float)thermalManager.temp_hotend[0].celsius, (float)thermalManager.temp_hotend[0].target,
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ (float)thermalManager.temp_hotend[1].celsius, (float)thermalManager.temp_hotend[1].target
+ #else
+ 0.0f, 0.0f
+ #endif
+ );
+ }
+ else {
+ sprintf((char *)tempBuf,"T:%d /%d B:%d /%d T0:%d /%d T1:%d /%d @:0 B@:0\r\n",
+
+ (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target,
+ #if HAS_HEATED_BED
+ (int)thermalManager.temp_bed.celsius, (int)thermalManager.temp_bed.target,
+ #else
+ 0, 0,
+ #endif
+ (int)thermalManager.temp_hotend[0].celsius, (int)thermalManager.temp_hotend[0].target,
+ #if DISABLED(SINGLENOZZLE) && HAS_MULTI_EXTRUDER
+ (int)thermalManager.temp_hotend[1].celsius, (int)thermalManager.temp_hotend[1].target
+ #else
+ 0, 0
+ #endif
+ );
+ }
+
+ send_to_wifi((uint8_t *)tempBuf, strlen((char *)tempBuf));
+ queue.enqueue_one_P(PSTR("M105"));
+ break;
+
+ case 992:
+ if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)) {
+ ZERO(tempBuf);
+ sprintf((char *)tempBuf, "M992 %d%d:%d%d:%d%d\r\n", print_time.hours/10, print_time.hours%10, print_time.minutes/10, print_time.minutes%10, print_time.seconds/10, print_time.seconds%10);
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)tempBuf, strlen((char *)tempBuf));
+ }
+ break;
+
+ case 994:
+ if ((uiCfg.print_state == WORKING) || (uiCfg.print_state == PAUSED)) {
+ ZERO(tempBuf);
+ if (strlen((char *)list_file.file_name[sel_id]) > (100 - 1)) return;
+ sprintf((char *)tempBuf, "M994 %s;%d\n", list_file.file_name[sel_id],(int)gCfgItems.curFilesize);
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)tempBuf, strlen((char *)tempBuf));
+ }
+ break;
+
+ case 997:
+ if (uiCfg.print_state == IDLE) {
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)"M997 IDLE\r\n", strlen("M997 IDLE\r\n"));
+ }
+ else if (uiCfg.print_state == WORKING) {
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)"M997 PRINTING\r\n", strlen("M997 PRINTING\r\n"));
+ }
+ else if (uiCfg.print_state == PAUSED) {
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)"M997 PAUSE\r\n", strlen("M997 PAUSE\r\n"));
+ }
+ else if (uiCfg.print_state == REPRINTING) {
+ wifi_ret_ack();
+ send_to_wifi((uint8_t *)"M997 PAUSE\r\n", strlen("M997 PAUSE\r\n"));
+ }
+ if (uiCfg.command_send == 0) get_wifi_list_command_send();
+ break;
+
+ case 998:
+ if (uiCfg.print_state == IDLE) {
+ int v = atoi((char *)tmpStr);
+ if (v == 0)
+ set_cur_file_sys(0);
+ else if (v == 1)
+ set_cur_file_sys(1);
+ wifi_ret_ack();
+ }
+ break;
+
+ case 115:
+ ZERO(tempBuf);
+ SEND_OK_TO_WIFI;
+ send_to_wifi((uint8_t *)"FIRMWARE_NAME:Robin_nano\r\n", strlen("FIRMWARE_NAME:Robin_nano\r\n"));
+ break;
+
+ default:
+ strcat((char *)cmd_line, "\n");
+
+ if (espGcodeFifo.wait_tick > 5) {
+ uint32_t left;
+ if (espGcodeFifo.r > espGcodeFifo.w)
+ left = espGcodeFifo.r - espGcodeFifo.w - 1;
+ else
+ left = WIFI_GCODE_BUFFER_SIZE + espGcodeFifo.r - espGcodeFifo.w - 1;
+
+ if (left >= strlen((const char *)cmd_line)) {
+ uint32_t index = 0;
+ while (index < strlen((const char *)cmd_line)) {
+ espGcodeFifo.Buffer[espGcodeFifo.w] = cmd_line[index] ;
+ espGcodeFifo.w = (espGcodeFifo.w + 1) % WIFI_GCODE_BUFFER_SIZE;
+ index++;
+ }
+ if (left - WIFI_GCODE_BUFFER_LEAST_SIZE >= strlen((const char *)cmd_line))
+ SEND_OK_TO_WIFI;
+ else
+ need_ok_later = true;
+ }
+ }
+ break;
+ }
+ }
+ else {
+ strcat((char *)cmd_line, "\n");
+
+ if (espGcodeFifo.wait_tick > 5) {
+ uint32_t left_g;
+ if (espGcodeFifo.r > espGcodeFifo.w)
+ left_g = espGcodeFifo.r - espGcodeFifo.w - 1;
+ else
+ left_g = WIFI_GCODE_BUFFER_SIZE + espGcodeFifo.r - espGcodeFifo.w - 1;
+
+ if (left_g >= strlen((const char *)cmd_line)) {
+ uint32_t index = 0;
+ while (index < strlen((const char *)cmd_line)) {
+ espGcodeFifo.Buffer[espGcodeFifo.w] = cmd_line[index] ;
+ espGcodeFifo.w = (espGcodeFifo.w + 1) % WIFI_GCODE_BUFFER_SIZE;
+ index++;
+ }
+ if (left_g - WIFI_GCODE_BUFFER_LEAST_SIZE >= strlen((const char *)cmd_line))
+ SEND_OK_TO_WIFI;
+ else
+ need_ok_later = true;
+ }
+ }
+ }
+ }
+}
+
+static int32_t charAtArray(const uint8_t *_array, uint32_t _arrayLen, uint8_t _char) {
+ for (uint32_t i = 0; i < _arrayLen; i++)
+ if (*(_array + i) == _char) return i;
+ return -1;
+}
+
+void get_wifi_list_command_send() {
+ uint8_t cmd_wifi_list[] = { 0xA5, 0x07, 0x00, 0x00, 0xFC };
+ raw_send_to_wifi(cmd_wifi_list, COUNT(cmd_wifi_list));
+}
+
+static void net_msg_handle(uint8_t * msg, uint16_t msgLen) {
+ int wifiNameLen, wifiKeyLen, hostLen, id_len, ver_len;
+
+ if (msgLen <= 0) return;
+
+ // ip
+ sprintf(ipPara.ip_addr, "%d.%d.%d.%d", msg[0], msg[1], msg[2], msg[3]);
+
+ // port
+ // connect state
+ switch (msg[6]) {
+ case 0x0A: wifi_link_state = WIFI_CONNECTED; break;
+ case 0x0E: wifi_link_state = WIFI_EXCEPTION; break;
+ default: wifi_link_state = WIFI_NOT_CONFIG; break;
+ }
+
+ // mode
+ wifiPara.mode = msg[7];
+
+ // wifi name
+ wifiNameLen = msg[8];
+ wifiKeyLen = msg[9 + wifiNameLen];
+ if (wifiNameLen < 32) {
+ ZERO(wifiPara.ap_name);
+ memcpy(wifiPara.ap_name, &msg[9], wifiNameLen);
+
+ memset(&wifi_list.wifiConnectedName, 0, sizeof(wifi_list.wifiConnectedName));
+ memcpy(&wifi_list.wifiConnectedName, &msg[9], wifiNameLen);
+
+ // wifi key
+ if (wifiKeyLen < 64) {
+ ZERO(wifiPara.keyCode);
+ memcpy(wifiPara.keyCode, &msg[10 + wifiNameLen], wifiKeyLen);
+ }
+ }
+
+ cloud_para.state =msg[10 + wifiNameLen + wifiKeyLen];
+ hostLen = msg[11 + wifiNameLen + wifiKeyLen];
+ if (cloud_para.state) {
+ if (hostLen < 96) {
+ ZERO(cloud_para.hostUrl);
+ memcpy(cloud_para.hostUrl, &msg[12 + wifiNameLen + wifiKeyLen], hostLen);
+ }
+ cloud_para.port = msg[12 + wifiNameLen + wifiKeyLen + hostLen] + (msg[13 + wifiNameLen + wifiKeyLen + hostLen] << 8);
+ }
+
+ // id
+ id_len = msg[14 + wifiNameLen + wifiKeyLen + hostLen];
+ if (id_len == 20) {
+ ZERO(cloud_para.id);
+ memcpy(cloud_para.id, (const char *)&msg[15 + wifiNameLen + wifiKeyLen + hostLen], id_len);
+ }
+ ver_len = msg[15 + wifiNameLen + wifiKeyLen + hostLen + id_len];
+ if (ver_len < 20) {
+ ZERO(wifi_firm_ver);
+ memcpy(wifi_firm_ver, (const char *)&msg[16 + wifiNameLen + wifiKeyLen + hostLen + id_len], ver_len);
+ }
+
+ if (uiCfg.configWifi == 1) {
+ if ((wifiPara.mode != gCfgItems.wifi_mode_sel)
+ || (strncmp(wifiPara.ap_name, (const char *)uiCfg.wifi_name, 32) != 0)
+ || (strncmp(wifiPara.keyCode, (const char *)uiCfg.wifi_key, 64) != 0)) {
+ package_to_wifi(WIFI_PARA_SET, (uint8_t *)0, 0);
+ }
+ else uiCfg.configWifi = 0;
+ }
+ if (cfg_cloud_flag == 1) {
+ if (((cloud_para.state >> 4) != (char)gCfgItems.cloud_enable)
+ || (strncmp(cloud_para.hostUrl, (const char *)uiCfg.cloud_hostUrl, 96) != 0)
+ || (cloud_para.port != uiCfg.cloud_port)) {
+ package_to_wifi(WIFI_CLOUD_CFG, (uint8_t *)0, 0);
+ }
+ else cfg_cloud_flag = 0;
+ }
+}
+
+static void wifi_list_msg_handle(uint8_t * msg, uint16_t msgLen) {
+ int wifiNameLen,wifiMsgIdex = 1;
+ int8_t wifi_name_is_same = 0;
+ int8_t i, j;
+ int8_t wifi_name_num = 0;
+ uint8_t *str = 0;
+ int8_t valid_name_num;
+
+ if (msgLen <= 0) return;
+ if (disp_state == KEY_BOARD_UI) return;
+
+ wifi_list.getNameNum = msg[0];
+
+ if (wifi_list.getNameNum < 20) {
+ uiCfg.command_send = 1;
+ ZERO(wifi_list.wifiName);
+ wifi_name_num = wifi_list.getNameNum;
+ valid_name_num = 0;
+ str = wifi_list.wifiName[0];
+
+ if (wifi_list.getNameNum > 0) wifi_list.currentWifipage = 1;
+
+ for (i = 0; i < wifi_list.getNameNum; i++) {
+ wifiNameLen = msg[wifiMsgIdex++];
+ if (wifiNameLen < 32) {
+ memset(str, 0, WIFI_NAME_BUFFER_SIZE);
+ memcpy(str, &msg[wifiMsgIdex], wifiNameLen);
+ for (j = 0; j < valid_name_num; j++) {
+ if (strcmp((const char *)str,(const char *)wifi_list.wifiName[j]) == 0) {
+ wifi_name_is_same = 1;
+ break;
+ }
+ }
+ if (wifi_name_is_same != 1) {
+ if (str[0] > 0x80) {
+ wifi_name_is_same = 1;
+ }
+ }
+ if (wifi_name_is_same == 1) {
+ wifi_name_is_same = 0;
+ wifiMsgIdex += wifiNameLen;
+ wifiMsgIdex += 1;
+ wifi_name_num--;
+ //i--;
+ continue;
+ }
+ if (i < WIFI_TOTAL_NUMBER - 1)
+ str = wifi_list.wifiName[++valid_name_num];
+ }
+ wifiMsgIdex += wifiNameLen;
+ wifi_list.RSSI[i] = msg[wifiMsgIdex++];
+ }
+ wifi_list.getNameNum = wifi_name_num;
+ wifi_list.getPage = wifi_list.getNameNum / NUMBER_OF_PAGE + ((wifi_list.getNameNum % NUMBER_OF_PAGE) != 0);
+ wifi_list.nameIndex = 0;
+
+ if (disp_state == WIFI_LIST_UI) disp_wifi_list();
+ }
+}
+
+static void gcode_msg_handle(uint8_t * msg, uint16_t msgLen) {
+ uint8_t gcodeBuf[100] = { 0 };
+ char *index_s, *index_e;
+
+ if (msgLen <= 0) return;
+
+ index_s = (char *)msg;
+ index_e = (char *)strchr((char *)msg, '\n');
+ if (*msg == 'N') {
+ index_s = (char *)strchr((char *)msg, ' ');
+ while (*index_s == ' ') index_s++;
+ }
+ while ((index_e != 0) && ((int)index_s < (int)index_e)) {
+ if ((int)(index_e - index_s) < (int)sizeof(gcodeBuf)) {
+ ZERO(gcodeBuf);
+ memcpy(gcodeBuf, index_s, index_e - index_s + 1);
+ wifi_gcode_exec(gcodeBuf);
+ }
+ while ((*index_e == '\r') || (*index_e == '\n')) index_e++;
+ index_s = index_e;
+ index_e = (char *)strchr(index_s, '\n');
+ }
+}
+
+void utf8_2_unicode(uint8_t *source,uint8_t Len) {
+ uint8_t i = 0, char_i = 0, char_byte_num = 0;
+ uint16_t u16_h, u16_m, u16_l, u16_value;
+ uint8_t FileName_unicode[30];
+
+ ZERO(FileName_unicode);
+
+ while (1) {
+ char_byte_num = source[i] & 0xF0;
+ if (source[i] < 0X80) {
+ //ASCII --1byte
+ FileName_unicode[char_i] = source[i];
+ i += 1;
+ char_i += 1;
+ }
+ else if (char_byte_num == 0XC0 || char_byte_num == 0XD0) {
+ //--2byte
+
+ u16_h = (((uint16_t)source[i] << 8) & 0x1F00) >> 2;
+ u16_l = ((uint16_t)source[i + 1] & 0x003F);
+ u16_value = (u16_h | u16_l);
+ FileName_unicode[char_i] = (uint8_t)((u16_value & 0xFF00) >> 8);
+ FileName_unicode[char_i + 1] = (uint8_t)(u16_value & 0x00FF);
+ i += 2;
+ char_i += 2;
+ }
+ else if (char_byte_num == 0XE0) {
+ //--3byte
+ u16_h = (((uint16_t)source[i] << 8) & 0x0F00) << 4;
+ u16_m = (((uint16_t)source[i + 1] << 8) & 0x3F00) >> 2;
+ u16_l = ((uint16_t)source[i + 2] & 0x003F);
+ u16_value = (u16_h | u16_m | u16_l);
+ FileName_unicode[char_i] = (uint8_t)((u16_value & 0xFF00) >> 8);
+ FileName_unicode[char_i + 1] = (uint8_t)(u16_value & 0x00FF);
+ i += 3;
+ char_i += 2;
+ }
+ else if (char_byte_num == 0XF0) {
+ //--4byte
+ i += 4;
+ //char_i += 3;
+ }
+ else {
+ break;
+ }
+ if (i >= Len || i >= 255) break;
+ }
+ COPY(source, FileName_unicode);
+}
+
+static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) {
+ uint8_t fileNameLen = *msg;
+
+ if (msgLen != fileNameLen + 5) return;
+
+ file_writer.fileLen = *((uint32_t *)(msg + 1));
+ ZERO(file_writer.saveFileName);
+
+ memcpy(file_writer.saveFileName, msg + 5, fileNameLen);
+
+ utf8_2_unicode(file_writer.saveFileName,fileNameLen);
+
+ ZERO(public_buf);
+
+ if (strlen((const char *)file_writer.saveFileName) > sizeof(saveFilePath))
+ return;
+
+ ZERO(saveFilePath);
+
+ if (gCfgItems.fileSysType == FILE_SYS_SD) {
+ TERN_(SDSUPPORT, card.mount());
+ }
+ else if (gCfgItems.fileSysType == FILE_SYS_USB) {
+
+ }
+ file_writer.write_index = 0;
+ lastFragment = -1;
+
+ wifiTransError.flag = 0;
+ wifiTransError.start_tick = 0;
+ wifiTransError.now_tick = 0;
+
+ TERN_(SDSUPPORT, card.closefile());
+
+ wifi_delay(1000);
+
+ #if ENABLED(SDSUPPORT)
+
+ uint8_t dosName[FILENAME_LENGTH];
+
+ if (!longName2DosName((const char *)file_writer.saveFileName,dosName)) {
+ lv_clear_cur_ui();
+ upload_result = 2;
+ wifiTransError.flag = 1;
+ wifiTransError.start_tick = getWifiTick();
+ lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE);
+ return;
+ }
+ sprintf((char *)saveFilePath, "%s", dosName);
+
+ card.cdroot();
+ upload_file.close();
+ const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+
+ if (!upload_file.open(upload_curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
+ lv_clear_cur_ui();
+ upload_result = 2;
+
+ wifiTransError.flag = 1;
+ wifiTransError.start_tick = getWifiTick();
+
+ lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE);
+ return;
+ }
+ #endif
+
+ wifi_link_state = WIFI_TRANS_FILE;
+
+ upload_result = 1;
+
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE);
+
+ lv_task_handler();
+
+ file_writer.tick_begin = getWifiTick();
+
+ file_writer.fileTransfer = 1;
+}
+
+#define FRAG_MASK ~(1 << 31)
+
+static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) {
+ uint32_t frag = *((uint32_t *)msg);
+
+ if ((frag & FRAG_MASK) != (uint32_t)(lastFragment + 1)) {
+ ZERO(public_buf);
+ file_writer.write_index = 0;
+ wifi_link_state = WIFI_CONNECTED;
+ upload_result = 2;
+ }
+ else {
+ if (write_to_file((char *)msg + 4, msgLen - 4) < 0) {
+ ZERO(public_buf);
+ file_writer.write_index = 0;
+ wifi_link_state = WIFI_CONNECTED;
+ upload_result = 2;
+ return;
+ }
+ lastFragment = frag;
+
+ if ((frag & (~FRAG_MASK)) != 0) {
+ wifiDmaRcvFifo.receiveEspData = false;
+ int res = upload_file.write(public_buf, file_writer.write_index);
+ if (res == -1) {
+ upload_file.close();
+ const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+
+ if (upload_file.open(upload_curDir, fname, O_WRITE)) {
+ upload_file.setpos(&pos);
+ res = upload_file.write(public_buf, file_writer.write_index);
+ }
+ }
+ upload_file.close();
+ SdFile file, *curDir;
+ const char * const fname = card.diveToFile(true, curDir, saveFilePath);
+ if (file.open(curDir, fname, O_RDWR)) {
+ gCfgItems.curFilesize = file.fileSize();
+ file.close();
+ }
+ else {
+ ZERO(public_buf);
+ file_writer.write_index = 0;
+ wifi_link_state = WIFI_CONNECTED;
+ upload_result = 2;
+ return;
+ }
+ ZERO(public_buf);
+ file_writer.write_index = 0;
+ file_writer.tick_end = getWifiTick();
+ upload_time = getWifiTickDiff(file_writer.tick_begin, file_writer.tick_end) / 1000;
+ upload_size = gCfgItems.curFilesize;
+ wifi_link_state = WIFI_CONNECTED;
+ upload_result = 3;
+ }
+
+ }
+}
+
+void esp_data_parser(char *cmdRxBuf, int len) {
+ int32_t head_pos;
+ int32_t tail_pos;
+ uint16_t cpyLen;
+ int16_t leftLen = len;
+ bool loop_again = false;
+
+ ESP_PROTOC_FRAME esp_frame;
+
+ while (leftLen > 0 || loop_again) {
+ loop_again = false;
+
+ if (esp_msg_index != 0) {
+ head_pos = 0;
+ cpyLen = (leftLen < (int16_t)((sizeof(esp_msg_buf) - esp_msg_index)) ? leftLen : sizeof(esp_msg_buf) - esp_msg_index);
+
+ memcpy(&esp_msg_buf[esp_msg_index], cmdRxBuf + len - leftLen, cpyLen);
+
+ esp_msg_index += cpyLen;
+
+ leftLen = leftLen - cpyLen;
+ tail_pos = charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL);
+
+ if (tail_pos == -1) {
+ if (esp_msg_index >= sizeof(esp_msg_buf)) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ }
+ return;
+ }
+ }
+ else {
+ head_pos = charAtArray((uint8_t const *)&cmdRxBuf[len - leftLen], leftLen, ESP_PROTOC_HEAD);
+ if (head_pos == -1) return;
+
+ ZERO(esp_msg_buf);
+ memcpy(esp_msg_buf, &cmdRxBuf[len - leftLen + head_pos], leftLen - head_pos);
+
+ esp_msg_index = leftLen - head_pos;
+
+ leftLen = 0;
+ head_pos = 0;
+ tail_pos = charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL);
+ if (tail_pos == -1) {
+ if (esp_msg_index >= sizeof(esp_msg_buf)) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ }
+ return;
+ }
+ }
+
+ esp_frame.type = esp_msg_buf[1];
+ if ( esp_frame.type != ESP_TYPE_NET
+ && esp_frame.type != ESP_TYPE_GCODE
+ && esp_frame.type != ESP_TYPE_FILE_FIRST
+ && esp_frame.type != ESP_TYPE_FILE_FRAGMENT
+ && esp_frame.type != ESP_TYPE_WIFI_LIST
+ ) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ return;
+ }
+
+ esp_frame.dataLen = esp_msg_buf[2] + (esp_msg_buf[3] << 8);
+
+ if ((int)(4 + esp_frame.dataLen) > (int)(sizeof(esp_msg_buf))) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ return;
+ }
+
+ if (esp_msg_buf[4 + esp_frame.dataLen] != ESP_PROTOC_TAIL) {
+ if (esp_msg_index >= sizeof(esp_msg_buf)) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ }
+ return;
+ }
+
+ esp_frame.data = &esp_msg_buf[4];
+ switch (esp_frame.type) {
+ case ESP_TYPE_NET:
+ net_msg_handle(esp_frame.data, esp_frame.dataLen);
+ break;
+ case ESP_TYPE_GCODE:
+ gcode_msg_handle(esp_frame.data, esp_frame.dataLen);
+ break;
+ case ESP_TYPE_FILE_FIRST:
+ file_first_msg_handle(esp_frame.data, esp_frame.dataLen);
+ break;
+ case ESP_TYPE_FILE_FRAGMENT:
+ file_fragment_msg_handle(esp_frame.data, esp_frame.dataLen);
+ break;
+ case ESP_TYPE_WIFI_LIST:
+ wifi_list_msg_handle(esp_frame.data, esp_frame.dataLen);
+ break;
+ default: break;
+ }
+
+ esp_msg_index = cut_msg_head(esp_msg_buf, esp_msg_index, esp_frame.dataLen + 5);
+ if (esp_msg_index > 0) {
+ if (charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_HEAD) == -1) {
+ ZERO(esp_msg_buf);
+ esp_msg_index = 0;
+ return;
+ }
+
+ if ((charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_HEAD) != -1) && (charAtArray(esp_msg_buf, esp_msg_index, ESP_PROTOC_TAIL) != -1))
+ loop_again = true;
+ }
+ }
+}
+
+int32_t tick_net_time1, tick_net_time2;
+int32_t readWifiFifo(uint8_t *retBuf, uint32_t bufLen) {
+ unsigned char tmpR = wifiDmaRcvFifo.read_cur;
+ if (bufLen >= UDISKBUFLEN && wifiDmaRcvFifo.state[tmpR] == udisk_buf_full) {
+ memcpy(retBuf, (unsigned char *)wifiDmaRcvFifo.bufferAddr[tmpR], UDISKBUFLEN);
+ wifiDmaRcvFifo.state[tmpR] = udisk_buf_empty;
+ wifiDmaRcvFifo.read_cur = (tmpR + 1) % TRANS_RCV_FIFO_BLOCK_NUM;
+ return UDISKBUFLEN;
+ }
+ return 0;
+}
+
+void stopEspTransfer() {
+ if (wifi_link_state == WIFI_TRANS_FILE)
+ wifi_link_state = WIFI_CONNECTED;
+
+ TERN_(SDSUPPORT, card.closefile());
+
+ if (upload_result != 3) {
+ wifiTransError.flag = 1;
+ wifiTransError.start_tick = getWifiTick();
+ card.removeFile((const char *)saveFilePath);
+ }
+
+ wifi_delay(200);
+
+ WIFI_IO1_SET();
+
+ // disable dma
+ #ifdef __STM32F1__
+ dma_clear_isr_bits(DMA1, DMA_CH5);
+ bb_peri_set_bit(&USART1_BASE->CR3, USART_CR3_DMAR_BIT, 0);
+ dma_disable(DMA1, DMA_CH5);
+ #else
+ // First, abort any running dma
+ HAL_DMA_Abort(&wifiUsartDMArx);
+ // DeInit objects
+ HAL_DMA_DeInit(&wifiUsartDMArx);
+ #endif
+
+ wifi_delay(200);
+
+ exchangeFlashMode(1); //change spi flash to use dma mode
+
+ esp_port_begin(1);
+
+ wifi_delay(200);
+
+ W25QXX.init(SPI_QUARTER_SPEED);
+
+ #if HAS_TFT_LVGL_UI_SPI
+ SPI_TFT.spi_init(SPI_FULL_SPEED);
+ #endif
+
+ TERN_(HAS_SERVOS, servo_init());
+
+ TERN_(HAS_Z_SERVO_PROBE, probe.servo_probe_init());
+
+ if (wifiTransError.flag != 0x1)
+ WIFI_IO1_RESET();
+}
+
+void wifi_rcv_handle() {
+ int32_t len = 0;
+ uint8_t ucStr[(UART_RX_BUFFER_SIZE) + 1] = {0};
+ int8_t getDataF = 0;
+
+ if (wifi_link_state == WIFI_TRANS_FILE) {
+ #if 0
+ if (WIFISERIAL.available() == UART_RX_BUFFER_SIZE) {
+ for (uint16_t i=0;i<UART_RX_BUFFER_SIZE;i++) {
+ ucStr[i] = WIFISERIAL.read();
+ len++;
+ }
+ }
+ #else
+ #ifndef __STM32F1__
+ if (wifiDmaRcvFifo.receiveEspData) storeRcvData(WIFISERIAL.wifiRxBuf, UART_RX_BUFFER_SIZE);
+ #endif
+ len = readWifiFifo(ucStr, UART_RX_BUFFER_SIZE);
+ #endif
+ if (len > 0) {
+ esp_data_parser((char *)ucStr, len);
+ if (wifi_link_state == WIFI_CONNECTED) {
+ lv_clear_cur_ui();
+ lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE);
+ stopEspTransfer();
+ }
+ getDataF = 1;
+ }
+ #ifdef __STM32F1__
+ if (esp_state == TRANSFER_STORE) {
+ if (storeRcvData(WIFISERIAL.wifiRxBuf, UART_RX_BUFFER_SIZE)) {
+ esp_state = TRANSFERING;
+ esp_dma_pre();
+ if (wifiTransError.flag != 0x1) WIFI_IO1_RESET();
+ }
+ else WIFI_IO1_SET();
+ }
+ #endif
+ }
+ else {
+ len = readWifiBuf((int8_t *)ucStr, UART_RX_BUFFER_SIZE);
+ if (len > 0) {
+ esp_data_parser((char *)ucStr, len);
+
+ if (wifi_link_state == WIFI_TRANS_FILE) {
+ exchangeFlashMode(0); //change spi flash not use dma mode
+
+ wifi_delay(10);
+
+ esp_port_begin(0);
+
+ wifi_delay(10);
+
+ tick_net_time1 = 0;
+ #ifndef __STM32F1__
+ wifiDmaRcvFifo.receiveEspData = true;
+ return;
+ #endif
+ }
+ if (wifiTransError.flag != 0x1) {
+ WIFI_IO1_RESET();
+ }
+ getDataF = 1;
+ }
+ if (need_ok_later && (queue.length < BUFSIZE)) {
+ need_ok_later = false;
+ send_to_wifi((uint8_t *)"ok\r\n", strlen("ok\r\n"));
+ }
+ }
+
+ if (getDataF == 1) {
+ tick_net_time1 = getWifiTick();
+ }
+ else {
+ tick_net_time2 = getWifiTick();
+
+ if (wifi_link_state == WIFI_TRANS_FILE) {
+ if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 8000)) {
+ wifi_link_state = WIFI_CONNECTED;
+
+ upload_result = 2;
+
+ lv_clear_cur_ui();
+
+ stopEspTransfer();
+
+ lv_draw_dialog(DIALOG_TYPE_UPLOAD_FILE);
+ }
+ }
+ if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 10000)) {
+ wifi_link_state = WIFI_NOT_CONFIG;
+ }
+ if ((tick_net_time1 != 0) && (getWifiTickDiff(tick_net_time1, tick_net_time2) > 120000)) {
+ wifi_link_state = WIFI_NOT_CONFIG;
+
+ wifi_reset();
+
+ tick_net_time1 = getWifiTick();
+ }
+ }
+
+ if (wifiTransError.flag == 0x1) {
+ wifiTransError.now_tick = getWifiTick();
+ if (getWifiTickDiff(wifiTransError.start_tick, wifiTransError.now_tick) > WAIT_ESP_TRANS_TIMEOUT_TICK) {
+ wifiTransError.flag = 0;
+ WIFI_IO1_RESET();
+ }
+ }
+}
+
+void wifi_looping() {
+ do {
+ wifi_rcv_handle();
+ watchdog_refresh();
+ } while (wifi_link_state == WIFI_TRANS_FILE);
+}
+
+void mks_esp_wifi_init() {
+ wifi_link_state = WIFI_NOT_CONFIG;
+
+ SET_OUTPUT(WIFI_RESET_PIN);
+ WIFI_SET();
+ SET_OUTPUT(WIFI_IO1_PIN);
+ SET_INPUT_PULLUP(WIFI_IO0_PIN);
+ WIFI_IO1_SET();
+
+ esp_state = TRANSFER_IDLE;
+ esp_port_begin(1);
+
+ wifi_reset();
+
+ #if 0
+ if (update_flag == 0) {
+ res = f_open(&esp_upload.uploadFile, ESP_WEB_FIRMWARE_FILE, FA_OPEN_EXISTING | FA_READ);
+
+ if (res == FR_OK) {
+ f_close(&esp_upload.uploadFile);
+
+ wifi_delay(2000);
+
+ if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20) {
+ return;
+ }
+
+ lv_clear_cur_ui();
+
+ draw_dialog(DIALOG_TYPE_UPDATE_ESP_FIRMARE);
+ if (wifi_upload(1) >= 0) {
+
+ f_unlink("1:/MKS_WIFI_CUR");
+ f_rename(ESP_WEB_FIRMWARE_FILE,"/MKS_WIFI_CUR");
+ }
+ lv_draw_return_ui();
+ update_flag = 1;
+ }
+
+ }
+ if (update_flag == 0) {
+ res = f_open(&esp_upload.uploadFile, ESP_WEB_FILE, FA_OPEN_EXISTING | FA_READ);
+ if (res == FR_OK) {
+ f_close(&esp_upload.uploadFile);
+
+ wifi_delay(2000);
+
+ if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20) {
+ return;
+ }
+
+ lv_clear_cur_ui();
+
+ draw_dialog(DIALOG_TYPE_UPDATE_ESP_DATA);
+
+ if (wifi_upload(2) >= 0) {
+
+ f_unlink("1:/MKS_WEB_CONTROL_CUR");
+ f_rename(ESP_WEB_FILE,"/MKS_WEB_CONTROL_CUR");
+ }
+ lv_draw_return_ui();
+ }
+ }
+ #endif
+ wifiPara.decodeType = WIFI_DECODE_TYPE;
+ wifiPara.baud = 115200;
+ wifi_link_state = WIFI_NOT_CONFIG;
+}
+
+
+void mks_wifi_firmware_upddate() {
+ card.openFileRead((char *)ESP_FIRMWARE_FILE);
+
+ if (card.isFileOpen()) {
+ card.closefile();
+
+ wifi_delay(2000);
+
+ if (usartFifoAvailable((SZ_USART_FIFO *)&WifiRxFifo) < 20)
+ return;
+
+ lv_clear_cur_ui();
+
+ lv_draw_dialog(DIALOG_TYPE_UPDATE_ESP_FIRMARE);
+
+ lv_task_handler();
+ watchdog_refresh();
+
+ if (wifi_upload(0) >= 0) {
+ card.removeFile((char *)ESP_FIRMWARE_FILE_RENAME);
+ SdFile file, *curDir;
+ const char * const fname = card.diveToFile(true, curDir, ESP_FIRMWARE_FILE);
+ if (file.open(curDir, fname, O_READ)) {
+ file.rename(curDir, (char *)ESP_FIRMWARE_FILE_RENAME);
+ file.close();
+ }
+ }
+ lv_clear_cur_ui();
+ }
+}
+
+void get_wifi_commands() {
+ static char wifi_line_buffer[MAX_CMD_SIZE];
+ static bool wifi_comment_mode = false;
+ static int wifi_read_count = 0;
+
+ if (espGcodeFifo.wait_tick > 5) {
+ while ((queue.length < BUFSIZE) && (espGcodeFifo.r != espGcodeFifo.w)) {
+
+ espGcodeFifo.wait_tick = 0;
+
+ char wifi_char = espGcodeFifo.Buffer[espGcodeFifo.r];
+
+ espGcodeFifo.r = (espGcodeFifo.r + 1) % WIFI_GCODE_BUFFER_SIZE;
+
+ /**
+ * If the character ends the line
+ */
+ if (wifi_char == '\n' || wifi_char == '\r') {
+
+ wifi_comment_mode = false; // end of line == end of comment
+
+ if (!wifi_read_count) continue; // skip empty lines
+
+ wifi_line_buffer[wifi_read_count] = 0; // terminate string
+ wifi_read_count = 0; //reset buffer
+
+ char* command = wifi_line_buffer;
+ while (*command == ' ') command++; // skip any leading spaces
+
+ // Movement commands alert when stopped
+ if (IsStopped()) {
+ char* gpos = strchr(command, 'G');
+ if (gpos) {
+ switch (strtol(gpos + 1, nullptr, 10)) {
+ case 0 ... 1:
+ #if ENABLED(ARC_SUPPORT)
+ case 2 ... 3:
+ #endif
+ #if ENABLED(BEZIER_CURVE_SUPPORT)
+ case 5:
+ #endif
+ SERIAL_ECHOLNPGM(STR_ERR_STOPPED);
+ LCD_MESSAGEPGM(MSG_STOPPED);
+ break;
+ }
+ }
+ }
+
+ #if DISABLED(EMERGENCY_PARSER)
+ // Process critical commands early
+ if (strcmp(command, "M108") == 0) {
+ wait_for_heatup = false;
+ TERN_(HAS_LCD_MENU, wait_for_user = false);
+ }
+ if (strcmp(command, "M112") == 0) kill(M112_KILL_STR, nullptr, true);
+ if (strcmp(command, "M410") == 0) quickstop_stepper();
+ #endif
+
+ // Add the command to the queue
+ queue.enqueue_one_P(wifi_line_buffer);
+ }
+ else if (wifi_read_count >= MAX_CMD_SIZE - 1) {
+
+ }
+ else { // it's not a newline, carriage return or escape char
+ if (wifi_char == ';') wifi_comment_mode = true;
+ if (!wifi_comment_mode) wifi_line_buffer[wifi_read_count++] = wifi_char;
+ }
+ }
+ } // queue has space, serial has data
+ else
+ espGcodeFifo.wait_tick++;
+}
+
+int readWifiBuf(int8_t *buf, int32_t len) {
+ int i = 0;
+ while (i < len && WIFISERIAL.available())
+ buf[i++] = WIFISERIAL.read();
+ return i;
+}
+
+int usartFifoAvailable(SZ_USART_FIFO *fifo) {
+ return WIFISERIAL.available();
+}
+
+#endif // MKS_WIFI_MODULE
+#endif // HAS_TFT_LVGL_UI
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h
new file mode 100644
index 0000000..856c619
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.h
@@ -0,0 +1,201 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#include "../../../../inc/MarlinConfigPre.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define UART_RX_BUFFER_SIZE 1024
+#define UART_FIFO_BUFFER_SIZE 1024
+
+#define WIFI_DECODE_TYPE 1
+
+#define IP_DHCP_FLAG 1
+
+#define WIFI_AP_NAME "TP-LINK_MKS"
+#define WIFI_KEY_CODE "makerbase"
+
+#define IP_ADDR "192.168.3.100"
+#define IP_MASK "255.255.255.0"
+#define IP_GATE "192.168.3.1"
+#define IP_DNS "192.168.3.1"
+
+#define AP_IP_DHCP_FLAG 1
+#define AP_IP_ADDR "192.168.3.100"
+#define AP_IP_MASK "255.255.255.0"
+#define AP_IP_GATE "192.168.3.1"
+#define AP_IP_DNS "192.168.3.1"
+#define IP_START_IP "192.168.3.1"
+#define IP_END_IP "192.168.3.255"
+
+#define UDISKBUFLEN 1024
+
+typedef enum{
+ udisk_buf_empty = 0,
+ udisk_buf_full,
+} UDISK_DATA_BUFFER_STATE;
+
+#define TRANS_RCV_FIFO_BLOCK_NUM 14
+
+typedef struct {
+ bool receiveEspData;
+ unsigned char *bufferAddr[TRANS_RCV_FIFO_BLOCK_NUM];
+ unsigned char *p;
+ UDISK_DATA_BUFFER_STATE state[TRANS_RCV_FIFO_BLOCK_NUM];
+ unsigned char read_cur;
+ unsigned char write_cur;
+} WIFI_DMA_RCV_FIFO;
+
+typedef struct {
+ uint8_t flag; // 0x0: no error; 0x01: error
+ uint32_t start_tick; //error start time
+ uint32_t now_tick;
+} WIFI_TRANS_ERROR;
+
+extern volatile WIFI_TRANS_ERROR wifiTransError;
+
+typedef struct {
+ char ap_name[32]; //wifi-name
+ char keyCode[64]; //wifi password
+ int decodeType;
+ int baud;
+ int mode;
+} WIFI_PARA;
+
+typedef struct {
+ char state;
+ char hostUrl[96];
+ int port;
+ char id[21];
+} CLOUD_PARA;
+
+typedef struct {
+ char dhcp_flag;
+ char ip_addr[16];
+ char mask[16];
+ char gate[16];
+ char dns[16];
+
+ char dhcpd_flag;
+ char dhcpd_ip[16];
+ char dhcpd_mask[16];
+ char dhcpd_gate[16];
+ char dhcpd_dns[16];
+ char start_ip_addr[16];
+ char end_ip_addr[16];
+} IP_PARA;
+
+typedef enum {
+ WIFI_NOT_CONFIG,
+ WIFI_CONFIG_MODE,
+ WIFI_CONFIG_DHCP,
+ WIFI_CONFIG_AP,
+ WIFI_CONFIG_IP_INF,
+ WIFI_CONFIG_DNS,
+ WIFI_CONFIG_TCP,
+ WIFI_CONFIG_SERVER,
+ WIFI_CONFIG_REMOTE_PORT,
+ WIFI_CONFIG_BAUD,
+ WIFI_CONFIG_COMMINT,
+ WIFI_CONFIG_OK,
+ WIFI_GET_IP_OK,
+ WIFI_RECONN,
+ WIFI_CONNECTED,
+ WIFI_WAIT_TRANS_START,
+ WIFI_TRANS_FILE,
+ WIFI_CONFIG_DHCPD,
+ WIFI_COFIG_DHCPD_IP,
+ WIFI_COFIG_DHCPD_DNS,
+ WIFI_EXCEPTION,
+} WIFI_STATE;
+
+typedef enum {
+ TRANSFER_IDLE,
+ TRANSFERING,
+ TRANSFER_STORE,
+} TRANSFER_STATE;
+extern volatile TRANSFER_STATE esp_state;
+
+typedef struct {
+ char buf[20][80];
+ int rd_index;
+ int wt_index;
+} QUEUE;
+
+typedef enum {
+ WIFI_PARA_SET, // 0x0:net parameter
+ WIFI_PRINT_INF, // 0x1:print message
+ WIFI_TRANS_INF, // 0x2:Pass through information
+ WIFI_EXCEP_INF, // 0x3:Exception information
+ WIFI_CLOUD_CFG, // 0x4:cloud config
+ WIFI_CLOUD_UNBIND, // 0x5:Unbind ID
+} WIFI_RET_TYPE;
+
+typedef struct {
+ uint32_t uart_read_point;
+ uint32_t uart_write_point;
+ //uint8_t uartTxBuffer[UART_FIFO_BUFFER_SIZE];
+} SZ_USART_FIFO;
+
+#define WIFI_GCODE_BUFFER_LEAST_SIZE 96
+#define WIFI_GCODE_BUFFER_SIZE (WIFI_GCODE_BUFFER_LEAST_SIZE * 3)
+typedef struct {
+ uint8_t wait_tick;
+ uint8_t Buffer[WIFI_GCODE_BUFFER_SIZE];
+ uint32_t r;
+ uint32_t w;
+} WIFI_GCODE_BUFFER;
+
+extern volatile WIFI_STATE wifi_link_state;
+extern WIFI_PARA wifiPara;
+extern IP_PARA ipPara;
+extern CLOUD_PARA cloud_para;
+
+extern WIFI_GCODE_BUFFER espGcodeFifo;
+
+extern uint32_t getWifiTick();
+extern uint32_t getWifiTickDiff(int32_t lastTick, int32_t curTick);
+
+extern void mks_esp_wifi_init();
+extern int cfg_cloud_flag;
+extern int send_to_wifi(uint8_t *buf, int len);
+extern void wifi_looping();
+extern int raw_send_to_wifi(uint8_t *buf, int len);
+extern int package_to_wifi(WIFI_RET_TYPE type, uint8_t *buf, int len);
+extern void get_wifi_list_command_send();
+extern void get_wifi_commands();
+extern int readWifiBuf(int8_t *buf, int32_t len);
+extern void mks_wifi_firmware_upddate();
+extern int usartFifoAvailable(SZ_USART_FIFO *fifo);
+extern int readUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len);
+extern void esp_port_begin(uint8_t interrupt);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp
new file mode 100644
index 0000000..da35254
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.cpp
@@ -0,0 +1,726 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#include "../../../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_TFT_LVGL_UI, MKS_WIFI_MODULE)
+
+#include "draw_ui.h"
+#include "wifi_module.h"
+#include "wifi_upload.h"
+
+#include "../../../../MarlinCore.h"
+#include "../../../../sd/cardreader.h"
+
+#define WIFI_SET() WRITE(WIFI_RESET_PIN, HIGH);
+#define WIFI_RESET() WRITE(WIFI_RESET_PIN, LOW);
+#define WIFI_IO1_SET() WRITE(WIFI_IO1_PIN, HIGH);
+#define WIFI_IO1_RESET() WRITE(WIFI_IO1_PIN, LOW);
+
+extern SZ_USART_FIFO WifiRxFifo;
+
+extern int readUsartFifo(SZ_USART_FIFO *fifo, int8_t *buf, int32_t len);
+extern int writeUsartFifo(SZ_USART_FIFO * fifo, int8_t * buf, int32_t len);
+extern void esp_port_begin(uint8_t interrupt);
+extern void wifi_delay(int n);
+
+#define ARRAY_SIZE(a) sizeof(a) / sizeof((a)[0])
+
+//typedef signed char bool;
+
+// ESP8266 command codes
+const uint8_t ESP_FLASH_BEGIN = 0x02;
+const uint8_t ESP_FLASH_DATA = 0x03;
+const uint8_t ESP_FLASH_END = 0x04;
+const uint8_t ESP_MEM_BEGIN = 0x05;
+const uint8_t ESP_MEM_END = 0x06;
+const uint8_t ESP_MEM_DATA = 0x07;
+const uint8_t ESP_SYNC = 0x08;
+const uint8_t ESP_WRITE_REG = 0x09;
+const uint8_t ESP_READ_REG = 0x0A;
+
+// MAC address storage locations
+const uint32_t ESP_OTP_MAC0 = 0x3FF00050;
+const uint32_t ESP_OTP_MAC1 = 0x3FF00054;
+const uint32_t ESP_OTP_MAC2 = 0x3FF00058;
+const uint32_t ESP_OTP_MAC3 = 0x3FF0005C;
+
+const size_t EspFlashBlockSize = 0x0400; // 1K byte blocks
+
+const uint8_t ESP_IMAGE_MAGIC = 0xE9;
+const uint8_t ESP_CHECKSUM_MAGIC = 0xEF;
+
+const uint32_t ESP_ERASE_CHIP_ADDR = 0x40004984; // &SPIEraseChip
+const uint32_t ESP_SEND_PACKET_ADDR = 0x40003C80; // &send_packet
+const uint32_t ESP_SPI_READ_ADDR = 0x40004B1C; // &SPIRead
+const uint32_t ESP_UNKNOWN_ADDR = 0x40001121; // not used
+const uint32_t ESP_USER_DATA_RAM_ADDR = 0x3FFE8000; // &user data ram
+const uint32_t ESP_IRAM_ADDR = 0x40100000; // instruction RAM
+const uint32_t ESP_FLASH_ADDR = 0x40200000; // address of start of Flash
+
+UPLOAD_STRUCT esp_upload;
+
+static const unsigned int retriesPerReset = 3;
+static const uint32_t connectAttemptInterval = 50;
+static const unsigned int percentToReportIncrement = 5; // how often we report % complete
+static const uint32_t defaultTimeout = 500;
+static const uint32_t eraseTimeout = 15000;
+static const uint32_t blockWriteTimeout = 200;
+static const uint32_t blockWriteInterval = 15; // 15ms is long enough, 10ms is mostly too short
+static SdFile update_file, *update_curDir;
+
+// Messages corresponding to result codes, should make sense when followed by " error"
+const char *resultMessages[] = {
+ "no",
+ "timeout",
+ "comm write",
+ "connect",
+ "bad reply",
+ "file read",
+ "empty file",
+ "response header",
+ "slip frame",
+ "slip state",
+ "slip data"
+};
+
+// A note on baud rates.
+// The ESP8266 supports 921600, 460800, 230400, 115200, 74880 and some lower baud rates.
+// 921600b is not reliable because even though it sometimes succeeds in connecting, we get a bad response during uploading after a few blocks.
+// Probably our UART ISR cannot receive bytes fast enough, perhaps because of the latency of the system tick ISR.
+// 460800b doesn't always manage to connect, but if it does then uploading appears to be reliable.
+// 230400b always manages to connect.
+static const uint32_t uploadBaudRates[] = { 460800, 230400, 115200, 74880 };
+
+signed char IsReady() {
+ return esp_upload.state == upload_idle;
+}
+
+void uploadPort_write(const uint8_t *buf, size_t len) {
+ for(size_t i = 0; i < len; i++) {
+ WIFISERIAL.write(*(buf + i));
+ }
+}
+
+char uploadPort_read() {
+ uint8_t retChar;
+ retChar = WIFISERIAL.read();
+ if (retChar > 0) return retChar;
+ else return 0;
+}
+
+int uploadPort_available() {
+ return usartFifoAvailable(&WifiRxFifo);
+}
+
+void uploadPort_begin() {
+ esp_port_begin(1);
+}
+
+void uploadPort_close() {
+ //WIFI_COM.end();
+ //WIFI_COM.begin(115200, true);
+ esp_port_begin(0);
+}
+
+void flushInput() {
+ while (uploadPort_available() != 0) {
+ (void)uploadPort_read();
+ //IWDG_ReloadCounter();
+ }
+}
+
+// Extract 1-4 bytes of a value in little-endian order from a buffer beginning at a specified offset
+uint32_t getData(unsigned byteCnt, const uint8_t *buf, int ofst) {
+ uint32_t val = 0;
+
+ if (buf && byteCnt) {
+ unsigned int shiftCnt = 0;
+ if (byteCnt > 4)
+ byteCnt = 4;
+ do{
+ val |= (uint32_t)buf[ofst++] << shiftCnt;
+ shiftCnt += 8;
+ } while (--byteCnt);
+ }
+ return(val);
+}
+
+// Put 1-4 bytes of a value in little-endian order into a buffer beginning at a specified offset.
+void putData(uint32_t val, unsigned byteCnt, uint8_t *buf, int ofst) {
+ if (buf && byteCnt) {
+ if (byteCnt > 4) {
+ byteCnt = 4;
+ }
+ do {
+ buf[ofst++] = (uint8_t)(val & 0xFF);
+ val >>= 8;
+ } while (--byteCnt);
+ }
+}
+
+// Read a byte optionally performing SLIP decoding. The return values are:
+//
+// 2 - an escaped byte was read successfully
+// 1 - a non-escaped byte was read successfully
+// 0 - no data was available
+// -1 - the value 0xC0 was encountered (shouldn't happen)
+// -2 - a SLIP escape byte was found but the following byte wasn't available
+// -3 - a SLIP escape byte was followed by an invalid byte
+int ReadByte(uint8_t *data, signed char slipDecode) {
+ if (uploadPort_available() == 0) {
+ return(0);
+ }
+
+ // at least one byte is available
+ *data = uploadPort_read();
+ if (!slipDecode) {
+ return(1);
+ }
+
+ if (*data == 0xC0) {
+ // this shouldn't happen
+ return(-1);
+ }
+
+ // if not the SLIP escape, we're done
+ if (*data != 0xDB) {
+ return(1);
+ }
+
+ // SLIP escape, check availability of subsequent byte
+ if (uploadPort_available() == 0) {
+ return(-2);
+ }
+
+ // process the escaped byte
+ *data = uploadPort_read();
+ if (*data == 0xDC) {
+ *data = 0xC0;
+ return(2);
+ }
+
+ if (*data == 0xDD) {
+ *data = 0xDB;
+ return(2);
+ }
+ // invalid
+ return(-3);
+}
+// When we write a sync packet, there must be no gaps between most of the characters.
+// So use this function, which does a block write to the UART buffer in the latest CoreNG.
+void _writePacketRaw(const uint8_t *buf, size_t len) {
+ uploadPort_write(buf, len);
+}
+
+// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written.
+void WriteByteRaw(uint8_t b) {
+ uploadPort_write((const uint8_t *)&b, 1);
+}
+
+// Write a byte to the serial port optionally SLIP encoding. Return the number of bytes actually written.
+void WriteByteSlip(uint8_t b) {
+ if (b == 0xC0) {
+ WriteByteRaw(0xDB);
+ WriteByteRaw(0xDC);
+ }
+ else if (b == 0xDB) {
+ WriteByteRaw(0xDB);
+ WriteByteRaw(0xDD);
+ }
+ else {
+ uploadPort_write((const uint8_t *)&b, 1);
+ }
+}
+
+// Wait for a data packet to be returned. If the body of the packet is
+// non-zero length, return an allocated buffer indirectly containing the
+// data and return the data length. Note that if the pointer for returning
+// the data buffer is nullptr, the response is expected to be two bytes of zero.
+//
+// If an error occurs, return a negative value. Otherwise, return the number
+// of bytes in the response (or zero if the response was not the standard "two bytes of zero").
+EspUploadResult readPacket(uint8_t op, uint32_t *valp, size_t *bodyLen, uint32_t msTimeout) {
+ typedef enum {
+ begin = 0,
+ header,
+ body,
+ end,
+ done
+ } PacketState;
+
+ uint8_t resp, opRet;
+
+ const size_t headerLength = 8;
+
+ uint32_t startTime = getWifiTick();
+ uint8_t hdr[headerLength];
+ uint16_t hdrIdx = 0;
+
+ uint16_t bodyIdx = 0;
+ uint8_t respBuf[2];
+
+ // wait for the response
+ uint16_t needBytes = 1;
+
+ PacketState state = begin;
+
+ *bodyLen = 0;
+
+ while (state != done) {
+ uint8_t c;
+ EspUploadResult stat;
+
+ //IWDG_ReloadCounter();
+ watchdog_refresh();
+
+ if (getWifiTickDiff(startTime, getWifiTick()) > msTimeout)
+ return timeout;
+
+ if (uploadPort_available() < needBytes) {
+ // insufficient data available
+ // preferably, return to Spin() here
+ continue;
+ }
+
+ // sufficient bytes have been received for the current state, process them
+ switch (state) {
+ case begin: // expecting frame start
+ c = uploadPort_read();
+ if (c != (uint8_t)0xC0) break;
+ state = header;
+ needBytes = 2;
+ break;
+ case end: // expecting frame end
+ c = uploadPort_read();
+ if (c != (uint8_t)0xC0) return slipFrame;
+ state = done;
+ break;
+
+ case header: // reading an 8-byte header
+ case body: { // reading the response body
+ int rslt;
+ // retrieve a byte with SLIP decoding
+ rslt = ReadByte(&c, 1);
+ if (rslt != 1 && rslt != 2) {
+ // some error occurred
+ stat = (rslt == 0 || rslt == -2) ? slipData : slipFrame;
+ return stat;
+ }
+ else if (state == header) {
+ //store the header byte
+ hdr[hdrIdx++] = c;
+ if (hdrIdx >= headerLength) {
+ // get the body length, prepare a buffer for it
+ *bodyLen = (uint16_t)getData(2, hdr, 2);
+
+ // extract the value, if requested
+ if (valp)
+ *valp = getData(4, hdr, 4);
+
+ if (*bodyLen != 0)
+ state = body;
+ else {
+ needBytes = 1;
+ state = end;
+ }
+ }
+ }
+ else {
+ // Store the response body byte, check for completion
+ if (bodyIdx < ARRAY_SIZE(respBuf))
+ respBuf[bodyIdx] = c;
+
+ if (++bodyIdx >= *bodyLen) {
+ needBytes = 1;
+ state = end;
+ }
+ }
+ } break;
+
+ default: return slipState; // this shouldn't happen
+ }
+ }
+
+ // Extract elements from the header
+ resp = (uint8_t)getData(1, hdr, 0);
+ opRet = (uint8_t)getData(1, hdr, 1);
+ // Sync packets often provoke a response with a zero opcode instead of ESP_SYNC
+ if (resp != 0x01 || opRet != op) {
+ return respHeader;
+ }
+
+ return success;
+}
+
+// Send a block of data performing SLIP encoding of the content.
+void _writePacket(const uint8_t *data, size_t len) {
+ unsigned char outBuf[2048] = {0};
+ unsigned int outIndex = 0;
+ while (len != 0) {
+ if (*data == 0xC0) {
+ outBuf[outIndex++] = 0xDB;
+ outBuf[outIndex++] = 0xDC;
+ }
+ else if (*data == 0xDB) {
+ outBuf[outIndex++] = 0xDB;
+ outBuf[outIndex++] = 0xDD;
+ }
+ else {
+ outBuf[outIndex++] = *data;
+ }
+ data++;
+ --len;
+ }
+ uploadPort_write((const uint8_t *)outBuf, outIndex);
+}
+
+// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block.
+// A SLIP packet begins and ends with 0xC0. The data encapsulated has the bytes
+// 0xC0 and 0xDB replaced by the two-byte sequences {0xDB, 0xDC} and {0xDB, 0xDD} respectively.
+
+void writePacket(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) {
+ WriteByteRaw(0xC0); // send the packet start character
+ _writePacket(hdr, hdrLen); // send the header
+ _writePacket(data, dataLen); // send the data block
+ WriteByteRaw(0xC0); // send the packet end character
+}
+
+// Send a packet to the serial port while performing SLIP framing. The packet data comprises a header and an optional data block.
+// This is like writePacket except that it does a fast block write for both the header and the main data with no SLIP encoding. Used to send sync commands.
+void writePacketRaw(const uint8_t *hdr, size_t hdrLen, const uint8_t *data, size_t dataLen) {
+ WriteByteRaw(0xC0); // send the packet start character
+ _writePacketRaw(hdr, hdrLen); // send the header
+ _writePacketRaw(data, dataLen); // send the data block in raw mode
+ WriteByteRaw(0xC0); // send the packet end character
+}
+
+// Send a command to the attached device together with the supplied data, if any.
+// The data is supplied via a list of one or more segments.
+void sendCommand(uint8_t op, uint32_t checkVal, const uint8_t *data, size_t dataLen) {
+ // populate the header
+ uint8_t hdr[8];
+ putData(0, 1, hdr, 0);
+ putData(op, 1, hdr, 1);
+ putData(dataLen, 2, hdr, 2);
+ putData(checkVal, 4, hdr, 4);
+
+ // send the packet
+ if (op == ESP_SYNC)
+ writePacketRaw(hdr, sizeof(hdr), data, dataLen);
+ else
+ writePacket(hdr, sizeof(hdr), data, dataLen);
+}
+
+// Send a command to the attached device together with the supplied data, if any, and get the response
+EspUploadResult doCommand(uint8_t op, const uint8_t *data, size_t dataLen, uint32_t checkVal, uint32_t *valp, uint32_t msTimeout) {
+ size_t bodyLen;
+ EspUploadResult stat;
+
+ sendCommand(op, checkVal, data, dataLen);
+
+ stat = readPacket(op, valp, &bodyLen, msTimeout);
+ if (stat == success && bodyLen != 2)
+ stat = badReply;
+
+ return stat;
+}
+
+// Send a synchronising packet to the serial port in an attempt to induce
+// the ESP8266 to auto-baud lock on the baud rate.
+EspUploadResult Sync(uint16_t timeout) {
+ uint8_t buf[36];
+ EspUploadResult stat;
+ int i ;
+
+ // compose the data for the sync attempt
+ memset(buf, 0x55, sizeof(buf));
+ buf[0] = 0x07;
+ buf[1] = 0x07;
+ buf[2] = 0x12;
+ buf[3] = 0x20;
+
+ stat = doCommand(ESP_SYNC, buf, sizeof(buf), 0, 0, timeout);
+
+ // If we got a response other than sync, discard it and wait for a sync response. This happens at higher baud rates.
+ for (i = 0; i < 10 && stat == respHeader; ++i) {
+ size_t bodyLen;
+ stat = readPacket(ESP_SYNC, 0, &bodyLen, timeout);
+ }
+
+ if (stat == success) {
+ // Read and discard additional replies
+ for (;;) {
+ size_t bodyLen;
+ EspUploadResult rc = readPacket(ESP_SYNC, 0, &bodyLen, defaultTimeout);
+ watchdog_refresh();
+ if (rc != success || bodyLen != 2) break;
+ }
+ }
+ //DEBUG
+ //else debug//printf("stat=%d\n", (int)stat);
+ return stat;
+}
+
+// Send a command to the device to begin the Flash process.
+EspUploadResult flashBegin(uint32_t addr, uint32_t size) {
+ // determine the number of blocks represented by the size
+ uint32_t blkCnt;
+ uint8_t buf[16];
+ uint32_t timeout;
+
+ blkCnt = (size + EspFlashBlockSize - 1) / EspFlashBlockSize;
+
+ // ensure that the address is on a block boundary
+ addr &= ~(EspFlashBlockSize - 1);
+
+ // begin the Flash process
+ putData(size, 4, buf, 0);
+ putData(blkCnt, 4, buf, 4);
+ putData(EspFlashBlockSize, 4, buf, 8);
+ putData(addr, 4, buf, 12);
+
+ timeout = (size != 0) ? eraseTimeout : defaultTimeout;
+ return doCommand(ESP_FLASH_BEGIN, buf, sizeof(buf), 0, 0, timeout);
+}
+
+// Send a command to the device to terminate the Flash process
+EspUploadResult flashFinish(signed char reboot) {
+ uint8_t buf[4];
+ putData(reboot ? 0 : 1, 4, buf, 0);
+ return doCommand(ESP_FLASH_END, buf, sizeof(buf), 0, 0, defaultTimeout);
+}
+
+// Compute the checksum of a block of data
+uint16_t checksum(const uint8_t *data, uint16_t dataLen, uint16_t cksum) {
+ if (data) while (dataLen--) cksum ^= (uint16_t)*data++;
+ return cksum;
+}
+
+EspUploadResult flashWriteBlock(uint16_t flashParmVal, uint16_t flashParmMask) {
+ const uint32_t blkSize = EspFlashBlockSize;
+ int i;
+
+ // Allocate a data buffer for the combined header and block data
+ const uint16_t hdrOfst = 0;
+ const uint16_t dataOfst = 16;
+ const uint16_t blkBufSize = dataOfst + blkSize;
+ uint32_t blkBuf32[blkBufSize/4];
+ uint8_t * const blkBuf = (uint8_t*)(blkBuf32);
+ uint32_t cnt;
+ uint16_t cksum;
+ EspUploadResult stat;
+
+ // Prepare the header for the block
+ putData(blkSize, 4, blkBuf, hdrOfst + 0);
+ putData(esp_upload.uploadBlockNumber, 4, blkBuf, hdrOfst + 4);
+ putData(0, 4, blkBuf, hdrOfst + 8);
+ putData(0, 4, blkBuf, hdrOfst + 12);
+
+ // Get the data for the block
+ cnt = update_file.read(blkBuf + dataOfst, blkSize);//->Read(reinterpret_cast<char *>(blkBuf + dataOfst), blkSize);
+ if (cnt != blkSize) {
+ if (update_file.curPosition() == esp_upload.fileSize) {
+ // partial last block, fill the remainder
+ memset(blkBuf + dataOfst + cnt, 0xff, blkSize - cnt);
+ }
+ else
+ return fileRead;
+ }
+
+ // Patch the flash parameters into the first block if it is loaded at address 0
+ if (esp_upload.uploadBlockNumber == 0 && esp_upload.uploadAddress == 0 && blkBuf[dataOfst] == ESP_IMAGE_MAGIC && flashParmMask != 0) {
+ // update the Flash parameters
+ uint32_t flashParm = getData(2, blkBuf + dataOfst + 2, 0) & ~(uint32_t)flashParmMask;
+ putData(flashParm | flashParmVal, 2, blkBuf + dataOfst + 2, 0);
+ }
+
+ // Calculate the block checksum
+ cksum = checksum(blkBuf + dataOfst, blkSize, ESP_CHECKSUM_MAGIC);
+
+ for (i = 0; i < 3; i++)
+ if ((stat = doCommand(ESP_FLASH_DATA, blkBuf, blkBufSize, cksum, 0, blockWriteTimeout)) == success)
+ break;
+ return stat;
+}
+
+void upload_spin() {
+
+ switch (esp_upload.state) {
+ case resetting:
+
+ if (esp_upload.connectAttemptNumber == 9) {
+ esp_upload.uploadResult = connected;
+ esp_upload.state = done;
+ }
+ else{
+ uploadPort_begin();
+
+ wifi_delay(2000);
+
+ flushInput();
+
+ esp_upload.lastAttemptTime = esp_upload.lastResetTime = getWifiTick();
+ esp_upload.state = connecting;
+ }
+
+ break;
+
+ case connecting:
+ if ((getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= connectAttemptInterval) && (getWifiTickDiff(esp_upload.lastResetTime, getWifiTick()) >= 500)) {
+ EspUploadResult res = Sync(5000);
+ esp_upload.lastAttemptTime = getWifiTick();
+ if (res == success) {
+ esp_upload.state = erasing;
+ }
+ else {
+ esp_upload.connectAttemptNumber++;
+ if (esp_upload.connectAttemptNumber % retriesPerReset == 0) {
+ esp_upload.state = resetting;
+ }
+ }
+ }
+ break;
+
+ case erasing:
+ if (getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= blockWriteInterval) {
+ uint32_t eraseSize;
+ const uint32_t sectorsPerBlock = 16;
+ const uint32_t sectorSize = 4096;
+ const uint32_t numSectors = (esp_upload.fileSize + sectorSize - 1)/sectorSize;
+ const uint32_t startSector = esp_upload.uploadAddress/sectorSize;
+
+ uint32_t headSectors = sectorsPerBlock - (startSector % sectorsPerBlock);
+ NOMORE(headSectors, numSectors);
+
+ eraseSize = (numSectors < 2 * headSectors)
+ ? (numSectors + 1) / 2 * sectorSize
+ : (numSectors - headSectors) * sectorSize;
+
+ esp_upload.uploadResult = flashBegin(esp_upload.uploadAddress, eraseSize);
+ if (esp_upload.uploadResult == success) {
+ esp_upload.uploadBlockNumber = 0;
+ esp_upload.uploadNextPercentToReport = percentToReportIncrement;
+ esp_upload.lastAttemptTime = getWifiTick();
+ esp_upload.state = uploading;
+ }
+ else {
+ esp_upload.state = done;
+ }
+ }
+ break;
+
+ case uploading:
+ // The ESP needs several milliseconds to recover from one packet before it will accept another
+ if (getWifiTickDiff(esp_upload.lastAttemptTime, getWifiTick()) >= 15) {
+ unsigned int percentComplete;
+ const uint32_t blkCnt = (esp_upload.fileSize + EspFlashBlockSize - 1) / EspFlashBlockSize;
+ if (esp_upload.uploadBlockNumber < blkCnt) {
+ esp_upload.uploadResult = flashWriteBlock(0, 0);
+ esp_upload.lastAttemptTime = getWifiTick();
+ if (esp_upload.uploadResult != success) {
+ esp_upload.state = done;
+ }
+ percentComplete = (100 * esp_upload.uploadBlockNumber)/blkCnt;
+ ++esp_upload.uploadBlockNumber;
+ if (percentComplete >= esp_upload.uploadNextPercentToReport) {
+ esp_upload.uploadNextPercentToReport += percentToReportIncrement;
+ }
+ }
+ else
+ esp_upload.state = done;
+ }
+ break;
+
+ case done:
+ update_file.close();
+ esp_upload.state = upload_idle;//idle;
+ break;
+
+ default: break;
+ }
+}
+
+// Try to upload the given file at the given address
+void SendUpdateFile(const char *file, uint32_t address) {
+
+ const char * const fname = card.diveToFile(true, update_curDir, ESP_FIRMWARE_FILE);
+ if (!update_file.open(update_curDir, fname, O_READ)) return;
+
+ esp_upload.fileSize = update_file.fileSize();
+
+ if (esp_upload.fileSize == 0) {
+ update_file.close();
+ return;
+ }
+
+ esp_upload.uploadAddress = address;
+ esp_upload.connectAttemptNumber = 0;
+ esp_upload.state = resetting;
+}
+
+static const uint32_t FirmwareAddress = 0x00000000, WebFilesAddress = 0x00100000;
+
+void ResetWiFiForUpload(int begin_or_end) {
+ //#if 0
+ uint32_t start, now;
+
+ start = getWifiTick();
+ now = start;
+
+ if (begin_or_end == 0) {
+ SET_OUTPUT(WIFI_IO0_PIN);
+ WRITE(WIFI_IO0_PIN, LOW);
+ }
+ else
+ SET_INPUT_PULLUP(WIFI_IO0_PIN);
+
+ WIFI_RESET();
+ while (getWifiTickDiff(start, now) < 500) now = getWifiTick();
+ WIFI_SET();
+ //#endif
+}
+
+int32_t wifi_upload(int type) {
+ esp_upload.retriesPerBaudRate = 9;
+
+ ResetWiFiForUpload(0);
+
+ if (type == 0)
+ SendUpdateFile(ESP_FIRMWARE_FILE, FirmwareAddress);
+ else if (type == 1)
+ SendUpdateFile(ESP_WEB_FIRMWARE_FILE, FirmwareAddress);
+ else if (type == 2)
+ SendUpdateFile(ESP_WEB_FILE, WebFilesAddress);
+ else
+ return -1;
+
+ while (esp_upload.state != upload_idle) {
+ upload_spin();
+ watchdog_refresh();
+ }
+
+ ResetWiFiForUpload(1);
+
+ return esp_upload.uploadResult == success ? 0 : -1;
+}
+
+#endif // HAS_TFT_LVGL_UI && MKS_WIFI_MODULE
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h
new file mode 100644
index 0000000..ff98173
--- /dev/null
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_upload.h
@@ -0,0 +1,74 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" { /* C-declarations for C++ */
+#endif
+
+#define ESP_FIRMWARE_FILE "MksWifi.bin"
+#define ESP_FIRMWARE_FILE_RENAME "MKSWIFI.CUR"
+#define ESP_WEB_FIRMWARE_FILE "1:/MksWifi_Web.bin"
+#define ESP_WEB_FILE "1:/MksWifi_WebView.bin"
+
+typedef enum {
+ upload_idle,
+ resetting,
+ connecting,
+ erasing,
+ uploading,
+ done
+} UploadState;
+
+typedef enum {
+ success = 0,
+ timeout,
+ connected,
+ badReply,
+ fileRead,
+ emptyFile,
+ respHeader,
+ slipFrame,
+ slipState,
+ slipData,
+} EspUploadResult;
+
+typedef struct {
+ uint32_t fileSize;
+
+ uint32_t uploadAddress;
+ UploadState state;
+ uint32_t retriesPerBaudRate;
+ uint32_t connectAttemptNumber;
+ uint32_t lastAttemptTime;
+ uint32_t lastResetTime;
+ uint32_t uploadBlockNumber;
+ uint32_t uploadNextPercentToReport;
+ EspUploadResult uploadResult;
+} UPLOAD_STRUCT;
+
+extern UPLOAD_STRUCT esp_upload;
+int32_t wifi_upload(int type);
+
+#ifdef __cplusplus
+ } /* C-declarations for C++ */
+#endif