From 6a4e5df2ce531057ec9e6aa6d7375a9eff6d3788 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Mon, 14 Aug 2017 16:34:00 +0200 Subject: [PATCH] using ram/stack with and without folders for time sorting, progress bar improved --- Firmware/Configuration_adv.h | 10 +++-- Firmware/cardreader.cpp | 82 ++++++++++++++++++------------------ Firmware/cardreader.h | 2 + Firmware/ultralcd.cpp | 2 + Firmware/ultralcd.h | 3 ++ 5 files changed, 54 insertions(+), 45 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 6a44efbc7..d83137c56 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -247,15 +247,17 @@ * - 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 +#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 false. #ifdef SDCARD_SORT_ALPHA - #define SDSORT_LIMIT 30 // Maximum number of sorted items (10-256). + #define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code. - #define SDSORT_USES_RAM false // Pre-allocate a static array for faster pre-sorting. - #define SDSORT_USES_STACK false // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) + #define SDSORT_USES_RAM true // Pre-allocate a static array for faster pre-sorting. + #define SDSORT_USES_STACK true // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.) #define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option. #define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use! #endif diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 752886bd8..8268c3bcc 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -709,8 +709,9 @@ void CardReader::presort() { uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); if (sdSort == 2) return; //sd sort is turned off - - lcd_set_progress(); + #if !SDSORT_USES_RAM + lcd_set_progress(); + #endif lcd_implementation_clear(); lcd_print_at_PGM(0, 1, MSG_SORTING); @@ -746,6 +747,8 @@ void CardReader::presort() { #endif #elif SDSORT_USES_STACK char sortnames[fileCnt][LONG_FILENAME_LENGTH]; + uint16_t creation_time[SDSORT_LIMIT]; + uint16_t creation_date[SDSORT_LIMIT]; #endif // Folder sorting needs 1 bit per entry for flags. @@ -762,7 +765,9 @@ 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 + 1]; + uint16_t creation_time_bckp; + uint16_t creation_date_bckp; #endif @@ -784,6 +789,8 @@ void CardReader::presort() { #else // Copy filenames into the static array strcpy(sortnames[i], LONGEST_FILENAME); + creation_time[i] = creationTime; + creation_date[i] = creationDate; #if SDSORT_CACHE_NAMES strcpy(sortshort[i], filename); #endif @@ -800,25 +807,29 @@ void CardReader::presort() { } // Bubble Sort uint16_t counter = 0; - uint16_t cycles_count = 0; - - for (int i = fileCnt; --i;) cycles_count += i; - for (uint16_t i = fileCnt; --i;) { bool didSwap = false; + #if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used + int8_t percent = ((counter * 100) / (fileCnt-1)); + for (int column = 0; column < 20; column++) { + if (column < (percent/5)) lcd_implementation_print_at(column, 2, "\x01"); //simple progress bar + } + counter++; + #endif + //MYSERIAL.println(int(i)); for (uint16_t j = 0; j < i; ++j) { - int8_t percent = ((counter * 100) / cycles_count); - lcd_implementation_print_at(percent / 5, 2, "\x01"); //progress bar - counter++; - const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; - + const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1]; // 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() (((creation_date[o1] == creation_date[o2]) && (creation_time[o1] < creation_time[o2])) || \ + (creation_date[o1] < creation_date [o2])) #else #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2) + #define _SORT_CMP_TIME_NODIR() (((creation_date_bckp == creationDate) && (creation_time_bckp < creationTime)) || \ + (creation_date_bckp < creationDate)) #endif #if HAS_FOLDER_SORTING @@ -830,22 +841,24 @@ void CardReader::presort() { (((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 // The most economical method reads names as-needed // throughout the loop. Slow if there are many. #if !SDSORT_USES_RAM - /*SERIAL_ECHOPGM("o1 & o2: "); - MYSERIAL.println(int(o1)); - MYSERIAL.println(int(o2));*/ getfilename(o1); strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it) - uint16_t creation_date_bckp = creationDate; - uint16_t creation_time_bckp = creationTime; + creation_date_bckp = creationDate; + creation_time_bckp = creationTime; #if HAS_FOLDER_SORTING bool dir1 = filenameIsDir; #endif @@ -854,32 +867,14 @@ void CardReader::presort() { #endif // !SDSORT_USES_RAM - - // Sort the current pair according to settings. - /*if ( - - //write_date_bckp < writeDate - + if( #if HAS_FOLDER_SORTING - #if SDSORT_GCODE - sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_NODIR() - #else - _SORT_CMP_DIR(FOLDER_SORTING) - #endif + (sdSort == 0 && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == 1 && _SORT_CMP_DIR(FOLDER_SORTING)) #else - _SORT_CMP_NODIR() + (sdSort == 0 && _SORT_CMP_TIME_NODIR()) || (sdSort == 1 && _SORT_CMP_NODIR()) #endif - - )*/ - // o1 o2 - bool swap = false; - if (creation_date_bckp == creationDate) { - if (creation_time_bckp < creationTime) swap = true; - } - else if (creation_date_bckp < creationDate) swap = true; - - if((sdSort == 0 && swap) || (sdSort == 1 && _SORT_CMP_DIR(FOLDER_SORTING))) + ) { sort_order[j] = o2; sort_order[j + 1] = o1; @@ -919,8 +914,13 @@ void CardReader::presort() { } sort_count = fileCnt; - } - lcd_set_arrows(); + } + #if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used + for(int column = 0; column <=19; column++ ) lcd_implementation_print_at(column, 2, "\x01"); //simple progress bar + delay(500); + lcd_set_arrows(); + lcd_update(2); + #endif } void CardReader::flush_presort() { diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index ed1df2c77..33f67f9ff 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -105,6 +105,8 @@ private: #endif #elif !SDSORT_USES_STACK char sortnames[SDSORT_LIMIT][FILENAME_LENGTH]; + uint16_t creation_time[SDSORT_LIMIT]; + uint16_t creation_date[SDSORT_LIMIT]; #endif // Folder sorting uses an isDir array when caching items. diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ca3fc7a4e..3be5dcf01 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2432,6 +2432,7 @@ static void lcd_set_lang(unsigned char lang) { langsel = LANGSEL_ACTIVE; } +#if !SDSORT_USES_RAM void lcd_set_arrows() { void lcd_set_custom_characters_arrows(); } @@ -2439,6 +2440,7 @@ void lcd_set_arrows() { void lcd_set_progress() { lcd_set_custom_characters_progress(); } +#endif void lcd_force_language_selection() { eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION); diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 8eac1ef90..99b3c4485 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -261,6 +261,9 @@ void display_loading(); void lcd_service_mode_show_result(); +#if !SDSORT_USES_RAM void lcd_set_arrows(); void lcd_set_progress(); +#endif + #endif //ULTRALCD_H \ No newline at end of file