From b3a587f5a4b82f4fb6a360354fae5f057efcf0e5 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 20 Nov 2019 20:25:51 +0200 Subject: [PATCH 01/58] SD first attempt. Broken --- Firmware/lcd.cpp | 1 + Firmware/lcd.h | 2 + Firmware/menu.cpp | 19 ++++++ Firmware/menu.h | 4 ++ Firmware/ultralcd.cpp | 140 ++++++++++++++++++++---------------------- 5 files changed, 94 insertions(+), 72 deletions(-) diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 3e39312c1..d7c90b266 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -645,6 +645,7 @@ lcd_lcdupdate_func_t lcd_lcdupdate_func = 0; static ShortTimer buttonBlanking; ShortTimer longPressTimer; LongTimer lcd_timeoutToStatus; +ShortTimer lcd_scrollTimer; //! @brief Was button clicked? diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 790c0a955..f4ea6a6f7 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -102,6 +102,8 @@ extern uint8_t lcd_update_enabled; extern LongTimer lcd_timeoutToStatus; +extern ShortTimer lcd_scrollTimer; + extern uint32_t lcd_next_update_millis; extern uint8_t lcd_status_update_delay; diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 38f5d4e80..0ea1c636c 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -111,6 +111,15 @@ static void menu_back_no_reset(void) } } +void menu_back_no_feedback(void) +{ + if (menu_depth > 0) + { + menu_depth--; + menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, false, true); + } +} + void menu_back_if_clicked(void) { if (lcd_clicked()) @@ -146,6 +155,16 @@ static void menu_submenu_no_reset(menu_func_t submenu) } } +void menu_submenu_scroll(menu_func_t submenu) +{ + if (menu_depth < MENU_DEPTH_MAX) + { + menu_stack[menu_depth].menu = menu_menu; + menu_stack[menu_depth++].position = lcd_encoder; + menu_goto(submenu, menu_row, false, true); + } +} + uint8_t menu_item_ret(void) { lcd_beeper_quick_feedback(); diff --git a/Firmware/menu.h b/Firmware/menu.h index a9526c318..88d962949 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -78,12 +78,16 @@ extern void menu_end(void); extern void menu_back(void); extern void menu_back(uint8_t nLevel); +extern void menu_back_no_feedback(void); + extern void menu_back_if_clicked(void); extern void menu_back_if_clicked_fb(void); extern void menu_submenu(menu_func_t submenu); +extern void menu_submenu_scroll(menu_func_t submenu); + extern uint8_t menu_item_ret(void); //extern int menu_draw_item_printf_P(char type_char, const char* format, ...); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2ed8d5de4..0a574877b 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -46,8 +46,8 @@ #include "first_lay_cal.h" -int scrollstuff = 0; -char longFilenameOLD[LONG_FILENAME_LENGTH]; +//filename scrolling +const char* scrollPointer; static void lcd_sd_updir(); @@ -313,7 +313,53 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; +static void lcd_filename_scroll() //this is a submenu +{ + typedef struct + { + int8_t status; + int encoderInitial; + } _menu_data_t; + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); + _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); + if (_md->status == 0) + { + _md->status = 1; + _md->encoderInitial = lcd_encoder_diff / ENCODER_PULSES_PER_STEP; + lcd_scrollTimer.start(); + } + if (LCD_CLICKED || (_md->encoderInitial != (lcd_encoder_diff / ENCODER_PULSES_PER_STEP))) //go back to sd_menu. + { + lcd_scrollTimer.stop(); + // menu_depth--; + // menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + lcd_encoder_diff / ENCODER_PULSES_PER_STEP, false, true); + menu_back_no_feedback(); + } + if(lcd_scrollTimer.expired(300)) + { + uint8_t i = LCD_WIDTH - 1; + lcd_set_cursor(0, lcd_encoder); + lcd_print('>'); + for (; i != 0; i--) + { + char c = *(scrollPointer + LCD_WIDTH - i); + if (c == '\0') break; //stop at the end of the string + else + { + lcd_print(c); + lcd_scrollTimer.start(); + } + } + if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). + { + lcd_space(i); + } + scrollPointer++; + } +} + +/* static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename) { char c; @@ -372,21 +418,17 @@ static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* while(n--) lcd_print(' '); } -static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* filename, char* longFilename) +*/ +static void lcd_implementation_drawmenu_sdfile(uint8_t row, char* longFilename) { char c; uint8_t n = LCD_WIDTH - 1; lcd_set_cursor(0, row); - lcd_print(' '); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-1] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) + lcd_print((lcd_encoder == menu_item)?'>':' '); + while( ((c = *longFilename) != '\0') && (n>0) ) { lcd_print(c); - filename++; + longFilename++; n--; } while(n--) @@ -441,9 +483,7 @@ static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* fil //#define MENU_ITEM_SDDIR(str, str_fn, str_fnl) MENU_ITEM(sddirectory, str, str_fn, str_fnl) //extern uint8_t menu_item_sddir(const char* str, const char* str_fn, char* str_fnl); -#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) do { if (menu_item_sdfile(str, str_fn, str_fnl)) return; } while (0) -//#define MENU_ITEM_SDFILE(str, str_fn, str_fnl) MENU_ITEM(sdfile, str, str_fn, str_fnl) -//extern uint8_t menu_item_sdfile(const char* str, const char* str_fn, char* str_fnl); +#define MENU_ITEM_SDFILE(str_fn, str_fnl) do { if (menu_item_sdfile(str_fn, str_fnl)) return; } while (0) uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) @@ -496,60 +536,18 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) #endif //NEW_SD_MENU } -static uint8_t menu_item_sdfile(const char* -#ifdef NEW_SD_MENU - str -#endif //NEW_SD_MENU - ,const char* str_fn, char* str_fnl) +static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { -#ifdef NEW_SD_MENU -// printf_P(PSTR("menu sdfile\n")); -// str_fnl[19] = 0; -// printf_P(PSTR("menu file %d '%s' '%s'\n"), menu_row, str_fn, str_fnl); - if (menu_item == menu_line) - { - if (lcd_draw_update) - { -// printf_P(PSTR("menu file %d %d '%s'\n"), menu_row, menuData.sdcard_menu.viewState, str_fnl[0]?str_fnl:str_fn); - lcd_set_cursor(0, menu_row); -/* if (lcd_encoder == menu_item) - { - lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1); - if (menuData.sdcard_menu.viewState == 0) - { - menuData.sdcard_menu.viewState++; - lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 1); - } - else if (menuData.sdcard_menu.viewState == 1) - { - lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', (str_fnl[0]?str_fnl:str_fn) + 2); - } - } - else*/ - { - str_fnl[19] = 0; - lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', str_fnl[0]?str_fnl:str_fn); - } - -// int cnt = lcd_printf_P(PSTR("%c%-19s"), (lcd_encoder == menu_item)?'>':' ', str_fnl); -// int cnt = lcd_printf_P(PSTR("%cTESTIK.gcode"), (lcd_encoder == menu_item)?'>':' '); - } - if (menu_clicked && (lcd_encoder == menu_item)) - { - return menu_item_ret(); - } - } - menu_item++; - return 0; -#else //NEW_SD_MENU if (menu_item == menu_line) { if (lcd_draw_update) { + scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; if (lcd_encoder == menu_item) - lcd_implementation_drawmenu_sdfile_selected(menu_row, str_fn, str_fnl); - else - lcd_implementation_drawmenu_sdfile(menu_row, str_fn, str_fnl); + { + if (lcd_scrollTimer.expired(1000)) menu_submenu_scroll(lcd_filename_scroll); + } + else lcd_implementation_drawmenu_sdfile(menu_row, str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -560,7 +558,6 @@ static uint8_t menu_item_sdfile(const char* } menu_item++; return 0; -#endif //NEW_SD_MENU } // Print temperature (nozzle/bed) (9 chars total) @@ -727,7 +724,7 @@ void lcdui_print_time(void) //Print status line on status screen void lcdui_print_status_line(void) { - if (IS_SD_PRINTING) +/* if (IS_SD_PRINTING) { if (strcmp(longFilenameOLD, (card.longFilename[0] ? card.longFilename : card.filename)) != 0) { @@ -735,7 +732,7 @@ void lcdui_print_status_line(void) sprintf_P(longFilenameOLD, PSTR("%s"), (card.longFilename[0] ? card.longFilename : card.filename)); scrollstuff = 0; } - } + } */ if (heating_status) { // If heating flag, show progress of heating @@ -780,7 +777,7 @@ void lcdui_print_status_line(void) } else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status)) { // If printing from SD, show what we are printing - if(strlen(longFilenameOLD) > LCD_WIDTH) + /* if(strlen(longFilenameOLD) > LCD_WIDTH) { int inters = 0; int gh = scrollstuff; @@ -806,7 +803,7 @@ void lcdui_print_status_line(void) else { lcd_printf_P(PSTR("%-20s"), longFilenameOLD); - } + } */ } else { // Otherwise check for other special events @@ -4275,7 +4272,7 @@ static void prusa_stat_printinfo() SERIAL_ECHO("][FEM:"); SERIAL_ECHO(itostr3(feedmultiply)); SERIAL_ECHO("][FNM:"); - SERIAL_ECHO(longFilenameOLD); + SERIAL_ECHO(card.longFilename); SERIAL_ECHO("][TIM:"); if (starttime != 0) { @@ -7279,7 +7276,7 @@ void lcd_sdcard_menu() return; // nothing to do (so don't thrash the SD card) uint16_t fileCnt = card.getnrfilenames(); - + lcd_scrollTimer.start(); MENU_BEGIN(); MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion card.getWorkDirName(); @@ -7309,11 +7306,10 @@ void lcd_sdcard_menu() #else card.getfilename(nr); #endif - if (card.filenameIsDir) MENU_ITEM_SDDIR(card.filename, card.longFilename); - else - MENU_ITEM_SDFILE(_T(MSG_CARD_MENU), card.filename, card.longFilename); + else + MENU_ITEM_SDFILE(card.filename, card.longFilename); } else { MENU_ITEM_DUMMY(); } From 8f901d261339abba522d9db44d7d4be52a6b08a2 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 21 Nov 2019 14:58:13 +0200 Subject: [PATCH 02/58] Temporary fix --- Firmware/ultralcd.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0a574877b..a0323841f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -419,7 +419,7 @@ static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* lcd_print(' '); } */ -static void lcd_implementation_drawmenu_sdfile(uint8_t row, char* longFilename) +static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename) { char c; uint8_t n = LCD_WIDTH - 1; @@ -547,13 +547,14 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { if (lcd_scrollTimer.expired(1000)) menu_submenu_scroll(lcd_filename_scroll); } - else lcd_implementation_drawmenu_sdfile(menu_row, str_fnl); + else lcd_implementation_drawmenu_sdfile(menu_row, scrollPointer); } if (menu_clicked && (lcd_encoder == menu_item)) { lcd_consume_click(); menu_action_sdfile(str_fn); - return menu_item_ret(); + // return menu_item_ret(); + return 1; } } menu_item++; From 6538262e758198987923200a2db41933022cd7c6 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 21 Nov 2019 19:04:45 +0200 Subject: [PATCH 03/58] First build that actually works --- Firmware/menu.cpp | 7 ++++--- Firmware/menu.h | 2 +- Firmware/ultralcd.cpp | 46 ++++++++++++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 0ea1c636c..bfb018e81 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -54,6 +54,7 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo // Resets the global shared C union. // This ensures, that the menu entered will find out, that it shall initialize itself. memset(&menu_data, 0, sizeof(menu_data)); + menu_entering = 1; //next menu that supports entering will clear this flag on first enter. Used for initializing some menus only one time. } if (feedback) lcd_quick_feedback(); } @@ -111,12 +112,12 @@ static void menu_back_no_reset(void) } } -void menu_back_no_feedback(void) +void menu_back_scroll(int scrollback) { if (menu_depth > 0) { - menu_depth--; - menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position, false, true); + menu_depth--; + menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + scrollback, false, true); } } diff --git a/Firmware/menu.h b/Firmware/menu.h index 88d962949..b354bb97f 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -78,7 +78,7 @@ extern void menu_end(void); extern void menu_back(void); extern void menu_back(uint8_t nLevel); -extern void menu_back_no_feedback(void); +extern void menu_back_scroll(int scrollback); extern void menu_back_if_clicked(void); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a0323841f..dfc0da43f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -326,25 +326,30 @@ static void lcd_filename_scroll() //this is a submenu if (_md->status == 0) { _md->status = 1; - _md->encoderInitial = lcd_encoder_diff / ENCODER_PULSES_PER_STEP; + _md->encoderInitial = lcd_encoder; lcd_scrollTimer.start(); } - if (LCD_CLICKED || (_md->encoderInitial != (lcd_encoder_diff / ENCODER_PULSES_PER_STEP))) //go back to sd_menu. + if (LCD_CLICKED || (_md->encoderInitial != lcd_encoder)) //go back to sd_menu. { - lcd_scrollTimer.stop(); + lcd_scrollTimer.start(); // menu_depth--; // menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + lcd_encoder_diff / ENCODER_PULSES_PER_STEP, false, true); - menu_back_no_feedback(); + menu_back_scroll(lcd_encoder - _md->encoderInitial); } - if(lcd_scrollTimer.expired(300)) + if(lcd_scrollTimer.expired(200) && (scrollPointer != NULL)) { uint8_t i = LCD_WIDTH - 1; - lcd_set_cursor(0, lcd_encoder); + lcd_set_cursor(0, _md->encoderInitial = lcd_encoder); lcd_print('>'); for (; i != 0; i--) { - char c = *(scrollPointer + LCD_WIDTH - i); - if (c == '\0') break; //stop at the end of the string + char c = *(scrollPointer + ((LCD_WIDTH - 1) - i)); + if (c == '\0') + { + scrollPointer = NULL; //invalidate string + lcd_scrollTimer.stop(); + break; //stop at the end of the string + } else { lcd_print(c); @@ -424,7 +429,9 @@ static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFile char c; uint8_t n = LCD_WIDTH - 1; lcd_set_cursor(0, row); - lcd_print((lcd_encoder == menu_item)?'>':' '); + if (lcd_encoder == menu_item) lcd_print('>'); + else lcd_print(' '); + // lcd_print((lcd_encoder == menu_item)?'>':' '); while( ((c = *longFilename) != '\0') && (n>0) ) { lcd_print(c); @@ -540,12 +547,14 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update) + if (lcd_draw_update || !lcd_scrollTimer.running()) { scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; - if (lcd_encoder == menu_item) + if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { - if (lcd_scrollTimer.expired(1000)) menu_submenu_scroll(lcd_filename_scroll); + // lcd_beeper_quick_feedback(); + menu_submenu_scroll(lcd_filename_scroll); + return 1; } else lcd_implementation_drawmenu_sdfile(menu_row, scrollPointer); } @@ -7272,12 +7281,17 @@ void lcd_sdcard_menu() presort_flag = false; card.presort(); } - if (lcd_draw_update == 0 && LCD_CLICKED == 0) - //_delay(100); + if (!lcd_scrollTimer.running()) lcd_scrollTimer.start(); + bool scrollEnter = lcd_scrollTimer.expired(500); + if (lcd_draw_update == 0 && LCD_CLICKED == 0 && !scrollEnter && !menu_entering) return; // nothing to do (so don't thrash the SD card) uint16_t fileCnt = card.getnrfilenames(); - - lcd_scrollTimer.start(); + if (menu_entering) + { + menu_entering = 0; //clear entering flag + lcd_draw_update = 1; //draw lines again + } + if (!scrollEnter) lcd_scrollTimer.start(); MENU_BEGIN(); MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion card.getWorkDirName(); From 8a806bceea6e0514cb52a33803ee607f29337f33 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 21 Nov 2019 21:32:52 +0200 Subject: [PATCH 04/58] SDDIR --- Firmware/menu.cpp | 2 +- Firmware/ultralcd.cpp | 178 +++++++++--------------------------------- 2 files changed, 36 insertions(+), 144 deletions(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index bfb018e81..16ba86ea7 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -162,7 +162,7 @@ void menu_submenu_scroll(menu_func_t submenu) { menu_stack[menu_depth].menu = menu_menu; menu_stack[menu_depth++].position = lcd_encoder; - menu_goto(submenu, menu_row, false, true); + menu_goto(submenu, 0, false, false); } } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index dfc0da43f..ab7e38302 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -313,33 +313,32 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; +typedef struct +{ + int8_t status; + bool isDir = 0; + uint8_t row = 0; +} _menu_data_scroll_t; +static_assert(sizeof(menu_data)>= sizeof(_menu_data_scroll_t),"_menu_data_scroll_t doesn't fit into menu_data"); + static void lcd_filename_scroll() //this is a submenu { - typedef struct - { - int8_t status; - int encoderInitial; - } _menu_data_t; - static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); - _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); + _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); if (_md->status == 0) { _md->status = 1; - _md->encoderInitial = lcd_encoder; lcd_scrollTimer.start(); } - if (LCD_CLICKED || (_md->encoderInitial != lcd_encoder)) //go back to sd_menu. + if (LCD_CLICKED || (lcd_encoder != 0)) //go back to sd_menu. { lcd_scrollTimer.start(); - // menu_depth--; - // menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + lcd_encoder_diff / ENCODER_PULSES_PER_STEP, false, true); - menu_back_scroll(lcd_encoder - _md->encoderInitial); + menu_back_scroll(lcd_encoder); } if(lcd_scrollTimer.expired(200) && (scrollPointer != NULL)) { uint8_t i = LCD_WIDTH - 1; - lcd_set_cursor(0, _md->encoderInitial = lcd_encoder); + lcd_set_cursor(0, _md->row); lcd_print('>'); for (; i != 0; i--) { @@ -363,75 +362,12 @@ static void lcd_filename_scroll() //this is a submenu scrollPointer++; } } - -/* -static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename) -{ - char c; - int enc_dif = lcd_encoder_diff / ENCODER_PULSES_PER_STEP; - uint8_t n = LCD_WIDTH - 1; - - for(uint_least8_t g = 0; g<4;g++){ - lcd_set_cursor(0, g); - lcd_print(' '); - } - lcd_set_cursor(0, row); - lcd_print('>'); - - if (longFilename[0] == '\0') - { - longFilename = filename; - } - - int i = 1; - int j = 0; - char* longFilenameTMP = longFilename; - - while((c = *longFilenameTMP) != '\0') - { - lcd_set_cursor(i, row); - lcd_print(c); - i++; - longFilenameTMP++; - if(i==LCD_WIDTH){ - i=1; - j++; - longFilenameTMP = longFilename + j; - n = LCD_WIDTH - 1; - for(int g = 0; g<300 ;g++){ - manage_heater(); - if(LCD_CLICKED || ( enc_dif != (lcd_encoder_diff / ENCODER_PULSES_PER_STEP))){ - longFilenameTMP = longFilename; - *(longFilenameTMP + LCD_WIDTH - 2) = '\0'; - i = 1; - j = 0; - break; - }else{ - if (j == 1) _delay_ms(3); //wait around 1.2 s to start scrolling text - _delay_ms(1); //then scroll with redrawing every 300 ms - } - - } - } - } - if(c!='\0'){ - lcd_set_cursor(i, row); - lcd_print(c); - i++; - } - n=n-i+1; - while(n--) - lcd_print(' '); -} -*/ static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename) { char c; uint8_t n = LCD_WIDTH - 1; lcd_set_cursor(0, row); - if (lcd_encoder == menu_item) lcd_print('>'); - else lcd_print(' '); - // lcd_print((lcd_encoder == menu_item)?'>':' '); + lcd_print((lcd_encoder == menu_item)?'>':' '); while( ((c = *longFilename) != '\0') && (n>0) ) { lcd_print(c); @@ -441,43 +377,17 @@ static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFile while(n--) lcd_print(' '); } -static void lcd_implementation_drawmenu_sddirectory_selected(uint8_t row, const char* filename, char* longFilename) +static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* longFilename) { char c; uint8_t n = LCD_WIDTH - 2; lcd_set_cursor(0, row); - lcd_print('>'); - lcd_print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) + lcd_print((lcd_encoder == menu_item)?'>':' '); + lcd_print(LCD_STR_FOLDER[0]); + while( ((c = *longFilename) != '\0') && (n>0) ) { lcd_print(c); - filename++; - n--; - } - while(n--) - lcd_print(' '); -} -static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* filename, char* longFilename) -{ - char c; - uint8_t n = LCD_WIDTH - 2; - lcd_set_cursor(0, row); - lcd_print(' '); - lcd_print(LCD_STR_FOLDER[0]); - if (longFilename[0] != '\0') - { - filename = longFilename; - longFilename[LCD_WIDTH-2] = '\0'; - } - while( ((c = *filename) != '\0') && (n>0) ) - { - lcd_print(c); - filename++; + longFilename++; n--; } while(n--) @@ -487,46 +397,26 @@ static void lcd_implementation_drawmenu_sddirectory(uint8_t row, const char* fil #define MENU_ITEM_SDDIR(str_fn, str_fnl) do { if (menu_item_sddir(str_fn, str_fnl)) return; } while (0) -//#define MENU_ITEM_SDDIR(str, str_fn, str_fnl) MENU_ITEM(sddirectory, str, str_fn, str_fnl) -//extern uint8_t menu_item_sddir(const char* str, const char* str_fn, char* str_fnl); - #define MENU_ITEM_SDFILE(str_fn, str_fnl) do { if (menu_item_sdfile(str_fn, str_fnl)) return; } while (0) uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) { -#ifdef NEW_SD_MENU -// str_fnl[18] = 0; -// printf_P(PSTR("menu dir %d '%s' '%s'\n"), menu_row, str_fn, str_fnl); if (menu_item == menu_line) { - if (lcd_draw_update) + if (lcd_draw_update || !lcd_scrollTimer.running()) { - lcd_set_cursor(0, menu_row); - int cnt = lcd_printf_P(PSTR("%c%c%-18s"), (lcd_encoder == menu_item)?'>':' ', LCD_STR_FOLDER[0], str_fnl[0]?str_fnl:str_fn); -// int cnt = lcd_printf_P(PSTR("%c%c%-18s"), (lcd_encoder == menu_item)?'>':' ', LCD_STR_FOLDER[0], str_fn); - } - if (menu_clicked && (lcd_encoder == menu_item)) - { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); - strcpy(dir_names[depth], str_fn); -// printf_P(PSTR("%s\n"), dir_names[depth]); - card.chdir(str_fn); - lcd_encoder = 0; - return menu_item_ret(); - } - } - menu_item++; - return 0; -#else //NEW_SD_MENU - if (menu_item == menu_line) - { - if (lcd_draw_update) - { - if (lcd_encoder == menu_item) - lcd_implementation_drawmenu_sddirectory_selected(menu_row, str_fn, str_fnl); - else - lcd_implementation_drawmenu_sddirectory(menu_row, str_fn, str_fnl); + scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; + if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) + { + // lcd_beeper_quick_feedback(); + _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); + _md->isDir = 1; + _md->row = menu_row; + menu_submenu_scroll(lcd_filename_scroll); + return 1; + } + else lcd_implementation_drawmenu_sddirectory(menu_row, scrollPointer); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -534,13 +424,12 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) lcd_update_enabled = 0; menu_action_sddirectory(str_fn); lcd_update_enabled = 1; - return menu_item_ret(); + // return menu_item_ret(); + return 1; } } menu_item++; return 0; - -#endif //NEW_SD_MENU } static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) @@ -553,6 +442,9 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { // lcd_beeper_quick_feedback(); + _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); + _md->isDir = 0; + _md->row = menu_row; menu_submenu_scroll(lcd_filename_scroll); return 1; } From fdab70fa3a2627173f9e60159db3c86d12e01a9b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 22 Nov 2019 14:39:21 +0200 Subject: [PATCH 05/58] Dir fixes --- Firmware/cardreader.cpp | 1 + Firmware/ultralcd.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 3c01bf84b..7d64286e5 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -960,6 +960,7 @@ void CardReader::presort() { lcd_set_degree(); lcd_clear(); #endif + lcd_scrollTimer.start(); lcd_update(2); KEEPALIVE_STATE(NOT_BUSY); lcd_timeoutToStatus.start(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ab7e38302..c4bbb94cc 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -337,12 +337,13 @@ static void lcd_filename_scroll() //this is a submenu } if(lcd_scrollTimer.expired(200) && (scrollPointer != NULL)) { - uint8_t i = LCD_WIDTH - 1; + uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); lcd_set_cursor(0, _md->row); lcd_print('>'); + if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); for (; i != 0; i--) { - char c = *(scrollPointer + ((LCD_WIDTH - 1) - i)); + char c = *(scrollPointer + ((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); if (c == '\0') { scrollPointer = NULL; //invalidate string @@ -414,7 +415,7 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) _md->isDir = 1; _md->row = menu_row; menu_submenu_scroll(lcd_filename_scroll); - return 1; + return 1; //stop menu generation early } else lcd_implementation_drawmenu_sddirectory(menu_row, scrollPointer); } @@ -424,7 +425,7 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) lcd_update_enabled = 0; menu_action_sddirectory(str_fn); lcd_update_enabled = 1; - // return menu_item_ret(); + /* return */ menu_item_ret(); return 1; } } @@ -454,7 +455,7 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { lcd_consume_click(); menu_action_sdfile(str_fn); - // return menu_item_ret(); + /* return */ menu_item_ret(); return 1; } } From 2fd192a95d853d8371876a425271b330b734aaa2 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 22 Nov 2019 20:14:55 +0200 Subject: [PATCH 06/58] Set scroll delay to 300ms --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index c4bbb94cc..f51765499 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -335,7 +335,7 @@ static void lcd_filename_scroll() //this is a submenu lcd_scrollTimer.start(); menu_back_scroll(lcd_encoder); } - if(lcd_scrollTimer.expired(200) && (scrollPointer != NULL)) + if(lcd_scrollTimer.expired(300) && (scrollPointer != NULL)) { uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); lcd_set_cursor(0, _md->row); From 273d834b19d3927e7008aec4b47d71d0a8c05b47 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 22 Nov 2019 20:27:24 +0200 Subject: [PATCH 07/58] Fix card removal --- Firmware/ultralcd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f51765499..a4ce454ff 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8759,6 +8759,8 @@ void menu_lcd_lcdupdate_func(void) { if(menu_menu==lcd_sdcard_menu) menu_back(); + else if (menu_menu==lcd_filename_scroll) + menu_back(2); //back 2 levels. Exit lcd_filename_scroll and lcd sd_card_menu card.release(); LCD_MESSAGERPGM(_i("Card removed"));////MSG_SD_REMOVED } From d40656e3ca683f00d1e2286fd21c192b049dd4e9 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sun, 24 Nov 2019 19:16:22 +0200 Subject: [PATCH 08/58] Small changes to rendering --- Firmware/menu.cpp | 2 +- Firmware/ultralcd.cpp | 39 ++++++++++++++++++--------------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 16ba86ea7..63b15bd53 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -54,8 +54,8 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo // Resets the global shared C union. // This ensures, that the menu entered will find out, that it shall initialize itself. memset(&menu_data, 0, sizeof(menu_data)); - menu_entering = 1; //next menu that supports entering will clear this flag on first enter. Used for initializing some menus only one time. } + menu_entering = 1; //next menu that supports entering will clear this flag on first enter. Used for initializing some menus only one time. if (feedback) lcd_quick_feedback(); } else diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a4ce454ff..6e118eba6 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -46,10 +46,6 @@ #include "first_lay_cal.h" -//filename scrolling -const char* scrollPointer; - - static void lcd_sd_updir(); static void lcd_mesh_bed_leveling_settings(); @@ -315,27 +311,24 @@ const char STR_SEPARATOR[] PROGMEM = "------------"; typedef struct { - int8_t status; + uint8_t offset = 0; bool isDir = 0; uint8_t row = 0; + const char* scrollPointer; } _menu_data_scroll_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_scroll_t),"_menu_data_scroll_t doesn't fit into menu_data"); static void lcd_filename_scroll() //this is a submenu { _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - - if (_md->status == 0) + if (menu_entering) { - _md->status = 1; + menu_entering = 0; //clear entering flag lcd_scrollTimer.start(); } - if (LCD_CLICKED || (lcd_encoder != 0)) //go back to sd_menu. - { - lcd_scrollTimer.start(); - menu_back_scroll(lcd_encoder); - } - if(lcd_scrollTimer.expired(300) && (scrollPointer != NULL)) + bool rewindFlag = LCD_CLICKED || (lcd_encoder != 0); //go back to sd_menu. + if (rewindFlag == 1) _md->offset = 0; + if (lcd_scrollTimer.expired(300) || rewindFlag) { uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); lcd_set_cursor(0, _md->row); @@ -343,10 +336,9 @@ static void lcd_filename_scroll() //this is a submenu if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); for (; i != 0; i--) { - char c = *(scrollPointer + ((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); + char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); if (c == '\0') { - scrollPointer = NULL; //invalidate string lcd_scrollTimer.stop(); break; //stop at the end of the string } @@ -360,7 +352,12 @@ static void lcd_filename_scroll() //this is a submenu { lcd_space(i); } - scrollPointer++; + _md->offset++; + } + if (rewindFlag) //go back to sd_menu. + { + lcd_scrollTimer.start(); + menu_back_scroll(lcd_encoder); } } static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename) @@ -407,17 +404,17 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) { if (lcd_draw_update || !lcd_scrollTimer.running()) { - scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { // lcd_beeper_quick_feedback(); _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); _md->isDir = 1; _md->row = menu_row; + _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; menu_submenu_scroll(lcd_filename_scroll); return 1; //stop menu generation early } - else lcd_implementation_drawmenu_sddirectory(menu_row, scrollPointer); + else lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -439,17 +436,17 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { if (lcd_draw_update || !lcd_scrollTimer.running()) { - scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { // lcd_beeper_quick_feedback(); _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); _md->isDir = 0; _md->row = menu_row; + _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; menu_submenu_scroll(lcd_filename_scroll); return 1; } - else lcd_implementation_drawmenu_sdfile(menu_row, scrollPointer); + else lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { From b803b2a2ddb8df531ab84e6dfed393604b7360a0 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 11:29:57 +0200 Subject: [PATCH 09/58] Another first implementation --- Firmware/Configuration_adv.h | 1 + Firmware/cardreader.cpp | 55 +++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index dd77c91c6..3e7e74a17 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -236,6 +236,7 @@ #define SD_SORT_TIME 0 #define SD_SORT_ALPHA 1 #define SD_SORT_NONE 2 + #define SHELLSORT #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 3c01bf84b..026f5ca0d 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -830,7 +830,55 @@ void CardReader::presort() { #ifdef QUICKSORT quicksort(0, fileCnt - 1); -#else //Qicksort not defined, use Bubble Sort +#elif defined(SHELLSORT) + +#define _SORT_CMP_NODIR() (strcasecmp(name2, name1) > 0) +#define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp < modificationTime)) || (modification_date_bckp < modificationDate)) +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) +#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) + + for (int16_t gap = fileCnt/2; gap > 0; gap /= 2) + { + for (int16_t i = gap; i < fileCnt; i++) + { + if (!IS_SD_INSERTED) return; + manage_heater(); + uint8_t orderBckp = sort_order[i]; + getfilename_simple(positions[orderBckp]); + strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) + modification_date_bckp = modificationDate; + modification_time_bckp = modificationTime; + #if HAS_FOLDER_SORTING + bool dir1 = filenameIsDir; + #endif + + int16_t j = i; + getfilename_simple(positions[sort_order[j - gap]]); + char *name2 = LONGEST_FILENAME; // use the string in-place + #if HAS_FOLDER_SORTING + for (; j >= gap && ((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING)));) + #else + for (; j >= gap && ((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR()));) + #endif + { + sort_order[j] = sort_order[j - gap]; + j -= gap; + for (uint16_t z = 0; z < fileCnt; z++) + { + printf_P(PSTR("%2u "), sort_order[z]); + } + printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d"), i, j, gap, orderBckp); + MYSERIAL.println(); + if (j < gap) break; + getfilename_simple(positions[sort_order[j - gap]]); + name2 = LONGEST_FILENAME; // use the string in-place + } + sort_order[j] = orderBckp; + } + } + + +#else //Bubble Sort uint32_t counter = 0; uint16_t total = 0.5*(fileCnt - 1)*(fileCnt); @@ -884,6 +932,11 @@ void CardReader::presort() { //MYSERIAL.println(int(i)); for (uint16_t j = 0; j < i; ++j) { if (!IS_SD_INSERTED) return; + for (uint16_t z = 0; z < fileCnt; z++) + { + printf_P(PSTR("%2u "), sort_order[z]); + } + MYSERIAL.println(); manage_heater(); const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; From f87b5a2be7dbe3cbe87975fab48fdb30e2856c73 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 12:18:11 +0200 Subject: [PATCH 10/58] SORTING_DUMP --- Firmware/cardreader.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 026f5ca0d..0c780cd90 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -863,12 +863,13 @@ void CardReader::presort() { { sort_order[j] = sort_order[j - gap]; j -= gap; + #ifdef SORTING_DUMP for (uint16_t z = 0; z < fileCnt; z++) { printf_P(PSTR("%2u "), sort_order[z]); } - printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d"), i, j, gap, orderBckp); - MYSERIAL.println(); + printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp); + #endif if (j < gap) break; getfilename_simple(positions[sort_order[j - gap]]); name2 = LONGEST_FILENAME; // use the string in-place @@ -932,11 +933,13 @@ void CardReader::presort() { //MYSERIAL.println(int(i)); for (uint16_t j = 0; j < i; ++j) { if (!IS_SD_INSERTED) return; - for (uint16_t z = 0; z < fileCnt; z++) - { - printf_P(PSTR("%2u "), sort_order[z]); - } - MYSERIAL.println(); + #ifdef SORTING_DUMP + for (uint16_t z = 0; z < fileCnt; z++) + { + printf_P(PSTR("%2u "), sort_order[z]); + } + MYSERIAL.println(); + #endif manage_heater(); const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; From 960f4a88edc59a7c8f4de1b90b9ef71063f63c0a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 13:36:05 +0200 Subject: [PATCH 11/58] Status bar, lcd optimization, compile warning fix --- Firmware/cardreader.cpp | 30 ++++++++++++++++++++---------- Firmware/lcd.cpp | 15 --------------- Firmware/lcd.h | 1 - Firmware/ultralcd.cpp | 11 +---------- Firmware/ultralcd.h | 3 --- 5 files changed, 21 insertions(+), 39 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 0c780cd90..d8d6f0638 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -741,9 +741,6 @@ void CardReader::presort() { fileCnt = SDSORT_LIMIT; } lcd_clear(); - #if !SDSORT_USES_RAM - lcd_set_progress(); - #endif lcd_puts_at_P(0, 1, _i("Sorting files"));////MSG_SORTING c=20 r=1 // Sort order is always needed. May be static or dynamic. @@ -837,11 +834,26 @@ void CardReader::presort() { #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) - for (int16_t gap = fileCnt/2; gap > 0; gap /= 2) + uint16_t counter = 0; + uint16_t total = 0; + for (uint16_t i = fileCnt/2; i > 0; i /= 2) total += fileCnt - i; //total runs for progress bar + + for (uint16_t gap = fileCnt/2; gap > 0; gap /= 2) { - for (int16_t i = gap; i < fileCnt; i++) + for (uint16_t i = gap; i < fileCnt; i++) { if (!IS_SD_INSERTED) return; + + int8_t percent = (counter * 100) / total; + for (int column = 0; column < 20; column++) { + if (column < (percent / 5)) + { + lcd_set_cursor(column, 2); + lcd_print('\xFF'); //simple progress bar + } + } + counter++; + manage_heater(); uint8_t orderBckp = sort_order[i]; getfilename_simple(positions[orderBckp]); @@ -852,7 +864,7 @@ void CardReader::presort() { bool dir1 = filenameIsDir; #endif - int16_t j = i; + uint16_t j = i; getfilename_simple(positions[sort_order[j - gap]]); char *name2 = LONGEST_FILENAME; // use the string in-place #if HAS_FOLDER_SORTING @@ -878,7 +890,6 @@ void CardReader::presort() { } } - #else //Bubble Sort uint32_t counter = 0; uint16_t total = 0.5*(fileCnt - 1)*(fileCnt); @@ -924,7 +935,7 @@ void CardReader::presort() { if (column < (percent / 5)) { lcd_set_cursor(column, 2); - lcd_print('\x01'); //simple progress bar + lcd_print('\xFF'); //simple progress bar } } counter++; @@ -1010,10 +1021,9 @@ void CardReader::presort() { for (int column = 0; column <= 19; column++) { lcd_set_cursor(column, 2); - lcd_print('\x01'); //simple progress bar + lcd_print('\xFF'); //simple progress bar } _delay(300); - lcd_set_degree(); lcd_clear(); #endif lcd_update(2); diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 3e39312c1..ecb25c2a8 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -957,21 +957,6 @@ void lcd_set_custom_characters_arrows(void) lcd_createChar_P(1, lcd_chardata_arrdown); } -const uint8_t lcd_chardata_progress[8] PROGMEM = { - B11111, - B11111, - B11111, - B11111, - B11111, - B11111, - B11111, - B11111}; - -void lcd_set_custom_characters_progress(void) -{ - lcd_createChar_P(1, lcd_chardata_progress); -} - const uint8_t lcd_chardata_arr2down[8] PROGMEM = { B00000, B00000, diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 790c0a955..cd180a441 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -201,7 +201,6 @@ private: extern void lcd_set_custom_characters(void); extern void lcd_set_custom_characters_arrows(void); -extern void lcd_set_custom_characters_progress(void); extern void lcd_set_custom_characters_nextpage(void); extern void lcd_set_custom_characters_degree(void); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2ed8d5de4..e8c268984 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4590,17 +4590,10 @@ static void lcd_fsensor_state_set() } #endif //FILAMENT_SENSOR - -#if !SDSORT_USES_RAM void lcd_set_degree() { lcd_set_custom_characters_degree(); } -void lcd_set_progress() { - lcd_set_custom_characters_progress(); -} -#endif - #if (LANG_MODE != 0) void menu_setlang(unsigned char lang) @@ -8665,7 +8658,6 @@ static void lcd_connect_printer() { int i = 0; int t = 0; - lcd_set_custom_characters_progress(); lcd_puts_at_P(0, 0, _i("Connect printer to")); lcd_puts_at_P(0, 1, _i("monitoring or hold")); lcd_puts_at_P(0, 2, _i("the knob to continue")); @@ -8682,12 +8674,11 @@ static void lcd_connect_printer() { i = 0; lcd_puts_at_P(0, 3, PSTR(" ")); } - if (i!=0) lcd_puts_at_P((i * 20) / (NC_BUTTON_LONG_PRESS * 10), 3, "\x01"); + if (i!=0) lcd_puts_at_P((i * 20) / (NC_BUTTON_LONG_PRESS * 10), 3, "\xFF"); if (i == NC_BUTTON_LONG_PRESS * 10) { no_response = false; } } - lcd_set_custom_characters_degree(); lcd_update_enable(true); lcd_update(2); } diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index cdddb9cfe..01f598aea 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -213,10 +213,7 @@ void lcd_temp_calibration_set(); void display_loading(); -#if !SDSORT_USES_RAM void lcd_set_degree(); -void lcd_set_progress(); -#endif void lcd_language(); From a7f2e640e0d15649445928971ad2eaf5db5b1893 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 13:57:08 +0200 Subject: [PATCH 12/58] Put folders at the beginning --- Firmware/cardreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index d8d6f0638..9f97c800e 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -831,8 +831,8 @@ void CardReader::presort() { #define _SORT_CMP_NODIR() (strcasecmp(name2, name1) > 0) #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp < modificationTime)) || (modification_date_bckp < modificationDate)) -#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) -#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? !dir1 : dir1)) +#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? !dir1 : dir1)) uint16_t counter = 0; uint16_t total = 0; From f5bdbcc0bd91679ec5964bac162c949b28a2c28f Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 14:10:44 +0200 Subject: [PATCH 13/58] Cleanup file compare statement --- Firmware/cardreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 9f97c800e..26e63b879 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -868,9 +868,9 @@ void CardReader::presort() { getfilename_simple(positions[sort_order[j - gap]]); char *name2 = LONGEST_FILENAME; // use the string in-place #if HAS_FOLDER_SORTING - for (; j >= gap && ((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING)));) + for (; j >= gap && ((sdSort == SD_SORT_TIME)?(_SORT_CMP_TIME_DIR(FOLDER_SORTING)):(_SORT_CMP_DIR(FOLDER_SORTING)));) #else - for (; j >= gap && ((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR()));) + for (; j >= gap && ((sdSort == SD_SORT_TIME)?(_SORT_CMP_TIME_NODIR()):(_SORT_CMP_NODIR()));) #endif { sort_order[j] = sort_order[j - gap]; From 66e51aa29831c17b4986d294adc362f1c948b6d0 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 26 Nov 2019 15:49:45 +0200 Subject: [PATCH 14/58] Folder sorting finished --- Firmware/cardreader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 26e63b879..1bbfca023 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -831,8 +831,10 @@ void CardReader::presort() { #define _SORT_CMP_NODIR() (strcasecmp(name2, name1) > 0) #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp < modificationTime)) || (modification_date_bckp < modificationDate)) -#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? !dir1 : dir1)) -#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? !dir1 : dir1)) +#if HAS_FOLDER_SORTING +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? filenameIsDir : !filenameIsDir)) +#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? filenameIsDir : !filenameIsDir)) +#endif uint16_t counter = 0; uint16_t total = 0; From 11ba616d7363747eaaba350793fe484d48439228 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 Nov 2019 11:03:34 +0200 Subject: [PATCH 15/58] Define for dumping sorting process --- Firmware/Configuration_adv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 3e7e74a17..d2a7221c5 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -237,6 +237,7 @@ #define SD_SORT_ALPHA 1 #define SD_SORT_NONE 2 #define SHELLSORT + // #define SORTING_DUMP #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below From 7753750fa76482a775d838ceed9a242c1dde260b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 Nov 2019 17:31:47 +0200 Subject: [PATCH 16/58] Change for to while --- Firmware/cardreader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 1bbfca023..d925f2cb3 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -870,9 +870,9 @@ void CardReader::presort() { getfilename_simple(positions[sort_order[j - gap]]); char *name2 = LONGEST_FILENAME; // use the string in-place #if HAS_FOLDER_SORTING - for (; j >= gap && ((sdSort == SD_SORT_TIME)?(_SORT_CMP_TIME_DIR(FOLDER_SORTING)):(_SORT_CMP_DIR(FOLDER_SORTING)));) + while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING))) #else - for (; j >= gap && ((sdSort == SD_SORT_TIME)?(_SORT_CMP_TIME_NODIR()):(_SORT_CMP_NODIR()));) + while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_NODIR():_SORT_CMP_NODIR())) #endif { sort_order[j] = sort_order[j - gap]; From f0f7db57ea3f807e7ab410f9e173461ead898609 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 17 Dec 2019 00:44:47 +0200 Subject: [PATCH 17/58] Fist attempt at "saved position SD menu" --- Firmware/cardreader.cpp | 144 ++++++---------------------------------- Firmware/cardreader.h | 35 +--------- Firmware/ultralcd.cpp | 31 +++------ Firmware/ultralcd.h | 2 + 4 files changed, 34 insertions(+), 178 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index dbe751a08..e78c083e3 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -416,6 +416,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru getfilename(0, fname); lcd_setstatus(longFilename[0] ? longFilename : fname); lcd_setstatus("SD-PRINTING "); + scrollstuff = 0; } else { @@ -689,12 +690,20 @@ void CardReader::updir() * Get the name of a file in the current directory by sort-index */ void CardReader::getfilename_sorted(const uint16_t nr) { - getfilename( - #if SDSORT_GCODE - sort_alpha && - #endif - (nr < sort_count) ? sort_order[nr] : nr - ); + if (nr < sort_count) + getfilename_simple( + #if SDSORT_GCODE + sort_alpha && + #endif + sort_positions[sort_order[nr]] + ); + else + getfilename( + #if SDSORT_GCODE + sort_alpha && + #endif + nr + ); } /** @@ -730,44 +739,10 @@ void CardReader::presort() { fileCnt = SDSORT_LIMIT; } lcd_clear(); - #if !SDSORT_USES_RAM - lcd_set_progress(); - #endif + lcd_set_progress(); lcd_puts_at_P(0, 1, _i("Sorting files"));////MSG_SORTING c=20 r=1 - // Sort order is always needed. May be static or dynamic. - #if SDSORT_DYNAMIC_RAM - sort_order = new uint8_t[fileCnt]; - #endif - - // Use RAM to store the entire directory during pre-sort. - // SDSORT_LIMIT should be set to prevent over-allocation. - #if SDSORT_USES_RAM - - // If using dynamic ram for names, allocate on the heap. - #if SDSORT_CACHE_NAMES - #if SDSORT_DYNAMIC_RAM - sortshort = new char*[fileCnt]; - sortnames = new char*[fileCnt]; - #endif - #elif SDSORT_USES_STACK - char sortnames[fileCnt][LONG_FILENAME_LENGTH]; - uint16_t modification_time[fileCnt]; - uint16_t modification_date[fileCnt]; - #endif - - // Folder sorting needs 1 bit per entry for flags. - #if HAS_FOLDER_SORTING - #if SDSORT_DYNAMIC_RAM - isDir = new uint8_t[(fileCnt + 7) >> 3]; - #elif SDSORT_USES_STACK - uint8_t isDir[(fileCnt + 7) >> 3]; - #endif - #endif - - #else // !SDSORT_USES_RAM - - uint32_t positions[fileCnt]; + // uint32_t positions[fileCnt]; // By default re-read the names from SD for every compare // retaining only two filenames at a time. This is very @@ -776,7 +751,6 @@ void CardReader::presort() { uint16_t modification_time_bckp; uint16_t modification_date_bckp; - #endif position = 0; if (fileCnt > 1) { // Init sort order. @@ -784,37 +758,8 @@ void CardReader::presort() { if (!IS_SD_INSERTED) return; manage_heater(); sort_order[i] = i; - positions[i] = position; + sort_positions[i] = position; getfilename(i); - // If using RAM then read all filenames now. - #if SDSORT_USES_RAM - getfilename(i); - #if SDSORT_DYNAMIC_RAM - // Use dynamic method to copy long filename - sortnames[i] = strdup(LONGEST_FILENAME); - #if SDSORT_CACHE_NAMES - // When caching also store the short name, since - // we're replacing the getfilename() behavior. - sortshort[i] = strdup(filename); - #endif - #else - // Copy filenames into the static array - strcpy(sortnames[i], LONGEST_FILENAME); - modification_time[i] = modificationTime; - modification_date[i] = modificationDate; - #if SDSORT_CACHE_NAMES - strcpy(sortshort[i], filename); - #endif - #endif - // char out[30]; - // sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]); - // SERIAL_ECHOLN(out); - #if HAS_FOLDER_SORTING - const uint16_t bit = i & 0x07, ind = i >> 3; - if (bit == 0) isDir[ind] = 0x00; - if (filenameIsDir) isDir[ind] |= _BV(bit); - #endif - #endif } #ifdef QUICKSORT @@ -824,41 +769,18 @@ void CardReader::presort() { uint16_t total = 0.5*(fileCnt - 1)*(fileCnt); // Compare names from the array or just the two buffered names - #if SDSORT_USES_RAM - #define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0) - #define _SORT_CMP_TIME_NODIR() (((modification_date[o1] == modification_date[o2]) && (modification_time[o1] < modification_time[o2])) || \ - (modification_date[o1] < modification_date [o2])) - #else #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2) - #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp > modificationTime)) || \ - (modification_date_bckp > modificationDate)) - - #endif + #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp > modificationTime)) || (modification_date_bckp > modificationDate)) #if HAS_FOLDER_SORTING - #if SDSORT_USES_RAM - // Folder sorting needs an index and bit to test for folder-ness. - const uint8_t ind1 = o1 >> 3, bit1 = o1 & 0x07, - ind2 = o2 >> 3, bit2 = o2 & 0x07; - #define _SORT_CMP_DIR(fs) \ - (((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \ - ? _SORT_CMP_NODIR() \ - : (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0) - #define _SORT_CMP_TIME_DIR(fs) \ - (((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \ - ? _SORT_CMP_TIME_NODIR() \ - : (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0) - #else #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) #endif - #endif for (uint16_t i = fileCnt; --i;) { if (!IS_SD_INSERTED) return; bool didSwap = false; - #if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used int8_t percent = (counter * 100) / total;//((counter * 100) / pow((fileCnt-1),2)); for (int column = 0; column < 20; column++) { if (column < (percent / 5)) @@ -868,7 +790,6 @@ void CardReader::presort() { } } counter++; - #endif //MYSERIAL.println(int(i)); for (uint16_t j = 0; j < i; ++j) { @@ -880,14 +801,14 @@ void CardReader::presort() { // throughout the loop. Slow if there are many. #if !SDSORT_USES_RAM counter++; - getfilename_simple(positions[o1]); + getfilename_simple(sort_positions[o1]); strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) modification_date_bckp = modificationDate; modification_time_bckp = modificationTime; #if HAS_FOLDER_SORTING bool dir1 = filenameIsDir; #endif - getfilename_simple(positions[o2]); + getfilename_simple(sort_positions[o2]); char *name2 = LONGEST_FILENAME; // use the string in-place #endif // !SDSORT_USES_RAM @@ -909,32 +830,9 @@ void CardReader::presort() { if (!didSwap) break; } //end of bubble sort loop #endif - // Using RAM but not keeping names around - #if (SDSORT_USES_RAM && !SDSORT_CACHE_NAMES) - #if SDSORT_DYNAMIC_RAM - for (uint16_t i = 0; i < fileCnt; ++i) free(sortnames[i]); - #if HAS_FOLDER_SORTING - free(isDir); - #endif - #endif - #endif } else { sort_order[0] = 0; - #if (SDSORT_USES_RAM && SDSORT_CACHE_NAMES) - getfilename(0); - #if SDSORT_DYNAMIC_RAM - sortnames = new char*[1]; - sortnames[0] = strdup(LONGEST_FILENAME); // malloc - sortshort = new char*[1]; - sortshort[0] = strdup(filename); // malloc - isDir = new uint8_t[1]; - #else - strcpy(sortnames[0], LONGEST_FILENAME); - strcpy(sortshort[0], filename); - #endif - isDir[0] = filenameIsDir ? 0x01 : 0x00; - #endif } sort_count = fileCnt; diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9a7d0f697..c51829043 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -93,39 +93,8 @@ private: //bool sort_reverse; // Flag to enable / disable reverse sorting #endif - // By default the sort index is static - #if SDSORT_DYNAMIC_RAM - uint8_t *sort_order; - #else - uint8_t sort_order[SDSORT_LIMIT]; - #endif - // Cache filenames to speed up SD menus. - #if SDSORT_USES_RAM - - // If using dynamic ram for names, allocate on the heap. - #if SDSORT_CACHE_NAMES - #if SDSORT_DYNAMIC_RAM - char **sortshort, **sortnames; - #else - char sortshort[SDSORT_LIMIT][FILENAME_LENGTH]; - char sortnames[SDSORT_LIMIT][FILENAME_LENGTH]; - #endif - #elif !SDSORT_USES_STACK - char sortnames[SDSORT_LIMIT][FILENAME_LENGTH]; - uint16_t modification_time[SDSORT_LIMIT]; - uint16_t modification_date[SDSORT_LIMIT]; - #endif - - // Folder sorting uses an isDir array when caching items. - #if HAS_FOLDER_SORTING - #if SDSORT_DYNAMIC_RAM - uint8_t *isDir; - #elif (SDSORT_CACHE_NAMES) || !(SDSORT_USES_STACK) - uint8_t isDir[(SDSORT_LIMIT + 7) >> 3]; - #endif - #endif - - #endif // SDSORT_USES_RAM + uint8_t sort_order[SDSORT_LIMIT]; // By default the sort index is static. + uint32_t sort_positions[SDSORT_LIMIT]; #endif // SDCARD_SORT_ALPHA diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 1d7dd6d51..9df980222 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -57,7 +57,7 @@ static void lcd_mesh_bed_leveling_settings(); static void lcd_backlight_menu(); int8_t ReInitLCD = 0; - +uint8_t scrollstuff = 0; int8_t SilentModeMenu = SILENT_MODE_OFF; uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode @@ -325,6 +325,7 @@ typedef struct bool isDir = 0; uint8_t row = 0; const char* scrollPointer; + uint16_t fileCnt; } _menu_data_scroll_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_scroll_t),"_menu_data_scroll_t doesn't fit into menu_data"); @@ -634,16 +635,6 @@ void lcdui_print_time(void) //Print status line on status screen void lcdui_print_status_line(void) { -/* if (IS_SD_PRINTING) - { - if (strcmp(longFilenameOLD, (card.longFilename[0] ? card.longFilename : card.filename)) != 0) - { - memset(longFilenameOLD, '\0', strlen(longFilenameOLD)); - sprintf_P(longFilenameOLD, PSTR("%s"), (card.longFilename[0] ? card.longFilename : card.filename)); - scrollstuff = 0; - } - } */ - if (heating_status) { // If heating flag, show progress of heating heating_status_counter++; @@ -687,7 +678,8 @@ void lcdui_print_status_line(void) } else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status)) { // If printing from SD, show what we are printing - /* if(strlen(longFilenameOLD) > LCD_WIDTH) + const char* longFilenameOLD = (card.longFilename[0] ? card.longFilename : card.filename); + if(strlen(longFilenameOLD) > LCD_WIDTH) { int inters = 0; int gh = scrollstuff; @@ -713,7 +705,7 @@ void lcdui_print_status_line(void) else { lcd_printf_P(PSTR("%-20s"), longFilenameOLD); - } */ + } } else { // Otherwise check for other special events @@ -7292,11 +7284,12 @@ void lcd_sdcard_menu() bool scrollEnter = lcd_scrollTimer.expired(500); if (lcd_draw_update == 0 && LCD_CLICKED == 0 && !scrollEnter && !menu_entering) return; // nothing to do (so don't thrash the SD card) - uint16_t fileCnt = card.getnrfilenames(); + _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); if (menu_entering) { menu_entering = 0; //clear entering flag lcd_draw_update = 1; //draw lines again + _md->fileCnt = card.getnrfilenames(); } if (!scrollEnter) lcd_scrollTimer.start(); MENU_BEGIN(); @@ -7311,17 +7304,11 @@ void lcd_sdcard_menu() MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); } - for (uint16_t i = 0; i < fileCnt; i++) + for (uint16_t i = 0; i < _md->fileCnt; i++) { if (menu_item == menu_line) { - const uint16_t nr = ((sdSort == SD_SORT_NONE) || farm_mode || (sdSort == SD_SORT_TIME)) ? (fileCnt - 1 - i) : i; - /*#ifdef SDCARD_RATHERRECENTFIRST - #ifndef SDCARD_SORT_ALPHA - fileCnt - 1 - - #endif - #endif - i;*/ + const uint16_t nr = ((sdSort == SD_SORT_NONE) || farm_mode || (sdSort == SD_SORT_TIME)) ? (_md->fileCnt - 1 - i) : i; #ifdef SDCARD_SORT_ALPHA if (sdSort == SD_SORT_NONE) card.getfilename(nr); else card.getfilename_sorted(nr); diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 9e0c35b00..174491e1e 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -144,6 +144,8 @@ extern uint8_t SilentModeMenu_MMU; extern bool cancel_heatup; extern bool isPrintPaused; +extern uint8_t scrollstuff; + void lcd_ignore_click(bool b=true); void lcd_commands(); From e295c83d099d86a5fd2ebade6e8e923484259cdf Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 8 Jan 2020 21:16:08 +0200 Subject: [PATCH 18/58] Folder sorting shellSort --- Firmware/cardreader.cpp | 131 ++++++++++++++++++++++++---------------- Firmware/ultralcd.cpp | 2 +- 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index f8e3ba213..c94d4f118 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -749,8 +749,12 @@ void CardReader::presort() { char name1[LONG_FILENAME_LENGTH + 1]; uint16_t modification_time_bckp; uint16_t modification_date_bckp; + #if HAS_FOLDER_SORTING + uint16_t dirCnt = 0; + #endif position = 0; + //might need to also load the file at position 0 for filenameIsDir to work on the first file if (fileCnt > 1) { // Init sort order. for (uint16_t i = 0; i < fileCnt; i++) { @@ -759,72 +763,95 @@ void CardReader::presort() { sort_order[i] = i; sort_positions[i] = position; getfilename(i); + #if HAS_FOLDER_SORTING + if (filenameIsDir) dirCnt++; + #endif } #ifdef QUICKSORT quicksort(0, fileCnt - 1); #elif defined(SHELLSORT) -#define _SORT_CMP_NODIR() (strcasecmp(name2, name1) > 0) +#define _SORT_CMP_NODIR() (strcasecmp(name2, name1) < 0) #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp < modificationTime)) || (modification_date_bckp < modificationDate)) #if HAS_FOLDER_SORTING -#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? filenameIsDir : !filenameIsDir)) +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? filenameIsDir : !filenameIsDir)) #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? filenameIsDir : !filenameIsDir)) #endif - - uint16_t counter = 0; - uint16_t total = 0; - for (uint16_t i = fileCnt/2; i > 0; i /= 2) total += fileCnt - i; //total runs for progress bar - - for (uint16_t gap = fileCnt/2; gap > 0; gap /= 2) + for (uint8_t runs = 0; runs < 2; runs++) { - for (uint16_t i = gap; i < fileCnt; i++) + uint8_t* sortingBaseArray; + //run=0: sorts all files and moves folders to the beginning + //run=1: assumes all folders are at the beginning of the list and sorts them + uint16_t sortCountFiles = 0; + if (runs == 0) { - if (!IS_SD_INSERTED) return; - - int8_t percent = (counter * 100) / total; - for (int column = 0; column < 20; column++) { - if (column < (percent / 5)) - { - lcd_set_cursor(column, 2); - lcd_print('\xFF'); //simple progress bar - } - } - counter++; - - manage_heater(); - uint8_t orderBckp = sort_order[i]; - getfilename_simple(positions[orderBckp]); - strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) - modification_date_bckp = modificationDate; - modification_time_bckp = modificationTime; - #if HAS_FOLDER_SORTING - bool dir1 = filenameIsDir; - #endif - - uint16_t j = i; - getfilename_simple(positions[sort_order[j - gap]]); - char *name2 = LONGEST_FILENAME; // use the string in-place - #if HAS_FOLDER_SORTING - while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING))) - #else - while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_NODIR():_SORT_CMP_NODIR())) - #endif + sortingBaseArray = sort_order; + sortCountFiles = fileCnt; + } + #if HAS_FOLDER_SORTING + else + { + sortingBaseArray = sort_order + /* sizeof(sort_order[0]) * */ (fileCnt - dirCnt); + sortCountFiles = dirCnt; + } + #endif + if (sortCountFiles < 2) break; + + uint16_t counter = 0; + uint16_t total = 0; + for (uint16_t i = sortCountFiles/2; i > 0; i /= 2) total += sortCountFiles - i; //total runs for progress bar + + for (uint16_t gap = sortCountFiles/2; gap > 0; gap /= 2) + { + for (uint16_t i = gap; i < sortCountFiles; i++) { - sort_order[j] = sort_order[j - gap]; - j -= gap; - #ifdef SORTING_DUMP - for (uint16_t z = 0; z < fileCnt; z++) - { - printf_P(PSTR("%2u "), sort_order[z]); + if (!IS_SD_INSERTED) return; + + int8_t percent = (counter * 100) / total; + for (int column = 0; column < 20; column++) { + if (column < (percent / 5)) + { + lcd_set_cursor(column, 2); + lcd_print('\xFF'); //simple progress bar + } } - printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp); + counter++; + + manage_heater(); + uint8_t orderBckp = sortingBaseArray[i]; + getfilename_simple(sort_positions[orderBckp]); + strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) + modification_date_bckp = modificationDate; + modification_time_bckp = modificationTime; + #if HAS_FOLDER_SORTING + bool dir1 = filenameIsDir; #endif - if (j < gap) break; - getfilename_simple(positions[sort_order[j - gap]]); - name2 = LONGEST_FILENAME; // use the string in-place + + uint16_t j = i; + getfilename_simple(sort_positions[sortingBaseArray[j - gap]]); + char *name2 = LONGEST_FILENAME; // use the string in-place + #if HAS_FOLDER_SORTING + while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING))) + #else + while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_NODIR():_SORT_CMP_NODIR())) + #endif + { + sortingBaseArray[j] = sortingBaseArray[j - gap]; + j -= gap; + #ifdef SORTING_DUMP + for (uint16_t z = 0; z < sortCountFiles; z++) + { + printf_P(PSTR("%2u "), sortingBaseArray[z]); + } + printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp); + #endif + if (j < gap) break; + getfilename_simple(sort_positions[sortingBaseArray[j - gap]]); + name2 = LONGEST_FILENAME; // use the string in-place + } + sortingBaseArray[j] = orderBckp; } - sort_order[j] = orderBckp; } } @@ -833,11 +860,11 @@ void CardReader::presort() { uint16_t total = 0.5*(fileCnt - 1)*(fileCnt); // Compare names from the array or just the two buffered names - #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2) + #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) #define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp > modificationTime)) || (modification_date_bckp > modificationDate)) #if HAS_FOLDER_SORTING - #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1)) + #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? dir1 : !dir1)) #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) #endif diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index bdb0284da..715f5802c 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7300,7 +7300,7 @@ void lcd_sdcard_menu() { if (menu_item == menu_line) { - const uint16_t nr = ((sdSort == SD_SORT_NONE) || farm_mode || (sdSort == SD_SORT_TIME)) ? (_md->fileCnt - 1 - i) : i; + const uint16_t nr = _md->fileCnt - 1 - i; #ifdef SDCARD_SORT_ALPHA if (sdSort == SD_SORT_NONE) card.getfilename(nr); else card.getfilename_sorted(nr); From 29d0537004018c44caa7742d98a647be8ab9c69b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 8 Jan 2020 21:32:45 +0200 Subject: [PATCH 19/58] Adjusted progress bar --- Firmware/cardreader.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index c94d4f118..f508df7d1 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -809,12 +809,10 @@ void CardReader::presort() { if (!IS_SD_INSERTED) return; int8_t percent = (counter * 100) / total; + lcd_set_cursor(0, 2); for (int column = 0; column < 20; column++) { - if (column < (percent / 5)) - { - lcd_set_cursor(column, 2); - lcd_print('\xFF'); //simple progress bar - } + if (column < (percent / 5)) lcd_print('\xFF'); //simple progress bar + else lcd_print(' '); } counter++; @@ -873,12 +871,10 @@ void CardReader::presort() { bool didSwap = false; int8_t percent = (counter * 100) / total;//((counter * 100) / pow((fileCnt-1),2)); + lcd_set_cursor(0, 2); for (int column = 0; column < 20; column++) { - if (column < (percent / 5)) - { - lcd_set_cursor(column, 2); - lcd_print('\xFF'); //simple progress bar - } + if (column < (percent / 5)) lcd_print('\xFF'); //simple progress bar + else lcd_print(' '); } counter++; @@ -936,11 +932,8 @@ void CardReader::presort() { sort_count = fileCnt; } #if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used - for (int column = 0; column <= 19; column++) - { - lcd_set_cursor(column, 2); - lcd_print('\xFF'); //simple progress bar - } + lcd_set_cursor(0, 2); + for (int column = 0; column <= 19; column++) lcd_print('\xFF'); //simple progress bar _delay(300); lcd_clear(); #endif From f69a68b9661b8a4dca6dd6750206574918473528 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 3 Mar 2020 14:55:08 +0200 Subject: [PATCH 20/58] Fix subdir enter and exit --- Firmware/ultralcd.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 57245c907..ec7ced9ba 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7173,6 +7173,9 @@ static void lcd_sd_updir() { card.updir(); menu_top = 0; + lcd_encoder = 0; + lcd_scrollTimer.start(); + menu_entering = 1; } void lcd_print_stop() @@ -7279,6 +7282,8 @@ void lcd_sdcard_menu() if (presort_flag == true) { presort_flag = false; card.presort(); + lcd_scrollTimer.start(); + lcd_draw_update = 1; } if (!lcd_scrollTimer.running()) lcd_scrollTimer.start(); bool scrollEnter = lcd_scrollTimer.expired(500); @@ -8672,6 +8677,8 @@ void menu_action_sddirectory(const char* filename) MYSERIAL.println(dir_names[depth]); card.chdir(filename); lcd_encoder = 0; + lcd_scrollTimer.start(); + menu_entering = 1; } /** LCD API **/ From d1968f6ff0b324fbec4b7c0129054dba42ca25ca Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 3 Mar 2020 15:17:50 +0200 Subject: [PATCH 21/58] Option to refresh/resort SDcard files when flashAir type is selected --- Firmware/messages.c | 2 +- Firmware/ultralcd.cpp | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Firmware/messages.c b/Firmware/messages.c index 4e229ba76..485228412 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -65,7 +65,7 @@ const char MSG_PRESS_TO_UNLOAD[] PROGMEM_I1 = ISTR("Please press the knob to unl const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20 const char MSG_PULL_OUT_FILAMENT[] PROGMEM_I1 = ISTR("Please pull out filament immediately"); ////c=20 r=4 const char MSG_RECOVER_PRINT[] PROGMEM_I1 = ISTR("Blackout occurred. Recover print?"); ////c=20 r=2 -const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\xF8" "Refresh"); //// +const char MSG_REFRESH[] PROGMEM_I1 = ISTR("\x04" "Refresh"); //// const char MSG_RESUMING_PRINT[] PROGMEM_I1 = ISTR("Resuming print"); //// const char MSG_REMOVE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please remove steel sheet from heatbed."); ////c=20 r=4 const char MSG_SELFTEST_COOLING_FAN[] PROGMEM_I1 = ISTR("Front print fan?"); ////c=20 diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ec7ced9ba..33d786c14 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7162,13 +7162,20 @@ static void lcd_control_temperature_menu() } -#if SDCARDDETECT == -1 + static void lcd_sd_refresh() { +#if SDCARDDETECT == -1 card.initsd(); - menu_top = 0; -} +#else + card.presort(); #endif + menu_top = 0; + lcd_encoder = 0; + lcd_scrollTimer.start(); + menu_entering = 1; +} + static void lcd_sd_updir() { card.updir(); @@ -7304,6 +7311,8 @@ void lcd_sdcard_menu() { #if SDCARDDETECT == -1 MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); +#else + if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); #endif } else { MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); From 8e47cb35a3d2d5876b0861eddc9396e717594bda Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 3 Mar 2020 15:29:10 +0200 Subject: [PATCH 22/58] Possible fix to longpress in sdcard menu --- Firmware/ultralcd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 33d786c14..2ef0ee9b1 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8877,6 +8877,7 @@ void menu_lcd_longpress_func(void) || menu_menu == lcd_main_menu || menu_menu == lcd_preheat_menu || menu_menu == lcd_sdcard_menu + || menu_menu == lcd_filename_scroll || menu_menu == lcd_settings_menu || menu_menu == lcd_control_temperature_menu #if (LANG_MODE != 0) @@ -8884,6 +8885,7 @@ void menu_lcd_longpress_func(void) #endif || menu_menu == lcd_support_menu ){ + if (menu_menu == lcd_filename_scroll) menu_back(); move_menu_scale = 1.0; menu_submenu(lcd_move_z); } else { From f35e5533739159cf621e961c73544bb793018be5 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 20:33:43 +0200 Subject: [PATCH 23/58] Code cleanup --- Firmware/cardreader.cpp | 1 - Firmware/lcd.cpp | 1 - Firmware/lcd.h | 2 - Firmware/menu.cpp | 21 ---- Firmware/menu.h | 5 - Firmware/ultralcd.cpp | 261 ++++++++++++++++++++-------------------- 6 files changed, 133 insertions(+), 158 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index f508df7d1..2bbfe2c7c 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -937,7 +937,6 @@ void CardReader::presort() { _delay(300); lcd_clear(); #endif - lcd_scrollTimer.start(); lcd_update(2); KEEPALIVE_STATE(NOT_BUSY); lcd_timeoutToStatus.start(); diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 1041aba8e..ecb25c2a8 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -645,7 +645,6 @@ lcd_lcdupdate_func_t lcd_lcdupdate_func = 0; static ShortTimer buttonBlanking; ShortTimer longPressTimer; LongTimer lcd_timeoutToStatus; -ShortTimer lcd_scrollTimer; //! @brief Was button clicked? diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 81f27bb22..cd180a441 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -102,8 +102,6 @@ extern uint8_t lcd_update_enabled; extern LongTimer lcd_timeoutToStatus; -extern ShortTimer lcd_scrollTimer; - extern uint32_t lcd_next_update_millis; extern uint8_t lcd_status_update_delay; diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 55ea82b59..3ab409956 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -33,7 +33,6 @@ uint8_t menu_top = 0; uint8_t menu_clicked = 0; -uint8_t menu_entering = 0; uint8_t menu_leaving = 0; menu_func_t menu_menu = 0; @@ -55,7 +54,6 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo // This ensures, that the menu entered will find out, that it shall initialize itself. memset(&menu_data, 0, sizeof(menu_data)); } - menu_entering = 1; //next menu that supports entering will clear this flag on first enter. Used for initializing some menus only one time. if (feedback) lcd_quick_feedback(); } else @@ -112,15 +110,6 @@ void menu_back_no_reset(void) } } -void menu_back_scroll(int scrollback) -{ - if (menu_depth > 0) - { - menu_depth--; - menu_goto(menu_stack[menu_depth].menu, menu_stack[menu_depth].position + scrollback, false, true); - } -} - void menu_back_if_clicked(void) { if (lcd_clicked()) @@ -156,16 +145,6 @@ void menu_submenu_no_reset(menu_func_t submenu) } } -void menu_submenu_scroll(menu_func_t submenu) -{ - if (menu_depth < MENU_DEPTH_MAX) - { - menu_stack[menu_depth].menu = menu_menu; - menu_stack[menu_depth++].position = lcd_encoder; - menu_goto(submenu, 0, false, false); - } -} - uint8_t menu_item_ret(void) { lcd_beeper_quick_feedback(); diff --git a/Firmware/menu.h b/Firmware/menu.h index d0595bb3f..180485c7f 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -59,7 +59,6 @@ extern uint8_t menu_top; extern uint8_t menu_clicked; -extern uint8_t menu_entering; extern uint8_t menu_leaving; //function pointer to the currently active menu @@ -79,8 +78,6 @@ extern void menu_back(void); extern void menu_back_no_reset(void); extern void menu_back(uint8_t nLevel); -extern void menu_back_scroll(int scrollback); - extern void menu_back_if_clicked(void); extern void menu_back_if_clicked_fb(void); @@ -88,8 +85,6 @@ extern void menu_back_if_clicked_fb(void); extern void menu_submenu(menu_func_t submenu); extern void menu_submenu_no_reset(menu_func_t submenu); -extern void menu_submenu_scroll(menu_func_t submenu); - extern uint8_t menu_item_ret(void); //extern int menu_draw_item_printf_P(char type_char, const char* format, ...); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 2ef0ee9b1..beae6edcb 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -321,58 +321,6 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; -typedef struct -{ - uint8_t offset = 0; - bool isDir = 0; - uint8_t row = 0; - const char* scrollPointer; - uint16_t fileCnt; -} _menu_data_scroll_t; -static_assert(sizeof(menu_data)>= sizeof(_menu_data_scroll_t),"_menu_data_scroll_t doesn't fit into menu_data"); - -static void lcd_filename_scroll() //this is a submenu -{ - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - if (menu_entering) - { - menu_entering = 0; //clear entering flag - lcd_scrollTimer.start(); - } - bool rewindFlag = LCD_CLICKED || (lcd_encoder != 0); //go back to sd_menu. - if (rewindFlag == 1) _md->offset = 0; - if (lcd_scrollTimer.expired(300) || rewindFlag) - { - uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); - lcd_set_cursor(0, _md->row); - lcd_print('>'); - if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); - for (; i != 0; i--) - { - char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); - if (c == '\0') - { - lcd_scrollTimer.stop(); - break; //stop at the end of the string - } - else - { - lcd_print(c); - lcd_scrollTimer.start(); - } - } - if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). - { - lcd_space(i); - } - _md->offset++; - } - if (rewindFlag) //go back to sd_menu. - { - lcd_scrollTimer.start(); - menu_back_scroll(lcd_encoder); - } -} static void lcd_implementation_drawmenu_sdfile(uint8_t row, const char* longFilename) { char c; @@ -415,19 +363,19 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update || !lcd_scrollTimer.running()) + if (lcd_draw_update/* || !lcd_scrollTimer.running() */) { - if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) +/* if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) { // lcd_beeper_quick_feedback(); - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); + _menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]); _md->isDir = 1; _md->row = menu_row; _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; menu_submenu_scroll(lcd_filename_scroll); return 1; //stop menu generation early } - else lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); + else */lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -447,19 +395,9 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update || !lcd_scrollTimer.running()) + if (lcd_draw_update) { - if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) - { - // lcd_beeper_quick_feedback(); - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - _md->isDir = 0; - _md->row = menu_row; - _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; - menu_submenu_scroll(lcd_filename_scroll); - return 1; - } - else lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); + lcd_implementation_drawmenu_sdfile(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { @@ -7172,8 +7110,9 @@ static void lcd_sd_refresh() #endif menu_top = 0; lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + //todo: clear menu data. Resets sdcard_menu state and timer + // lcd_scrollTimer.start(); + // menu_entering = 1; } static void lcd_sd_updir() @@ -7181,8 +7120,8 @@ static void lcd_sd_updir() card.updir(); menu_top = 0; lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + // lcd_scrollTimer.start(); + // menu_entering = 1; } void lcd_print_stop() @@ -7284,60 +7223,130 @@ void lcd_sdcard_stop() void lcd_sdcard_menu() { - uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - - if (presort_flag == true) { - presort_flag = false; - card.presort(); - lcd_scrollTimer.start(); - lcd_draw_update = 1; - } - if (!lcd_scrollTimer.running()) lcd_scrollTimer.start(); - bool scrollEnter = lcd_scrollTimer.expired(500); - if (lcd_draw_update == 0 && LCD_CLICKED == 0 && !scrollEnter && !menu_entering) - return; // nothing to do (so don't thrash the SD card) - _menu_data_scroll_t* _md = (_menu_data_scroll_t*)&(menu_data[0]); - if (menu_entering) - { - menu_entering = 0; //clear entering flag - lcd_draw_update = 1; //draw lines again - _md->fileCnt = card.getnrfilenames(); - } - if (!scrollEnter) lcd_scrollTimer.start(); - MENU_BEGIN(); - MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion - card.getWorkDirName(); - if (card.filename[0] == '/') - { + typedef struct + { + uint8_t menuState = 0; //start as uninitialized + uint8_t offset; + bool isDir; + const char* scrollPointer; + uint16_t fileCnt; + uint8_t row; + ShortTimer lcd_scrollTimer; + } _menu_data_sdcard_t; + static_assert(sizeof(menu_data)>= sizeof(_menu_data_sdcard_t),"_menu_data_sdcard_t doesn't fit into menu_data"); + _menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]); + + switch(_md->menuState) + { + case 0: //Initialize menu data + { + if (presort_flag == true) { //used to force resorting if sorting type is changed. + presort_flag = false; + card.presort(); + } + _md->fileCnt = card.getnrfilenames(); + _md->menuState = 1; + } //Begin the first menu state instantly. + case 1: //normal menu structure. + { + if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen. + { + _md->lcd_scrollTimer.start(); + lcd_draw_update = 1; + } + if (_md->lcd_scrollTimer.expired(500) && _md->scrollPointer) //switch to the scrolling state on timeout if a file/dir is selected. + { + _md->menuState = 2; + _md->offset = 0; + _md->lcd_scrollTimer.start(); + lcd_draw_update = 1; //forces last load before switching to state:2. + } + if (lcd_draw_update == 0 && !LCD_CLICKED) return; // nothing to do (so don't thrash the SD card) + + //if we reached this point it means that the encoder moved or clicked or the state is being switched. Reset the scrollTimer. + _md->lcd_scrollTimer.start(); + + _md->scrollPointer = NULL; //clear scrollPointer. Used for differentiating between a file/dir and another menu item that is selected. + + const uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); + MENU_BEGIN(); + MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion + card.getWorkDirName(); + if (card.filename[0] == '/') + { #if SDCARDDETECT == -1 - MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); + MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); #else - if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); + if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); //show the refresh option if in flashAir mode. #endif - } else { - MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); - } + } + else MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir. - for (uint16_t i = 0; i < _md->fileCnt; i++) - { - if (menu_item == menu_line) - { - const uint16_t nr = _md->fileCnt - 1 - i; - #ifdef SDCARD_SORT_ALPHA - if (sdSort == SD_SORT_NONE) card.getfilename(nr); - else card.getfilename_sorted(nr); - #else - card.getfilename(nr); - #endif - if (card.filenameIsDir) - MENU_ITEM_SDDIR(card.filename, card.longFilename); - else - MENU_ITEM_SDFILE(card.filename, card.longFilename); - } else { - MENU_ITEM_DUMMY(); - } - } - MENU_END(); + for (uint16_t i = 0; i < _md->fileCnt; i++) // Every file, from top to bottom. + { + if (menu_item == menu_line) //If the file is on the screen. + { + const uint16_t nr = _md->fileCnt - 1 - i; //file index inversion. + + //load filename to memory. +#ifdef SDCARD_SORT_ALPHA + if (sdSort == SD_SORT_NONE) card.getfilename(nr); + else card.getfilename_sorted(nr); +#else + card.getfilename(nr); +#endif + if (lcd_encoder == menu_item) //If the file is selected. + { + _md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename; + _md->isDir = card.filenameIsDir; + _md->row = menu_row; + if(_md->menuState == 2) return; //return early if switching states. At this point the selected filename should be loaded into memory. + } + if (card.filenameIsDir) MENU_ITEM_SDDIR(card.filename, card.longFilename); + else MENU_ITEM_SDFILE(card.filename, card.longFilename); + } + else MENU_ITEM_DUMMY(); //dummy item that just increments the internal menu counters. + } + MENU_END(); + } break; + case 2: //scrolling filename + { + const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to state:1. + if (rewindFlag == 1) _md->offset = 0; //redraw once again from the beginning. + if (_md->lcd_scrollTimer.expired(300) || rewindFlag) + { + uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); + lcd_set_cursor(0, _md->row); + lcd_print('>'); + if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); + for (; i != 0; i--) + { + char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); + if (c == '\0') + { + _md->lcd_scrollTimer.stop(); + break; //stop at the end of the string + } + else + { + lcd_print(c); + _md->lcd_scrollTimer.start(); + } + } + if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). + { + lcd_space(i); + } + _md->offset++; + } + if (rewindFlag) //go back to sd_menu. + { + _md->lcd_scrollTimer.stop(); //forces redraw in state:1 + _md->menuState = 1; + } + } break; + default: _md->menuState = 0; //shouldn't ever happen. Anyways, initialize the menu. + } } #ifdef TMC2130 static void lcd_belttest_v() @@ -8686,8 +8695,8 @@ void menu_action_sddirectory(const char* filename) MYSERIAL.println(dir_names[depth]); card.chdir(filename); lcd_encoder = 0; - lcd_scrollTimer.start(); - menu_entering = 1; + // lcd_scrollTimer.start(); + // menu_entering = 1; } /** LCD API **/ @@ -8877,7 +8886,6 @@ void menu_lcd_longpress_func(void) || menu_menu == lcd_main_menu || menu_menu == lcd_preheat_menu || menu_menu == lcd_sdcard_menu - || menu_menu == lcd_filename_scroll || menu_menu == lcd_settings_menu || menu_menu == lcd_control_temperature_menu #if (LANG_MODE != 0) @@ -8885,7 +8893,6 @@ void menu_lcd_longpress_func(void) #endif || menu_menu == lcd_support_menu ){ - if (menu_menu == lcd_filename_scroll) menu_back(); move_menu_scale = 1.0; menu_submenu(lcd_move_z); } else { @@ -8944,8 +8951,6 @@ void menu_lcd_lcdupdate_func(void) { if(menu_menu==lcd_sdcard_menu) menu_back(); - else if (menu_menu==lcd_filename_scroll) - menu_back(2); //back 2 levels. Exit lcd_filename_scroll and lcd sd_card_menu card.release(); LCD_MESSAGERPGM(_i("Card removed"));////MSG_SD_REMOVED } From 7b19715c99231dee1e5694e7fb5b1637524e0c8c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 20:40:56 +0200 Subject: [PATCH 24/58] Cache sdSort --- Firmware/ultralcd.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index beae6edcb..e94b4f6ad 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7231,6 +7231,7 @@ void lcd_sdcard_menu() const char* scrollPointer; uint16_t fileCnt; uint8_t row; + uint8_t sdSort; ShortTimer lcd_scrollTimer; } _menu_data_sdcard_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_sdcard_t),"_menu_data_sdcard_t doesn't fit into menu_data"); @@ -7245,6 +7246,7 @@ void lcd_sdcard_menu() card.presort(); } _md->fileCnt = card.getnrfilenames(); + _md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); _md->menuState = 1; } //Begin the first menu state instantly. case 1: //normal menu structure. @@ -7268,7 +7270,6 @@ void lcd_sdcard_menu() _md->scrollPointer = NULL; //clear scrollPointer. Used for differentiating between a file/dir and another menu item that is selected. - const uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); MENU_BEGIN(); MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion card.getWorkDirName(); @@ -7290,7 +7291,7 @@ void lcd_sdcard_menu() //load filename to memory. #ifdef SDCARD_SORT_ALPHA - if (sdSort == SD_SORT_NONE) card.getfilename(nr); + if (_md->sdSort == SD_SORT_NONE) card.getfilename(nr); else card.getfilename_sorted(nr); #else card.getfilename(nr); From 57c149e7b5c56e0201991391d96a1ff55d7b11ea Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 21:01:08 +0200 Subject: [PATCH 25/58] Comment cleanup --- Firmware/ultralcd.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e94b4f6ad..e0992110b 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -363,19 +363,9 @@ uint8_t menu_item_sddir(const char* str_fn, char* str_fnl) { if (menu_item == menu_line) { - if (lcd_draw_update/* || !lcd_scrollTimer.running() */) + if (lcd_draw_update) { -/* if (lcd_encoder == menu_item && !lcd_scrollTimer.running()) - { - // lcd_beeper_quick_feedback(); - _menu_data_sdcard_t* _md = (_menu_data_sdcard_t*)&(menu_data[0]); - _md->isDir = 1; - _md->row = menu_row; - _md->scrollPointer = (str_fnl[0] == '\0') ? str_fn : str_fnl; - menu_submenu_scroll(lcd_filename_scroll); - return 1; //stop menu generation early - } - else */lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); + lcd_implementation_drawmenu_sddirectory(menu_row, (str_fnl[0] == '\0') ? str_fn : str_fnl); } if (menu_clicked && (lcd_encoder == menu_item)) { From 5edc1ef2978eebd1f72c50f075a1db490469efee Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 21:03:57 +0200 Subject: [PATCH 26/58] Fix updir and dir again --- Firmware/ultralcd.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e0992110b..8be2c7c4d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7110,8 +7110,7 @@ static void lcd_sd_updir() card.updir(); menu_top = 0; lcd_encoder = 0; - // lcd_scrollTimer.start(); - // menu_entering = 1; + memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. } void lcd_print_stop() @@ -8686,8 +8685,7 @@ void menu_action_sddirectory(const char* filename) MYSERIAL.println(dir_names[depth]); card.chdir(filename); lcd_encoder = 0; - // lcd_scrollTimer.start(); - // menu_entering = 1; + memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. } /** LCD API **/ From 22432b1053a593a76a4bc153dfdb78fff820f822 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 21:07:31 +0200 Subject: [PATCH 27/58] Reset menu state after lcd_sd_refresh --- Firmware/ultralcd.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 8be2c7c4d..86f6752da 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7100,9 +7100,7 @@ static void lcd_sd_refresh() #endif menu_top = 0; lcd_encoder = 0; - //todo: clear menu data. Resets sdcard_menu state and timer - // lcd_scrollTimer.start(); - // menu_entering = 1; + memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. } static void lcd_sd_updir() From 40ebd455f2d810377165a0d615c01e6de04596b1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 22:14:53 +0200 Subject: [PATCH 28/58] Safer menu interrupt call --- Firmware/menu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 3ab409956..5d1385ff9 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -42,12 +42,12 @@ static_assert(sizeof(menu_data)>= sizeof(menu_data_edit_t),"menu_data_edit_t doe void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state) { - asm("cli"); + CRITICAL_SECTION_START; if (menu_menu != menu) { menu_menu = menu; lcd_encoder = encoder; - asm("sei"); + CRITICAL_SECTION_END; if (reset_menu_state) { // Resets the global shared C union. @@ -57,7 +57,7 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo if (feedback) lcd_quick_feedback(); } else - asm("sei"); + CRITICAL_SECTION_END; } void menu_start(void) From 355b003b7fdb692e64aa761af027bd7b19e3ebef Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 4 Mar 2020 22:20:53 +0200 Subject: [PATCH 29/58] menu_data_reset() --- Firmware/menu.cpp | 13 ++++++++----- Firmware/menu.h | 2 +- Firmware/ultralcd.cpp | 6 +++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 5d1385ff9..3995faf4c 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -39,6 +39,12 @@ menu_func_t menu_menu = 0; static_assert(sizeof(menu_data)>= sizeof(menu_data_edit_t),"menu_data_edit_t doesn't fit into menu_data"); +void menu_data_reset(void) +{ + // Resets the global shared C union. + // This ensures, that the menu entered will find out, that it shall initialize itself. + memset(&menu_data, 0, sizeof(menu_data)); +} void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state) { @@ -49,11 +55,8 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo lcd_encoder = encoder; CRITICAL_SECTION_END; if (reset_menu_state) - { - // Resets the global shared C union. - // This ensures, that the menu entered will find out, that it shall initialize itself. - memset(&menu_data, 0, sizeof(menu_data)); - } + menu_data_reset(); + if (feedback) lcd_quick_feedback(); } else diff --git a/Firmware/menu.h b/Firmware/menu.h index 180485c7f..6212edeed 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -64,7 +64,7 @@ extern uint8_t menu_leaving; //function pointer to the currently active menu extern menu_func_t menu_menu; - +extern void menu_data_reset(void); extern void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bool reset_menu_state); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 86f6752da..3781b1211 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7100,7 +7100,7 @@ static void lcd_sd_refresh() #endif menu_top = 0; lcd_encoder = 0; - memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. + menu_data_reset(); //Forces reloading of cached variables. } static void lcd_sd_updir() @@ -7108,7 +7108,7 @@ static void lcd_sd_updir() card.updir(); menu_top = 0; lcd_encoder = 0; - memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. + menu_data_reset(); //Forces reloading of cached variables. } void lcd_print_stop() @@ -8683,7 +8683,7 @@ void menu_action_sddirectory(const char* filename) MYSERIAL.println(dir_names[depth]); card.chdir(filename); lcd_encoder = 0; - memset(&menu_data, 0, sizeof(menu_data)); //reset menu state. Forces reloading of cached variables. + menu_data_reset(); //Forces reloading of cached variables. } /** LCD API **/ From e914f8e0da7dda80cd896ab7b4022989b69ac417 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 5 Mar 2020 13:06:37 +0200 Subject: [PATCH 30/58] Show "Sorting folders" when folders are being sorted --- Firmware/cardreader.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 2bbfe2c7c..cc0d2e98d 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -739,7 +739,6 @@ void CardReader::presort() { fileCnt = SDSORT_LIMIT; } lcd_clear(); - lcd_puts_at_P(0, 1, _i("Sorting files"));////MSG_SORTING c=20 r=1 // uint32_t positions[fileCnt]; @@ -783,6 +782,10 @@ void CardReader::presort() { uint8_t* sortingBaseArray; //run=0: sorts all files and moves folders to the beginning //run=1: assumes all folders are at the beginning of the list and sorts them + + lcd_set_cursor(0, 1); + lcd_printf_P(PSTR("%-20.20S"), (runs == 0)?_i("Sorting files"):_i("Sorting folders")); + uint16_t sortCountFiles = 0; if (runs == 0) { From d25b4a6bc907fdf27b0c5ffc2b4e698a64f48d1c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 3 Feb 2021 19:18:13 +0200 Subject: [PATCH 31/58] Remove dead code (SDSORT_GCODE) --- Firmware/Configuration_adv.h | 3 +-- Firmware/cardreader.cpp | 24 +++--------------------- Firmware/cardreader.h | 10 ---------- 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index d1f62f775..1803a3966 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -251,7 +251,6 @@ #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below - #define SDSORT_GCODE 0 // Allow turning sorting on/off with LCD and M34 g-code. #define SDSORT_USES_RAM 0 // Pre-allocate a static array for faster pre-sorting. #define SDSORT_USES_STACK 0 // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES 0 // Keep sorted items in RAM longer for speedy performance. Most expensive option. @@ -259,7 +258,7 @@ #endif #if defined(SDCARD_SORT_ALPHA) - #define HAS_FOLDER_SORTING (FOLDER_SORTING || SDSORT_GCODE) + #define HAS_FOLDER_SORTING (FOLDER_SORTING) #endif // Enable the option to stop SD printing when hitting and endstops, needs to be enabled from the LCD menu when this option is enabled. diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 46c34d437..7cd7594ab 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -15,11 +15,6 @@ CardReader::CardReader() #ifdef SDCARD_SORT_ALPHA sort_count = 0; - #if SDSORT_GCODE - sort_alpha = true; - sort_folders = FOLDER_SORTING; - //sort_reverse = false; - #endif #endif filesize = 0; @@ -721,20 +716,10 @@ void CardReader::updir() * Get the name of a file in the current directory by sort-index */ void CardReader::getfilename_sorted(const uint16_t nr) { - if (nr < sort_count) - getfilename_simple( - #if SDSORT_GCODE - sort_alpha && - #endif - sort_positions[sort_order[nr]] - ); + if (nr < sort_count) + getfilename_simple(sort_positions[sort_order[nr]]); else - getfilename( - #if SDSORT_GCODE - sort_alpha && - #endif - nr - ); + getfilename(nr); } /** @@ -751,9 +736,6 @@ void CardReader::presort() { if (sdSort == SD_SORT_NONE) return; //sd sort is turned off - #if SDSORT_GCODE - if (!sort_alpha) return; - #endif KEEPALIVE_STATE(IN_HANDLER); // Throw away old sort index diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9542221bf..84267287b 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -50,11 +50,6 @@ public: void quicksort(uint8_t left, uint8_t right); #endif //SDSORT_QUICKSORT void getfilename_sorted(const uint16_t nr); - #if SDSORT_GCODE - FORCE_INLINE void setSortOn(bool b) { sort_alpha = b; presort(); } - FORCE_INLINE void setSortFolders(int i) { sort_folders = i; presort(); } - //FORCE_INLINE void setSortReverse(bool b) { sort_reverse = b; } - #endif #endif FORCE_INLINE bool isFileOpen() { return file.isOpen(); } @@ -89,11 +84,6 @@ private: // Sort files and folders alphabetically. #ifdef SDCARD_SORT_ALPHA uint16_t sort_count; // Count of sorted items in the current directory - #if SDSORT_GCODE - bool sort_alpha; // Flag to enable / disable the feature - int sort_folders; // Flag to enable / disable folder sorting - //bool sort_reverse; // Flag to enable / disable reverse sorting - #endif uint8_t sort_order[SDSORT_LIMIT]; // By default the sort index is static. uint32_t sort_positions[SDSORT_LIMIT]; From ffc3a445ca5656fd0ec89892862dfd532559692d Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 11:35:15 +0200 Subject: [PATCH 32/58] Remove even more dead code --- Firmware/Configuration_adv.h | 11 ----------- Firmware/cardreader.cpp | 20 ++------------------ 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 1803a3966..9faa7683e 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -231,17 +231,10 @@ * SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the * compiler to calculate the worst-case usage and throw an error if the SRAM * limit is exceeded. -* -* - SDSORT_USES_RAM provides faster sorting via a static directory buffer. -* - SDSORT_USES_STACK does the same, but uses a local stack-based buffer. -* - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!) -* - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!) */ #define SDCARD_SORT_ALPHA //Alphabetical sorting of SD files menu // SD Card Sorting options - // In current firmware Prusa Firmware version, - // SDSORT_CACHE_NAMES and SDSORT_DYNAMIC_RAM is not supported and must be set to 0. #ifdef SDCARD_SORT_ALPHA #define SD_SORT_TIME 0 #define SD_SORT_ALPHA 1 @@ -251,10 +244,6 @@ #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below - #define SDSORT_USES_RAM 0 // Pre-allocate a static array for faster pre-sorting. - #define SDSORT_USES_STACK 0 // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) - #define SDSORT_CACHE_NAMES 0 // Keep sorted items in RAM longer for speedy performance. Most expensive option. - #define SDSORT_DYNAMIC_RAM 0 // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! #endif #if defined(SDCARD_SORT_ALPHA) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 7cd7594ab..a2c459ba1 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -908,9 +908,6 @@ void CardReader::presort() { manage_heater(); const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; - // The most economical method reads names as-needed - // throughout the loop. Slow if there are many. - #if !SDSORT_USES_RAM counter++; getfilename_simple(sort_positions[o1]); strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) @@ -922,8 +919,6 @@ void CardReader::presort() { getfilename_simple(sort_positions[o2]); char *name2 = LONGEST_FILENAME; // use the string in-place - #endif // !SDSORT_USES_RAM - // Sort the current pair according to settings. if ( #if HAS_FOLDER_SORTING @@ -948,12 +943,12 @@ void CardReader::presort() { sort_count = fileCnt; } -#if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used + lcd_set_cursor(0, 2); for (int column = 0; column <= 19; column++) lcd_print('\xFF'); //simple progress bar _delay(300); lcd_clear(); -#endif + lcd_update(2); KEEPALIVE_STATE(NOT_BUSY); lcd_timeoutToStatus.start(); @@ -961,17 +956,6 @@ void CardReader::presort() { void CardReader::flush_presort() { if (sort_count > 0) { - #if SDSORT_DYNAMIC_RAM - delete sort_order; - #if SDSORT_CACHE_NAMES - for (uint8_t i = 0; i < sort_count; ++i) { - free(sortshort[i]); // strdup - free(sortnames[i]); // strdup - } - delete sortshort; - delete sortnames; - #endif - #endif sort_count = 0; } } From 3c5c1e5167492db562f8c3b3b43c21f96746f2ab Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 13:19:22 +0200 Subject: [PATCH 33/58] Use enum for menu state code readability --- Firmware/ultralcd.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3b59f465d..0b004e6bb 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7007,9 +7007,10 @@ void lcd_sdcard_stop() void lcd_sdcard_menu() { + enum menuState_t : uint8_t {_uninitialized, _standard, _scrolling}; typedef struct { - uint8_t menuState = 0; //start as uninitialized + menuState_t menuState = _uninitialized; uint8_t offset; bool isDir; const char* scrollPointer; @@ -7023,7 +7024,7 @@ void lcd_sdcard_menu() switch(_md->menuState) { - case 0: //Initialize menu data + case _uninitialized: //Initialize menu data { if (presort_flag == true) { //used to force resorting if sorting type is changed. presort_flag = false; @@ -7031,9 +7032,9 @@ void lcd_sdcard_menu() } _md->fileCnt = card.getnrfilenames(); _md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - _md->menuState = 1; + _md->menuState = _standard; } //Begin the first menu state instantly. - case 1: //normal menu structure. + case _standard: //normal menu structure. { if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen. { @@ -7042,10 +7043,10 @@ void lcd_sdcard_menu() } if (_md->lcd_scrollTimer.expired(500) && _md->scrollPointer) //switch to the scrolling state on timeout if a file/dir is selected. { - _md->menuState = 2; + _md->menuState = _scrolling; _md->offset = 0; _md->lcd_scrollTimer.start(); - lcd_draw_update = 1; //forces last load before switching to state:2. + lcd_draw_update = 1; //forces last load before switching to scrolling. } if (lcd_draw_update == 0 && !LCD_CLICKED) return; // nothing to do (so don't thrash the SD card) @@ -7085,7 +7086,7 @@ void lcd_sdcard_menu() _md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename; _md->isDir = card.filenameIsDir; _md->row = menu_row; - if(_md->menuState == 2) return; //return early if switching states. At this point the selected filename should be loaded into memory. + if(_md->menuState == _scrolling) return; //return early if switching states. At this point the selected filename should be loaded into memory. } if (card.filenameIsDir) MENU_ITEM_SDDIR(card.filename, card.longFilename); else MENU_ITEM_SDFILE(card.filename, card.longFilename); @@ -7094,7 +7095,7 @@ void lcd_sdcard_menu() } MENU_END(); } break; - case 2: //scrolling filename + case _scrolling: //scrolling filename { const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to state:1. if (rewindFlag == 1) _md->offset = 0; //redraw once again from the beginning. @@ -7127,10 +7128,10 @@ void lcd_sdcard_menu() if (rewindFlag) //go back to sd_menu. { _md->lcd_scrollTimer.stop(); //forces redraw in state:1 - _md->menuState = 1; + _md->menuState = _standard; } } break; - default: _md->menuState = 0; //shouldn't ever happen. Anyways, initialize the menu. + default: _md->menuState = _uninitialized; //shouldn't ever happen. Anyways, initialize the menu. } } #ifdef TMC2130 From 8445f76eb9de74fabd7c7f2cd12ab6fefcc35004 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 13:26:15 +0200 Subject: [PATCH 34/58] Restructure for loop to work correctly in reverse --- Firmware/ultralcd.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0b004e6bb..f368ff2da 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7068,18 +7068,16 @@ void lcd_sdcard_menu() } else MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir. - for (uint16_t i = 0; i < _md->fileCnt; i++) // Every file, from top to bottom. + for (uint16_t i = _md->fileCnt; i-- > 0;) // Every file, from top to bottom. { if (menu_item == menu_line) //If the file is on the screen. { - const uint16_t nr = _md->fileCnt - 1 - i; //file index inversion. - //load filename to memory. #ifdef SDCARD_SORT_ALPHA - if (_md->sdSort == SD_SORT_NONE) card.getfilename(nr); - else card.getfilename_sorted(nr); + if (_md->sdSort == SD_SORT_NONE) card.getfilename(i); + else card.getfilename_sorted(i); #else - card.getfilename(nr); + card.getfilename(i); #endif if (lcd_encoder == menu_item) //If the file is selected. { From 640e8d899b5ee58b49039be1a2d0660db2482e51 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Wed, 3 Feb 2021 15:49:22 +0100 Subject: [PATCH 35/58] Don't scroll one character past the filename end --- Firmware/ultralcd.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index f368ff2da..c845c3298 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7105,17 +7105,15 @@ void lcd_sdcard_menu() if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); for (; i != 0; i--) { - char c = *(_md->scrollPointer + _md->offset +((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); - if (c == '\0') - { + const char* c = (_md->scrollPointer + _md->offset + ((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); + lcd_print(c[0]); + if (c[1]) + _md->lcd_scrollTimer.start(); + else + { _md->lcd_scrollTimer.stop(); break; //stop at the end of the string } - else - { - lcd_print(c); - _md->lcd_scrollTimer.start(); - } } if (i != 0) //adds spaces if string is incomplete or at the end (instead of null). { From 279c0aaa219fea2fafd7ce9654ba69d5f8f86b1b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 14:21:37 +0200 Subject: [PATCH 36/58] Fix double '>' bug and brutal refactoring --- Firmware/ultralcd.cpp | 76 +++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index c845c3298..02f66da08 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7014,8 +7014,9 @@ void lcd_sdcard_menu() uint8_t offset; bool isDir; const char* scrollPointer; + uint16_t selectedFileID; uint16_t fileCnt; - uint8_t row; + int8_t row; uint8_t sdSort; ShortTimer lcd_scrollTimer; } _menu_data_sdcard_t; @@ -7026,14 +7027,16 @@ void lcd_sdcard_menu() { case _uninitialized: //Initialize menu data { - if (presort_flag == true) { //used to force resorting if sorting type is changed. + if (presort_flag == true) //used to force resorting if sorting type is changed. + { presort_flag = false; card.presort(); } _md->fileCnt = card.getnrfilenames(); _md->sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); _md->menuState = _standard; - } //Begin the first menu state instantly. + // FALLTHRU + } case _standard: //normal menu structure. { if (!_md->lcd_scrollTimer.running()) //if the timer is not running, then the menu state was just switched, so redraw the screen. @@ -7041,20 +7044,22 @@ void lcd_sdcard_menu() _md->lcd_scrollTimer.start(); lcd_draw_update = 1; } - if (_md->lcd_scrollTimer.expired(500) && _md->scrollPointer) //switch to the scrolling state on timeout if a file/dir is selected. + if (_md->lcd_scrollTimer.expired(500) && (_md->row != -1)) //switch to the scrolling state on timeout if a file/dir is selected. { _md->menuState = _scrolling; _md->offset = 0; + _md->scrollPointer = NULL; _md->lcd_scrollTimer.start(); lcd_draw_update = 1; //forces last load before switching to scrolling. } - if (lcd_draw_update == 0 && !LCD_CLICKED) return; // nothing to do (so don't thrash the SD card) + if (lcd_draw_update == 0 && !LCD_CLICKED) + return; // nothing to do (so don't thrash the SD card) + + _md->row = -1; // assume that no SD file/dir is currently selected. Once they are rendered, it will be changed to the correct row for the _scrolling state. //if we reached this point it means that the encoder moved or clicked or the state is being switched. Reset the scrollTimer. _md->lcd_scrollTimer.start(); - _md->scrollPointer = NULL; //clear scrollPointer. Used for differentiating between a file/dir and another menu item that is selected. - MENU_BEGIN(); MENU_ITEM_BACK_P(_T(bMain?MSG_MAIN:MSG_BACK)); // i.e. default menu-item / menu-item after card insertion card.getWorkDirName(); @@ -7063,10 +7068,12 @@ void lcd_sdcard_menu() #if SDCARDDETECT == -1 MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); #else - if (card.ToshibaFlashAir_isEnabled()) MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); //show the refresh option if in flashAir mode. + if (card.ToshibaFlashAir_isEnabled()) + MENU_ITEM_FUNCTION_P(_T(MSG_REFRESH), lcd_sd_refresh); //show the refresh option if in flashAir mode. #endif } - else MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir. + else + MENU_ITEM_FUNCTION_P(PSTR(LCD_STR_FOLDER ".."), lcd_sd_updir); //Show the updir button if in a subdir. for (uint16_t i = _md->fileCnt; i-- > 0;) // Every file, from top to bottom. { @@ -7074,20 +7081,24 @@ void lcd_sdcard_menu() { //load filename to memory. #ifdef SDCARD_SORT_ALPHA - if (_md->sdSort == SD_SORT_NONE) card.getfilename(i); - else card.getfilename_sorted(i); + if (_md->sdSort == SD_SORT_NONE) + card.getfilename(i); + else + card.getfilename_sorted(i); #else card.getfilename(i); #endif if (lcd_encoder == menu_item) //If the file is selected. { - _md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename; + + _md->selectedFileID = i; _md->isDir = card.filenameIsDir; _md->row = menu_row; - if(_md->menuState == _scrolling) return; //return early if switching states. At this point the selected filename should be loaded into memory. } - if (card.filenameIsDir) MENU_ITEM_SDDIR(card.filename, card.longFilename); - else MENU_ITEM_SDFILE(card.filename, card.longFilename); + if (card.filenameIsDir) + MENU_ITEM_SDDIR(card.filename, card.longFilename); + else + MENU_ITEM_SDFILE(card.filename, card.longFilename); } else MENU_ITEM_DUMMY(); //dummy item that just increments the internal menu counters. } @@ -7095,22 +7106,39 @@ void lcd_sdcard_menu() } break; case _scrolling: //scrolling filename { - const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to state:1. - if (rewindFlag == 1) _md->offset = 0; //redraw once again from the beginning. + const bool rewindFlag = LCD_CLICKED || lcd_draw_update; //flag that says whether the menu should return to _standard state. + + if (_md->scrollPointer == NULL) + { + //load filename to memory. +#ifdef SDCARD_SORT_ALPHA + if (_md->sdSort == SD_SORT_NONE) + card.getfilename(_md->selectedFileID); + else + card.getfilename_sorted(_md->selectedFileID); +#else + card.getfilename(_md->selectedFileID); +#endif + _md->scrollPointer = (card.longFilename[0] == '\0') ? card.filename : card.longFilename; + } + + if (rewindFlag == 1) + _md->offset = 0; //redraw once again from the beginning. if (_md->lcd_scrollTimer.expired(300) || rewindFlag) { uint8_t i = LCD_WIDTH - ((_md->isDir)?2:1); lcd_set_cursor(0, _md->row); lcd_print('>'); - if (_md->isDir) lcd_print(LCD_STR_FOLDER[0]); + if (_md->isDir) + lcd_print(LCD_STR_FOLDER[0]); for (; i != 0; i--) { const char* c = (_md->scrollPointer + _md->offset + ((LCD_WIDTH - ((_md->isDir)?2:1)) - i)); - lcd_print(c[0]); - if (c[1]) - _md->lcd_scrollTimer.start(); - else - { + lcd_print(c[0]); + if (c[1]) + _md->lcd_scrollTimer.start(); + else + { _md->lcd_scrollTimer.stop(); break; //stop at the end of the string } @@ -7123,7 +7151,7 @@ void lcd_sdcard_menu() } if (rewindFlag) //go back to sd_menu. { - _md->lcd_scrollTimer.stop(); //forces redraw in state:1 + _md->lcd_scrollTimer.stop(); //forces redraw in _standard state _md->menuState = _standard; } } break; From df163066fb100df394f4379ab42c572d1e8b97cb Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 15:44:15 +0200 Subject: [PATCH 37/58] Fix "sorting files" messages for both ShellSort and BubbleSort --- Firmware/cardreader.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index a2c459ba1..962b73989 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -883,6 +883,9 @@ void CardReader::presort() { #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) #endif + lcd_set_cursor(0, 1); + lcd_printf_P(PSTR("%-20.20S"), _i("Sorting files")); + for (uint16_t i = fileCnt; --i;) { if (!IS_SD_INSERTED) return; bool didSwap = false; @@ -936,6 +939,11 @@ void CardReader::presort() { if (!didSwap) break; } //end of bubble sort loop #endif + lcd_set_cursor(0, 2); + for (int column = 0; column <= 19; column++) + lcd_print('\xFF'); //simple progress bar + _delay(300); + lcd_clear(); } else { sort_order[0] = 0; @@ -944,11 +952,6 @@ void CardReader::presort() { sort_count = fileCnt; } - lcd_set_cursor(0, 2); - for (int column = 0; column <= 19; column++) lcd_print('\xFF'); //simple progress bar - _delay(300); - lcd_clear(); - lcd_update(2); KEEPALIVE_STATE(NOT_BUSY); lcd_timeoutToStatus.start(); From 080c44cb2e59efba285ff77da669f1892057fb62 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 16:37:24 +0200 Subject: [PATCH 38/58] Undo stupid hack for an error because of some compiler issue in the past --- Firmware/ultralcd.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 02f66da08..04ca97c78 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -395,10 +395,9 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) } if (menu_clicked && (lcd_encoder == menu_item)) { - lcd_consume_click(); + lcd_consume_click(); menu_action_sdfile(str_fn); - /* return */ menu_item_ret(); - return 1; + return menu_item_ret(); } } menu_item++; From 90c0f33bc5aa2b004f78126e176ab738ccacae4b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 16:40:15 +0200 Subject: [PATCH 39/58] Fix farm filename when LFN is missing --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 04ca97c78..3202a7d87 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3974,7 +3974,7 @@ static void prusa_stat_printinfo() SERIAL_ECHOPGM("][FEM:"); SERIAL_ECHO(itostr3(feedmultiply)); SERIAL_ECHOPGM("][FNM:"); - SERIAL_ECHO(card.longFilename); + SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename); SERIAL_ECHOPGM("][TIM:"); if (starttime != 0) { From 84d043d41bf2cbc6f47a6fe6fd434507919cdf39 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 4 Feb 2021 17:52:42 +0200 Subject: [PATCH 40/58] Fix WorkDirDepth limit (for good this time) --- Firmware/cardreader.cpp | 6 ++++-- Firmware/cardreader.h | 2 +- Firmware/ultralcd.cpp | 15 +++++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 962b73989..d9f681698 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -666,7 +666,7 @@ uint16_t CardReader::getnrfilenames() return nrFiles; } -void CardReader::chdir(const char * relpath) +bool CardReader::chdir(const char * relpath) { SdFile newfile; SdFile *parent=&root; @@ -674,11 +674,12 @@ void CardReader::chdir(const char * relpath) if(workDir.isOpen()) parent=&workDir; - if(!newfile.open(*parent,relpath, O_READ)) + if(!newfile.open(*parent,relpath, O_READ) || ((workDirDepth + 1) >= MAX_DIR_DEPTH)) { SERIAL_ECHO_START; SERIAL_ECHORPGM(_n("Cannot enter subdir: "));////MSG_SD_CANT_ENTER_SUBDIR SERIAL_ECHOLN(relpath); + return 0; } else { @@ -691,6 +692,7 @@ void CardReader::chdir(const char * relpath) #ifdef SDCARD_SORT_ALPHA presort(); #endif + return 1; } } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 84267287b..16bc4b255 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -39,7 +39,7 @@ public: void ls(bool printLFN); - void chdir(const char * relpath); + bool chdir(const char * relpath); void updir(); void setroot(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3202a7d87..0983c4407 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8490,13 +8490,16 @@ static void menu_action_sdfile(const char* filename) void menu_action_sddirectory(const char* filename) { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); + bool success = card.chdir(filename); - strcpy(dir_names[depth], filename); - MYSERIAL.println(dir_names[depth]); - card.chdir(filename); - lcd_encoder = 0; - menu_data_reset(); //Forces reloading of cached variables. + if (success) + { + strcpy(dir_names[card.getWorkDirDepth()], filename); + MYSERIAL.println(filename); + } + + lcd_encoder = 0; + menu_data_reset(); //Forces reloading of cached variables. } /** LCD API **/ From e6ffc99ff5c8c4eba64e29a8847cf9d87198f700 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Feb 2021 16:28:13 +0200 Subject: [PATCH 41/58] Fix compiler bug ... again ... :endit: :blobhydraulicpress: --- Firmware/ultralcd.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e0b3bb7a7..0326da88a 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -392,7 +392,8 @@ static uint8_t menu_item_sdfile(const char* str_fn, char* str_fnl) { lcd_consume_click(); menu_action_sdfile(str_fn); - return menu_item_ret(); + /* return */ menu_item_ret(); + return 1; } } menu_item++; From 8d1c5cbb27c51d0e27ada070814e6dc0a20e983b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Feb 2021 20:29:06 +0200 Subject: [PATCH 42/58] Fix position table offset --- Firmware/cardreader.cpp | 11 ++++++----- Firmware/cardreader.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 9e7d2f011..0d61b5f49 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -77,7 +77,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m dir_t p; uint8_t cnt = 0; // Read the next entry from a directory - while (parent.readDir(p, longFilename) > 0) { + for (position = parent.curPosition(); parent.readDir(p, longFilename) > 0; position = parent.curPosition()) { if (recursionCnt > MAX_DIR_DEPTH) return; else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint @@ -144,10 +144,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m break; case LS_GetFilename: - //SERIAL_ECHOPGM("File: "); + //SERIAL_ECHOPGM("File: "); createFilename(filename, p); - cluster = parent.curCluster(); - position = parent.curPosition(); + // cluster = parent.curCluster(); + // position = parent.curPosition(); /*MYSERIAL.println(filename); SERIAL_ECHOPGM("Write date: "); writeDate = p.lastWriteDate; @@ -792,9 +792,9 @@ void CardReader::presort() { for (uint16_t i = 0; i < fileCnt; i++) { if (!IS_SD_INSERTED) return; manage_heater(); + getfilename(i); sort_order[i] = i; sort_positions[i] = position; - getfilename(i); #if HAS_FOLDER_SORTING if (filenameIsDir) dirCnt++; #endif @@ -966,6 +966,7 @@ void CardReader::presort() { } else { sort_order[0] = 0; + sort_positions[0] = position; } sort_count = fileCnt; diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 5c59e20b2..9b5c5196d 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -74,7 +74,7 @@ public: // There are scenarios when simple modification time is not enough (on MS Windows) // Therefore these timestamps hold the most recent one of creation/modification date/times uint16_t crmodTime, crmodDate; - uint32_t cluster, position; + uint32_t /* cluster, */ position; char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; From a830d5b6b79fc7db649c7f2990b59d00597c296c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 9 Feb 2021 20:31:02 +0200 Subject: [PATCH 43/58] getfilename_next --- Firmware/cardreader.cpp | 15 ++++++++++++++- Firmware/cardreader.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 0d61b5f49..23669ca97 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -665,6 +665,15 @@ void CardReader::getfilename_simple(uint32_t position, const char * const match/ lsDive("", *curDir, match); } +void CardReader::getfilename_next(uint32_t position, const char * const match/*=NULL*/) +{ + curDir = &workDir; + lsAction = LS_GetFilename; + nrFiles = 1; + curDir->seekSet(position); + lsDive("", *curDir, match); +} + uint16_t CardReader::getnrfilenames() { curDir=&workDir; @@ -792,7 +801,10 @@ void CardReader::presort() { for (uint16_t i = 0; i < fileCnt; i++) { if (!IS_SD_INSERTED) return; manage_heater(); - getfilename(i); + if (i == 0) + getfilename(0); + else + getfilename_next(position); sort_order[i] = i; sort_positions[i] = position; #if HAS_FOLDER_SORTING @@ -966,6 +978,7 @@ void CardReader::presort() { } else { sort_order[0] = 0; + getfilename(0); sort_positions[0] = position; } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9b5c5196d..84462f6a8 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -31,6 +31,7 @@ public: void getfilename(uint16_t nr, const char* const match=NULL); void getfilename_simple(uint32_t position, const char * const match = NULL); + void getfilename_next(uint32_t position, const char * const match = NULL); uint16_t getnrfilenames(); void getAbsFilename(char *t); From b72ce00183e152287d8ede93f3ff77daec2c5ba1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 10 Feb 2021 13:43:46 +0200 Subject: [PATCH 44/58] Reduce reserved space on stack for LONG_FILENAME_LENGTH by 1 in presort LONG_FILENAME_LENGTH already includes a +1 for the \0 string termination --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 23669ca97..7eaba17a5 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -786,7 +786,7 @@ void CardReader::presort() { // By default re-read the names from SD for every compare // retaining only two filenames at a time. This is very // slow but is safest and uses minimal RAM. - char name1[LONG_FILENAME_LENGTH + 1]; + char name1[LONG_FILENAME_LENGTH]; uint16_t crmod_time_bckp; uint16_t crmod_date_bckp; From 8a068d4d36715778064edaf379c54b0bd5791651 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 10 Feb 2021 13:44:39 +0200 Subject: [PATCH 45/58] Remove redundant position=0 in ::presort --- Firmware/cardreader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 7eaba17a5..05bfdd193 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -794,7 +794,6 @@ void CardReader::presort() { uint16_t dirCnt = 0; #endif - position = 0; //might need to also load the file at position 0 for filenameIsDir to work on the first file if (fileCnt > 1) { // Init sort order. From a95d4972892fd9d151432936a385a91b447fdac0 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 10 Feb 2021 13:45:30 +0200 Subject: [PATCH 46/58] Remove commented out code and deprecated comments --- Firmware/cardreader.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 05bfdd193..6f8456664 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -781,8 +781,6 @@ void CardReader::presort() { } lcd_clear(); - // uint32_t positions[fileCnt]; - // By default re-read the names from SD for every compare // retaining only two filenames at a time. This is very // slow but is safest and uses minimal RAM. @@ -794,7 +792,6 @@ void CardReader::presort() { uint16_t dirCnt = 0; #endif - //might need to also load the file at position 0 for filenameIsDir to work on the first file if (fileCnt > 1) { // Init sort order. for (uint16_t i = 0; i < fileCnt; i++) { From 8397dae386f438421cb12774fd0fb96e646244e4 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 10 Feb 2021 18:15:18 +0200 Subject: [PATCH 47/58] Remove comment --- Firmware/cardreader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 717f58696..360e7f1a5 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -882,7 +882,7 @@ void CardReader::presort() { #if HAS_FOLDER_SORTING else { - sortingBaseArray = sort_order + /* sizeof(sort_order[0]) * */ (fileCnt - dirCnt); + sortingBaseArray = sort_order + (fileCnt - dirCnt); sortCountFiles = dirCnt; } #endif From 1c1ff722c014002780d075e385630ad952840372 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 10 Feb 2021 18:16:26 +0200 Subject: [PATCH 48/58] Move sort_order to stack during ::presort --- Firmware/cardreader.cpp | 28 ++++++++++++++++++++++++++-- Firmware/cardreader.h | 2 -- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 360e7f1a5..76b0758ee 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -791,7 +791,7 @@ void CardReader::updir() */ void CardReader::getfilename_sorted(const uint16_t nr) { if (nr < sort_count) - getfilename_simple(sort_positions[sort_order[nr]]); + getfilename_simple(sort_positions[nr]); else getfilename(nr); } @@ -840,6 +840,7 @@ void CardReader::presort() { if (fileCnt > 1) { // Init sort order. + uint8_t sort_order[fileCnt]; for (uint16_t i = 0; i < fileCnt; i++) { if (!IS_SD_INSERTED) return; manage_heater(); @@ -1012,6 +1013,30 @@ void CardReader::presort() { if (!didSwap) break; } //end of bubble sort loop #endif + + uint8_t sort_order_reverse_index[fileCnt]; + for (uint8_t i = 0; i < fileCnt; i++) + sort_order_reverse_index[sort_order[i]] = i; + for (uint8_t i = 0; i < fileCnt; i++) + { + if (sort_order_reverse_index[i] != i) + { + uint32_t el = sort_positions[i]; + uint8_t idx = sort_order_reverse_index[i]; + while (idx != i) + { + uint32_t el1 = sort_positions[idx]; + uint8_t idx1 = sort_order_reverse_index[idx]; + sort_order_reverse_index[idx] = idx; + sort_positions[idx] = el; + idx = idx1; + el = el1; + } + sort_order_reverse_index[idx] = idx; + sort_positions[idx] = el; + } + } + lcd_set_cursor(0, 2); for (int column = 0; column <= 19; column++) lcd_print('\xFF'); //simple progress bar @@ -1019,7 +1044,6 @@ void CardReader::presort() { lcd_clear(); } else { - sort_order[0] = 0; getfilename(0); sort_positions[0] = position; } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 0819d3bb8..9f9c880fe 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -95,8 +95,6 @@ private: // Sort files and folders alphabetically. #ifdef SDCARD_SORT_ALPHA uint16_t sort_count; // Count of sorted items in the current directory - - uint8_t sort_order[SDSORT_LIMIT]; // By default the sort index is static. uint32_t sort_positions[SDSORT_LIMIT]; #endif // SDCARD_SORT_ALPHA From 54b2edbc8c0fc481b33d0b1dca2191e14d5459b6 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 25 Feb 2021 19:26:01 +0200 Subject: [PATCH 49/58] Update debugging code --- Firmware/cardreader.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 76b0758ee..eca455eec 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -943,6 +943,12 @@ void CardReader::presort() { } } } + + #ifdef SORTING_DUMP + for (uint16_t z = 0; z < fileCnt; z++) + printf_P(PSTR("%2u "), sort_order[z]); + SERIAL_PROTOCOLLN(); + #endif #else //Bubble Sort uint32_t counter = 0; @@ -972,7 +978,6 @@ void CardReader::presort() { } counter++; - //MYSERIAL.println(int(i)); for (uint16_t j = 0; j < i; ++j) { if (!IS_SD_INSERTED) return; #ifdef SORTING_DUMP From afa7c7ab0313096565fd1fed7f1662a54f698570 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 25 Feb 2021 19:29:14 +0200 Subject: [PATCH 50/58] Remove forgotten (?) undef at the end of menu.cpp --- Firmware/menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index ae3d0a5c5..f3549635a 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -553,4 +553,4 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v template uint8_t menu_item_edit_P(const char* str, int16_t *pval, int16_t min_val, int16_t max_val); template uint8_t menu_item_edit_P(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val); -#undef _menu_data + From 8821439878eae3e30382a60bef2b9a7ed83cab3b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 25 Feb 2021 20:25:32 +0200 Subject: [PATCH 51/58] Cardreader progressbar code --- Firmware/cardreader.cpp | 37 +++++++------------------------------ Firmware/menu.cpp | 27 +++++++++++++++++++++++++++ Firmware/menu.h | 3 +++ 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index eca455eec..d9468a8f3 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -825,7 +825,6 @@ void CardReader::presort() { lcd_show_fullscreen_message_and_wait_P(_i("Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."));////MSG_FILE_CNT c=20 r=6 fileCnt = SDSORT_LIMIT; } - lcd_clear(); // By default re-read the names from SD for every compare // retaining only two filenames at a time. This is very @@ -867,13 +866,9 @@ void CardReader::presort() { #endif for (uint8_t runs = 0; runs < 2; runs++) { - uint8_t* sortingBaseArray; //run=0: sorts all files and moves folders to the beginning //run=1: assumes all folders are at the beginning of the list and sorts them - - lcd_set_cursor(0, 1); - lcd_printf_P(PSTR("%-20.20S"), (runs == 0)?_i("Sorting files"):_i("Sorting folders")); - + uint8_t* sortingBaseArray; uint16_t sortCountFiles = 0; if (runs == 0) { @@ -887,11 +882,11 @@ void CardReader::presort() { sortCountFiles = dirCnt; } #endif - if (sortCountFiles < 2) break; uint16_t counter = 0; uint16_t total = 0; for (uint16_t i = sortCountFiles/2; i > 0; i /= 2) total += sortCountFiles - i; //total runs for progress bar + menu_progressbar_init(total, (runs == 0)?_i("Sorting files"):_i("Sorting folders")); for (uint16_t gap = sortCountFiles/2; gap > 0; gap /= 2) { @@ -899,12 +894,7 @@ void CardReader::presort() { { if (!IS_SD_INSERTED) return; - int8_t percent = (counter * 100) / total; - lcd_set_cursor(0, 2); - for (int column = 0; column < 20; column++) { - if (column < (percent / 5)) lcd_print('\xFF'); //simple progress bar - else lcd_print(' '); - } + menu_progressbar_update(counter); counter++; manage_heater(); @@ -951,8 +941,8 @@ void CardReader::presort() { #endif #else //Bubble Sort - uint32_t counter = 0; - uint16_t total = 0.5*(fileCnt - 1)*(fileCnt); + uint16_t counter = 0; + menu_progressbar_init(0.5*(fileCnt - 1)*(fileCnt), _i("Sorting files")); // Compare names from the array or just the two buffered names #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) @@ -963,19 +953,11 @@ void CardReader::presort() { #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) #endif - lcd_set_cursor(0, 1); - lcd_printf_P(PSTR("%-20.20S"), _i("Sorting files")); - for (uint16_t i = fileCnt; --i;) { if (!IS_SD_INSERTED) return; bool didSwap = false; - int8_t percent = (counter * 100) / total;//((counter * 100) / pow((fileCnt-1),2)); - lcd_set_cursor(0, 2); - for (int column = 0; column < 20; column++) { - if (column < (percent / 5)) lcd_print('\xFF'); //simple progress bar - else lcd_print(' '); - } + menu_progressbar_update(counter); counter++; for (uint16_t j = 0; j < i; ++j) { @@ -1041,12 +1023,7 @@ void CardReader::presort() { sort_positions[idx] = el; } } - - lcd_set_cursor(0, 2); - for (int column = 0; column <= 19; column++) - lcd_print('\xFF'); //simple progress bar - _delay(300); - lcd_clear(); + menu_progressbar_finish(); } else { getfilename(0); diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index f3549635a..02023e735 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -553,4 +553,31 @@ uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_v template uint8_t menu_item_edit_P(const char* str, int16_t *pval, int16_t min_val, int16_t max_val); template uint8_t menu_item_edit_P(const char* str, uint8_t *pval, int16_t min_val, int16_t max_val); +static uint8_t progressbar_block_count = 0; +static uint16_t progressbar_total = 0; +void menu_progressbar_init(uint16_t total, const char* title) +{ + lcd_clear(); + progressbar_block_count = 0; + progressbar_total = total; + + lcd_set_cursor(0, 1); + lcd_printf_P(PSTR("%-20.20S\n"), title); +} +void menu_progressbar_update(uint16_t newVal) +{ + uint8_t newCnt = (newVal * LCD_WIDTH) / progressbar_total; + while (newCnt > progressbar_block_count) + { + lcd_print('\xFF'); + progressbar_block_count++; + } +} + +void menu_progressbar_finish(void) +{ + progressbar_total = 1; + menu_progressbar_update(1); + _delay(300); +} diff --git a/Firmware/menu.h b/Firmware/menu.h index 5103dbf3a..54c8a2cbb 100755 --- a/Firmware/menu.h +++ b/Firmware/menu.h @@ -150,5 +150,8 @@ extern void menu_format_sheet_E(const Sheet &sheet_E, SheetFormatBuffer &buffer) template extern uint8_t menu_item_edit_P(const char* str, T pval, int16_t min_val, int16_t max_val); +extern void menu_progressbar_init(uint16_t total, const char* title); +extern void menu_progressbar_update(uint16_t newVal); +extern void menu_progressbar_finish(void); #endif //_MENU_H From 204da1cc3fa066c04ee0455ab0e36239751b6f49 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 25 Feb 2021 21:04:05 +0200 Subject: [PATCH 52/58] Factory reset and check_file progress bar --- Firmware/Marlin_main.cpp | 26 ++++++-------------------- Firmware/ultralcd.cpp | 16 ++++------------ 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3eac5cf33..34356cdcf 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -710,7 +710,6 @@ void softReset() // Factory reset function // This function is used to erase parts or whole EEPROM memory which is used for storing calibration and and so on. // Level input parameter sets depth of reset -int er_progress = 0; static void factory_reset(char level) { lcd_clear(); @@ -790,28 +789,15 @@ static void factory_reset(char level) // Level 3: erase everything, whole EEPROM will be set to 0xFF case 3: - lcd_puts_P(PSTR("Factory RESET")); - lcd_puts_at_P(1, 2, PSTR("ERASING all data")); - - Sound_MakeCustom(100,0,false); - er_progress = 0; - lcd_puts_at_P(3, 3, PSTR(" ")); - lcd_set_cursor(3, 3); - lcd_print(er_progress); - + menu_progressbar_init(EEPROM_TOP, PSTR("ERASING all data")); + Sound_MakeCustom(100,0,false); + // Erase EEPROM - for (int i = 0; i < 4096; i++) { + for (uint16_t i = 0; i < EEPROM_TOP; i++) { eeprom_update_byte((uint8_t*)i, 0xFF); - - if (i % 41 == 0) { - er_progress++; - lcd_puts_at_P(3, 3, PSTR(" ")); - lcd_set_cursor(3, 3); - lcd_print(er_progress); - lcd_puts_P(PSTR("%")); - } - + menu_progressbar_update(i); } + menu_progressbar_finish(); softReset(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index c2d83572c..3a8586d0f 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8403,7 +8403,6 @@ static bool check_file(const char* filename) { const uint32_t filesize = card.getFileSize(); uint32_t startPos = 0; const uint16_t bytesToCheck = min(END_FILE_SECTION, filesize); - uint8_t blocksPrinted = 0; if (filesize > END_FILE_SECTION) { startPos = filesize - END_FILE_SECTION; card.setIndex(startPos); @@ -8411,22 +8410,15 @@ static bool check_file(const char* filename) { cmdqueue_reset(); cmdqueue_serial_disabled = true; - lcd_clear(); - lcd_puts_at_P(0, 1, _i("Checking file"));////c=20 r=1 - lcd_set_cursor(0, 2); + menu_progressbar_init(bytesToCheck, _i("Checking file")); while (!card.eof() && !result) { - for (; blocksPrinted < (((card.get_sdpos() - startPos) * LCD_WIDTH) / bytesToCheck); blocksPrinted++) - lcd_print('\xFF'); //simple progress bar - + menu_progressbar_update(card.get_sdpos() - startPos); card.sdprinting = true; get_command(); result = check_commands(); } - - for (; blocksPrinted < LCD_WIDTH; blocksPrinted++) - lcd_print('\xFF'); //simple progress bar - _delay(100); //for the user to see the end of the progress bar. - + + menu_progressbar_finish(); cmdqueue_serial_disabled = false; card.printingHasFinished(); From c63f92ae52cca15ff8091f87054a37a11b75145c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 08:57:49 +0200 Subject: [PATCH 53/58] Invert shellSort logic --- Firmware/cardreader.cpp | 61 ++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index d9468a8f3..36b6d45af 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -791,7 +791,7 @@ void CardReader::updir() */ void CardReader::getfilename_sorted(const uint16_t nr) { if (nr < sort_count) - getfilename_simple(sort_positions[nr]); + getfilename_simple(sort_positions[sort_count - nr - 1]); else getfilename(nr); } @@ -854,31 +854,29 @@ void CardReader::presort() { #endif } +#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) +#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || (crmod_date_bckp > crmodDate)) + +#if HAS_FOLDER_SORTING +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? dir1 : !dir1)) +#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) +#endif + #ifdef QUICKSORT quicksort(0, fileCnt - 1); #elif defined(SHELLSORT) - -#define _SORT_CMP_NODIR() (strcasecmp(name2, name1) < 0) -#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp < crmodTime)) || (crmod_date_bckp < crmodDate)) -#if HAS_FOLDER_SORTING -#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? filenameIsDir : !filenameIsDir)) -#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? filenameIsDir : !filenameIsDir)) -#endif for (uint8_t runs = 0; runs < 2; runs++) { //run=0: sorts all files and moves folders to the beginning //run=1: assumes all folders are at the beginning of the list and sorts them - uint8_t* sortingBaseArray; uint16_t sortCountFiles = 0; if (runs == 0) { - sortingBaseArray = sort_order; sortCountFiles = fileCnt; } #if HAS_FOLDER_SORTING else { - sortingBaseArray = sort_order + (fileCnt - dirCnt); sortCountFiles = dirCnt; } #endif @@ -898,7 +896,7 @@ void CardReader::presort() { counter++; manage_heater(); - uint8_t orderBckp = sortingBaseArray[i]; + uint8_t orderBckp = sort_order[i]; getfilename_simple(sort_positions[orderBckp]); strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) crmod_date_bckp = crmodDate; @@ -908,7 +906,7 @@ void CardReader::presort() { #endif uint16_t j = i; - getfilename_simple(sort_positions[sortingBaseArray[j - gap]]); + getfilename_simple(sort_positions[sort_order[j - gap]]); char *name2 = LONGEST_FILENAME; // use the string in-place #if HAS_FOLDER_SORTING while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_DIR(FOLDER_SORTING):_SORT_CMP_DIR(FOLDER_SORTING))) @@ -916,43 +914,28 @@ void CardReader::presort() { while (j >= gap && ((sdSort == SD_SORT_TIME)?_SORT_CMP_TIME_NODIR():_SORT_CMP_NODIR())) #endif { - sortingBaseArray[j] = sortingBaseArray[j - gap]; + sort_order[j] = sort_order[j - gap]; j -= gap; #ifdef SORTING_DUMP for (uint16_t z = 0; z < sortCountFiles; z++) { - printf_P(PSTR("%2u "), sortingBaseArray[z]); + printf_P(PSTR("%2u "), sort_order[z]); } printf_P(PSTR("i%2d j%2d gap%2d orderBckp%2d\n"), i, j, gap, orderBckp); #endif if (j < gap) break; - getfilename_simple(sort_positions[sortingBaseArray[j - gap]]); + getfilename_simple(sort_positions[sort_order[j - gap]]); name2 = LONGEST_FILENAME; // use the string in-place } - sortingBaseArray[j] = orderBckp; + sort_order[j] = orderBckp; } } } - - #ifdef SORTING_DUMP - for (uint16_t z = 0; z < fileCnt; z++) - printf_P(PSTR("%2u "), sort_order[z]); - SERIAL_PROTOCOLLN(); - #endif #else //Bubble Sort uint16_t counter = 0; menu_progressbar_init(0.5*(fileCnt - 1)*(fileCnt), _i("Sorting files")); - // Compare names from the array or just the two buffered names - #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) - #define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || (crmod_date_bckp > crmodDate)) - - #if HAS_FOLDER_SORTING - #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? dir1 : !dir1)) - #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) - #endif - for (uint16_t i = fileCnt; --i;) { if (!IS_SD_INSERTED) return; bool didSwap = false; @@ -986,12 +969,16 @@ void CardReader::presort() { // Sort the current pair according to settings. if ( #if HAS_FOLDER_SORTING - (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING)) + !((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING))) #else - (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR()) + !((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR())) #endif ) { + #ifdef SORTING_DUMP + puts_P(PSTR("swap")); + #endif + sort_order[j] = o2; sort_order[j + 1] = o1; didSwap = true; @@ -1001,6 +988,12 @@ void CardReader::presort() { } //end of bubble sort loop #endif + #ifdef SORTING_DUMP + for (uint16_t z = 0; z < fileCnt; z++) + printf_P(PSTR("%2u "), sort_order[z]); + SERIAL_PROTOCOLLN(); + #endif + uint8_t sort_order_reverse_index[fileCnt]; for (uint8_t i = 0; i < fileCnt; i++) sort_order_reverse_index[sort_order[i]] = i; From 225c456ae622b36c126bfa1398a8eb7fd9f0d4a4 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 09:18:28 +0200 Subject: [PATCH 54/58] Limit progressbar to LCD_WIDTH for some stupid reason bubbleSort sometimes exceeds the total value :) --- Firmware/menu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index 02023e735..fe58686cf 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -568,6 +568,8 @@ void menu_progressbar_init(uint16_t total, const char* title) void menu_progressbar_update(uint16_t newVal) { uint8_t newCnt = (newVal * LCD_WIDTH) / progressbar_total; + if (newCnt > LCD_WIDTH) + newCnt = LCD_WIDTH; while (newCnt > progressbar_block_count) { lcd_print('\xFF'); From f34612594848beaed4deef09e6dd19e9ce9d0c04 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 09:18:59 +0200 Subject: [PATCH 55/58] Use BubbleSort by default. Disable ShellSort until I fix it --- Firmware/Configuration_adv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 9faa7683e..15e6bb5b1 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -239,7 +239,7 @@ #define SD_SORT_TIME 0 #define SD_SORT_ALPHA 1 #define SD_SORT_NONE 2 - #define SHELLSORT + // #define SHELLSORT // #define SORTING_DUMP #define SDSORT_LIMIT 100 // Maximum number of sorted items (10-256). From 194438c130c72fd5cf0841e34cc423b55e54a5ae Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 09:54:57 +0200 Subject: [PATCH 56/58] Fix formatting --- Firmware/Marlin_main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f54b23030..941928c2e 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -750,6 +750,7 @@ static void factory_reset(char level) case 2: // Level 2: Prepare for shipping factory_reset_stats(); // [[fallthrough]] // there is no break intentionally + case 4: // Level 4: Preparation after being serviced // Force language selection at the next boot up. lang_reset(); @@ -764,6 +765,7 @@ static void factory_reset(char level) fsensor_autoload_set(true); #endif //FILAMENT_SENSOR break; + case 3: menu_progressbar_init(EEPROM_TOP, PSTR("ERASING all data")); Sound_MakeCustom(100,0,false); @@ -777,6 +779,7 @@ static void factory_reset(char level) softReset(); break; + #ifdef SNMM case 5: bowden_menu(); From 6e0ecf5cd2ccfac8e0841e85a6d7ecfce3544ca0 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 18:22:32 +0200 Subject: [PATCH 57/58] Remove redundant click sound in factory reset (MK3 merge issue) --- Firmware/Marlin_main.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 941928c2e..be86fedab 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -768,8 +768,6 @@ static void factory_reset(char level) case 3: menu_progressbar_init(EEPROM_TOP, PSTR("ERASING all data")); - Sound_MakeCustom(100,0,false); - // Erase EEPROM for (uint16_t i = 0; i < EEPROM_TOP; i++) { eeprom_update_byte((uint8_t*)i, 0xFF); From 28f21c8630bcdf49ef38fc35d7bb939146b0dea7 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 26 Feb 2021 19:17:14 +0200 Subject: [PATCH 58/58] Fix bubblesort sorting speed. ShellSort is probably broken --- Firmware/cardreader.cpp | 26 ++++++++++++++++++-------- Firmware/cardreader.h | 2 +- Firmware/ultralcd.cpp | 4 ++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 36b6d45af..673e88c17 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -789,9 +789,9 @@ void CardReader::updir() /** * Get the name of a file in the current directory by sort-index */ -void CardReader::getfilename_sorted(const uint16_t nr) { +void CardReader::getfilename_sorted(const uint16_t nr, uint8_t sdSort) { if (nr < sort_count) - getfilename_simple(sort_positions[sort_count - nr - 1]); + getfilename_simple(sort_positions[(sdSort == SD_SORT_ALPHA) ? (sort_count - nr - 1) : nr]); else getfilename(nr); } @@ -854,17 +854,18 @@ void CardReader::presort() { #endif } +#ifdef QUICKSORT + quicksort(0, fileCnt - 1); +#elif defined(SHELLSORT) + #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) -#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || (crmod_date_bckp > crmodDate)) +#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp < crmodTime)) || (crmod_date_bckp < crmodDate)) #if HAS_FOLDER_SORTING #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? dir1 : !dir1)) #define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) #endif -#ifdef QUICKSORT - quicksort(0, fileCnt - 1); -#elif defined(SHELLSORT) for (uint8_t runs = 0; runs < 2; runs++) { //run=0: sorts all files and moves folders to the beginning @@ -933,6 +934,15 @@ void CardReader::presort() { } #else //Bubble Sort + +#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) < 0) //true if lowercase(name1) < lowercase(name2) +#define _SORT_CMP_TIME_NODIR() (((crmod_date_bckp == crmodDate) && (crmod_time_bckp > crmodTime)) || (crmod_date_bckp > crmodDate)) + +#if HAS_FOLDER_SORTING +#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs < 0 ? dir1 : !dir1)) +#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs < 0 ? dir1 : !dir1)) +#endif + uint16_t counter = 0; menu_progressbar_init(0.5*(fileCnt - 1)*(fileCnt), _i("Sorting files")); @@ -969,9 +979,9 @@ void CardReader::presort() { // Sort the current pair according to settings. if ( #if HAS_FOLDER_SORTING - !((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING))) + (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && !_SORT_CMP_DIR(FOLDER_SORTING)) #else - !((sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR())) + (sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && !_SORT_CMP_NODIR()) #endif ) { diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 9f9c880fe..715d82fa5 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -54,7 +54,7 @@ public: void swap(uint8_t left, uint8_t right); void quicksort(uint8_t left, uint8_t right); #endif //SDSORT_QUICKSORT - void getfilename_sorted(const uint16_t nr); + void getfilename_sorted(const uint16_t nr, uint8_t sdSort); #endif FORCE_INLINE bool isFileOpen() { return file.isOpen(); } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index de007c8cd..e4c68a834 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -7162,7 +7162,7 @@ void lcd_sdcard_menu() if (_md->sdSort == SD_SORT_NONE) card.getfilename(i); else - card.getfilename_sorted(i); + card.getfilename_sorted(i, _md->sdSort); #else card.getfilename(i); #endif @@ -7193,7 +7193,7 @@ void lcd_sdcard_menu() if (_md->sdSort == SD_SORT_NONE) card.getfilename(_md->selectedFileID); else - card.getfilename_sorted(_md->selectedFileID); + card.getfilename_sorted(_md->selectedFileID, _md->sdSort); #else card.getfilename(_md->selectedFileID); #endif