Merge branch 'revert-1154-sd_sorting' into Marlin_v1

This commit is contained in:
daid 2014-12-18 23:14:15 +01:00
commit a5c059dcf5
8 changed files with 46 additions and 238 deletions

View File

@ -292,7 +292,6 @@
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order.
// 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. // 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.
// using: // using:

View File

@ -111,14 +111,12 @@ uint8_t const SOFT_SPI_SCK_PIN = 13;
/** /**
* Defines for long (vfat) filenames * Defines for long (vfat) filenames
*/ */
/** Number of UTF-16 characters per entry */
#define FILENAME_LENGTH 13
/** Number of VFAT entries used. Every entry has 13 UTF-16 characters */ /** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
#define MAX_VFAT_ENTRIES (2) #define MAX_VFAT_ENTRIES (2)
/** Number of UTF-16 characters per entry */ /** Number of UTF-16 characters per entry */
#define FILENAME_LENGTH 13 #define FILENAME_LENGTH 13
/** Total size of the buffer used to store the long filenames */ /** Total size of the buffer used to store the long filenames */
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1) #define LONG_FILENAME_LENGTH (13*MAX_VFAT_ENTRIES+1)
#endif // SdFatConfig_h #endif // SdFatConfig_h

View File

@ -11,9 +11,6 @@
CardReader::CardReader() CardReader::CardReader()
{ {
#ifdef SDCARD_SORT_ALPHA
sort_count = 0;
#endif
filesize = 0; filesize = 0;
sdpos = 0; sdpos = 0;
sdprinting = false; sdprinting = false;
@ -39,9 +36,13 @@ CardReader::CardReader()
char *createFilename(char *buffer,const dir_t &p) //buffer>12characters char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
{ {
char *pos=buffer; char *pos=buffer;
for (uint8_t i = 0; i < 11; i++) { for (uint8_t i = 0; i < 11; i++)
{
if (p.name[i] == ' ')continue; if (p.name[i] == ' ')continue;
if (i == 8) *pos++ = '.'; if (i == 8)
{
*pos++='.';
}
*pos++=p.name[i]; *pos++=p.name[i];
} }
*pos++=0; *pos++=0;
@ -59,8 +60,8 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
{ {
char path[FILENAME_LENGTH*2]; char path[13*2];
char lfilename[FILENAME_LENGTH]; char lfilename[13];
createFilename(lfilename,p); createFilename(lfilename,p);
path[0]=0; path[0]=0;
@ -86,6 +87,8 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
} }
lsDive(path,dir); lsDive(path,dir);
//close done automatically by destructor of SdFile //close done automatically by destructor of SdFile
} }
else else
{ {
@ -98,6 +101,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
filenameIsDir=DIR_IS_SUBDIR(&p); filenameIsDir=DIR_IS_SUBDIR(&p);
if(!filenameIsDir) if(!filenameIsDir)
{ {
if(p.name[8]!='G') continue; if(p.name[8]!='G') continue;
@ -121,6 +125,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
} }
else if (cnt == nrFiles) return; else if (cnt == nrFiles) return;
cnt++; cnt++;
} }
} }
} }
@ -129,6 +134,9 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
void CardReader::ls() void CardReader::ls()
{ {
lsAction=LS_SerialPrint; lsAction=LS_SerialPrint;
if(lsAction==LS_Count)
nrFiles=0;
root.rewind(); root.rewind();
lsDive("",root); lsDive("",root);
} }
@ -175,9 +183,6 @@ void CardReader::initsd()
} }
workDir=root; workDir=root;
curDir=&root; curDir=&root;
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
/* /*
if(!workDir.openRoot(&volume)) if(!workDir.openRoot(&volume))
{ {
@ -194,10 +199,8 @@ void CardReader::setroot()
SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
}*/ }*/
workDir=root; workDir=root;
curDir=&workDir; curDir=&workDir;
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
} }
void CardReader::release() void CardReader::release()
{ {
@ -210,9 +213,6 @@ void CardReader::startFileprint()
if(cardOK) if(cardOK)
{ {
sdprinting = true; sdprinting = true;
#ifdef SDCARD_SORT_ALPHA
flush_presort();
#endif
} }
} }
@ -241,7 +241,7 @@ void CardReader::getAbsFilename(char *t)
while(*t!=0 && cnt< MAXPATHNAMELENGTH) while(*t!=0 && cnt< MAXPATHNAMELENGTH)
{t++;cnt++;} //crawl counter forward. {t++;cnt++;} //crawl counter forward.
} }
if(cnt<MAXPATHNAMELENGTH-FILENAME_LENGTH) if(cnt<MAXPATHNAMELENGTH-13)
file.getFilename(t); file.getFilename(t);
else else
t[0]=0; t[0]=0;
@ -311,7 +311,7 @@ void CardReader::openFile(char* name,bool read, bool replace_current/*=true*/)
//SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name));
if(dirname_end>0 && dirname_end>dirname_start) if(dirname_end>0 && dirname_end>dirname_start)
{ {
char subdirname[FILENAME_LENGTH]; char subdirname[13];
strncpy(subdirname, dirname_start, dirname_end-dirname_start); strncpy(subdirname, dirname_start, dirname_end-dirname_start);
subdirname[dirname_end-dirname_start]=0; subdirname[dirname_end-dirname_start]=0;
SERIAL_ECHOLN(subdirname); SERIAL_ECHOLN(subdirname);
@ -408,7 +408,7 @@ void CardReader::removeFile(char* name)
//SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name)); //SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name));
if(dirname_end>0 && dirname_end>dirname_start) if(dirname_end>0 && dirname_end>dirname_start)
{ {
char subdirname[FILENAME_LENGTH]; char subdirname[13];
strncpy(subdirname, dirname_start, dirname_end-dirname_start); strncpy(subdirname, dirname_start, dirname_end-dirname_start);
subdirname[dirname_end-dirname_start]=0; subdirname[dirname_end-dirname_start]=0;
SERIAL_ECHOLN(subdirname); SERIAL_ECHOLN(subdirname);
@ -446,9 +446,6 @@ void CardReader::removeFile(char* name)
SERIAL_PROTOCOLPGM("File deleted:"); SERIAL_PROTOCOLPGM("File deleted:");
SERIAL_PROTOCOLLN(fname); SERIAL_PROTOCOLLN(fname);
sdpos = 0; sdpos = 0;
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
} }
else else
{ {
@ -564,14 +561,6 @@ void CardReader::closefile(bool store_location)
void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/)
{ {
#if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM
if (nr < sort_count) {
strcpy(filename, sortshort[nr]);
strcpy(longFilename, sortnames[nr]);
filenameIsDir = isDir[nr];
return;
}
#endif
curDir=&workDir; curDir=&workDir;
lsAction=LS_GetFilename; lsAction=LS_GetFilename;
nrFiles=nr; nrFiles=nr;
@ -613,9 +602,6 @@ void CardReader::chdir(const char * relpath)
workDirParents[0]=*parent; workDirParents[0]=*parent;
} }
workDir=newfile; workDir=newfile;
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
} }
} }
@ -625,152 +611,12 @@ void CardReader::updir()
{ {
--workDirDepth; --workDirDepth;
workDir = workDirParents[0]; workDir = workDirParents[0];
int d;
for (int d = 0; d < workDirDepth; d++) for (int d = 0; d < workDirDepth; d++)
workDirParents[d] = workDirParents[d+1]; workDirParents[d] = workDirParents[d+1];
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
} }
} }
#ifdef 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(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 and return filenames from RAM
* - Some RAM: Buffer the directory just for this sort
*/
void CardReader::presort()
{
flush_presort();
uint16_t fileCnt = getnrfilenames();
if (fileCnt > 0) {
if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT;
#if SORT_USES_RAM
#if SORT_USES_MORE_RAM
sortshort = (char**)calloc(fileCnt, sizeof(char*));
sortnames = (char**)calloc(fileCnt, sizeof(char*));
#else
char *sortnames[fileCnt];
#endif
#else
char name1[LONG_FILENAME_LENGTH+1];
#endif
#if FOLDER_SORTING != 0
#if SORT_USES_RAM && SORT_USES_MORE_RAM
isDir = (uint8_t*)calloc(fileCnt, sizeof(uint8_t));
#else
uint8_t isDir[fileCnt];
#endif
#endif
sort_order = new uint8_t[fileCnt];
if (fileCnt > 1) {
// Init sort order. If using RAM then read all filenames now.
for (uint16_t i=0; i<fileCnt; i++) {
sort_order[i] = i;
#if SORT_USES_RAM
getfilename(i);
sortnames[i] = strdup(longFilename[0] ? longFilename : filename);
#if SORT_USES_MORE_RAM
sortshort[i] = strdup(filename);
#endif
// char out[30];
// sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
// SERIAL_ECHOLN(out);
#if FOLDER_SORTING != 0
isDir[i] = filenameIsDir;
#endif
#endif
}
// Bubble Sort
for (uint16_t i=fileCnt; --i;) {
bool cmp, didSwap = false;
for (uint16_t j=0; j<i; ++j) {
uint16_t s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2];
#if SORT_USES_RAM
#if FOLDER_SORTING != 0
cmp = (isDir[o1] == isDir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isDir[FOLDER_SORTING > 0 ? o1 : o2];
#else
cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0;
#endif
#else
getfilename(o1);
strcpy(name1, longFilename[0] ? longFilename : filename);
#if FOLDER_SORTING != 0
bool dir1 = filenameIsDir;
#endif
getfilename(o2);
char *name2 = longFilename[0] ? longFilename : filename;
#if FOLDER_SORTING != 0
cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1);
#else
cmp = strcasecmp(name1, name2) > 0;
#endif
#endif
if (cmp) {
sort_order[s1] = o2;
sort_order[s2] = o1;
didSwap = true;
}
}
if (!didSwap) break;
}
#if SORT_USES_RAM && !SORT_USES_MORE_RAM
for (uint16_t i=0; i<fileCnt; ++i) free(sortnames[i]);
#endif
}
else {
sort_order[0] = 0;
#if SORT_USES_RAM && SORT_USES_MORE_RAM
sortnames = (char**)malloc(sizeof(char*));
sortshort = (char**)malloc(sizeof(char*));
isDir = (uint8_t*)malloc(sizeof(uint8_t));
getfilename(0);
sortnames[0] = strdup(longFilename[0] ? longFilename : filename);
sortshort[0] = strdup(filename);
isDir[0] = filenameIsDir;
#endif
}
sort_count = fileCnt;
}
}
void CardReader::flush_presort() {
if (sort_count > 0) {
#if SORT_USES_RAM && SORT_USES_MORE_RAM
for (uint8_t i=0; i<sort_count; ++i) {
free(sortshort[i]);
free(sortnames[i]);
}
free(sortshort);
free(sortnames);
#endif
delete sort_order;
sort_count = 0;
}
}
#endif // SDCARD_SORT_ALPHA
void CardReader::printingHasFinished() void CardReader::printingHasFinished()
{ {
@ -794,9 +640,6 @@ void CardReader::printingHasFinished()
enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
} }
autotempShutdown(); autotempShutdown();
#ifdef SDCARD_SORT_ALPHA
presort();
#endif
} }
} }
#endif //SDSUPPORT #endif //SDSUPPORT

View File

@ -3,14 +3,7 @@
#ifdef SDSUPPORT #ifdef SDSUPPORT
#define MAX_DIR_DEPTH 10 // Maximum folder depth #define MAX_DIR_DEPTH 10
#ifdef SDCARD_SORT_ALPHA
#define SORT_USES_RAM false // Buffer while sorting, else re-read from SD
#define SORT_USES_MORE_RAM false // Always keep the directory in RAM
#define SORT_LIMIT 256 // Maximum number of sorted items
#define FOLDER_SORTING -1 // -1=above 0=none 1=below
#endif
#include "SdFile.h" #include "SdFile.h"
enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename}; enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
@ -46,12 +39,6 @@ public:
void updir(); void updir();
void setroot(); void setroot();
#ifdef SDCARD_SORT_ALPHA
void presort();
void flush_presort();
void getfilename_sorted(const uint16_t nr);
#endif
FORCE_INLINE bool isFileOpen() { return file.isOpen(); } FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
FORCE_INLINE bool eof() { return sdpos>=filesize ;}; FORCE_INLINE bool eof() { return sdpos>=filesize ;};
@ -65,27 +52,18 @@ public:
bool logging; bool logging;
bool sdprinting ; bool sdprinting ;
bool cardOK ; bool cardOK ;
char filename[FILENAME_LENGTH]; char filename[13];
char longFilename[LONG_FILENAME_LENGTH]; char longFilename[LONG_FILENAME_LENGTH];
bool filenameIsDir; bool filenameIsDir;
int lastnr; //last number of the autostart; int lastnr; //last number of the autostart;
private: private:
SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
uint16_t workDirDepth; uint16_t workDirDepth;
#ifdef SDCARD_SORT_ALPHA
uint16_t sort_count;
uint8_t *sort_order;
#if SORT_USES_MORE_RAM
char **sortshort;
char **sortnames;
uint8_t *isDir;
#endif
#endif
Sd2Card card; Sd2Card card;
SdVolume volume; SdVolume volume;
SdFile file; SdFile file;
#define SD_PROCEDURE_DEPTH 1 #define SD_PROCEDURE_DEPTH 1
#define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1) #define MAXPATHNAMELENGTH (13*MAX_DIR_DEPTH+MAX_DIR_DEPTH+1)
uint8_t file_subcall_ctr; uint8_t file_subcall_ctr;
uint32_t filespos[SD_PROCEDURE_DEPTH]; uint32_t filespos[SD_PROCEDURE_DEPTH];
char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH]; char filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
@ -97,7 +75,7 @@ private:
bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware. 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. LsAction lsAction; //stored for recursion.
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. 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; char* diveDirName;
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
}; };

View File

@ -295,7 +295,6 @@
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order.
// 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. // 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.
// using: // using:

View File

@ -287,7 +287,6 @@
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the filesystem block order. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the filesystem block order.
// if a file is deleted, it frees a block. hence, the order is not purely cronological. To still have auto0.g accessible, there is again the option to do that. // if a file is deleted, it frees a block. hence, the order is not purely cronological. To still have auto0.g accessible, there is again the option to do that.
// using: // using:

View File

@ -291,7 +291,6 @@
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? #define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
//#define SDCARD_SORT_ALPHA // Sort SD file listings in ASCII order. Find additional options in cardreader.h
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order.
// 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. // 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.
// using: // using:

View File

@ -897,22 +897,15 @@ void lcd_sdcard_menu()
{ {
if (_menuItemNr == _lineNr) if (_menuItemNr == _lineNr)
{ {
#if defined(SDCARD_RATHERRECENTFIRST) && !defined(SDCARD_SORT_ALPHA) #ifndef SDCARD_RATHERRECENTFIRST
int nr = fileCnt-1-i; card.getfilename(i);
#else #else
int nr = i; card.getfilename(fileCnt-1-i);
#endif #endif
if (card.filenameIsDir)
#ifdef 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); MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
} }else{
else {
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename); MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
} }
}else{ }else{