diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 56058b0f9..e42bf1c2f 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -47,6 +47,7 @@ #define EEPROM_TEMP_CAL_ACTIVE (EEPROM_PROBE_TEMP_SHIFT - 1) #define EEPROM_BOWDEN_LENGTH (EEPROM_TEMP_CAL_ACTIVE - 2*4) //4 x int for bowden lengths for multimaterial #define EEPROM_CALIBRATION_STATUS_PINDA (EEPROM_BOWDEN_LENGTH - 1) //0 - not calibrated; 1 - calibrated +#define EEPROM_SD_SORT (EEPROM_CALIBRATION_STATUS_PINDA - 1) //0 -time, 1-alpha, 2-none // Currently running firmware, each digit stored as uint16_t. // The flavor differentiates a dev, alpha, beta, release candidate or a release version. diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index c5c4031c0..6a44efbc7 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -247,11 +247,11 @@ * - 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 #ifdef SDCARD_SORT_ALPHA - #define SDSORT_LIMIT 20 // Maximum number of sorted items (10-256). + #define SDSORT_LIMIT 30 // 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. diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index a5c7ffa2a..72879ff78 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -92,6 +92,12 @@ extern const char echomagic[] PROGMEM; #define SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value))) +typedef enum { + SDSORT_TIME, + SDSORT_ALPHA, + SDSORT_NONE +} sdsort; + void serial_echopair_P(const char *s_P, float v); void serial_echopair_P(const char *s_P, double v); void serial_echopair_P(const char *s_P, unsigned long v); @@ -327,6 +333,8 @@ extern bool mesh_bed_run_from_menu; extern float distance_from_min[3]; extern float angleDiff; +extern bool sortAlpha; + extern void calculate_volumetric_multipliers(); // Similar to the default Arduino delay function, diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 4ded6e3d6..0a24556db 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -83,7 +83,6 @@ #define TEST(n,b) (((n)&BIT(b))!=0) #define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (BIT(b)) - // look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html // http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes @@ -290,6 +289,8 @@ char snmm_filaments_used = 0; float distance_from_min[3]; float angleDiff; +bool sortAlpha = false; + bool volumetric_enabled = false; float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA #if EXTRUDERS > 1 @@ -1188,6 +1189,9 @@ void setup() if (eeprom_read_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA) == 255) { eeprom_write_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); } + if (eeprom_read_byte((uint8_t*)EEPROM_SD_SORT) == 255) { + eeprom_write_byte((uint8_t*)EEPROM_SD_SORT, 0); + } check_babystep(); //checking if Z babystep is in allowed range diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index e723261be..752886bd8 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -133,7 +133,23 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m break; case LS_GetFilename: + //SERIAL_ECHOPGM("File: "); createFilename(filename, p); + /*MYSERIAL.println(filename); + SERIAL_ECHOPGM("Write date: "); + writeDate = p.lastWriteDate; + MYSERIAL.println(writeDate); + writeTime = p.lastWriteTime; + SERIAL_ECHOPGM("Creation date: "); + MYSERIAL.println(p.creationDate); + SERIAL_ECHOPGM("Access date: "); + MYSERIAL.println(p.lastAccessDate); + SERIAL_ECHOLNPGM("");*/ + creationDate = p.creationDate; + creationTime = p.creationTime; + + //writeDate = p.lastAccessDate; + if (match != NULL) { if (strcasecmp(match, filename) == 0) return; } @@ -690,6 +706,14 @@ void CardReader::getfilename_sorted(const uint16_t nr) { */ 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(); + lcd_implementation_clear(); + lcd_print_at_PGM(0, 1, MSG_SORTING); + #if SDSORT_GCODE if (!sort_alpha) return; #endif @@ -743,7 +767,6 @@ void CardReader::presort() { #endif if (fileCnt > 1) { - SERIAL_ECHOLNPGM("Sort order:"); // Init sort order. for (uint16_t i = 0; i < fileCnt; i++) { sort_order[i] = i; @@ -775,15 +798,20 @@ void CardReader::presort() { #endif #endif } - - SERIAL_ECHOPGM("FILE_CNT:"); - MYSERIAL.println(int(fileCnt)); // 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; - MYSERIAL.println(int(i)); + + //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]; // Compare names from the array or just the two buffered names @@ -810,25 +838,29 @@ void CardReader::presort() { // The most economical method reads names as-needed // throughout the loop. Slow if there are many. #if !SDSORT_USES_RAM - SERIAL_ECHOPGM("o1 & o2: "); + /*SERIAL_ECHOPGM("o1 & o2: "); MYSERIAL.println(int(o1)); - MYSERIAL.println(int(o2)); + 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; #if HAS_FOLDER_SORTING bool dir1 = filenameIsDir; #endif getfilename(o2); char *name2 = LONGEST_FILENAME; // use the string in-place - SERIAL_ECHOLNPGM("Names:"); - MYSERIAL.println(name1); - MYSERIAL.println(name2); #endif // !SDSORT_USES_RAM + + // Sort the current pair according to settings. - if ( + /*if ( + + //write_date_bckp < writeDate + #if HAS_FOLDER_SORTING #if SDSORT_GCODE sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_NODIR() @@ -838,15 +870,25 @@ void CardReader::presort() { #else _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; didSwap = true; - SERIAL_ECHOLNPGM("Did swap"); + //SERIAL_ECHOLNPGM("did swap"); } } if (!didSwap) break; - } + } //end of bubble sort loop // Using RAM but not keeping names around #if (SDSORT_USES_RAM && !SDSORT_CACHE_NAMES) @@ -877,8 +919,8 @@ void CardReader::presort() { } sort_count = fileCnt; - } - + } + lcd_set_arrows(); } void CardReader::flush_presort() { diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 82929708a..ed1df2c77 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -7,6 +7,8 @@ #include "SdFile.h" enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename}; +enum SdSort {sdSortTime, sdSortAlpha, sdSortNone}; + class CardReader { public: @@ -30,7 +32,7 @@ public: void printingHasFinished(); void getfilename(uint16_t nr, const char* const match=NULL); - uint16_t getnrfilenames(); + uint16_t getnrfilenames(); void getAbsFilename(char *t); @@ -67,6 +69,7 @@ public: bool sdprinting ; bool cardOK ; char filename[13]; + uint16_t creationTime, creationDate; char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; @@ -89,7 +92,6 @@ private: #else uint8_t sort_order[SDSORT_LIMIT]; #endif - // Cache filenames to speed up SD menus. #if SDSORT_USES_RAM @@ -135,6 +137,7 @@ private: bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. LsAction lsAction; //stored for recursion. + uint8_t sdSort; int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory. char* diveDirName; void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); diff --git a/Firmware/language_all.cpp b/Firmware/language_all.cpp index 73f8477e1..7035a2d8f 100644 --- a/Firmware/language_all.cpp +++ b/Firmware/language_all.cpp @@ -2948,6 +2948,26 @@ const char * const MSG_SOFTWARE_RESET_LANG_TABLE[1] PROGMEM = { MSG_SOFTWARE_RESET_EN }; +const char MSG_SORTING_EN[] PROGMEM = "Sorting files"; +const char * const MSG_SORTING_LANG_TABLE[1] PROGMEM = { + MSG_SORTING_EN +}; + +const char MSG_SORT_ALPHA_EN[] PROGMEM = "Sort: [Alphabet]"; +const char * const MSG_SORT_ALPHA_LANG_TABLE[1] PROGMEM = { + MSG_SORT_ALPHA_EN +}; + +const char MSG_SORT_NONE_EN[] PROGMEM = "Sort: [None]"; +const char * const MSG_SORT_NONE_LANG_TABLE[1] PROGMEM = { + MSG_SORT_NONE_EN +}; + +const char MSG_SORT_TIME_EN[] PROGMEM = "Sort: [Time]"; +const char * const MSG_SORT_TIME_LANG_TABLE[1] PROGMEM = { + MSG_SORT_TIME_EN +}; + const char MSG_SPEED_EN[] PROGMEM = "Speed"; const char MSG_SPEED_CZ[] PROGMEM = "Rychlost"; const char MSG_SPEED_IT[] PROGMEM = "Velocita"; diff --git a/Firmware/language_all.h b/Firmware/language_all.h index 979123e35..209c4954a 100644 --- a/Firmware/language_all.h +++ b/Firmware/language_all.h @@ -550,6 +550,14 @@ extern const char* const MSG_SLIGHT_SKEW_LANG_TABLE[LANG_NUM]; #define MSG_SLIGHT_SKEW LANG_TABLE_SELECT(MSG_SLIGHT_SKEW_LANG_TABLE) extern const char* const MSG_SOFTWARE_RESET_LANG_TABLE[1]; #define MSG_SOFTWARE_RESET LANG_TABLE_SELECT_EXPLICIT(MSG_SOFTWARE_RESET_LANG_TABLE, 0) +extern const char* const MSG_SORTING_LANG_TABLE[1]; +#define MSG_SORTING LANG_TABLE_SELECT_EXPLICIT(MSG_SORTING_LANG_TABLE, 0) +extern const char* const MSG_SORT_ALPHA_LANG_TABLE[1]; +#define MSG_SORT_ALPHA LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_ALPHA_LANG_TABLE, 0) +extern const char* const MSG_SORT_NONE_LANG_TABLE[1]; +#define MSG_SORT_NONE LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_NONE_LANG_TABLE, 0) +extern const char* const MSG_SORT_TIME_LANG_TABLE[1]; +#define MSG_SORT_TIME LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_TIME_LANG_TABLE, 0) extern const char* const MSG_SPEED_LANG_TABLE[LANG_NUM]; #define MSG_SPEED LANG_TABLE_SELECT(MSG_SPEED_LANG_TABLE) extern const char* const MSG_STACK_ERROR_LANG_TABLE[1]; diff --git a/Firmware/language_en.h b/Firmware/language_en.h index 9a275fa30..4e5e7b195 100644 --- a/Firmware/language_en.h +++ b/Firmware/language_en.h @@ -311,4 +311,8 @@ #define(length=15, lines=1) MSG_MEASURED_SKEW "Measured skew:" #define(length=15, lines=1) MSG_SLIGHT_SKEW "Slight skew:" #define(length=15, lines=1) MSG_SEVERE_SKEW "Severe skew:" -#define(length=20, lines=4) MSG_DEFAULT_SETTINGS_LOADED "Default settings loaded" \ No newline at end of file +#define(length=20, lines=4) MSG_DEFAULT_SETTINGS_LOADED "Default settings loaded" +#define(length=17, lines=1) MSG_SORT_TIME "Sort: [Time]" +#define(length=17, lines=1) MSG_SORT_ALPHA "Sort: [Alphabet]" +#define(length=17, lines=1) MSG_SORT_NONE "Sort: [None]" +#define(length=20, lines=1) MSG_SORTING "Sorting files" \ No newline at end of file diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e858afe2b..4843274a5 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2394,8 +2394,24 @@ void EEPROM_read(int pos, uint8_t* value, uint8_t size) value++; } while (--size); } - - +#ifdef SDCARD_SORT_ALPHA +static void lcd_sort_type_set() { + uint8_t sdSort; + + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort)); + switch (sdSort) { + case 0: sdSort = 1; break; + case 1: sdSort = 2; break; + default: sdSort = 0; + } + eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort); + lcd_goto_menu(lcd_sdcard_menu, 1); + //lcd_update(2); + //delay(1000); + + card.presort(); +} +#endif //SDCARD_SORT_ALPHA static void lcd_silent_mode_set() { SilentModeMenu = !SilentModeMenu; @@ -2413,6 +2429,14 @@ static void lcd_set_lang(unsigned char lang) { langsel = LANGSEL_ACTIVE; } +void lcd_set_arrows() { + void lcd_set_custom_characters_arrows(); +} + +void lcd_set_progress() { + lcd_set_custom_characters_progress(); +} + void lcd_force_language_selection() { eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION); } @@ -4118,16 +4142,24 @@ void getFileDescription(char *name, char *description) { */ void lcd_sdcard_menu() -{ - - int tempScrool = 0; +{ + uint8_t sdSort; + int tempScrool = 0; if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) //delay(100); - return; // nothing to do (so don't thrash the SD card) + return; // nothing to do (so don't thrash the SD card) uint16_t fileCnt = card.getnrfilenames(); - + START_MENU(); MENU_ITEM(back, MSG_MAIN, lcd_main_menu); +#ifdef SDCARD_SORT_ALPHA + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort)); + switch(sdSort){ + case 0: MENU_ITEM(function, MSG_SORT_TIME, lcd_sort_type_set); break; + case 1: MENU_ITEM(function, MSG_SORT_ALPHA, lcd_sort_type_set); break; + default: MENU_ITEM(function, MSG_SORT_NONE, lcd_sort_type_set); + } +#endif // SDCARD_SORT_ALPHA card.getWorkDirName(); if (card.filename[0] == '/') { @@ -4142,16 +4174,16 @@ void lcd_sdcard_menu() { if (_menuItemNr == _lineNr) { - const uint16_t nr = - #ifdef SDCARD_RATHERRECENTFIRST + const uint16_t nr = (sdSort == 2) ? (fileCnt - 1 - i) : i; + /* #ifdef SDCARD_RATHERRECENTFIRST #ifndef SDCARD_SORT_ALPHA fileCnt - 1 - #endif #endif - i; - + i;*/ #ifdef SDCARD_SORT_ALPHA - card.getfilename_sorted(nr); + if (sdSort == 2) card.getfilename(nr); + else card.getfilename_sorted(nr); #else card.getfilename(nr); #endif diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 2a8fb89e0..8eac1ef90 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -227,7 +227,9 @@ void extr_unload_all(); void extr_unload_used(); void extr_unload(); static char snmm_stop_print_menu(); - +#ifdef SDCARD_SORT_ALPHA +static void lcd_sort_type_set(); +#endif void stack_error(); static void lcd_ping_allert(); void lcd_printer_connected(); @@ -259,4 +261,6 @@ void display_loading(); void lcd_service_mode_show_result(); +void lcd_set_arrows(); +void lcd_set_progress(); #endif //ULTRALCD_H \ No newline at end of file diff --git a/Firmware/ultralcd_implementation_hitachi_HD44780.h b/Firmware/ultralcd_implementation_hitachi_HD44780.h index 228a75d49..300d1c397 100644 --- a/Firmware/ultralcd_implementation_hitachi_HD44780.h +++ b/Firmware/ultralcd_implementation_hitachi_HD44780.h @@ -462,6 +462,22 @@ void lcd_set_custom_characters_arrows() lcd.createChar(1, arrdown); } +void lcd_set_custom_characters_progress() +{ + byte progress[8] = { + B11111, + B11111, + B11111, + B11111, + B11111, + B11111, + B11111, + B11111, + }; + + lcd.createChar(1, progress); +} + void lcd_set_custom_characters_nextpage() {