diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c8f5feb63..ddb9b2039 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1076,6 +1076,7 @@ void setup() SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); + //SERIAL_ECHOPAIR("Active sheet before:", static_cast(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))); #ifdef DEBUG_SEC_LANG lang_table_header_t header; @@ -1437,6 +1438,20 @@ void setup() if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0); if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0); if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0); + if (eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)) == 0xff) eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), 0); + for (uint_least8_t i = 0; i < (sizeof(Sheets::s)/sizeof(Sheets::s[0])); ++i) + { + bool is_uninitialized = true; + for (uint_least8_t j = 0; j < (sizeof(Sheet::name)/sizeof(Sheet::name[0])); ++j) + { + if (0xff != eeprom_read_byte(&(EEPROM_Sheets_base->s[i].name[j]))) is_uninitialized = false; + } + if(is_uninitialized) + { + eeprom_write_byte(&(EEPROM_Sheets_base->s[i].name[0]), i + '1'); + eeprom_write_byte(&(EEPROM_Sheets_base->s[i].name[1]), '\0'); + } + } #ifdef SNMM if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM @@ -1650,7 +1665,6 @@ void setup() #ifdef WATCHDOG wdt_enable(WDTO_4S); #endif //WATCHDOG - } diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index f8f944c65..989f6a394 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -1,6 +1,8 @@ #ifndef EEPROM_H #define EEPROM_H +#include + // The total size of the EEPROM is // 4096 for the Atmega2560 #define EEPROM_TOP 4096 @@ -167,8 +169,28 @@ #define EEPROM_NOZZLE_DIAMETER (EEPROM_CHECK_MODE-1) // uint8 #define EEPROM_NOZZLE_DIAMETER_uM (EEPROM_NOZZLE_DIAMETER-2) // uint16 +typedef struct +{ + char name[7]; +} Sheet; + +typedef struct +{ + Sheet s[3]; + uint8_t active_sheet; +} Sheets; +// sizeof(Sheets). Do not change it unless EEPROM_Sheets_base is last item in EEPROM. +// Otherwise it would move following items. +#define EEPROM_SHEETS_SIZEOF 22 + +static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_NOZZLE_DIAMETER - EEPROM_SHEETS_SIZEOF); + +#ifdef __cplusplus +static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEPROM_SHEETS_SIZEOF."); +#endif + //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_NOZZLE_DIAMETER_uM +#define EEPROM_LAST_ITEM ((uint16_t)EEPROM_Sheets_base) // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! @@ -189,7 +211,7 @@ #ifdef __cplusplus #include "ConfigurationStore.h" static_assert(EEPROM_FIRMWARE_VERSION_END < 20, "Firmware version EEPROM address conflicts with EEPROM_M500_base"); -static M500_conf * const EEPROM_M500_base = reinterpret_cast(20); //offset for storing settings using M500 +static constexpr M500_conf * const EEPROM_M500_base = reinterpret_cast(20); //offset for storing settings using M500 static_assert(((sizeof(M500_conf) + 20) < EEPROM_LAST_ITEM), "M500_conf address space conflicts with previous items."); #endif diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index e0364056e..71ddd1bad 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -174,6 +174,17 @@ static void menu_draw_item_puts_P(char type_char, const char* str) lcd_printf_P(PSTR("%c%-18.18S%c"), (lcd_encoder == menu_item)?'>':' ', str, type_char); } +static void menu_draw_item_puts_P(char type_char, const char *str_P, const Sheet &sheet) +{ + lcd_set_cursor(0, menu_row); + char buffer[19]; + uint_least8_t index = sprintf_P(buffer, PSTR("%.10S "), str_P); + eeprom_read_block(&(buffer[index]), sheet.name, 7); + index += 7; + buffer[index] = '\0'; + lcd_printf_P(PSTR("%c%-18.18s%c"), (lcd_encoder == menu_item)?'>':' ', buffer, type_char); +} + static void menu_draw_item_puts_P(char type_char, const char* str, char num) { lcd_set_cursor(0, menu_row); @@ -224,6 +235,21 @@ uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu) return 0; } +uint8_t menu_item_submenu_P(const char* str_P, const Sheet &sheet, menu_func_t submenu) +{ + if (menu_item == menu_line) + { + if (lcd_draw_update) menu_draw_item_puts_P(LCD_STR_ARROW_RIGHT[0], str_P, sheet); + if (menu_clicked && (lcd_encoder == menu_item)) + { + menu_submenu(submenu); + return menu_item_ret(); + } + } + menu_item++; + return 0; +} + uint8_t menu_item_back_P(const char* str) { if (menu_item == menu_line) diff --git a/Firmware/menu.h b/Firmware/menu.h index 5f73e18b0..1e4252874 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -3,6 +3,7 @@ #define _MENU_H #include +#include "eeprom.h" #define MENU_DATA_SIZE 32 @@ -99,6 +100,10 @@ extern uint8_t menu_item_text_P(const char* str); #define MENU_ITEM_SUBMENU_P(str, submenu) do { if (menu_item_submenu_P(str, submenu)) return; } while (0) extern uint8_t menu_item_submenu_P(const char* str, menu_func_t submenu); +#define MENU_ITEM_SUBMENU_P_E(str_P, eeprom_address_7b, submenu) do { if (menu_item_submenu_P(str_P, eeprom_address_7b, submenu)) return; } while (0) +extern uint8_t menu_item_submenu_P(const char *str_P, const Sheet &sheet, menu_func_t submenu); + + #define MENU_ITEM_BACK_P(str) do { if (menu_item_back_P(str)) return; } while (0) extern uint8_t menu_item_back_P(const char* str); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 52e5988d6..b057af506 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -6300,6 +6300,15 @@ void lcd_resume_print() isPrintPaused = false; } +static void lcd_sheet_menu() +{ + uint_least8_t sheet_index = eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)); + sheet_index++; + if (sheet_index >= (sizeof(Sheets::s)/sizeof(Sheets::s[0]))) sheet_index = 0; + eeprom_update_byte(&(EEPROM_Sheets_base->active_sheet), sheet_index); + menu_back(); +} + static void lcd_main_menu() { @@ -6334,8 +6343,14 @@ static void lcd_main_menu() } else { MENU_ITEM_SUBMENU_P(_i("Preheat"), lcd_preheat_menu);////MSG_PREHEAT + do + { + if (menu_item_submenu_P(_i("Sheet"), EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))], lcd_sheet_menu)) return; + } while (0); } + + #ifdef SDSUPPORT if (card.cardOK || lcd_commands_type == LcdCommands::Layer1Cal) {