From ae081d0fe01b91680586077a9a68f313a0c3493b Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 26 Nov 2014 07:17:47 -0800 Subject: [PATCH] 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. --- Marlin/cardreader.cpp | 137 +++++++++++++++++++++--------------------- Marlin/cardreader.h | 18 +++--- Marlin/ultralcd.cpp | 4 +- 3 files changed, 78 insertions(+), 81 deletions(-) diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp index 10a4e6b1c..5d465f47a 100644 --- a/Marlin/cardreader.cpp +++ b/Marlin/cardreader.cpp @@ -11,8 +11,7 @@ CardReader::CardReader() { - #if defined(SDCARD_SORT_ALPHA) && SORT_USES_MORE_RAM - sortnames = NULL; + #ifdef SDCARD_SORT_ALPHA sort_count = 0; #endif filesize = 0; @@ -37,19 +36,15 @@ CardReader::CardReader() autostart_atmillis=millis()+5000; } -char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +char *createFilename(char *buffer, const dir_t &p) //buffer>12characters { char *pos=buffer; - for (uint8_t i = 0; i < 11; i++) - { - if (p.name[i] == ' ')continue; - if (i == 8) - { - *pos++='.'; - } - *pos++=p.name[i]; + for (uint8_t i = 0; i < 11; i++) { + if (p.name[i] == ' ') continue; + if (i == 8) *pos++ = '.'; + *pos++ = p.name[i]; } - *pos++=0; + *pos++ = 0; return buffer; } @@ -59,7 +54,7 @@ void CardReader::lsDive(const char *prepend,SdFile parent) dir_t p; uint8_t cnt=0; - while (parent.readDir(p, diveFilename) > 0) + while (parent.readDir(p, longFilename) > 0) { if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint { @@ -96,8 +91,8 @@ void CardReader::lsDive(const char *prepend,SdFile parent) { if (p.name[0] == DIR_NAME_FREE) break; if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue; - if (diveFilename[0] != '\0' && - (diveFilename[0] == '.' || diveFilename[0] == '_')) continue; + if (longFilename[0] != '\0' && + (longFilename[0] == '.' || longFilename[0] == '_')) continue; if ( p.name[0] == '.') { if ( p.name[1] != '.') @@ -556,21 +551,20 @@ void CardReader::closefile(bool store_location) } -void CardReader::getfilename(const uint8_t nr) +void CardReader::getfilename(const uint16_t nr) { - #if defined(SDCARD_SORT_ALPHA) && SORT_USES_MORE_RAM + #if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM if (nr < sort_count) { - strcpy(diveFilename, sortnames[nr]); + strcpy(longFilename, sortnames[nr]); + filenameIsDir = isDir[nr]; return; } #endif - curDir=&workDir; lsAction=LS_GetFilename; nrFiles=nr; curDir->rewind(); lsDive("",*curDir); - } uint16_t CardReader::getnrfilenames() @@ -631,12 +625,8 @@ void CardReader::updir() /** * Get the name of a file in the current directory by sort-index */ -void CardReader::getfilename_sorted(const uint8_t nr) { - #if SORT_USES_MORE_RAM - getfilename(nr < sort_count ? sort_order[nr] : nr); - #else - getfilename(nr < SORT_LIMIT ? sort_order[nr] : nr); - #endif +void CardReader::getfilename_sorted(const uint16_t nr) { + getfilename(nr < sort_count ? sort_order[nr] : nr); } /** @@ -656,68 +646,73 @@ void CardReader::presort() if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT; - #if SORT_USES_MORE_RAM - sortnames = (char**)malloc(fileCnt * sizeof(char*)); - sort_count = fileCnt; - #elif SORT_USES_RAM - char *sortnames[fileCnt]; - #if FOLDER_SORTING != 0 - uint8_t isdir[fileCnt]; + #if SORT_USES_RAM + #if SORT_USES_MORE_RAM + sortnames = (char**)calloc(fileCnt, sizeof(char*)); + #else + char *sortnames[fileCnt]; #endif #else - char sortname[LONG_FILENAME_LENGTH+1]; + 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_count = fileCnt; + sort_order = new uint8_t[fileCnt]; + if (fileCnt > 1) { - // Init sort order [and get filenames] - for (int i=0; i 0) : isdir[FOLDER_SORTING > 0 ? o1 : o2]; + 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); + 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 - char *name = diveFilename[0] ? diveFilename : filename; - strcpy(sortname, name); getfilename(o2); - name = diveFilename[0] ? diveFilename : filename; + char *name2 = longFilename[0] ? longFilename : filename; #if FOLDER_SORTING != 0 - cmp = (dir1 == filenameIsDir) ? (strcasecmp(sortname, name) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1); + cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1); #else - cmp = strcasecmp(sortname, name) > 0); + cmp = strcasecmp(name1, name2) > 0; #endif #endif if (cmp) { - // SERIAL_ECHOPGM("Swap "); - // SERIAL_ECHOLN(sortnames[o1]); - // SERIAL_ECHOPGM(" for "); - // SERIAL_ECHOLN(sortnames[o2]); + // char out[LONG_FILENAME_LENGTH*2+20]; + // sprintf_P(out, PSTR("Swap %i %s for %i %s"), o1, sortnames[o1], o2, sortnames[o2]); + // SERIAL_ECHOLN(out); sort_order[s1] = o2; sort_order[s2] = o1; didSwap = true; @@ -727,30 +722,32 @@ void CardReader::presort() } #if SORT_USES_RAM && !SORT_USES_MORE_RAM - for (int i=0; i < fileCnt; ++i) free(sortnames[i]); + for (uint16_t i=0; i 0) { - for (int i=0; i < sort_count; ++i) { - free(sortnames[i]); - sort_order[i] = i; - } + if (sort_count > 0) { + #if SORT_USES_RAM && SORT_USES_MORE_RAM + for (uint8_t i=0; i