diff --git a/.travis.yml b/.travis.yml
index 6d1a2f97e6e6f40bd7eb4d6bcddec228dd487e59..2cad83912f14e9f5436eda3220cb319cab9dc29f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -298,6 +298,15 @@ script:
- opt_enable G3D_PANEL SDSUPPORT
- build_marlin
#
+ # Add SDCARD_SORT_ALPHA, test G3D_PANEL again
+ #
+ - opt_enable_adv SDCARD_SORT_ALPHA
+ - opt_set_adv SDSORT_GCODE true
+ - opt_set_adv SDSORT_USES_RAM true
+ - opt_set_adv SDSORT_USES_STACK true
+ - opt_set_adv SDSORT_CACHE_NAMES true
+ - build_marlin
+ #
# REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#
- restore_configs
diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index 709e87e64537ab6ac48de21ae9becd2351978798..dced199ba5c018c9aded759a9993d7637f15119c 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -722,4 +722,8 @@
#define DELTA_ENDSTOP_ADJ { 0 }
#endif
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
+ #endif
+
#endif // CONDITIONALS_POST_H
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 6ea97f5b848eddb65326d83e26077f5e0fe1951b..0e12ba18df2664883bebb6d5c9cace1ffe001eff 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 593b65d0fed9baa86383966c0d768d303ecdf40d..e1cd4a4e621acc998b21cdbf00a7f6b7337562f8 100755
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -91,6 +91,7 @@
* Use P to run other files as sub-programs: "M32 P !filename#"
* The '#' is necessary when calling from within sd files, as it stops buffer prereading
* M33 - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT)
+ * M34 - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA)
* M42 - Change pin status via gcode: M42 P<pin> S<value>. LED pin assumed if P is omitted.
* M43 - Monitor pins & report changes - report active pins
* M48 - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
@@ -4843,6 +4844,20 @@ inline void gcode_M31() {
#endif
+ #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE)
+ /**
+ * M34: Set SD Card Sorting Options
+ */
+ inline void gcode_M34() {
+ if (code_seen('S')) card.setSortOn(code_value_bool());
+ if (code_seen('F')) {
+ int v = code_value_long();
+ card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0);
+ }
+ //if (code_seen('R')) card.setSortReverse(code_value_bool());
+ }
+ #endif // SDCARD_SORT_ALPHA && SDSORT_GCODE
+
/**
* M928: Start SD Write
*/
@@ -8289,6 +8304,11 @@ void process_next_command() {
gcode_M33(); break;
#endif
+ #if ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_GCODE)
+ case 34: //M34 - Set SD card sorting options
+ gcode_M34(); break;
+ #endif // SDCARD_SORT_ALPHA && SDSORT_GCODE
+
case 928: // M928: Start SD write
gcode_M928(); break;
#endif //SDSUPPORT
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 561329ef80ee8fd95cb1609ff7da5f4cea0fb6ba..c37a813151f5e6e9c9430ab00ff4a044a5777c05 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -205,6 +205,23 @@
#endif
#endif
+/**
+ * SD File Sorting
+ */
+#if ENABLED(SDCARD_SORT_ALPHA)
+ #if SDSORT_LIMIT > 256
+ #error "SDSORT_LIMIT must be 256 or smaller."
+ #elif SDSORT_LIMIT < 10
+ #error "SDSORT_LIMIT should be greater than 9 to be useful."
+ #elif DISABLED(SDSORT_USES_RAM)
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ #error "SDSORT_DYNAMIC_RAM requires SDSORT_USES_RAM (which reads the directory into RAM)."
+ #elif ENABLED(SDSORT_CACHE_NAMES)
+ #error "SDSORT_CACHE_NAMES requires SDSORT_USES_RAM (which reads the directory into RAM)."
+ #endif
+ #endif
+#endif
+
/**
* Delta requirements
*/
diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp
index c8e94143c51a145126b958886fc2157d7f2e7f92..aefc2dee45df3e58b7491af8510dbd4d753a50dd 100644
--- a/Marlin/cardreader.cpp
+++ b/Marlin/cardreader.cpp
@@ -30,7 +30,17 @@
#if ENABLED(SDSUPPORT)
+#define LONGEST_FILENAME (longFilename[0] ? longFilename : filename)
+
CardReader::CardReader() {
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ sort_count = 0;
+ #if ENABLED(SDSORT_GCODE)
+ sort_alpha = true;
+ sort_folders = FOLDER_SORTING;
+ //sort_reverse = false;
+ #endif
+ #endif
sdprinting = cardOK = saving = logging = false;
filesize = 0;
sdpos = 0;
@@ -243,6 +253,9 @@ void CardReader::initsd() {
}
workDir = root;
curDir = &root;
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
/**
if (!workDir.openRoot(&volume)) {
SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
@@ -256,6 +269,9 @@ void CardReader::setroot() {
}*/
workDir = root;
curDir = &workDir;
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
}
void CardReader::release() {
@@ -272,7 +288,12 @@ void CardReader::openAndPrintFile(const char *name) {
}
void CardReader::startFileprint() {
- if (cardOK) sdprinting = true;
+ if (cardOK) {
+ sdprinting = true;
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ flush_presort();
+ #endif
+ }
}
void CardReader::stopSDPrint() {
@@ -463,6 +484,9 @@ void CardReader::removeFile(char* name) {
SERIAL_PROTOCOLPGM("File deleted:");
SERIAL_PROTOCOLLN(fname);
sdpos = 0;
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
}
else {
SERIAL_PROTOCOLPGM("Deletion failed, File: ");
@@ -551,6 +575,20 @@ void CardReader::closefile(bool store_location) {
* Get the name of a file in the current directory by index
*/
void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) {
+ #if ENABLED(SDSORT_CACHE_NAMES)
+ if (match != NULL) {
+ while (nr < sort_count) {
+ if (strcasecmp(match, sortshort[nr]) == 0) break;
+ nr++;
+ }
+ }
+ if (nr < sort_count) {
+ strcpy(filename, sortshort[nr]);
+ strcpy(longFilename, sortnames[nr]);
+ filenameIsDir = TEST(isDir[nr>>3], nr & 0x07);
+ return;
+ }
+ #endif // SDSORT_CACHE_NAMES
curDir = &workDir;
lsAction = LS_GetFilename;
nrFiles = nr;
@@ -583,14 +621,241 @@ void CardReader::chdir(const char * relpath) {
if (workDirDepth < MAX_DIR_DEPTH)
workDirParents[workDirDepth++] = *parent;
workDir = newfile;
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
}
}
void CardReader::updir() {
- if (workDirDepth > 0)
+ if (workDirDepth > 0) {
workDir = workDirParents[--workDirDepth];
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
+ }
}
+#if ENABLED(SDCARD_SORT_ALPHA)
+
+ /**
+ * Get the name of a file in the current directory by sort-index
+ */
+ void CardReader::getfilename_sorted(const uint16_t nr) {
+ getfilename(
+ #if ENABLED(SDSORT_GCODE)
+ sort_alpha &&
+ #endif
+ (nr < sort_count) ? sort_order[nr] : nr
+ );
+ }
+
+ /**
+ * Read all the files and produce a sort key
+ *
+ * We can do this in 3 ways...
+ * - Minimal RAM: Read two filenames at a time sorting along...
+ * - Some RAM: Buffer the directory just for this sort
+ * - Most RAM: Buffer the directory and return filenames from RAM
+ */
+ void CardReader::presort() {
+
+ // Sorting may be turned off
+ #if ENABLED(SDSORT_GCODE)
+ if (!sort_alpha) return;
+ #endif
+
+ // Throw away old sort index
+ flush_presort();
+
+ // If there are files, sort up to the limit
+ uint16_t fileCnt = getnrfilenames();
+ if (fileCnt > 0) {
+
+ // Never sort more than the max allowed
+ // If you use folders to organize, 20 may be enough
+ if (fileCnt > SDSORT_LIMIT) fileCnt = SDSORT_LIMIT;
+
+ // Sort order is always needed. May be static or dynamic.
+ #if ENABLED(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 ENABLED(SDSORT_USES_RAM)
+
+ // If using dynamic ram for names, allocate on the heap.
+ #if ENABLED(SDSORT_CACHE_NAMES)
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ sortshort = new char*[fileCnt];
+ sortnames = new char*[fileCnt];
+ #endif
+ #elif ENABLED(SDSORT_USES_STACK)
+ char sortnames[fileCnt][LONG_FILENAME_LENGTH];
+ #endif
+
+ // Folder sorting needs 1 bit per entry for flags.
+ #if HAS_FOLDER_SORTING
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ isDir = new uint8_t[(fileCnt + 7) >> 3];
+ #elif ENABLED(SDSORT_USES_STACK)
+ uint8_t isDir[(fileCnt + 7) >> 3];
+ #endif
+ #endif
+
+ #else // !SDSORT_USES_RAM
+
+ // 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];
+
+ #endif
+
+ if (fileCnt > 1) {
+
+ // Init sort order.
+ for (uint16_t i = 0; i < fileCnt; i++) {
+ sort_order[i] = i;
+ // If using RAM then read all filenames now.
+ #if ENABLED(SDSORT_USES_RAM)
+ getfilename(i);
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ // Use dynamic method to copy long filename
+ sortnames[i] = strdup(LONGEST_FILENAME);
+ #if ENABLED(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);
+ #if ENABLED(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
+ }
+
+ // Bubble Sort
+ for (uint16_t i = fileCnt; --i;) {
+ bool didSwap = false;
+ for (uint16_t j = 0; j < i; ++j) {
+ const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1];
+
+ // Compare names from the array or just the two buffered names
+ #if ENABLED(SDSORT_USES_RAM)
+ #define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0)
+ #else
+ #define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0)
+ #endif
+
+ #if HAS_FOLDER_SORTING
+ #if ENABLED(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)
+ #else
+ #define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1))
+ #endif
+ #endif
+
+ // The most economical method reads names as-needed
+ // throughout the loop. Slow if there are many.
+ #if DISABLED(SDSORT_USES_RAM)
+ getfilename(o1);
+ strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
+ #if HAS_FOLDER_SORTING
+ bool dir1 = filenameIsDir;
+ #endif
+ getfilename(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
+ #if ENABLED(SDSORT_GCODE)
+ sort_folders ? _SORT_CMP_DIR(sort_folders) : _SORT_CMP_NODIR()
+ #else
+ _SORT_CMP_DIR(FOLDER_SORTING)
+ #endif
+ #else
+ _SORT_CMP_NODIR()
+ #endif
+ ) {
+ sort_order[j] = o2;
+ sort_order[j + 1] = o1;
+ didSwap = true;
+ }
+ }
+ if (!didSwap) break;
+ }
+ // Using RAM but not keeping names around
+ #if ENABLED(SDSORT_USES_RAM) && DISABLED(SDSORT_CACHE_NAMES)
+ #if ENABLED(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 ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES)
+ getfilename(0);
+ #if ENABLED(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;
+ }
+ }
+
+ void CardReader::flush_presort() {
+ if (sort_count > 0) {
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ delete sort_order;
+ #if ENABLED(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;
+ }
+ }
+
+#endif // SDCARD_SORT_ALPHA
+
void CardReader::printingHasFinished() {
stepper.synchronize();
file.close();
@@ -607,6 +872,9 @@ void CardReader::printingHasFinished() {
print_job_timer.stop();
if (print_job_timer.duration() > 60)
enqueue_and_echo_commands_P(PSTR("M31"));
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ presort();
+ #endif
}
}
diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h
index b0ed92b89d8854043a9109ef0af2b0b20d9b2d31..05e8ecf0774ce701d887eb232cd8e7de210c9bae 100644
--- a/Marlin/cardreader.h
+++ b/Marlin/cardreader.h
@@ -69,6 +69,16 @@ public:
void updir();
void setroot();
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ void presort();
+ void getfilename_sorted(const uint16_t nr);
+ #if ENABLED(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 void pauseSDPrint() { sdprinting = false; }
FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
FORCE_INLINE bool eof() { return sdpos >= filesize; }
@@ -84,6 +94,51 @@ public:
private:
SdFile root, *curDir, workDir, workDirParents[MAX_DIR_DEPTH];
uint8_t workDirDepth;
+
+ // Sort files and folders alphabetically.
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ uint16_t sort_count; // Count of sorted items in the current directory
+ #if ENABLED(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
+
+ // By default the sort index is static
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ uint8_t *sort_order;
+ #else
+ uint8_t sort_order[SDSORT_LIMIT];
+ #endif
+
+ // Cache filenames to speed up SD menus.
+ #if ENABLED(SDSORT_USES_RAM)
+
+ // If using dynamic ram for names, allocate on the heap.
+ #if ENABLED(SDSORT_CACHE_NAMES)
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ char **sortshort, **sortnames;
+ #else
+ char sortshort[SDSORT_LIMIT][FILENAME_LENGTH];
+ char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
+ #endif
+ #elif DISABLED(SDSORT_USES_STACK)
+ char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
+ #endif
+
+ // Folder sorting uses an isDir array when caching items.
+ #if HAS_FOLDER_SORTING
+ #if ENABLED(SDSORT_DYNAMIC_RAM)
+ uint8_t *isDir;
+ #elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
+ uint8_t isDir[(SDSORT_LIMIT+7)>>3];
+ #endif
+ #endif
+
+ #endif // SDSORT_USES_RAM
+
+ #endif // SDCARD_SORT_ALPHA
+
Sd2Card card;
SdVolume volume;
SdFile file;
@@ -103,6 +158,10 @@ private:
uint16_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);
+
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ void flush_presort();
+ #endif
};
extern CardReader card;
diff --git a/Marlin/example_configurations/Cartesio/Configuration_adv.h b/Marlin/example_configurations/Cartesio/Configuration_adv.h
index dc5ffb731c891b9584b26765d12d1d89bdfcf23a..687dade67988af7569933a21f733123572a52ce5 100644
--- a/Marlin/example_configurations/Cartesio/Configuration_adv.h
+++ b/Marlin/example_configurations/Cartesio/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h
index 65b7d68c66f5313ff96c1ca4b179a511ae88d336..141879a94472e14a194bf903ea9a5aec4385e458 100644
--- a/Marlin/example_configurations/Felix/Configuration_adv.h
+++ b/Marlin/example_configurations/Felix/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/Hephestos/Configuration_adv.h b/Marlin/example_configurations/Hephestos/Configuration_adv.h
index f0653bf9e7db13ef30d785ad11d074503d529b32..c9cdf560e01746246607221f3c52f83bd983a8d4 100644
--- a/Marlin/example_configurations/Hephestos/Configuration_adv.h
+++ b/Marlin/example_configurations/Hephestos/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration_adv.h b/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
index 7b4fedeff8be7cef83090fd10ecf97f6441e57ee..ceb0dfe3702ad9c7b7eac7f0356bd31e477ce118 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/K8200/Configuration_adv.h b/Marlin/example_configurations/K8200/Configuration_adv.h
index b3b908ef5a55052cc863de7c37d87eff25839ac8..1a84914b1475fce69c608ba4e3976f8e3404e43d 100644
--- a/Marlin/example_configurations/K8200/Configuration_adv.h
+++ b/Marlin/example_configurations/K8200/Configuration_adv.h
@@ -455,6 +455,42 @@
// using:
#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/K8400/Configuration_adv.h b/Marlin/example_configurations/K8400/Configuration_adv.h
index b3de87f8e7236b205f9e6f4d656af7aaf615ddb4..67f0ee6682157713ca39c8abf94d9ba329d08693 100644
--- a/Marlin/example_configurations/K8400/Configuration_adv.h
+++ b/Marlin/example_configurations/K8400/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/RigidBot/Configuration_adv.h b/Marlin/example_configurations/RigidBot/Configuration_adv.h
index 77da9d60575386c492369c4c30c3fd208af05c32..e501cb328e28edc345d8ebded8ac0fda40af8742 100644
--- a/Marlin/example_configurations/RigidBot/Configuration_adv.h
+++ b/Marlin/example_configurations/RigidBot/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h
index 4e505c6dd9e39aeec509c1a1ca96ac68c58880fa..deefbf14267b3784d2eb133798369e1ba8e8c57b 100644
--- a/Marlin/example_configurations/SCARA/Configuration_adv.h
+++ b/Marlin/example_configurations/SCARA/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/TAZ4/Configuration_adv.h b/Marlin/example_configurations/TAZ4/Configuration_adv.h
index a6d58860f6ff4061b51410eab7282cf5d65735e6..816a454013a35729cfa5c486a30b895e2c1a1a1c 100644
--- a/Marlin/example_configurations/TAZ4/Configuration_adv.h
+++ b/Marlin/example_configurations/TAZ4/Configuration_adv.h
@@ -450,6 +450,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/WITBOX/Configuration_adv.h b/Marlin/example_configurations/WITBOX/Configuration_adv.h
index f0653bf9e7db13ef30d785ad11d074503d529b32..c9cdf560e01746246607221f3c52f83bd983a8d4 100644
--- a/Marlin/example_configurations/WITBOX/Configuration_adv.h
+++ b/Marlin/example_configurations/WITBOX/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h
index 6303a6daa6d569d7f8f2171df71de3773dad3a49..6680289697eed75b30aec784665f766233e4eda0 100644
--- a/Marlin/example_configurations/delta/generic/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h
@@ -444,6 +444,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
index 6303a6daa6d569d7f8f2171df71de3773dad3a49..6680289697eed75b30aec784665f766233e4eda0 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
@@ -444,6 +444,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
index 1ed931d9afb6650976eb23dddf5393b73d7e7fba..7553e02fa64de12b7c72a1d03eb7ebeab85be62b 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
@@ -449,6 +449,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
index e030642fb163c4178645b787d1e7ba0124dbbb51..4ce2bd808f0819269370607529e3506d23e26151 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
@@ -444,6 +444,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h
index 74f77cd313ff70d612d1f98674cb186b6e6ca3cc..34cc51e9edd73adf77774135087e91ec2daa7f9e 100644
--- a/Marlin/example_configurations/makibox/Configuration_adv.h
+++ b/Marlin/example_configurations/makibox/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
index 86484f691a5413571155fbaaea5976fd0e9f0a49..8f9df52d30f4b9c7bce7f52bad75d9748531765a 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
@@ -442,6 +442,42 @@
// using:
//#define MENU_ADDAUTOSTART
+ /**
+ * Sort SD file listings in alphabetical order.
+ *
+ * With this option enabled, items on SD cards will be sorted
+ * by name for easier navigation.
+ *
+ * By default...
+ *
+ * - Use the slowest -but safest- method for sorting.
+ * - Folders are sorted to the top.
+ * - The sort key is statically allocated.
+ * - No added G-code (M34) support.
+ * - 40 item sorting limit. (Items after the first 40 are unsorted.)
+ *
+ * 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
+
+ // SD Card Sorting options
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ #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_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
+
// Show a progress bar on HD44780 LCDs for SD printing
//#define LCD_PROGRESS_BAR
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 81aee75a6e63332b5ce2bb799a59cf75308aee33..b7123b02cb245983dd62a1df04ac081e081ac743 100755
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -2277,12 +2277,17 @@ KeepDrawing:
for (uint16_t i = 0; i < fileCnt; i++) {
if (_menuLineNr == _thisItemNr) {
- card.getfilename(
- #if ENABLED(SDCARD_RATHERRECENTFIRST)
- fileCnt-1 -
- #endif
- i
- );
+ #if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA)
+ int nr = fileCnt - 1 - i;
+ #else
+ int nr = i;
+ #endif
+
+ #if ENABLED(SDCARD_SORT_ALPHA)
+ card.getfilename_sorted(nr);
+ #else
+ card.getfilename(nr);
+ #endif
if (card.filenameIsDir)
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);