mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2026-03-12 22:06:07 -06:00
545 lines
15 KiB
C++
545 lines
15 KiB
C++
/**
|
|
* Marlin 3D Printer Firmware
|
|
* Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
*
|
|
* Based on Sprinter and grbl.
|
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "../../../inc/MarlinConfigPre.h"
|
|
|
|
#if ENABLED(DGUS_LCD_UI_E3S1PRO)
|
|
|
|
#include "DGUSDisplay.h"
|
|
#include "DGUSScreenHandler.h"
|
|
#include "DGUSSDCardHandler.h"
|
|
|
|
#include "definition/DGUS_ScreenAddrList.h"
|
|
#include "definition/DGUS_ScreenSetup.h"
|
|
|
|
#include "../../../gcode/queue.h"
|
|
|
|
#define DGUS_SCREEN_PAGE_DEBUG // uncomment to debug page changes
|
|
|
|
DGUSScreenHandler::eeprom_data_t DGUSScreenHandler::config = {};
|
|
uint16_t DGUSScreenHandler::currentMeshPointIndex = 0;
|
|
bool DGUSScreenHandler::isLeveling = false;
|
|
char DGUSScreenHandler::homeStatusMessage[128];
|
|
|
|
bool DGUSScreenHandler::settings_ready = false;
|
|
bool DGUSScreenHandler::booted = false;
|
|
|
|
DGUS_ScreenID DGUSScreenHandler::current_screen = DGUS_ScreenID::BOOT;
|
|
DGUS_ScreenID DGUSScreenHandler::new_screen = DGUS_ScreenID::BOOT;
|
|
DGUS_ScreenID DGUSScreenHandler::wait_return_screen = DGUS_ScreenID::BOOT;
|
|
DGUS_ScreenID DGUSScreenHandler::confirm_return_screen = DGUS_ScreenID::BOOT;
|
|
bool DGUSScreenHandler::full_update = false;
|
|
uint8_t DGUSScreenHandler::angry_beeps = 0;
|
|
|
|
#if HAS_MEDIA
|
|
static const char* const noFileSelected = "";
|
|
const char* DGUSScreenHandler::sdPrintFilename = noFileSelected;
|
|
#endif
|
|
|
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
|
bool DGUSScreenHandler::powerLossRecoveryAvailable = false;
|
|
#endif
|
|
|
|
#if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
|
|
ssize_t DGUSScreenHandler::currentScrollIndex = 0;
|
|
size_t DGUSScreenHandler::pageMaxStringLen = 0;
|
|
size_t DGUSScreenHandler::pageMaxControlLen = 0;
|
|
#endif
|
|
|
|
millis_t DGUSScreenHandler::status_expire = 0;
|
|
millis_t DGUSScreenHandler::eeprom_save = 0;
|
|
|
|
void DGUSScreenHandler::init() {
|
|
dgus.init();
|
|
moveToScreen(DGUS_ScreenID::BOOT, true);
|
|
}
|
|
|
|
void DGUSScreenHandler::ready() {
|
|
dgus.playSound(1);
|
|
}
|
|
|
|
void DGUSScreenHandler::loop() {
|
|
const millis_t ms = ExtUI::safe_millis();
|
|
static millis_t next_event_ms = 0, next_beep_ms = 0;
|
|
static bool wasLeveling = isLeveling;
|
|
|
|
if (new_screen != DGUS_ScreenID::BOOT) {
|
|
const DGUS_ScreenID screen = new_screen;
|
|
new_screen = DGUS_ScreenID::BOOT;
|
|
|
|
#if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
|
|
currentScrollIndex = -DGUS_AUTOSCROLL_START_CYCLES;
|
|
pageMaxStringLen = 0;
|
|
pageMaxControlLen = 0;
|
|
#endif
|
|
|
|
if (current_screen == screen)
|
|
triggerFullUpdate();
|
|
else
|
|
moveToScreen(screen);
|
|
return;
|
|
}
|
|
|
|
if (!booted && current_screen == DGUS_ScreenID::HOME) {
|
|
// Boot complete
|
|
booted = true;
|
|
dgus.readVersions();
|
|
return;
|
|
}
|
|
|
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
|
if (booted && powerLossRecoveryAvailable) {
|
|
triggerScreenChange(DGUS_ScreenID::POWERCONTINUE);
|
|
powerLossRecoveryAvailable = false;
|
|
}
|
|
#endif
|
|
|
|
if (ELAPSED(ms, next_event_ms) || full_update) {
|
|
next_event_ms = ms + (booted ? DGUS_UPDATE_INTERVAL_MS : 50);
|
|
|
|
#if ENABLED(DGUS_SOFTWARE_AUTOSCROLL)
|
|
currentScrollIndex += 1;
|
|
if (currentScrollIndex > (ssize_t)(pageMaxStringLen - pageMaxControlLen) + DGUS_AUTOSCROLL_END_CYCLES)
|
|
currentScrollIndex = -DGUS_AUTOSCROLL_START_CYCLES;
|
|
#endif
|
|
|
|
if (angry_beeps) {
|
|
--angry_beeps;
|
|
dgus.playSound(3);
|
|
}
|
|
|
|
if (!sendScreenVPData(current_screen, full_update))
|
|
DEBUG_ECHOLNPGM("SendScreenVPData failed");
|
|
|
|
return;
|
|
}
|
|
|
|
if (ELAPSED(ms, next_beep_ms)) {
|
|
next_beep_ms = ms + 300;
|
|
|
|
if (angry_beeps) {
|
|
--angry_beeps;
|
|
dgus.playSound(0, 500/8, 100);
|
|
}
|
|
}
|
|
|
|
if (wasLeveling && !isLeveling) {
|
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
|
ExtUI::injectCommands(ExtUI::getLevelingIsValid() ? F("G29 S0") : F("G29 S1\nG29 P3\nG29 S0"));
|
|
#endif
|
|
|
|
config.levelingEnabled = ExtUI::getLevelingIsValid();
|
|
ExtUI::setLevelingActive(config.levelingEnabled);
|
|
triggerEEPROMSave();
|
|
}
|
|
wasLeveling = isLeveling;
|
|
|
|
if (!settings_ready && booted) return;
|
|
|
|
if (status_expire > 0 && ELAPSED(ms, status_expire)) {
|
|
setStatusMessage(FPSTR(NUL_STR), 0);
|
|
return;
|
|
}
|
|
|
|
if (eeprom_save > 0 && ELAPSED(ms, eeprom_save) && isPrinterIdle()) {
|
|
eeprom_save = 0;
|
|
ExtUI::injectCommands(F("M500"));
|
|
return;
|
|
}
|
|
|
|
dgus.loop();
|
|
}
|
|
|
|
void DGUSScreenHandler::printerKilled(FSTR_P const error, FSTR_P const component) {
|
|
dgus.playSound(0, (uint8_t)(3000/8), 100);
|
|
setStatusMessage(error);
|
|
moveToScreen(DGUS_ScreenID::ABNORMAL);
|
|
}
|
|
|
|
void DGUSScreenHandler::userConfirmRequired(const char * const msg) {
|
|
#if ENABLED(DGUS_USERCONFIRM)
|
|
if (confirm_return_screen == DGUS_ScreenID::BOOT)
|
|
confirm_return_screen = getCurrentScreen();
|
|
|
|
strcpy(dgus_sdcard_handler.filenames[0], msg);
|
|
dgus_sdcard_handler.filenames[1][0] = '\0';
|
|
dgus_sdcard_handler.filenames[2][0] = '\0';
|
|
dgus_sdcard_handler.filenames[3][0] = '\0';
|
|
|
|
strcpy(dgus_sdcard_handler.filenames[4], "[");
|
|
strcat(dgus_sdcard_handler.filenames[4], GET_TEXT(MSG_BUTTON_CONFIRM));
|
|
strcat(dgus_sdcard_handler.filenames[4], "]");
|
|
|
|
new_screen = DGUS_ScreenID::FILE1;
|
|
#if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
|
|
DEBUG_ECHOLNPGM("trig confirm: ", msg, ", ret: ", (uint16_t)confirm_return_screen);
|
|
#endif
|
|
#else
|
|
UNUSED(msg);
|
|
#endif
|
|
}
|
|
|
|
void DGUSScreenHandler::userConfirmation() {
|
|
#if ENABLED(DGUS_USERCONFIRM)
|
|
if (confirm_return_screen == DGUS_ScreenID::BOOT) {
|
|
DEBUG_ECHOLNPGM("DGUS: User confirmation triggered but no return screen");
|
|
return;
|
|
}
|
|
|
|
if (confirm_return_screen >= DGUS_ScreenID::FILE1 && confirm_return_screen <= DGUS_ScreenID::FILE4)
|
|
dgus_sdcard_handler.onPageLoad(DGUS_SCREEN_TO_PAGE(confirm_return_screen));
|
|
|
|
#ifdef DEBUG_DGUSLCD
|
|
DEBUG_ECHOLNPGM("trig confirmed, ret:", (uint16_t)confirm_return_screen);
|
|
#endif
|
|
|
|
new_screen = confirm_return_screen;
|
|
confirm_return_screen = DGUS_ScreenID::BOOT;
|
|
ExtUI::setUserConfirmed();
|
|
#endif
|
|
}
|
|
|
|
void DGUSScreenHandler::settingsReset() {
|
|
config.initialized = true;
|
|
config.volume = DGUS_DEFAULT_VOLUME;
|
|
config.brightness = DGUS_DEFAULT_BRIGHTNESS;
|
|
config.language = DGUS_Data::Language::Default;
|
|
config.jogLength = DGUS_Data::AxisControlCommand::Jog_1mm;
|
|
config.plaExtruderTemp = PREHEAT_1_TEMP_HOTEND;
|
|
config.plaBedTemp = PREHEAT_1_TEMP_BED;
|
|
config.absExtruderTemp = PREHEAT_2_TEMP_HOTEND;
|
|
config.absBedTemp = PREHEAT_2_TEMP_BED;
|
|
config.levelingEnabled = ExtUI::getLevelingActive();
|
|
|
|
if (!settings_ready) {
|
|
settings_ready = true;
|
|
ready();
|
|
}
|
|
|
|
setStatusMessage(GET_TEXT_F(DGUS_MSG_RESET_EEPROM));
|
|
}
|
|
|
|
void DGUSScreenHandler::storeSettings(char *buff) {
|
|
static_assert(sizeof(config) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size.");
|
|
|
|
config.initialized = true;
|
|
config.volume = dgus.getVolume();
|
|
config.brightness = dgus.getBrightness();
|
|
|
|
memcpy(buff, &config, sizeof(config));
|
|
}
|
|
|
|
void DGUSScreenHandler::loadSettings(const char *buff) {
|
|
static_assert(sizeof(config) <= ExtUI::eeprom_data_size, "sizeof(eeprom_data_t) > eeprom_data_size.");
|
|
memcpy(&config, buff, sizeof(config));
|
|
|
|
if (!config.initialized
|
|
|| config.language < DGUS_Data::Language::Chinese_Simplified
|
|
|| config.language > DGUS_Data::Language::Turkish
|
|
|| config.jogLength < DGUS_Data::AxisControlCommand::Jog_10mm
|
|
|| config.jogLength > DGUS_Data::AxisControlCommand::Jog_0_1mm) {
|
|
DEBUG_ECHOLNPGM("invalid DGUS settings, resetting");
|
|
settingsReset();
|
|
}
|
|
|
|
ExtUI::setLevelingActive(config.levelingEnabled);
|
|
dgus.setVolume(config.volume);
|
|
dgus.setBrightness(config.brightness);
|
|
}
|
|
|
|
void DGUSScreenHandler::configurationStoreWritten(bool success) {
|
|
if (!success)
|
|
setStatusMessage(GET_TEXT_F(DGUS_MSG_WRITE_EEPROM_FAILED));
|
|
}
|
|
|
|
void DGUSScreenHandler::configurationStoreRead(bool success) {
|
|
if (!success) {
|
|
setStatusMessage(GET_TEXT_F(DGUS_MSG_READ_EEPROM_FAILED));
|
|
}
|
|
else if (!settings_ready) {
|
|
settings_ready = true;
|
|
ready();
|
|
}
|
|
}
|
|
|
|
void DGUSScreenHandler::playTone(const uint16_t frequency, const uint16_t duration/*=0*/) {
|
|
if (WITHIN(frequency, 1, 255)) {
|
|
if (WITHIN(duration, 1, 255))
|
|
dgus.playSound((uint8_t)frequency, (uint8_t)duration);
|
|
else
|
|
dgus.playSound((uint8_t)frequency);
|
|
}
|
|
}
|
|
|
|
void DGUSScreenHandler::angryBeeps(const uint8_t beepCount) {
|
|
angry_beeps = beepCount;
|
|
}
|
|
|
|
void DGUSScreenHandler::levelingStart() {
|
|
isLeveling = true;
|
|
currentMeshPointIndex = 0;
|
|
triggerFullUpdate();
|
|
}
|
|
|
|
void DGUSScreenHandler::levelingEnd() {
|
|
if (!isLeveling) return;
|
|
|
|
#if ENABLED(DEBUG_DGUSLCD)
|
|
DEBUG_ECHOLNPGM("levelingEnd(), valid=", ExtUI::getLevelingIsValid());
|
|
#endif
|
|
|
|
isLeveling = false;
|
|
currentMeshPointIndex = 0;
|
|
triggerFullUpdate();
|
|
}
|
|
|
|
void DGUSScreenHandler::meshUpdate(const int8_t xpos, const int8_t ypos) {
|
|
if (!isLeveling) return;
|
|
|
|
currentMeshPointIndex++;
|
|
triggerFullUpdate();
|
|
}
|
|
|
|
void DGUSScreenHandler::printTimerStarted() {
|
|
TERN_(HAS_FILAMENT_SENSOR, ExtUI::setFilamentRunoutState(false));
|
|
triggerScreenChange(DGUS_ScreenID::PAUSE);
|
|
}
|
|
|
|
void DGUSScreenHandler::printTimerPaused() {
|
|
dgus.playSound(3);
|
|
triggerScreenChange(DGUS_ScreenID::RESUME);
|
|
}
|
|
|
|
void DGUSScreenHandler::printTimerStopped() {
|
|
dgus.playSound(3);
|
|
triggerScreenChange(DGUS_ScreenID::FINISH);
|
|
}
|
|
|
|
void DGUSScreenHandler::filamentRunout(const ExtUI::extruder_t extruder) {
|
|
triggerScreenChange(DGUS_ScreenID::FILAMENTUSEUP);
|
|
dgus.playSound(3);
|
|
}
|
|
|
|
ssize_t DGUSScreenHandler::getScrollIndex() {
|
|
return currentScrollIndex;
|
|
}
|
|
|
|
void DGUSScreenHandler::addCurrentPageStringLength(size_t stringLength, size_t textControlLength) {
|
|
NOLESS(pageMaxStringLen, stringLength);
|
|
NOLESS(pageMaxControlLen, textControlLength);
|
|
}
|
|
|
|
#if HAS_MEDIA
|
|
|
|
void DGUSScreenHandler::sdCardInserted() {}
|
|
|
|
void DGUSScreenHandler::sdCardRemoved() {
|
|
sdPrintFilename = noFileSelected;
|
|
if (WITHIN(getCurrentScreen(), DGUS_ScreenID::FILE1, DGUS_ScreenID::FILE4))
|
|
triggerTempScreenChange(DGUS_ScreenID::SDCARDCHECK, DGUS_ScreenID::HOME);
|
|
}
|
|
|
|
void DGUSScreenHandler::sdCardError() {}
|
|
|
|
#endif // HAS_MEDIA
|
|
|
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
|
void DGUSScreenHandler::powerLossResume() {
|
|
powerLossRecoveryAvailable = true;
|
|
}
|
|
#endif
|
|
|
|
#if HAS_PID_HEATING
|
|
void DGUSScreenHandler::pidTuning(const ExtUI::result_t rst) {
|
|
dgus.playSound(3);
|
|
}
|
|
#endif
|
|
|
|
void DGUSScreenHandler::steppersStatusChanged(bool steppersEnabled) {
|
|
refreshVP(DGUS_Addr::AXIS_StepperStatus);
|
|
}
|
|
|
|
void DGUSScreenHandler::homingDone() {
|
|
if (isOnTempScreen(DGUS_ScreenID::AUTOHOME))
|
|
triggerReturnScreen();
|
|
}
|
|
|
|
void DGUSScreenHandler::startPrintFromSD(const char* const filename) {
|
|
triggerScreenChange(DGUS_ScreenID::HOME);
|
|
sdPrintFilename = filename;
|
|
setStatusMessage(sdPrintFilename, 0);
|
|
}
|
|
|
|
void DGUSScreenHandler::setStatusMessage(FSTR_P msg, const millis_t duration) {
|
|
setStatusMessage(FTOP(msg), duration);
|
|
}
|
|
|
|
void DGUSScreenHandler::setStatusMessage(const char* msg, const millis_t duration) {
|
|
homeStatusMessage[0] = '\0';
|
|
strncat(homeStatusMessage, msg, sizeof(homeStatusMessage) / sizeof(char) - 1);
|
|
status_expire = duration ? ExtUI::safe_millis() + duration : 0;
|
|
}
|
|
|
|
DGUS_ScreenID DGUSScreenHandler::getCurrentScreen() { return current_screen; }
|
|
|
|
void DGUSScreenHandler::homeThenChangeScreen(DGUS_ScreenID screen) {
|
|
triggerTempScreenChange(DGUS_ScreenID::AUTOHOME, screen);
|
|
ExtUI::injectCommands(F("G28"));
|
|
}
|
|
|
|
void DGUSScreenHandler::triggerScreenChange(DGUS_ScreenID screen) {
|
|
if (confirm_return_screen != DGUS_ScreenID::BOOT)
|
|
confirm_return_screen = screen;
|
|
else
|
|
new_screen = screen;
|
|
wait_return_screen = DGUS_ScreenID::BOOT; // cancel temp screen
|
|
|
|
#if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
|
|
DEBUG_ECHOLNPGM("trig scr: ", (uint16_t)screen);
|
|
#endif
|
|
}
|
|
|
|
void DGUSScreenHandler::triggerTempScreenChange(DGUS_ScreenID screen, DGUS_ScreenID returnScreen) {
|
|
if (confirm_return_screen != DGUS_ScreenID::BOOT)
|
|
confirm_return_screen = screen;
|
|
else
|
|
new_screen = screen;
|
|
wait_return_screen = returnScreen;
|
|
|
|
#if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
|
|
DEBUG_ECHOLNPGM("trig tmp: ", (uint16_t)screen, " ret: ", (uint16_t)returnScreen);
|
|
#endif
|
|
}
|
|
|
|
void DGUSScreenHandler::triggerReturnScreen() {
|
|
new_screen = wait_return_screen;
|
|
wait_return_screen = DGUS_ScreenID::BOOT;
|
|
#if ALL(DEBUG_OUT, DGUS_SCREEN_PAGE_DEBUG)
|
|
DEBUG_ECHOLNPGM("trig ret scr");
|
|
#endif
|
|
}
|
|
|
|
bool DGUSScreenHandler::isOnTempScreen(DGUS_ScreenID screen) {
|
|
return wait_return_screen != DGUS_ScreenID::BOOT
|
|
&& (screen == DGUS_ScreenID::BOOT || current_screen == screen);
|
|
}
|
|
|
|
void DGUSScreenHandler::triggerFullUpdate() {
|
|
full_update = true;
|
|
}
|
|
|
|
void DGUSScreenHandler::triggerEEPROMSave() {
|
|
eeprom_save = ExtUI::safe_millis() + 500;
|
|
}
|
|
|
|
bool DGUSScreenHandler::isPrinterIdle() {
|
|
return (!ExtUI::commandsInQueue() && !ExtUI::isMoving());
|
|
}
|
|
|
|
const DGUS_Addr* DGUSScreenHandler::findScreenAddrList(DGUS_ScreenID screen) {
|
|
DGUS_ScreenAddrList list;
|
|
const DGUS_ScreenAddrList *map = screen_addr_list_map;
|
|
|
|
do {
|
|
memcpy_P(&list, map, sizeof(*map));
|
|
if (!list.addr_list) break;
|
|
if (list.screen == screen) return list.addr_list;
|
|
} while (++map);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool DGUSScreenHandler::callScreenSetup(DGUS_ScreenID screen) {
|
|
DGUS_ScreenSetup setup;
|
|
const DGUS_ScreenSetup *list = screen_setup_list;
|
|
|
|
do {
|
|
memcpy_P(&setup, list, sizeof(*list));
|
|
if (!setup.setup_fn) break;
|
|
if (setup.screen == screen) return setup.setup_fn();
|
|
} while (++list);
|
|
|
|
return true;
|
|
}
|
|
|
|
void DGUSScreenHandler::moveToScreen(DGUS_ScreenID screen, bool abort_wait) {
|
|
current_screen = screen;
|
|
|
|
if (!callScreenSetup(screen)) return;
|
|
if (!sendScreenVPData(screen, true)) return;
|
|
|
|
dgus.switchScreen(current_screen);
|
|
}
|
|
|
|
bool DGUSScreenHandler::sendScreenVPData(DGUS_ScreenID screen, bool complete_update) {
|
|
if (complete_update) full_update = false;
|
|
|
|
const DGUS_Addr *list = findScreenAddrList(screen);
|
|
|
|
while (true) {
|
|
if (!list) return true; // Nothing left to send
|
|
|
|
const uint16_t addr = pgm_read_word(list++);
|
|
if (!addr) return true; // Nothing left to send
|
|
|
|
DGUS_VP vp;
|
|
if (!DGUS_PopulateVP((DGUS_Addr)addr, &vp)) continue; // Invalid VP
|
|
if (!vp.tx_handler) continue; // Nothing to send
|
|
if (!complete_update
|
|
&& !(vp.flags & VPFLAG_AUTOUPLOAD)
|
|
&& TERN1(DGUS_SOFTWARE_AUTOSCROLL, !(vp.flags & VPFLAG_TXSTRING_AUTOSCROLL))
|
|
) continue; // Unnecessary VP
|
|
|
|
uint8_t expected_tx = 6 + vp.size; // 6 bytes header + payload.
|
|
const millis_t try_until = ExtUI::safe_millis() + 1000;
|
|
|
|
while (expected_tx > dgus.getFreeTxBuffer()) {
|
|
if (ELAPSED(ExtUI::safe_millis(), try_until)) return false; // Stop trying after 1 second
|
|
|
|
dgus.flushTx(); // Flush the TX buffer
|
|
delay(50);
|
|
}
|
|
|
|
vp.tx_handler(vp);
|
|
}
|
|
}
|
|
|
|
bool DGUSScreenHandler::refreshVP(DGUS_Addr vpAddr) {
|
|
const DGUS_Addr *list = findScreenAddrList(current_screen);
|
|
|
|
while (list && (uint16_t)*list) {
|
|
if (*list == vpAddr) {
|
|
DGUS_VP vp;
|
|
if (!DGUS_PopulateVP((DGUS_Addr)vpAddr, &vp) || !vp.tx_handler)
|
|
return false;
|
|
|
|
vp.tx_handler(vp);
|
|
return true;
|
|
}
|
|
|
|
list++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif // DGUS_LCD_UI_E3S1PRO
|