Browse Source

# This is a combination of 4 commits.

# The first commit's message is:
SD Card Alpha Sorting

First iteration of alphabetical sorting for SD cards, both
slow+efficient and fast+rammy. Option for folders to sort first, last,
or not at all.

# This is the 2nd commit message:

Expand on More RAM concept, address minor bugs

# This is the 3rd commit message:

Improvements, more SORT_USES_MORE_RAM

With this option, always keeps the dir in RAM, doubling as a cache for
getfilename. A board with only 8K of SRAM is cutting it very close.

# This is the 4th commit message:

Completed SORT_USES_MORE_RAM implementation

For the MORE_RAM option we need to buffer both the short and long
names, even though long names are sometimes redundant. Worst case, all
the names are max length. We can save some RAM by not storing these. We
could save more RAM by only storing the visible part of the long name.
Scott Lahteine 10 years ago
parent
commit
de725bd408
5 changed files with 237 additions and 52 deletions
  1. 1
    0
      Marlin/Configuration_adv.h
  2. 3
    1
      Marlin/SdFatConfig.h
  3. 189
    33
      Marlin/cardreader.cpp
  4. 26
    7
      Marlin/cardreader.h
  5. 18
    11
      Marlin/ultralcd.cpp

+ 1
- 0
Marlin/Configuration_adv.h View File

290
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
290
 #define SD_FINISHED_STEPPERRELEASE true  //if sd support and the file is finished: disable steppers?
291
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
291
 #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
292
 
292
 
293
+#define SDCARD_SORT_ALPHA // Sort in ASCII order by pre-reading the folder and making a lookup table!
293
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
294
 #define SDCARD_RATHERRECENTFIRST  //reverse file order of sd card menu display. Its sorted practically after the file system block order.
294
 // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that.
295
 // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that.
295
 // using:
296
 // using:

+ 3
- 1
Marlin/SdFatConfig.h View File

111
 /**
111
 /**
112
  * Defines for long (vfat) filenames
112
  * Defines for long (vfat) filenames
113
  */
113
  */
114
+/** Number of UTF-16 characters per entry */
115
+#define FILENAME_LENGTH 13
114
 /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
116
 /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
115
 #define MAX_VFAT_ENTRIES (2)
117
 #define MAX_VFAT_ENTRIES (2)
116
 /** Total size of the buffer used to store the long filenames */
118
 /** Total size of the buffer used to store the long filenames */
117
-#define LONG_FILENAME_LENGTH (13*MAX_VFAT_ENTRIES+1)
119
+#define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1)
118
 #endif  // SdFatConfig_h
120
 #endif  // SdFatConfig_h
119
 
121
 
120
 
122
 

+ 189
- 33
Marlin/cardreader.cpp View File

11
 
11
 
12
 CardReader::CardReader()
12
 CardReader::CardReader()
13
 {
13
 {
14
+  #ifdef SDCARD_SORT_ALPHA
15
+   sort_count = 0;
16
+  #endif
14
    filesize = 0;
17
    filesize = 0;
15
    sdpos = 0;
18
    sdpos = 0;
16
    sdprinting = false;
19
    sdprinting = false;
33
   autostart_atmillis=millis()+5000;
36
   autostart_atmillis=millis()+5000;
34
 }
37
 }
35
 
38
 
36
-char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
39
+char *createFilename(char *buffer, const dir_t &p) //buffer>12characters
37
 {
40
 {
38
   char *pos=buffer;
41
   char *pos=buffer;
39
-  for (uint8_t i = 0; i < 11; i++) 
40
-  {
41
-    if (p.name[i] == ' ')continue;
42
-    if (i == 8) 
43
-    {
44
-      *pos++='.';
45
-    }
46
-    *pos++=p.name[i];
42
+  for (uint8_t i = 0; i < 11; i++) {
43
+    if (p.name[i] == ' ') continue;
44
+    if (i == 8) *pos++ = '.';
45
+    *pos++ = p.name[i];
47
   }
46
   }
48
-  *pos++=0;
47
+  *pos++ = 0;
49
   return buffer;
48
   return buffer;
50
 }
49
 }
51
 
50
 
53
 void  CardReader::lsDive(const char *prepend,SdFile parent)
52
 void  CardReader::lsDive(const char *prepend,SdFile parent)
54
 {
53
 {
55
   dir_t p;
54
   dir_t p;
56
- uint8_t cnt=0;
55
+  uint8_t cnt=0;
57
  
56
  
58
   while (parent.readDir(p, longFilename) > 0)
57
   while (parent.readDir(p, longFilename) > 0)
59
   {
58
   {
60
     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
59
     if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
61
     {
60
     {
62
 
61
 
63
-      char path[13*2];
64
-      char lfilename[13];
62
+      char path[FILENAME_LENGTH*2];
63
+      char lfilename[FILENAME_LENGTH];
65
       createFilename(lfilename,p);
64
       createFilename(lfilename,p);
66
       
65
       
67
       path[0]=0;
66
       path[0]=0;
87
       }
86
       }
88
       lsDive(path,dir);
87
       lsDive(path,dir);
89
       //close done automatically by destructor of SdFile
88
       //close done automatically by destructor of SdFile
90
-
91
-      
92
     }
89
     }
93
     else
90
     else
94
     {
91
     {
101
         if ( p.name[1] != '.')
98
         if ( p.name[1] != '.')
102
         continue;
99
         continue;
103
       }
100
       }
104
-      
101
+
105
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
102
       if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
106
       filenameIsDir=DIR_IS_SUBDIR(&p);
103
       filenameIsDir=DIR_IS_SUBDIR(&p);
107
-      
108
-      
104
+
109
       if(!filenameIsDir)
105
       if(!filenameIsDir)
110
       {
106
       {
111
         if(p.name[8]!='G') continue;
107
         if(p.name[8]!='G') continue;
124
       } 
120
       } 
125
       else if(lsAction==LS_GetFilename)
121
       else if(lsAction==LS_GetFilename)
126
       {
122
       {
127
-        if(cnt==nrFiles)
128
-          return;
123
+        if (cnt == nrFiles) return;
129
         cnt++;
124
         cnt++;
130
-        
131
       }
125
       }
132
     }
126
     }
133
   }
127
   }
136
 void CardReader::ls() 
130
 void CardReader::ls() 
137
 {
131
 {
138
   lsAction=LS_SerialPrint;
132
   lsAction=LS_SerialPrint;
139
-  if(lsAction==LS_Count)
140
-  nrFiles=0;
141
-
142
   root.rewind();
133
   root.rewind();
143
   lsDive("",root);
134
   lsDive("",root);
144
 }
135
 }
177
   }
168
   }
178
   workDir=root;
169
   workDir=root;
179
   curDir=&root;
170
   curDir=&root;
171
+  #ifdef SDCARD_SORT_ALPHA
172
+    presort();
173
+  #endif
180
   /*
174
   /*
181
   if(!workDir.openRoot(&volume))
175
   if(!workDir.openRoot(&volume))
182
   {
176
   {
193
     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
187
     SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
194
   }*/
188
   }*/
195
   workDir=root;
189
   workDir=root;
196
-  
197
   curDir=&workDir;
190
   curDir=&workDir;
191
+  #ifdef SDCARD_SORT_ALPHA
192
+    presort();
193
+  #endif
198
 }
194
 }
199
 void CardReader::release()
195
 void CardReader::release()
200
 {
196
 {
207
   if(cardOK)
203
   if(cardOK)
208
   {
204
   {
209
     sdprinting = true;
205
     sdprinting = true;
206
+    flush_presort();
210
   }
207
   }
211
 }
208
 }
212
 
209
 
235
     while(*t!=0 && cnt< MAXPATHNAMELENGTH) 
232
     while(*t!=0 && cnt< MAXPATHNAMELENGTH) 
236
     {t++;cnt++;}  //crawl counter forward.
233
     {t++;cnt++;}  //crawl counter forward.
237
   }
234
   }
238
-  if(cnt<MAXPATHNAMELENGTH-13)
235
+  if(cnt<MAXPATHNAMELENGTH-FILENAME_LENGTH)
239
     file.getFilename(t);
236
     file.getFilename(t);
240
   else
237
   else
241
     t[0]=0;
238
     t[0]=0;
305
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
302
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
306
       if(dirname_end>0 && dirname_end>dirname_start)
303
       if(dirname_end>0 && dirname_end>dirname_start)
307
       {
304
       {
308
-        char subdirname[13];
305
+        char subdirname[FILENAME_LENGTH];
309
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
306
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
310
         subdirname[dirname_end-dirname_start]=0;
307
         subdirname[dirname_end-dirname_start]=0;
311
         SERIAL_ECHOLN(subdirname);
308
         SERIAL_ECHOLN(subdirname);
401
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
398
       //SERIAL_ECHO("end  :");SERIAL_ECHOLN((int)(dirname_end-name));
402
       if(dirname_end>0 && dirname_end>dirname_start)
399
       if(dirname_end>0 && dirname_end>dirname_start)
403
       {
400
       {
404
-        char subdirname[13];
401
+        char subdirname[FILENAME_LENGTH];
405
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
402
         strncpy(subdirname, dirname_start, dirname_end-dirname_start);
406
         subdirname[dirname_end-dirname_start]=0;
403
         subdirname[dirname_end-dirname_start]=0;
407
         SERIAL_ECHOLN(subdirname);
404
         SERIAL_ECHOLN(subdirname);
439
       SERIAL_PROTOCOLPGM("File deleted:");
436
       SERIAL_PROTOCOLPGM("File deleted:");
440
       SERIAL_PROTOCOLLN(fname);
437
       SERIAL_PROTOCOLLN(fname);
441
       sdpos = 0;
438
       sdpos = 0;
439
+      #ifdef SDCARD_SORT_ALPHA
440
+        presort();
441
+      #endif
442
     }
442
     }
443
     else
443
     else
444
     {
444
     {
552
   
552
   
553
 }
553
 }
554
 
554
 
555
-void CardReader::getfilename(const uint8_t nr)
555
+void CardReader::getfilename(const uint16_t nr)
556
 {
556
 {
557
+  #if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM
558
+    if (nr < sort_count) {
559
+      strcpy(filename, sortshort[nr]);
560
+      strcpy(longFilename, sortnames[nr]);
561
+      filenameIsDir = isDir[nr];
562
+      return;
563
+    }
564
+  #endif
557
   curDir=&workDir;
565
   curDir=&workDir;
558
   lsAction=LS_GetFilename;
566
   lsAction=LS_GetFilename;
559
   nrFiles=nr;
567
   nrFiles=nr;
560
   curDir->rewind();
568
   curDir->rewind();
561
   lsDive("",*curDir);
569
   lsDive("",*curDir);
562
-  
563
 }
570
 }
564
 
571
 
565
 uint16_t CardReader::getnrfilenames()
572
 uint16_t CardReader::getnrfilenames()
577
 {
584
 {
578
   SdFile newfile;
585
   SdFile newfile;
579
   SdFile *parent=&root;
586
   SdFile *parent=&root;
580
-  
587
+
581
   if(workDir.isOpen())
588
   if(workDir.isOpen())
582
     parent=&workDir;
589
     parent=&workDir;
583
   
590
   
595
       workDirParents[0]=*parent;
602
       workDirParents[0]=*parent;
596
     }
603
     }
597
     workDir=newfile;
604
     workDir=newfile;
605
+    #ifdef SDCARD_SORT_ALPHA
606
+      presort();
607
+    #endif
598
   }
608
   }
599
 }
609
 }
600
 
610
 
601
 void CardReader::updir()
611
 void CardReader::updir()
602
 {
612
 {
603
-  if(workDirDepth > 0)
613
+  if (workDirDepth > 0)
604
   {
614
   {
605
     --workDirDepth;
615
     --workDirDepth;
606
     workDir = workDirParents[0];
616
     workDir = workDirParents[0];
607
-    int d;
608
     for (int d = 0; d < workDirDepth; d++)
617
     for (int d = 0; d < workDirDepth; d++)
609
       workDirParents[d] = workDirParents[d+1];
618
       workDirParents[d] = workDirParents[d+1];
619
+    #ifdef SDCARD_SORT_ALPHA
620
+      presort();
621
+    #endif
622
+  }
623
+}
624
+
625
+#ifdef SDCARD_SORT_ALPHA
626
+
627
+/**
628
+ * Get the name of a file in the current directory by sort-index
629
+ */
630
+void CardReader::getfilename_sorted(const uint16_t nr) {
631
+  getfilename(nr < sort_count ? sort_order[nr] : nr);
632
+}
633
+
634
+/**
635
+ * Read all the files and produce a sort key
636
+ *
637
+ * We can do this in 3 ways...
638
+ *  - Minimal RAM: Read two filenames at a time sorting along...
639
+ *  - Some RAM: Buffer the directory and return filenames from RAM
640
+ *  - Some RAM: Buffer the directory just for this sort
641
+ */
642
+void CardReader::presort()
643
+{
644
+  flush_presort();
645
+
646
+  uint16_t fileCnt = getnrfilenames();
647
+  if (fileCnt > 0) {
648
+
649
+    if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT;
650
+
651
+    #if SORT_USES_RAM
652
+      #if SORT_USES_MORE_RAM
653
+        sortshort = (char**)calloc(fileCnt, sizeof(char*));
654
+        sortnames = (char**)calloc(fileCnt, sizeof(char*));
655
+      #else
656
+        char *sortnames[fileCnt];
657
+      #endif
658
+    #else
659
+      char name1[LONG_FILENAME_LENGTH+1];
660
+    #endif
661
+
662
+    #if FOLDER_SORTING != 0
663
+      #if SORT_USES_RAM && SORT_USES_MORE_RAM
664
+        isDir = (uint8_t*)calloc(fileCnt, sizeof(uint8_t));
665
+      #else
666
+        uint8_t isDir[fileCnt];
667
+      #endif
668
+    #endif
669
+
670
+    sort_order = new uint8_t[fileCnt];
671
+
672
+    if (fileCnt > 1) {
673
+
674
+      // Init sort order. If using RAM then read all filenames now.
675
+      for (uint16_t i=0; i<fileCnt; i++) {
676
+        sort_order[i] = i;
677
+        #if SORT_USES_RAM
678
+          getfilename(i);
679
+          sortnames[i] = strdup(longFilename[0] ? longFilename : filename);
680
+          #if SORT_USES_MORE_RAM
681
+            sortshort[i] = strdup(filename);
682
+          #endif
683
+          // char out[30];
684
+          // sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
685
+          // SERIAL_ECHOLN(out);
686
+          #if FOLDER_SORTING != 0
687
+            isDir[i] = filenameIsDir;
688
+          #endif
689
+        #endif
690
+      }
691
+
692
+      // Bubble Sort
693
+      for (uint16_t i=fileCnt; --i;) {
694
+        bool cmp, didSwap = false;
695
+        for (uint16_t j=0; j<i; ++j) {
696
+          uint16_t s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2];
697
+          #if SORT_USES_RAM
698
+            #if FOLDER_SORTING != 0
699
+              cmp = (isDir[o1] == isDir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isDir[FOLDER_SORTING > 0 ? o1 : o2];
700
+            #else
701
+              cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0;
702
+            #endif
703
+          #else
704
+            getfilename(o1);
705
+            strcpy(name1, longFilename[0] ? longFilename : filename);
706
+            #if FOLDER_SORTING != 0
707
+              bool dir1 = filenameIsDir;
708
+            #endif
709
+            getfilename(o2);
710
+            char *name2 = longFilename[0] ? longFilename : filename;
711
+            #if FOLDER_SORTING != 0
712
+              cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1);
713
+            #else
714
+              cmp = strcasecmp(name1, name2) > 0;
715
+            #endif
716
+          #endif
717
+          if (cmp) {
718
+            // char out[LONG_FILENAME_LENGTH*2+20];
719
+            // sprintf_P(out, PSTR("Swap %i %s for %i %s"), o1, sortnames[o1], o2, sortnames[o2]);
720
+            // SERIAL_ECHOLN(out);
721
+            sort_order[s1] = o2;
722
+            sort_order[s2] = o1;
723
+            didSwap = true;
724
+          }
725
+        }
726
+        if (!didSwap) break;
727
+      }
728
+
729
+      #if SORT_USES_RAM && !SORT_USES_MORE_RAM
730
+        for (uint16_t i=0; i<fileCnt; ++i) free(sortnames[i]);
731
+      #endif
732
+    }
733
+    else {
734
+      sort_order[0] = 0;
735
+      #if SORT_USES_RAM && SORT_USES_MORE_RAM
736
+        sortnames = (char**)malloc(sizeof(char*));
737
+        sortshort = (char**)malloc(sizeof(char*));
738
+        isDir = (uint8_t*)malloc(sizeof(uint8_t));
739
+        getfilename(0);
740
+        sortnames[0] = strdup(longFilename[0] ? longFilename : filename);
741
+        sortshort[0] = strdup(filename);
742
+        isDir[0] = filenameIsDir;
743
+      #endif
744
+    }
745
+
746
+    sort_count = fileCnt;
747
+  }
748
+}
749
+
750
+void CardReader::flush_presort() {
751
+  if (sort_count > 0) {
752
+    #if SORT_USES_RAM && SORT_USES_MORE_RAM
753
+      for (uint8_t i=0; i<sort_count; ++i) {
754
+        free(sortshort[i]);
755
+        free(sortnames[i]);
756
+      }
757
+      free(sortshort);
758
+      free(sortnames);
759
+    #endif
760
+    delete sort_order;
761
+    sort_count = 0;
610
   }
762
   }
611
 }
763
 }
612
 
764
 
765
+#endif // SDCARD_SORT_ALPHA
613
 
766
 
614
 void CardReader::printingHasFinished()
767
 void CardReader::printingHasFinished()
615
 {
768
 {
633
           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
786
           enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
634
       }
787
       }
635
       autotempShutdown();
788
       autotempShutdown();
789
+      #ifdef SDCARD_SORT_ALPHA
790
+        presort();
791
+      #endif
636
     }
792
     }
637
 }
793
 }
638
 #endif //SDSUPPORT
794
 #endif //SDSUPPORT

+ 26
- 7
Marlin/cardreader.h View File

3
 
3
 
4
 #ifdef SDSUPPORT
4
 #ifdef SDSUPPORT
5
 
5
 
6
-#define MAX_DIR_DEPTH 10
6
+#define MAX_DIR_DEPTH 10          // Maximum folder depth
7
+#define SORT_USES_RAM false       // Buffer while sorting, else re-read from SD
8
+#define SORT_USES_MORE_RAM false  // Always keep the directory in RAM
9
+#define SORT_LIMIT 64             // Maximum number of sorted items
10
+#define FOLDER_SORTING -1         // -1=above  0=none  1=below
7
 
11
 
8
 #include "SdFile.h"
12
 #include "SdFile.h"
9
 enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
13
 enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
28
   void getStatus();
32
   void getStatus();
29
   void printingHasFinished();
33
   void printingHasFinished();
30
 
34
 
31
-  void getfilename(const uint8_t nr);
35
+  void getfilename(const uint16_t nr);
32
   uint16_t getnrfilenames();
36
   uint16_t getnrfilenames();
33
   
37
   
34
   void getAbsFilename(char *t);
38
   void getAbsFilename(char *t);
39
   void updir();
43
   void updir();
40
   void setroot();
44
   void setroot();
41
 
45
 
46
+#ifdef SDCARD_SORT_ALPHA
47
+  void presort();
48
+  void flush_presort();
49
+  void getfilename_sorted(const uint16_t nr);
50
+#endif
51
+
42
 
52
 
43
   FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
53
   FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
44
   FORCE_INLINE bool eof() { return sdpos>=filesize ;};
54
   FORCE_INLINE bool eof() { return sdpos>=filesize ;};
50
 public:
60
 public:
51
   bool saving;
61
   bool saving;
52
   bool logging;
62
   bool logging;
53
-  bool sdprinting ;  
54
-  bool cardOK ;
55
-  char filename[13];
63
+  bool sdprinting;
64
+  bool cardOK;
65
+  char filename[FILENAME_LENGTH];
56
   char longFilename[LONG_FILENAME_LENGTH];
66
   char longFilename[LONG_FILENAME_LENGTH];
57
   bool filenameIsDir;
67
   bool filenameIsDir;
58
   int lastnr; //last number of the autostart;
68
   int lastnr; //last number of the autostart;
59
 private:
69
 private:
60
   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
70
   SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
61
   uint16_t workDirDepth;
71
   uint16_t workDirDepth;
72
+#ifdef SDCARD_SORT_ALPHA
73
+  uint16_t sort_count;
74
+  uint8_t *sort_order;
75
+  #if SORT_USES_MORE_RAM
76
+    char **sortshort;
77
+    char **sortnames;
78
+    uint8_t *isDir;
79
+  #endif
80
+#endif
62
   Sd2Card card;
81
   Sd2Card card;
63
   SdVolume volume;
82
   SdVolume volume;
64
   SdFile file;
83
   SdFile file;
65
   #define SD_PROCEDURE_DEPTH 1
84
   #define SD_PROCEDURE_DEPTH 1
66
-  #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
85
+  #define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
67
   uint8_t file_subcall_ctr;
86
   uint8_t file_subcall_ctr;
68
   uint32_t filespos[SD_PROCEDURE_DEPTH];
87
   uint32_t filespos[SD_PROCEDURE_DEPTH];
69
   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
88
   char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
75
   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
94
   bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
76
   
95
   
77
   LsAction lsAction; //stored for recursion.
96
   LsAction lsAction; //stored for recursion.
78
-  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.
97
+  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.
79
   char* diveDirName;
98
   char* diveDirName;
80
   void lsDive(const char *prepend,SdFile parent);
99
   void lsDive(const char *prepend,SdFile parent);
81
 };
100
 };

+ 18
- 11
Marlin/ultralcd.cpp View File

993
     card.getWorkDirName();
993
     card.getWorkDirName();
994
     if(card.filename[0]=='/')
994
     if(card.filename[0]=='/')
995
     {
995
     {
996
-#if SDCARDDETECT == -1
996
+      #if SDCARDDETECT == -1
997
         MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh);
997
         MENU_ITEM(function, LCD_STR_REFRESH MSG_REFRESH, lcd_sd_refresh);
998
-#endif
998
+      #endif
999
     }else{
999
     }else{
1000
         MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir);
1000
         MENU_ITEM(function, LCD_STR_FOLDER "..", lcd_sd_updir);
1001
     }
1001
     }
1004
     {
1004
     {
1005
         if (_menuItemNr == _lineNr)
1005
         if (_menuItemNr == _lineNr)
1006
         {
1006
         {
1007
-            #ifndef SDCARD_RATHERRECENTFIRST
1008
-              card.getfilename(i);
1007
+            #if defined(SDCARD_RATHERRECENTFIRST) && !defined(SDCARD_SORT_ALPHA)
1008
+              int nr = fileCnt-1-i;
1009
             #else
1009
             #else
1010
-              card.getfilename(fileCnt-1-i);
1010
+              int nr = i;
1011
             #endif
1011
             #endif
1012
-            if (card.filenameIsDir)
1013
-            {
1014
-                MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
1015
-            }else{
1016
-                MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
1012
+
1013
+            #ifdef SDCARD_SORT_ALPHA
1014
+              card.getfilename_sorted(nr);
1015
+            #else
1016
+              card.getfilename(nr);
1017
+            #endif
1018
+
1019
+            if (card.filenameIsDir) {
1020
+              MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
1021
+            }
1022
+            else {
1023
+              MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
1017
             }
1024
             }
1018
         }else{
1025
         }else{
1019
             MENU_ITEM_DUMMY();
1026
             MENU_ITEM_DUMMY();
1219
   #endif // SR_LCD_2W_NL
1226
   #endif // SR_LCD_2W_NL
1220
 #endif//!NEWPANEL
1227
 #endif//!NEWPANEL
1221
 
1228
 
1222
-#if defined (SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
1229
+#if defined(SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
1223
     pinMode(SDCARDDETECT,INPUT);
1230
     pinMode(SDCARDDETECT,INPUT);
1224
     WRITE(SDCARDDETECT, HIGH);
1231
     WRITE(SDCARDDETECT, HIGH);
1225
     lcd_oldcardstatus = IS_SD_INSERTED;
1232
     lcd_oldcardstatus = IS_SD_INSERTED;

Loading…
Cancel
Save