diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 2b275db67..3eac5cf33 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4002,9 +4002,9 @@ void process_commands() }else if (code_seen_P("fv")) { // PRUSA fv // get file version #ifdef SDSUPPORT - card.openFile(strchr_pointer + 3,true); + card.openFileReadFilteredGcode(strchr_pointer + 3,true); while (true) { - uint16_t readByte = card.get(); + uint16_t readByte = card.getFilteredGcodeChar(); MYSERIAL.write(readByte); if (readByte=='\n') { break; @@ -4017,7 +4017,7 @@ void process_commands() } else if (code_seen_P(PSTR("M28"))) { // PRUSA M28 trace(); prusa_sd_card_upload = true; - card.openFile(strchr_pointer+4,false); + card.openFileWrite(strchr_pointer+4); } else if (code_seen_P(PSTR("SN"))) { // PRUSA SN char SN[20]; @@ -5786,7 +5786,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) starpos = (strchr(strchr_pointer + 4,'*')); if(starpos!=NULL) *(starpos)='\0'; - card.openFile(strchr_pointer + 4,true); + card.openFileReadFilteredGcode(strchr_pointer + 4); break; /*! @@ -5856,7 +5856,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) strchr_pointer = strchr(npos,' ') + 1; *(starpos) = '\0'; } - card.openFile(strchr_pointer+4,false); + card.openFileWrite(strchr_pointer+4); break; /*! ### M29 - Stop SD write M29: Stop writing to SD card @@ -5917,7 +5917,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if( card.cardOK ) { - card.openFile(namestartpos,true,!call_procedure); + card.openFileReadFilteredGcode(namestartpos,!call_procedure); if(code_seen('S')) if(strchr_pointercache()->data; // this is constant for the whole time, so it should be fast and sleek +} + +void SdFile::gfReset(){ + // reset cache read ptr to its begin + gfReadPtr = gfBlockBuffBegin() + gfOffset; +} + +// think twice before allowing this to inline - manipulating 4B longs is costly +// moreover - this function has its parameters in registers only, so no heavy stack usage besides the call/ret +void __attribute__((noinline)) SdFile::gfUpdateCurrentPosition(uint16_t inc){ + curPosition_ += inc; +} + +#define find_endl(resultP, startP) \ +__asm__ __volatile__ ( \ +"cycle: \n" \ +"ld r22, Z+ \n" \ +"cpi r22, 0x0A \n" \ +"brne cycle \n" \ +: "=z" (resultP) /* result of the ASM code - in our case the Z register (R30:R31) */ \ +: "z" (startP) /* input of the ASM code - in our case the Z register as well (R30:R31) */ \ +: "r22" /* modifying register R22 - so that the compiler knows */ \ +) + +// avoid calling the default heavy-weight read() for just one byte +int16_t SdFile::readFilteredGcode(){ + if( ! gfEnsureBlock() ){ + goto eof_or_fail; // this is unfortunate :( ... other calls are using the cache and we can loose the data block of our gcode file + } + // assume, we have the 512B block cache filled and terminated with a '\n' + { + const uint8_t *start = gfReadPtr; + + // It may seem unreasonable to copy the variable into a local one and copy it back at the end of this method, + // but there is an important point of view: the compiler is unsure whether it can optimize the reads/writes + // to gfReadPtr within this method, because it is a class member variable. + // The compiler cannot see, if omitting read/write won't have any incorrect side-effects to the rest of the whole FW. + // So this trick explicitly states, that rdPtr is a local variable limited to the scope of this method, + // therefore the compiler can omit read/write to it (keep it in registers!) as it sees fit. + // And it does! Codesize dropped by 68B! + const uint8_t *rdPtr = gfReadPtr; + + // the same applies to gfXBegin, codesize dropped another 100B! + const uint8_t *blockBuffBegin = gfBlockBuffBegin(); + + uint8_t consecutiveCommentLines = 0; + while( *rdPtr == ';' ){ + for(;;){ + + //while( *(++gfReadPtr) != '\n' ); // skip until a newline is found - suboptimal code! + // Wondering, why this "nice while cycle" is done in such a weird way using a separate find_endl() function? + // Have a look at the ASM code GCC produced! + + // At first - a separate find_endl() makes the compiler understand, + // that I don't need to store gfReadPtr every time, I'm only interested in the final address where the '\n' was found + // - the cycle can run on CPU registers only without touching memory besides reading the character being compared. + // Not only makes the code run considerably faster, but is also 40B shorter! + // This was the generated code: + //FORCE_INLINE const uint8_t * find_endl(const uint8_t *p){ + // while( *(++p) != '\n' ); // skip until a newline is found + // return p; } + // 11c5e: movw r30, r18 + // 11c60: subi r18, 0xFF ; 255 + // 11c62: sbci r19, 0xFF ; 255 + // 11c64: ld r22, Z + // 11c66: cpi r22, 0x0A ; 10 + // 11c68: brne .-12 ; 0x11c5e + + // Still, even that was suboptimal as the compiler seems not to understand the usage of ld r22, Z+ (the plus is important) + // aka automatic increment of the Z register (R30:R31 pair) + // There is no other way than pure ASM! + find_endl(rdPtr, rdPtr); + + // found a newline, prepare the next block if block cache end reached + if( rdPtr - blockBuffBegin > 512 ){ + // at the end of block cache, fill new data in + gfUpdateCurrentPosition( rdPtr - start - 1 ); + if( ! gfComputeNextFileBlock() )goto eof_or_fail; + if( ! gfEnsureBlock() )goto eof_or_fail; // fetch it into RAM + rdPtr = start = blockBuffBegin; + } else { + if(consecutiveCommentLines >= 250){ + --rdPtr; // unget the already consumed newline + goto emit_char; + } + // peek the next byte - we are inside the block at least at 511th index - still safe + if( *rdPtr == ';' ){ + // consecutive comment + ++consecutiveCommentLines; + } else { + --rdPtr; // unget the already consumed newline + goto emit_char; + } + break; // found the real end of the line even across many blocks + } + } + } +emit_char: + { + gfUpdateCurrentPosition( rdPtr - start + 1 ); + int16_t rv = *rdPtr++; + + if( curPosition_ >= fileSize_ ){ + // past the end of file + goto eof_or_fail; + } else if( rdPtr - blockBuffBegin >= 512 ){ + // past the end of current bufferred block - prepare the next one... + if( ! gfComputeNextFileBlock() )goto eof_or_fail; + // don't need to force fetch the block here, it will get loaded on the next call + rdPtr = blockBuffBegin; + } + + // save the current read ptr for the next run + gfReadPtr = rdPtr; + return rv; + } + +} + +eof_or_fail: + // make the rdptr point to a safe location - end of file + gfReadPtr = gfBlockBuffBegin() + 512; + return -1; +} + +bool SdFile::gfEnsureBlock(){ + if ( vol_->cacheRawBlock(gfBlock, SdVolume::CACHE_FOR_READ)){ + // terminate with a '\n' + const uint16_t terminateOfs = fileSize_ - gfOffset; + vol_->cache()->data[ terminateOfs < 512 ? terminateOfs : 512 ] = '\n'; + return true; + } else { + return false; + } +} + +bool SdFile::gfComputeNextFileBlock() { + // error if not open or write only + if (!isOpen() || !(flags_ & O_READ)) return false; + + gfOffset = curPosition_ & 0X1FF; // offset in block + if (type_ == FAT_FILE_TYPE_ROOT_FIXED) { + // SHR by 9 means skip the last byte and shift just 3 bytes by 1 + // -> should be 8 instructions... and not the horrible loop shifting 4 bytes at once + // still need to get some work on this + gfBlock = vol_->rootDirStart() + (curPosition_ >> 9); + } else { + uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_); + if (gfOffset == 0 && blockOfCluster == 0) { + // start of new cluster + if (curPosition_ == 0) { + // use first cluster in file + curCluster_ = firstCluster_; + } else { + // get next cluster from FAT + if (!vol_->fatGet(curCluster_, &curCluster_)) return false; + } + } + gfBlock = vol_->clusterStartBlock(curCluster_) + blockOfCluster; + } + return true; +} + //------------------------------------------------------------------------------ /** Write data to an open file. * diff --git a/Firmware/SdFile.h b/Firmware/SdFile.h index 60e2f5deb..465224623 100644 --- a/Firmware/SdFile.h +++ b/Firmware/SdFile.h @@ -34,7 +34,24 @@ * \brief SdBaseFile with Print. */ class SdFile : public SdBaseFile/*, public Print*/ { - public: + // GCode filtering vars and methods - due to optimization reasons not wrapped in a separate class + + // beware - this read ptr is manipulated inside just 2 methods - readFilteredGcode and gfReset + // If you even want to call gfReset from readFilteredGcode, you must make sure + // to update gfReadPtr inside readFilteredGcode from a local copy (see explanation of this trick in readFilteredGcode) + const uint8_t *gfReadPtr; + + uint32_t gfBlock; // remember the current file block to be kept in cache - due to reuse of the memory, the block may fall out a must be read back + uint16_t gfOffset; + + const uint8_t *gfBlockBuffBegin()const; + + void gfReset(); + + bool gfEnsureBlock(); + bool gfComputeNextFileBlock(); + void gfUpdateCurrentPosition(uint16_t inc); +public: SdFile() {} SdFile(const char* name, uint8_t oflag); #if ARDUINO >= 100 @@ -43,6 +60,9 @@ class SdFile : public SdBaseFile/*, public Print*/ { void write(uint8_t b); #endif + bool openFilteredGcode(SdBaseFile* dirFile, const char* path); + int16_t readFilteredGcode(); + bool seekSetFilteredGcode(uint32_t pos); int16_t write(const void* buf, uint16_t nbyte); void write(const char* str); void write_P(PGM_P str); @@ -51,4 +71,4 @@ class SdFile : public SdBaseFile/*, public Print*/ { #endif // SdFile_h -#endif \ No newline at end of file +#endif diff --git a/Firmware/SdVolume.h b/Firmware/SdVolume.h index 2ff2b6eb9..17699190e 100644 --- a/Firmware/SdVolume.h +++ b/Firmware/SdVolume.h @@ -36,7 +36,7 @@ */ union cache_t { /** Used to access cached file data blocks. */ - uint8_t data[512]; + uint8_t data[512 + 1]; // abuse the last byte for saving '\n' - ugly optimization of read_filtered's inner skipping loop /** Used to access cached FAT16 entries. */ uint16_t fat16[256]; /** Used to access cached FAT32 entries. */ @@ -119,6 +119,7 @@ class SdVolume { bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);} //------------------------------------------------------------------------------ private: + friend class SdFile; // Allow SdBaseFile access to SdVolume private data. friend class SdBaseFile; @@ -211,4 +212,4 @@ class SdVolume { #endif // ALLOW_DEPRECATED_FUNCTIONS }; #endif // SdVolume -#endif \ No newline at end of file +#endif diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 6f8456664..717f58696 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -284,7 +284,7 @@ void CardReader::startFileprint() void CardReader::openLogFile(const char* name) { logging = true; - openFile(name, false); + openFileWrite(name); } void CardReader::getDirName(char* name, uint8_t level) @@ -383,98 +383,144 @@ bool CardReader::diveSubfolder (const char *&fileName) return 1; } -void CardReader::openFile(const char* name,bool read, bool replace_current/*=true*/) -{ - if(!cardOK) - return; - if(file.isOpen()) //replacing current file by new file, or subfile call - { - if(!replace_current) - { - if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1) - { - // SERIAL_ERROR_START; - // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); - // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); - kill(_n("trying to call sub-gcode files with too many levels."), 1); - return; - } - - SERIAL_ECHO_START; - SERIAL_ECHOPGM("SUBROUTINE CALL target:\""); - SERIAL_ECHO(name); - SERIAL_ECHOPGM("\" parent:\""); - - //store current filename and position - getAbsFilename(filenames[file_subcall_ctr]); - - SERIAL_ECHO(filenames[file_subcall_ctr]); - SERIAL_ECHOPGM("\" pos"); - SERIAL_ECHOLN(sdpos); - filespos[file_subcall_ctr]=sdpos; - file_subcall_ctr++; - } - else - { - SERIAL_ECHO_START; - SERIAL_ECHOPGM("Now doing file: "); - SERIAL_ECHOLN(name); - } - file.close(); - } - else //opening fresh file - { - file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure - SERIAL_ECHO_START; - SERIAL_ECHOPGM("Now fresh file: "); - SERIAL_ECHOLN(name); - } - sdprinting = false; +static const char ofKill[] PROGMEM = "trying to call sub-gcode files with too many levels."; +static const char ofSubroutineCallTgt[] PROGMEM = "SUBROUTINE CALL target:\""; +static const char ofParent[] PROGMEM = "\" parent:\""; +static const char ofPos[] PROGMEM = "\" pos"; +static const char ofNowDoingFile[] PROGMEM = "Now doing file: "; +static const char ofNowFreshFile[] PROGMEM = "Now fresh file: "; +static const char ofFileOpened[] PROGMEM = "File opened: "; +static const char ofSize[] PROGMEM = " Size: "; +static const char ofFileSelected[] PROGMEM = "File selected"; +static const char ofSDPrinting[] PROGMEM = "SD-PRINTING"; +static const char ofWritingToFile[] PROGMEM = "Writing to file: "; - const char *fname=name; - if (!diveSubfolder(fname)) - return; - - if(read) - { - if (file.open(curDir, fname, O_READ)) - { - getfilename(0, fname); - filesize = file.fileSize(); - SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - printAbsFilenameFast(); - SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE - SERIAL_PROTOCOLLN(filesize); - sdpos = 0; - - SERIAL_PROTOCOLLNRPGM(MSG_FILE_SELECTED); - lcd_setstatuspgm(MSG_FILE_SELECTED); - scrollstuff = 0; +void CardReader::openFileReadFilteredGcode(const char* name, bool replace_current/* = false*/){ + if(!cardOK) + return; + + if(file.isOpen()){ //replacing current file by new file, or subfile call + if(!replace_current){ + if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1){ + // SERIAL_ERROR_START; + // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(ofKill, 1); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofSubroutineCallTgt); + SERIAL_ECHO(name); + SERIAL_ECHORPGM(ofParent); + + //store current filename and position + getAbsFilename(filenames[file_subcall_ctr]); + + SERIAL_ECHO(filenames[file_subcall_ctr]); + SERIAL_ECHORPGM(ofPos); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr]=sdpos; + file_subcall_ctr++; + } else { + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofNowDoingFile); + SERIAL_ECHOLN(name); + } + file.close(); + } else { //opening fresh file + file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofNowFreshFile); + SERIAL_ECHOLN(name); } - else - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLN('.'); - } - } - else - { //write - if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLN('.'); - } - else - { - saving = true; - SERIAL_PROTOCOLRPGM(_N("Writing to file: "));////MSG_SD_WRITE_TO_FILE - SERIAL_PROTOCOLLN(name); - lcd_setstatus(fname); - } - } + sdprinting = false; + const char *fname=name; + if (!diveSubfolder(fname)) + return; + + if (file.openFilteredGcode(curDir, fname)) { + getfilename(0, fname); + filesize = file.fileSize(); + SERIAL_PROTOCOLRPGM(ofFileOpened);////MSG_SD_FILE_OPENED + printAbsFilenameFast(); + SERIAL_PROTOCOLRPGM(ofSize);////MSG_SD_SIZE + SERIAL_PROTOCOLLN(filesize); + sdpos = 0; + + SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED + lcd_setstatuspgm(ofFileSelected); + scrollstuff = 0; + } else { + SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLLN('.'); + } +} + +void CardReader::openFileWrite(const char* name) +{ + if(!cardOK) + return; + if(file.isOpen()){ //replacing current file by new file, or subfile call +#if 0 + // I doubt chained files support is necessary for file saving: + // Intentionally disabled because it takes a lot of code size while being not used + + if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1){ + // SERIAL_ERROR_START; + // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); + // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH); + kill(ofKill, 1); + return; + } + + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofSubroutineCallTgt); + SERIAL_ECHO(name); + SERIAL_ECHORPGM(ofParent); + + //store current filename and position + getAbsFilename(filenames[file_subcall_ctr]); + + SERIAL_ECHO(filenames[file_subcall_ctr]); + SERIAL_ECHORPGM(ofPos); + SERIAL_ECHOLN(sdpos); + filespos[file_subcall_ctr]=sdpos; + file_subcall_ctr++; + file.close(); +#else + SERIAL_ECHOLNPGM("File already opened"); +#endif + } else { //opening fresh file + file_subcall_ctr=0; //resetting procedure depth in case user cancels print while in procedure + SERIAL_ECHO_START; + SERIAL_ECHORPGM(ofNowFreshFile); + SERIAL_ECHOLN(name); + } + sdprinting = false; + + const char *fname=name; + if (!diveSubfolder(fname)) + return; + + //write + if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)){ + SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLLN('.'); + } else { + saving = true; + getfilename(0, fname); + SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE + printAbsFilenameFast(); + SERIAL_PROTOCOLLN(); + + SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED + lcd_setstatuspgm(ofFileSelected); + scrollstuff = 0; + } } void CardReader::removeFile(const char* name) @@ -1003,7 +1049,7 @@ void CardReader::printingHasFinished() { file.close(); file_subcall_ctr--; - openFile(filenames[file_subcall_ctr],true,true); + openFileReadFilteredGcode(filenames[file_subcall_ctr],true); setIndex(filespos[file_subcall_ctr]); startFileprint(); } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 84462f6a8..0819d3bb8 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -1,6 +1,8 @@ #ifndef CARDREADER_H #define CARDREADER_H +#define SDSUPPORT + #ifdef SDSUPPORT #define MAX_DIR_DEPTH 6 @@ -19,7 +21,8 @@ public: //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset void checkautostart(bool x); - void openFile(const char* name,bool read,bool replace_current=true); + void openFileWrite(const char* name); + void openFileReadFilteredGcode(const char* name, bool replace_current = false); void openLogFile(const char* name); void removeFile(const char* name); void closefile(bool store_location=false); @@ -55,9 +58,11 @@ public: #endif FORCE_INLINE bool isFileOpen() { return file.isOpen(); } - FORCE_INLINE bool eof() { return sdpos>=filesize ;}; - FORCE_INLINE int16_t get() { sdpos = file.curPosition();return (int16_t)file.read();}; - FORCE_INLINE void setIndex(long index) {sdpos = index;file.seekSet(index);}; + bool eof() { return sdpos>=filesize; } + // There may be a potential performance problem - when the comment reading fails, sdpos points to the last correctly read character. + // However, repeated reading (e.g. after power panic) the comment will be read again - it should survive correctly, it will just take a few moments to skip + FORCE_INLINE int16_t getFilteredGcodeChar() { sdpos = file.curPosition();return (int16_t)file.readFilteredGcode();}; + void setIndex(long index) {sdpos = index;file.seekSetFilteredGcode(index);}; FORCE_INLINE uint8_t percentDone(){if(!isFileOpen()) return 0; if(filesize) return sdpos/((filesize+99)/100); else return 0;}; FORCE_INLINE char* getWorkDirName(){workDir.getFilename(filename);return filename;}; FORCE_INLINE uint32_t get_sdpos() { if (!isFileOpen()) return 0; else return(sdpos); }; diff --git a/Firmware/cmdqueue.cpp b/Firmware/cmdqueue.cpp index afdddfba2..9c822dab5 100755 --- a/Firmware/cmdqueue.cpp +++ b/Firmware/cmdqueue.cpp @@ -584,13 +584,14 @@ void get_command() sd_count.value = 0; // Reads whole lines from the SD card. Never leaves a half-filled line in the cmdbuffer. while( !card.eof() && !stop_buffering) { - int16_t n=card.get(); + int16_t n=card.getFilteredGcodeChar(); char serial_char = (char)n; - if(serial_char == '\n' || - serial_char == '\r' || - ((serial_char == '#' || serial_char == ':') && comment_mode == false) || - serial_count >= (MAX_CMD_SIZE - 1) || n==-1) - { + if( serial_char == '\n' + || serial_char == '\r' + || ((serial_char == '#' || serial_char == ':') ) + || serial_count >= (MAX_CMD_SIZE - 1) + || n==-1 + ){ if(serial_char=='#') stop_buffering=true; @@ -601,8 +602,7 @@ void get_command() // read from the sdcard into sd_count, // so that the lenght of the already read empty lines and comments will be added // to the following non-empty line. - comment_mode = false; - continue; //if empty line + return; // prevent cycling indefinitely - let manage_heaters do their job } // The new command buffer could be updated non-atomically, because it is not yet considered // to be inside the active queue. @@ -618,10 +618,10 @@ void get_command() // MYSERIAL.print(sd_count.value, DEC); // SERIAL_ECHOPGM(") "); // SERIAL_ECHOLN(cmdbuffer+bufindw+CMDHDRSIZE); -// SERIAL_ECHOPGM("cmdbuffer:"); -// MYSERIAL.print(cmdbuffer); -// SERIAL_ECHOPGM("buflen:"); -// MYSERIAL.print(buflen+1); +// SERIAL_ECHOPGM("cmdbuffer:"); +// MYSERIAL.print(cmdbuffer); +// SERIAL_ECHOPGM("buflen:"); +// MYSERIAL.print(buflen+1); sd_count.value = 0; cli(); @@ -640,15 +640,15 @@ void get_command() serial_count = 0; //clear buffer if(card.eof()) break; - + // The following line will reserve buffer space if available. if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1, true)) return; } else { - if(serial_char == ';') comment_mode = true; - else if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char; + // there are no comments coming from the filtered file + cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char; } } if(card.eof()) diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index a0efc3aae..fb79022ff 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -944,7 +944,7 @@ static inline void update_current_position_z() // At the current position, find the Z stop. -inline bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, int +bool find_bed_induction_sensor_point_z(float minimum_z, uint8_t n_iter, int #ifdef SUPPORT_VERBOSITY verbosity_level #endif //SUPPORT_VERBOSITY @@ -1065,7 +1065,7 @@ error: } #ifdef NEW_XYZCAL -extern bool xyzcal_find_bed_induction_sensor_point_xy(); +bool xyzcal_find_bed_induction_sensor_point_xy(); #endif //NEW_XYZCAL // Search around the current_position[X,Y], // look for the induction sensor response. @@ -1081,7 +1081,7 @@ extern bool xyzcal_find_bed_induction_sensor_point_xy(); #endif //HEATBED_V2 #ifdef HEATBED_V2 -inline bool find_bed_induction_sensor_point_xy(int +bool find_bed_induction_sensor_point_xy(int #if !defined (NEW_XYZCAL) && defined (SUPPORT_VERBOSITY) verbosity_level #endif @@ -1335,7 +1335,7 @@ inline bool find_bed_induction_sensor_point_xy(int #endif //NEW_XYZCAL } #else //HEATBED_V2 -inline bool find_bed_induction_sensor_point_xy(int verbosity_level) +bool find_bed_induction_sensor_point_xy(int verbosity_level) { #ifdef NEW_XYZCAL return xyzcal_find_bed_induction_sensor_point_xy(); diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index 8adc1c119..7ca93c953 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/Firmware/mesh_bed_calibration.h @@ -146,9 +146,9 @@ inline bool world2machine_clamp(float &x, float &y) return clamped; } -extern bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); -extern bool find_bed_induction_sensor_point_xy(int verbosity_level = 0); -extern void go_home_with_z_lift(); +bool find_bed_induction_sensor_point_z(float minimum_z = -10.f, uint8_t n_iter = 3, int verbosity_level = 0); +bool find_bed_induction_sensor_point_xy(int verbosity_level = 0); +void go_home_with_z_lift(); /** * @brief Bed skew and offest detection result diff --git a/Firmware/messages.c b/Firmware/messages.c index 58e131d68..97cae85d7 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -197,4 +197,3 @@ const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20 const char MSG_ADVANCE_K[] PROGMEM_N1 = "Advance K:"; ////c=13 const char MSG_POWERPANIC_DETECTED[] PROGMEM_N1 = "POWER PANIC DETECTED"; ////c=20 const char MSG_LCD_STATUS_CHANGED[] PROGMEM_N1 = "LCD status changed"; -const char MSG_FILE_SELECTED[] PROGMEM_N1 = "File selected"; ////c=20 diff --git a/Firmware/messages.h b/Firmware/messages.h index a5b672fa2..0a05c58f5 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -197,7 +197,6 @@ extern const char MSG_M112_KILL[]; extern const char MSG_ADVANCE_K[]; extern const char MSG_POWERPANIC_DETECTED[]; extern const char MSG_LCD_STATUS_CHANGED[]; -extern const char MSG_FILE_SELECTED[]; #if defined(__cplusplus) } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 0326da88a..c2d83572c 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8398,7 +8398,7 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char static bool check_file(const char* filename) { if (farm_mode) return true; - card.openFile((char*)filename, true); + card.openFileReadFilteredGcode(filename, true); bool result = false; const uint32_t filesize = card.getFileSize(); uint32_t startPos = 0;