diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 7a9a4929a..ee12716e6 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -338,6 +338,11 @@ const unsigned int dropsegments=5; //everything with less than this number of st // Control heater 0 and heater 1 in parallel. //#define HEATERS_PARALLEL +//LCD status clock interval timer to switch between +// remaining print time +// and time to change/pause/interaction +#define CLOCK_INTERVAL_TIME 5 + //=========================================================================== //=============================Buffers ============================ //=========================================================================== diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 1ed5e0bd3..a1b6fe4eb 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -350,10 +350,6 @@ extern unsigned long t_fan_rising_edge; extern bool mesh_bed_leveling_flag; extern bool mesh_bed_run_from_menu; -extern bool sortAlpha; - -extern char dir_names[][9]; - extern int8_t lcd_change_fil_state; // save/restore printing extern bool saved_printing; @@ -370,6 +366,8 @@ extern uint8_t print_percent_done_normal; extern uint16_t print_time_remaining_normal; extern uint8_t print_percent_done_silent; extern uint16_t print_time_remaining_silent; +extern uint16_t print_time_to_change_normal; +extern uint16_t print_time_to_change_silent; #define PRINT_TIME_REMAINING_INIT 0xffff @@ -441,7 +439,6 @@ extern void cancel_saved_printing(); //estimated time to end of the print -extern uint16_t print_time_remaining(); extern uint8_t calc_percent_done(); diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index d6602ef87..4f83109fd 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -228,10 +228,6 @@ bool fan_state[2]; int fan_edge_counter[2]; int fan_speed[2]; -char dir_names[MAX_DIR_DEPTH][9]; - -bool sortAlpha = false; - float extruder_multiplier[EXTRUDERS] = {1.0 #if EXTRUDERS > 1 @@ -320,6 +316,8 @@ uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes uint8_t print_percent_done_silent = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes +uint16_t print_time_to_change_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes +uint16_t print_time_to_change_silent = PRINT_TIME_REMAINING_INIT; //estimated remaining time to next change in minutes uint32_t IP_address = 0; @@ -4069,9 +4067,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; @@ -4084,7 +4082,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]; @@ -5803,7 +5801,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; /*! @@ -5873,7 +5871,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 @@ -5934,7 +5932,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_pointerM73: Set/Get build percentage - #### Usage + /*! + ### M73 - Set/get print progress M73: Set/Get build percentage + #### Usage - M73 [ P | R | Q | S ] - - #### Parameters - - `P` - Percent in normal mode - - `R` - Time remaining in normal mode - - `Q` - Percent in silent mode - - `S` - Time in silent mode - */ - case 73: //M73 show percent done and time remaining - if(code_seen('P')) print_percent_done_normal = code_value(); - if(code_seen('R')) print_time_remaining_normal = code_value(); - if(code_seen('Q')) print_percent_done_silent = code_value(); - if(code_seen('S')) print_time_remaining_silent = code_value(); + M73 [ P | R | Q | S | C | D ] - { - const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d\n"); - printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal); - printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent); - } - break; + #### Parameters + - `P` - Percent in normal mode + - `R` - Time remaining in normal mode + - `Q` - Percent in silent mode + - `S` - Time in silent mode + - `C` - Time to change/pause/user interaction in normal mode + - `D` - Time to change/pause/user interaction in silent mode + */ + //!@todo update RepRap Gcode wiki + case 73: //M73 show percent done, time remaining and time to change/pause + { + if(code_seen('P')) print_percent_done_normal = code_value(); + if(code_seen('R')) print_time_remaining_normal = code_value(); + if(code_seen('Q')) print_percent_done_silent = code_value(); + if(code_seen('S')) print_time_remaining_silent = code_value(); + if(code_seen('C')) print_time_to_change_normal = code_value(); + if(code_seen('D')) print_time_to_change_silent = code_value(); + { + const char* _msg_mode_done_remain = _N("%S MODE: Percent done: %d; print time remaining in mins: %d; Change in mins: %d\n"); + printf_P(_msg_mode_done_remain, _N("NORMAL"), int(print_percent_done_normal), print_time_remaining_normal, print_time_to_change_normal); + printf_P(_msg_mode_done_remain, _N("SILENT"), int(print_percent_done_silent), print_time_remaining_silent, print_time_to_change_silent); + } + break; + } /*! ### M104 - Set hotend temperature M104: Set Extruder Temperature #### Usage @@ -7005,14 +7009,14 @@ Sigma_Exit: ### M120 - Enable endstops M120: Enable endstop detection */ case 120: - enable_endstops(false) ; + enable_endstops(true) ; break; /*! ### M121 - Disable endstops M121: Disable endstop detection */ case 121: - enable_endstops(true) ; + enable_endstops(false) ; break; /*! @@ -11294,8 +11298,8 @@ void restore_print_from_eeprom(bool mbl_was_active) { } dir_name[8] = '\0'; MYSERIAL.println(dir_name); - strcpy(dir_names[i], dir_name); - card.chdir(dir_name); + // strcpy(dir_names[i], dir_name); + card.chdir(dir_name, false); } for (int i = 0; i < 8; i++) { @@ -11670,46 +11674,40 @@ void print_mesh_bed_leveling_table() SERIAL_ECHOLN(); } -uint16_t print_time_remaining() { - uint16_t print_t = PRINT_TIME_REMAINING_INIT; -#ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF) print_t = print_time_remaining_normal; - else print_t = print_time_remaining_silent; -#else - print_t = print_time_remaining_normal; -#endif //TMC2130 - if ((print_t != PRINT_TIME_REMAINING_INIT) && (feedmultiply != 0)) print_t = 100ul * print_t / feedmultiply; - return print_t; -} - uint8_t calc_percent_done() { - //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize - uint8_t percent_done = 0; + //in case that we have information from M73 gcode return percentage counted by slicer, else return percentage counted as byte_printed/filesize + uint8_t percent_done = 0; #ifdef TMC2130 - if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) { - percent_done = print_percent_done_normal; - } - else if (print_percent_done_silent <= 100) { - percent_done = print_percent_done_silent; - } + if (SilentModeMenu == SILENT_MODE_OFF && print_percent_done_normal <= 100) + { + percent_done = print_percent_done_normal; + } + else if (print_percent_done_silent <= 100) + { + percent_done = print_percent_done_silent; + } #else - if (print_percent_done_normal <= 100) { - percent_done = print_percent_done_normal; - } + if (print_percent_done_normal <= 100) + { + percent_done = print_percent_done_normal; + } #endif //TMC2130 - else { - percent_done = card.percentDone(); - } - return percent_done; + else + { + percent_done = card.percentDone(); + } + return percent_done; } static void print_time_remaining_init() { - print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; - print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; - print_percent_done_normal = PRINT_PERCENT_DONE_INIT; - print_percent_done_silent = PRINT_PERCENT_DONE_INIT; + print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; + print_percent_done_normal = PRINT_PERCENT_DONE_INIT; + print_time_remaining_silent = PRINT_TIME_REMAINING_INIT; + print_percent_done_silent = PRINT_PERCENT_DONE_INIT; + print_time_to_change_normal = PRINT_TIME_REMAINING_INIT; + print_time_to_change_silent = PRINT_TIME_REMAINING_INIT; } void load_filament_final_feed() @@ -11799,7 +11797,7 @@ void M600_wait_for_user(float HotendTempBckp) { delay_keep_alive(4); if (_millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) { - lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 + lcd_display_message_fullscreen_P(_i("Press the knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 wait_for_user_state = 1; setAllTargetHotends(0); st_synchronize(); diff --git a/Firmware/SdBaseFile.cpp b/Firmware/SdBaseFile.cpp index b9e881ef2..e3b1c18c8 100644 --- a/Firmware/SdBaseFile.cpp +++ b/Firmware/SdBaseFile.cpp @@ -530,9 +530,9 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) { * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ - bool SdBaseFile::open(const char* path, uint8_t oflag) { - return open(cwd_, path, oflag); - } +bool SdBaseFile::open(const char* path, uint8_t oflag) { + return open(cwd_, path, oflag); +} //------------------------------------------------------------------------------ /** Open a file or directory by name. * diff --git a/Firmware/SdBaseFile.h b/Firmware/SdBaseFile.h index 923a391dd..a6bd311fe 100644 --- a/Firmware/SdBaseFile.h +++ b/Firmware/SdBaseFile.h @@ -281,8 +281,10 @@ class SdBaseFile { static void printFatDate(uint16_t fatDate); static void printFatTime( uint16_t fatTime); bool printName(); +protected: int16_t read(); int16_t read(void* buf, uint16_t nbyte); +public: int8_t readDir(dir_t* dir, char* longFilename); static bool remove(SdBaseFile* dirFile, const char* path); bool remove(); @@ -321,7 +323,7 @@ class SdBaseFile { SdVolume* volume() const {return vol_;} int16_t write(const void* buf, uint16_t nbyte); //------------------------------------------------------------------------------ - private: + protected: // allow SdFat to set cwd_ friend class SdFat; // global pointer to cwd dir diff --git a/Firmware/SdFile.cpp b/Firmware/SdFile.cpp index 2fb4d5943..1bad4319f 100644 --- a/Firmware/SdFile.cpp +++ b/Firmware/SdFile.cpp @@ -30,6 +30,191 @@ */ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { } + +bool SdFile::openFilteredGcode(SdBaseFile* dirFile, const char* path){ + if( open(dirFile, path, O_READ) ){ + // compute the block to start with + if( ! gfComputeNextFileBlock() ) + return false; + gfReset(); + return true; + } else { + return false; + } +} + +bool SdFile::seekSetFilteredGcode(uint32_t pos){ + if(! seekSet(pos) )return false; + if(! gfComputeNextFileBlock() )return false; + gfReset(); + return true; +} + +const uint8_t *SdFile::gfBlockBuffBegin() const { + return vol_->cache()->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 a96268972..6fe890095 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -32,6 +32,7 @@ CardReader::CardReader() workDirDepth = 0; file_subcall_ctr=0; memset(workDirParents, 0, sizeof(workDirParents)); + presort_flag = false; autostart_stilltocheck=true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software. lastnr=0; @@ -69,12 +70,23 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +*/ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { + static uint8_t recursionCnt = 0; + // RAII incrementer for the recursionCnt + class _incrementer + { + public: + _incrementer() {recursionCnt++;} + ~_incrementer() {recursionCnt--;} + } recursionCntIncrementer; + dir_t p; uint8_t cnt = 0; // Read the next entry from a directory while (parent.readDir(p, longFilename) > 0) { - // If the entry is a directory and the action is LS_SerialPrint - if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { + if (recursionCnt > MAX_DIR_DEPTH) + return; + else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint + // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -241,18 +253,18 @@ void CardReader::initsd() } -void CardReader::setroot() +void CardReader::setroot(bool doPresort) { - /*if(!workDir.openRoot(&volume)) - { - SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL); - }*/ workDir=root; + workDirDepth = 0; curDir=&workDir; - #ifdef SDCARD_SORT_ALPHA - presort(); - #endif +#ifdef SDCARD_SORT_ALPHA + if (doPresort) + presort(); + else + presort_flag = true; +#endif } void CardReader::release() { @@ -277,7 +289,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) @@ -304,6 +316,18 @@ void CardReader::getAbsFilename(char *t) else t[0]=0; } + +void CardReader::printAbsFilenameFast() +{ + SERIAL_PROTOCOL('/'); + for (uint8_t i = 0; i < getWorkDirDepth(); i++) + { + SERIAL_PROTOCOL(dir_names[i]); + SERIAL_PROTOCOL('/'); + } + SERIAL_PROTOCOL(LONGEST_FILENAME); +} + /** * @brief Dive into subfolder * @@ -317,19 +341,17 @@ void CardReader::getAbsFilename(char *t) * @param[in,out] fileName * expects file name including path * in case of absolute path, file name without path is returned - * @param[in,out] dir SdFile object to operate with, - * in case of absolute path, curDir is modified to point to dir, - * so it is not possible to create on stack inside this function, - * as curDir would point to destroyed object. */ -void CardReader::diveSubfolder (const char *fileName, SdFile& dir) +bool CardReader::diveSubfolder (const char *&fileName) { curDir=&root; - if (!fileName) return; + if (!fileName) + return 1; const char *dirname_start, *dirname_end; if (fileName[0] == '/') // absolute path { + setroot(false); dirname_start = fileName + 1; while (*dirname_start) { @@ -340,23 +362,13 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { const size_t maxLen = 12; char subdirname[maxLen+1]; - subdirname[maxLen] = 0; const size_t len = ((static_cast(dirname_end-dirname_start))>maxLen) ? maxLen : (dirname_end-dirname_start); strncpy(subdirname, dirname_start, len); - SERIAL_ECHOLN(subdirname); - if (!dir.open(curDir, subdirname, O_READ)) - { - SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); - SERIAL_PROTOCOL(subdirname); - SERIAL_PROTOCOLLN('.'); - return; - } - else - { - //SERIAL_ECHOLN("dive ok"); - } + subdirname[len] = 0; + if (!chdir(subdirname, false)) + return 0; - curDir = &dir; + curDir = &workDir; dirname_start = dirname_end + 1; } else // the reminder after all /fsa/fdsa/ is the filename @@ -373,100 +385,142 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { curDir = &workDir; } + 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: "; - SdFile myDir; - const char *fname=name; - diveSubfolder(fname,myDir); - - if(read) - { - if (file.open(curDir, fname, O_READ)) - { - filesize = file.fileSize(); - SERIAL_PROTOCOLRPGM(_N("File opened: "));////MSG_SD_FILE_OPENED - SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLRPGM(_n(" Size: "));////MSG_SD_SIZE - SERIAL_PROTOCOLLN(filesize); - sdpos = 0; - - SERIAL_PROTOCOLLNRPGM(_N("File selected"));////MSG_SD_FILE_SELECTED - getfilename(0, fname); - lcd_setstatus(longFilename[0] ? longFilename : fname); - lcd_setstatuspgm(PSTR("SD-PRINTING")); +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)) { + filesize = file.fileSize(); + SERIAL_PROTOCOLRPGM(ofFileOpened);////MSG_SD_FILE_OPENED + SERIAL_PROTOCOL(fname); + SERIAL_PROTOCOLRPGM(ofSize);////MSG_SD_SIZE + SERIAL_PROTOCOLLN(filesize); + sdpos = 0; + + SERIAL_PROTOCOLLNRPGM(ofFileSelected);////MSG_SD_FILE_SELECTED + getfilename(0, fname); + lcd_setstatus(longFilename[0] ? longFilename : fname); + lcd_setstatuspgm(ofSDPrinting); + } 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; + SERIAL_PROTOCOLRPGM(ofWritingToFile);////MSG_SD_WRITE_TO_FILE + SERIAL_PROTOCOLLN(fname); + lcd_setstatus(fname); + } } void CardReader::removeFile(const char* name) @@ -475,9 +529,9 @@ void CardReader::removeFile(const char* name) file.close(); sdprinting = false; - SdFile myDir; const char *fname=name; - diveSubfolder(fname,myDir); + if (!diveSubfolder(fname)) + return; if (file.remove(curDir, fname)) { @@ -515,10 +569,8 @@ void CardReader::getStatus(bool arg_P) { if (arg_P) { - SERIAL_PROTOCOL('/'); - for (uint8_t i = 0; i < getWorkDirDepth(); i++) - printf_P(PSTR("%s/"), dir_names[i]); - puts(filename); + printAbsFilenameFast(); + SERIAL_PROTOCOLLN(); } else SERIAL_PROTOCOLLN(LONGEST_FILENAME); @@ -670,7 +722,7 @@ uint16_t CardReader::getnrfilenames() return nrFiles; } -void CardReader::chdir(const char * relpath) +bool CardReader::chdir(const char * relpath, bool doPresort) { SdFile newfile; SdFile *parent=&root; @@ -678,23 +730,32 @@ void CardReader::chdir(const char * relpath) if(workDir.isOpen()) parent=&workDir; - if(!newfile.open(*parent,relpath, O_READ)) + if(!newfile.open(*parent,relpath, O_READ) || ((workDirDepth + 1) >= MAX_DIR_DEPTH)) { SERIAL_ECHO_START; SERIAL_ECHORPGM(_n("Cannot enter subdir: "));////MSG_SD_CANT_ENTER_SUBDIR SERIAL_ECHOLN(relpath); + return 0; } else { + strcpy(dir_names[workDirDepth], relpath); + puts(relpath); + if (workDirDepth < MAX_DIR_DEPTH) { for (int d = ++workDirDepth; d--;) workDirParents[d+1] = workDirParents[d]; workDirParents[0]=*parent; } workDir=newfile; - #ifdef SDCARD_SORT_ALPHA + +#ifdef SDCARD_SORT_ALPHA + if (doPresort) presort(); - #endif + else + presort_flag = true; +#endif + return 1; } } @@ -1011,7 +1072,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 9bf9bd0a6..c79420737 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); @@ -34,14 +37,15 @@ public: uint16_t getnrfilenames(); void getAbsFilename(char *t); + void printAbsFilenameFast(); void getDirName(char* name, uint8_t level); uint16_t getWorkDirDepth(); void ls(bool printLFN); - void chdir(const char * relpath); + bool chdir(const char * relpath, bool doPresort); void updir(); - void setroot(); + void setroot(bool doPresort); #ifdef SDCARD_SORT_ALPHA void presort(); @@ -58,9 +62,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); }; @@ -82,6 +88,10 @@ public: char longFilename[LONG_FILENAME_LENGTH]; bool filenameIsDir; int lastnr; //last number of the autostart; +#ifdef SDCARD_SORT_ALPHA + bool presort_flag; + char dir_names[MAX_DIR_DEPTH][9]; +#endif // SDCARD_SORT_ALPHA private: SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH]; uint16_t workDirDepth; @@ -155,7 +165,7 @@ private: 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; - void diveSubfolder (const char *fileName, SdFile& dir); + bool diveSubfolder (const char *&fileName); void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); #ifdef SDCARD_SORT_ALPHA void flush_presort(); 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 0b1d58e04..aa05ad990 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -16,7 +16,7 @@ const char MSG_BED_DONE[] PROGMEM_I1 = ISTR("Bed done"); //// const char MSG_BED_HEATING[] PROGMEM_I1 = ISTR("Bed Heating"); //// const char MSG_BED_LEVELING_FAILED_POINT_LOW[] PROGMEM_I1 = ISTR("Bed leveling failed. Sensor didnt trigger. Debris on nozzle? Waiting for reset."); ////c=20 r=5 const char MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED[] PROGMEM_I1 = ISTR("XYZ calibration failed. Please consult the manual."); ////c=20 r=8 -const char MSG_BELT_STATUS[] PROGMEM_I1 = ISTR("Belt Status");////c=18 +const char MSG_BELT_STATUS[] PROGMEM_I1 = ISTR("Belt status");////c=18 const char MSG_CALIBRATE_Z_AUTO[] PROGMEM_I1 = ISTR("Calibrating Z"); ////c=20 r=2 const char MSG_CARD_MENU[] PROGMEM_I1 = ISTR("Print from SD"); //// const char MSG_CHECKING_X[] PROGMEM_I1 = ISTR("Checking X axis"); ////c=20 @@ -29,7 +29,7 @@ const char MSG_CRASHDETECT[] PROGMEM_I1 = ISTR("Crash det."); ////c=13 const char MSG_ERROR[] PROGMEM_I1 = ISTR("ERROR:"); //// const char MSG_EXTRUDER[] PROGMEM_I1 = ISTR("Extruder"); ////c=17 const char MSG_FANS_CHECK[] PROGMEM_I1 = ISTR("Fans check"); ////c=13 -const char MSG_FIL_RUNOUTS[] PROGMEM_I1 = ISTR("Fil. runouts"); ////c=14 +const char MSG_FIL_RUNOUTS[] PROGMEM_I1 = ISTR("Fil. runouts"); ////c=15 const char MSG_FILAMENT[] PROGMEM_I1 = ISTR("Filament"); ////c=17 r=1 const char MSG_FAN_SPEED[] PROGMEM_I1 = ISTR("Fan speed"); ////c=14 const char MSG_FILAMENT_CLEAN[] PROGMEM_I1 = ISTR("Filament extruding & with correct color?"); ////c=20 r=2 @@ -65,14 +65,14 @@ const char MSG_STEEL_SHEETS[] PROGMEM_I1 = ISTR("Steel sheets"); ////c=18 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring reference height of calibration point"); ////c=60 const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2[] PROGMEM_I1 = ISTR(" of 9"); ////c=14 const char MSG_MENU_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); //// -const char MSG_MMU_FAILS[] PROGMEM_I1 = ISTR("MMU fails"); ////c=14 -const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////c=14 +const char MSG_MMU_FAILS[] PROGMEM_I1 = ISTR("MMU fails"); ////c=15 +const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////c=15 const char MSG_NO[] PROGMEM_I1 = ISTR("No"); //// const char MSG_NOZZLE[] PROGMEM_I1 = ISTR("Nozzle"); //// const char MSG_PAPER[] PROGMEM_I1 = ISTR("Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."); ////c=20 r=10 const char MSG_PLACE_STEEL_SHEET[] PROGMEM_I1 = ISTR("Please place steel sheet on heatbed."); ////c=20 r=4 const char MSG_PLEASE_WAIT[] PROGMEM_I1 = ISTR("Please wait"); ////c=20 -const char MSG_POWER_FAILURES[] PROGMEM_I1 = ISTR("Power failures"); ////c=14 +const char MSG_POWER_FAILURES[] PROGMEM_I1 = ISTR("Power failures"); ////c=15 const char MSG_PREHEAT_NOZZLE[] PROGMEM_I1 = ISTR("Preheat the nozzle!"); ////c=20 const char MSG_PRESS_TO_UNLOAD[] PROGMEM_I1 = ISTR("Please press the knob to unload filament"); ////c=20 r=4 const char MSG_PRINT_ABORTED[] PROGMEM_I1 = ISTR("Print aborted"); ////c=20 @@ -131,7 +131,7 @@ const char MSG_MODEL[] PROGMEM_I1 = ISTR("Model"); //// const char MSG_FIRMWARE[] PROGMEM_I1 = ISTR("Firmware"); //// const char MSG_GCODE[] PROGMEM_I1 = ISTR("Gcode"); //// const char MSG_GCODE_DIFF_PRINTER_CONTINUE[] PROGMEM_I1 = ISTR("G-code sliced for a different printer type. Continue?"); ////c=20 r=5 -const char MSG_GCODE_DIFF_PRINTER_CANCELLED[] PROGMEM_I1 =ISTR("G-code sliced for a different printer type. Please re-slice the model again. Print cancelled."); ////c=20 r=6 +const char MSG_GCODE_DIFF_PRINTER_CANCELLED[] PROGMEM_I1 =ISTR("G-code sliced for a different printer type. Please re-slice the model again. Print cancelled."); ////c=20 r=7 const char MSG_NOZZLE_DIAMETER[] PROGMEM_I1 = ISTR("Nozzle d."); //// const char MSG_MMU_MODE[] PROGMEM_I1 = ISTR("MMU Mode"); //// const char MSG_SD_CARD[] PROGMEM_I1 = ISTR("SD card"); //// @@ -197,3 +197,4 @@ 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 0a05c58f5..a5b672fa2 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -197,6 +197,7 @@ 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 6939b1ea6..03446fc3e 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -57,7 +57,7 @@ int scrollstuff = 0; char longFilenameOLD[LONG_FILENAME_LENGTH]; - +int clock_interval = 0; static void lcd_sd_updir(); static void lcd_mesh_bed_leveling_settings(); @@ -75,11 +75,6 @@ int8_t FSensorStateMenu = 1; bool bMenuFSDetect=false; #endif //IR_SENSOR_ANALOG - -#ifdef SDCARD_SORT_ALPHA -bool presort_flag = false; -#endif - LcdCommands lcd_commands_type = LcdCommands::Idle; static uint8_t lcd_commands_step = 0; @@ -676,31 +671,85 @@ void lcdui_print_cmd_diag(void) // Print time (8 chars total) void lcdui_print_time(void) { - //if remaining print time estimation is available print it else print elapsed time - uint16_t print_t = 0; - if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) - print_t = print_time_remaining(); - else if(starttime != 0) - print_t = _millis() / 60000 - starttime / 60000; - int chars = 0; - if ((PRINTER_ACTIVE) && ((print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) || (starttime != 0))) - { - char suff = ' '; - char suff_doubt = ' '; - if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) - { - suff = 'R'; - if (feedmultiply != 100) - suff_doubt = '?'; - } - if (print_t < 6000) //time<100h - chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); - else //time>=100h - chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); - } - else - chars = lcd_printf_P(_N("%c--:-- "), LCD_STR_CLOCK[0]); - lcd_space(8 - chars); + //if remaining print time estimation is available print it else print elapsed time + int chars = 0; + if ((PRINTER_ACTIVE) && (starttime != 0)) + { + uint16_t print_t = 0; + uint16_t print_tr = 0; + uint16_t print_tc = 0; + char suff = ' '; + char suff_doubt = ' '; + +#ifdef TMC2130 + if (SilentModeMenu != SILENT_MODE_OFF) + { + if (print_time_remaining_silent != PRINT_TIME_REMAINING_INIT) + { + print_tr = print_time_remaining_silent; + } +//#ifdef CLOCK_INTERVAL_TIME + if (print_time_to_change_silent != PRINT_TIME_REMAINING_INIT) + { + print_tc = print_time_to_change_silent; + } +//#endif //CLOCK_INTERVAL_TIME + } + else + { +#endif //TMC2130 + if (print_time_remaining_normal != PRINT_TIME_REMAINING_INIT) + { + print_tr = print_time_remaining_normal; + } +//#ifdef CLOCK_INTERVAL_TIME + if (print_time_to_change_normal != PRINT_TIME_REMAINING_INIT) + { + print_tc = print_time_to_change_normal; + } +//#endif //CLOCK_INTERVAL_TIME +#ifdef TMC2130 + } +#endif //TMC2130 + +//#ifdef CLOCK_INTERVAL_TIME + if (clock_interval == CLOCK_INTERVAL_TIME*2) + { + clock_interval = 0; + } + clock_interval++; + + if (print_tc != 0 && clock_interval > CLOCK_INTERVAL_TIME) + { + print_t = print_tc; + suff = 'C'; + } + else +//#endif //CLOCK_INTERVAL_TIME + if (print_tr != 0) + { + print_t = print_tr; + suff = 'R'; + } + else + { + print_t = _millis() / 60000 - starttime / 60000; + } + + if (feedmultiply != 100 && (print_t == print_tr || print_t == print_tc)) + { + suff_doubt = '?'; + print_t = 100ul * print_t / feedmultiply; + } + + if (print_t < 6000) //time<100h + chars = lcd_printf_P(_N("%c%02u:%02u%c%c"), LCD_STR_CLOCK[0], print_t / 60, print_t % 60, suff, suff_doubt); + else //time>=100h + chars = lcd_printf_P(_N("%c%3uh %c%c"), LCD_STR_CLOCK[0], print_t / 60, suff, suff_doubt); + } + else + chars = lcd_printf_P(_N("%c--:-- "), LCD_STR_CLOCK[0]); + lcd_space(8 - chars); } //Print status line on status screen @@ -1659,8 +1708,8 @@ static void lcd_menu_fails_stats_mmu() //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | MMU fails: 000| MSG_MMU_FAILS c=14 -//! | MMU load fails: 000| MSG_MMU_LOAD_FAILS c=14 +//! | MMU fails 000| MSG_MMU_FAILS c=15 +//! | MMU load fails 000| MSG_MMU_LOAD_FAILS c=15 //! | | //! ---------------------- //! @endcode @@ -1673,8 +1722,8 @@ static void lcd_menu_fails_stats_mmu_print() lcd_home(); lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n" " %-16.16S%-3d"), _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_MMU_FAILS), fails, ////c=14 - _T(MSG_MMU_LOAD_FAILS), load_fails); ////c=14 + _T(MSG_MMU_FAILS), fails, ////c=15 + _T(MSG_MMU_LOAD_FAILS), load_fails); ////c=15 menu_back_if_clicked_fb(); } @@ -1683,9 +1732,9 @@ static void lcd_menu_fails_stats_mmu_print() //! @code{.unparsed} //! |01234567890123456789| //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | MMU fails: 000| MSG_MMU_FAILS c=14 -//! | MMU load fails: 000| MSG_MMU_LOAD_FAILS c=14 -//! | MMU power fails:000| c=14 r=1 +//! | MMU fails 000| MSG_MMU_FAILS c=15 +//! | MMU load fails 000| MSG_MMU_LOAD_FAILS c=15 +//! | MMU power fails 000| c=15 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1698,9 +1747,9 @@ static void lcd_menu_fails_stats_mmu_total() lcd_home(); lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n" " %-16.16S%-3d\n" " %-16.16S%-3d"), _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_MMU_FAILS), fails, ////c=14 - _T(MSG_MMU_LOAD_FAILS), load_fails, ////c=14 - _i("MMU power fails"), mmu_power_failures); ////c=14 r=1 + _T(MSG_MMU_FAILS), fails, ////c=15 + _T(MSG_MMU_LOAD_FAILS), load_fails, ////c=15 + _i("MMU power fails"), mmu_power_failures); ////c=15 r=1 menu_back_if_clicked_fb(); } @@ -1712,8 +1761,8 @@ static const char failStatsFmt[] PROGMEM = "%S\n" " %-16.16S%-3d\n" " %-16.16S%- //! @code{.unparsed} //! |01234567890123456789| //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | Power failures: 000| MSG_POWER_FAILURES c=14 -//! | Fil. runouts : 000| MSG_FIL_RUNOUTS c=14 +//! | Power failures 000| MSG_POWER_FAILURES c=15 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! | Crash X:000 Y:000| MSG_CRASH c=7 //! ---------------------- //! @endcode @@ -1728,8 +1777,8 @@ static void lcd_menu_fails_stats_total() lcd_home(); lcd_printf_P(failStatsFmt, _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 - _T(MSG_FIL_RUNOUTS), filam, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 + _T(MSG_FIL_RUNOUTS), filam, ////c=15 _T(MSG_CRASH), crashX, crashY); ////c=7 menu_back_if_clicked_fb(); } @@ -1739,9 +1788,9 @@ static void lcd_menu_fails_stats_total() //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | Power failures 000| MSG_POWER_FAILURES c=14 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 -//! | Crash X:000 Y:000| MSG_CRASH c=7 +//! | Power failures 000| MSG_POWER_FAILURES c=15 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 +//! | Crash X 000 Y 000| MSG_CRASH c=7 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1756,8 +1805,8 @@ static void lcd_menu_fails_stats_print() #ifndef PAT9125 lcd_printf_P(failStatsFmt, _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 - _T(MSG_FIL_RUNOUTS), filam, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 + _T(MSG_FIL_RUNOUTS), filam, ////c=15 _T(MSG_CRASH), crashX, crashY); ////c=7 #else // On the MK3 include detailed PAT9125 statistics about soft failures @@ -1766,7 +1815,7 @@ static void lcd_menu_fails_stats_print() " %-7.7S H %-3d S %-3d\n" " %-7.7S X %-3d Y %-3d"), _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_POWER_FAILURES), power, ////c=14 + _T(MSG_POWER_FAILURES), power, ////c=15 _i("Runouts"), filam, fsensor_softfail, //c=7 _T(MSG_CRASH), crashX, crashY); ////c=7 #endif @@ -1809,9 +1858,9 @@ static const char failStatsFmt[] PROGMEM = "%S\n" " %-16.16S%-3d\n" "%S\n" " %-1 //! @code{.unparsed} //! |01234567890123456789| //! |Last print failures | MSG_LAST_PRINT_FAILURES c=20 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! |Total failures | MSG_TOTAL_FAILURES c=20 -//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=14 +//! | Fil. runouts 000| MSG_FIL_RUNOUTS c=15 //! ---------------------- //! @endcode //! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations. @@ -1823,9 +1872,9 @@ static void lcd_menu_fails_stats() lcd_home(); lcd_printf_P(failStatsFmt, _T(MSG_LAST_PRINT_FAILURES), ////c=20 - _T(MSG_FIL_RUNOUTS), filamentLast, ////c=14 + _T(MSG_FIL_RUNOUTS), filamentLast, ////c=15 _T(MSG_TOTAL_FAILURES), ////c=20 - _T(MSG_FIL_RUNOUTS), filamentTotal); ////c=14 + _T(MSG_FIL_RUNOUTS), filamentTotal); ////c=15 menu_back_if_clicked(); } @@ -2237,18 +2286,18 @@ uint8_t nLevel; lcd_set_cursor(0,0); lcdui_print_temp(LCD_STR_THERMOMETER[0],(int)degHotend(0),(int)degTargetHotend(0)); -lcd_puts_at_P(0,2, _i("Press the knob")); ////MSG_ c=20 r=1 -lcd_set_cursor(0,3); +lcd_puts_at_P(0,1, _i("Press the knob")); ////MSG_ c=20 +lcd_set_cursor(0,2); switch(eFilamentAction) { case FilamentAction::Load: case FilamentAction::AutoLoad: case FilamentAction::MmuLoad: - lcd_puts_P(_i("to load filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to load filament")); ////MSG_ c=20 break; case FilamentAction::UnLoad: case FilamentAction::MmuUnLoad: - lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 r=1 + lcd_puts_P(_i("to unload filament")); ////MSG_ c=20 break; case FilamentAction::MmuEject: case FilamentAction::MmuCut: @@ -4319,7 +4368,7 @@ static void lcd_sort_type_set() { default: sdSort = SD_SORT_TIME; } eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort); - presort_flag = true; + card.presort_flag = true; } #endif //SDCARD_SORT_ALPHA @@ -5293,16 +5342,13 @@ do\ else\ MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_NORMAL), lcd_toshiba_flash_air_compatibility_toggle);\ \ - if (!farm_mode)\ + uint8_t sdSort;\ + EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ + switch (sdSort)\ {\ - uint8_t sdSort;\ - EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\ - switch (sdSort)\ - {\ - case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ - case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ - default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ - }\ + case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\ + case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\ + default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\ }\ }\ while (0) @@ -7185,8 +7231,8 @@ void lcd_sdcard_menu() { uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); - if (presort_flag == true) { - presort_flag = false; + if (card.presort_flag == true) { + card.presort_flag = false; card.presort(); } if (lcd_draw_update == 0 && LCD_CLICKED == 0) @@ -8399,7 +8445,7 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s if (screen == TestScreen::EndStops) lcd_puts_P(_i("Checking endstops"));////MSG_SELFTEST_CHECK_ENDSTOPS c=20 if (screen == TestScreen::AxisX) lcd_puts_P(_T(MSG_CHECKING_X)); if (screen == TestScreen::AxisY) lcd_puts_P(_T(MSG_CHECKING_Y)); - if (screen == TestScreen::AxisZ) lcd_puts_P(_i("Checking Z axis "));////MSG_SELFTEST_CHECK_Z c=20 + if (screen == TestScreen::AxisZ) lcd_puts_P(_i("Checking Z axis"));////MSG_SELFTEST_CHECK_Z c=20 if (screen == TestScreen::Bed) lcd_puts_P(_T(MSG_SELFTEST_CHECK_BED)); if (screen == TestScreen::Hotend || screen == TestScreen::HotendOk) lcd_puts_P(_i("Checking hotend "));////MSG_SELFTEST_CHECK_HOTEND c=20 @@ -8483,7 +8529,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; @@ -8550,7 +8596,7 @@ static void menu_action_sdfile(const char* filename) for (uint_least8_t i = 0; i < depth; i++) { for (uint_least8_t j = 0; j < 8; j++) { - eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, dir_names[i][j]); + eeprom_write_byte((uint8_t*)EEPROM_DIRS + j + 8 * i, card.dir_names[i][j]); } } @@ -8568,12 +8614,8 @@ static void menu_action_sdfile(const char* filename) void menu_action_sddirectory(const char* filename) { - uint8_t depth = (uint8_t)card.getWorkDirDepth(); - - strcpy(dir_names[depth], filename); - MYSERIAL.println(dir_names[depth]); - card.chdir(filename); - lcd_encoder = 0; + card.chdir(filename, true); + lcd_encoder = 0; } /** LCD API **/ diff --git a/lang/lang_en.txt b/lang/lang_en.txt index bcb0a4444..79848fe87 100644 --- a/lang/lang_en.txt +++ b/lang/lang_en.txt @@ -253,8 +253,8 @@ #MSG_FSENSOR "Fil. sensor" -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" @@ -448,13 +448,13 @@ # "Measured skew" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" # "MMU load failed " -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" #MSG_MMU_OK_RESUMING c=20 r=4 @@ -620,12 +620,12 @@ "Please upgrade." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." #MSG_FS_PAUSE c=5 "Pause" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" #MSG_PRINT_ABORTED c=20 @@ -643,7 +643,7 @@ #MSG_CARD_MENU "Print from SD" -# +# c=20 "Press the knob" #MSG_PRINT_PAUSED c=20 r=1 @@ -874,10 +874,10 @@ #MSG_TOTAL_FAILURES c=20 "Total failures" -# +# c=20 "to load filament" -# +# c=20 "to unload filament" #MSG_UNLOAD_FILAMENT c=17 @@ -1048,7 +1048,7 @@ #MSG_GCODE_DIFF_PRINTER_CONTINUE c=20 r=5 "G-code sliced for a different printer type. Continue?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." # diff --git a/lang/lang_en_cz.txt b/lang/lang_en_cz.txt index 0b3d7b14f..ea2dbc83d 100644 --- a/lang/lang_en_cz.txt +++ b/lang/lang_en_cz.txt @@ -338,8 +338,8 @@ "Fil. sensor" "Fil. senzor" -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" "Vypadky filam." #MSG_FILAMENT_CLEAN c=20 r=2 @@ -598,7 +598,7 @@ "Measured skew" "Merene zkoseni" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Selhani MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Zavedeni MMU selhalo" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "MMU selhani zavadeni" @@ -827,14 +827,14 @@ "Prosim aktualizujte." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pro nahrati trysky a pokracovani stisknete tlacitko." #MSG_FS_PAUSE c=5 "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Vypadky proudu" @@ -858,7 +858,7 @@ "Print from SD" "Tisk z SD" -# +# c=20 "Press the knob" "Stisknete hl. tlacitko" @@ -1166,11 +1166,11 @@ "Total failures" "Celkem selhani" -# +# c=20 "to load filament" "k zavedeni filamentu" -# +# c=20 "to unload filament" "k vyjmuti filamentu" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code je pripraven pro jiny typ tiskarny. Pokracovat?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code je pripraven pro jiny typ tiskarny. Prosim preslicujte model znovu. Tisk zrusen." diff --git a/lang/lang_en_de.txt b/lang/lang_en_de.txt index 0a436a9ee..ffc35678e 100644 --- a/lang/lang_en_de.txt +++ b/lang/lang_en_de.txt @@ -338,9 +338,9 @@ "Fil. sensor" "Fil. Sensor" -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " -"Fil. Maengel " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" +"Fil. Maengel" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" @@ -598,7 +598,7 @@ "Measured skew" "Schraeglauf" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "MMU Fehler" @@ -606,7 +606,7 @@ "MMU load failed " "MMU Ladefehler" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "MMU Ladefehler" @@ -827,14 +827,14 @@ "Bitte aktualisieren." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Bitte druecken Sie den Knopf um die Duese vorzuheizen und fortzufahren." #MSG_FS_PAUSE c=5 "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Netzfehler" @@ -858,7 +858,7 @@ "Print from SD" "Drucken von SD" -# +# c=20 "Press the knob" "Knopf druecken zum" @@ -1166,11 +1166,11 @@ "Total failures" "Gesamte Fehler" -# +# c=20 "to load filament" "Filament laden" -# +# c=20 "to unload filament" "Filament entladen" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-Code ist fuer einen anderen Drucker geslict. Fortfahren?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-Code ist fuer einen anderen Drucker geslict. Bitte slicen Sie das Modell erneut. Druck abgebrochen." diff --git a/lang/lang_en_es.txt b/lang/lang_en_es.txt index 2e29fa20a..b5bca7656 100644 --- a/lang/lang_en_es.txt +++ b/lang/lang_en_es.txt @@ -338,9 +338,9 @@ "Fil. sensor" "Sensor Fil." -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " -"Fil. acabado " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" +"Fil. acabado" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" @@ -598,7 +598,7 @@ "Measured skew" "Desviacion med:" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Fallos MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Carga MMU fallida" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Carga MMU falla" @@ -827,16 +827,16 @@ "Actualize por favor" #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Pulsa el dial para precalentar la boquilla y continue." #MSG_FS_PAUSE c=5 "Pause" "Pausa" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" -"Cortes de energia" +"Fallas energia" #MSG_PRINT_ABORTED c=20 "Print aborted" @@ -858,7 +858,7 @@ "Print from SD" "Menu tarjeta SD" -# +# c=20 "Press the knob" "Pulsa el dial" @@ -1166,13 +1166,13 @@ "Total failures" "Fallos totales" -# +# c=20 "to load filament" -"para cargar el filamento" +"para cargar el fil." -# +# c=20 "to unload filament" -"para descargar el filamento" +"para descargar fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "Codigo G laminado para un tipo de impresora diferente. ?Continuar?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "Codigo G laminado para una impresora diferente. Por favor relamina el modelo de nuevo. Impresion cancelada." diff --git a/lang/lang_en_fr.txt b/lang/lang_en_fr.txt index cc0cbb95b..7bd47294e 100644 --- a/lang/lang_en_fr.txt +++ b/lang/lang_en_fr.txt @@ -338,9 +338,9 @@ "Fil. sensor" "Capteur Fil." -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " -"Fins filament " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" +"Fins filament" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" @@ -598,7 +598,7 @@ "Measured skew" "Deviat.mesuree" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Echecs MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Echec chargement MMU" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Echecs charg. MMU" @@ -827,14 +827,14 @@ "Mettez a jour le FW." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Appuyez sur le bouton pour prechauffer la buse et continuer." #MSG_FS_PAUSE c=5 "Pause" "\x00" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Coup.de courant" @@ -858,7 +858,7 @@ "Print from SD" "Impr. depuis la SD" -# +# c=20 "Press the knob" "App. sur sur bouton" @@ -1166,11 +1166,11 @@ "Total failures" "Total des echecs" -# +# c=20 "to load filament" "pour charger le fil." -# +# c=20 "to unload filament" "pour decharger fil." @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "Le G-code a ete prepare pour une autre version de l'imprimante. Continuer?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "Le G-code a ete prepare pour une autre version de l'imprimante. Veuillez decouper le modele a nouveau. L'impression a ete annulee." diff --git a/lang/lang_en_it.txt b/lang/lang_en_it.txt index 8cd939082..d4cac7620 100644 --- a/lang/lang_en_it.txt +++ b/lang/lang_en_it.txt @@ -338,9 +338,9 @@ "Fil. sensor" "Sensore fil." -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " -"Fil. esauriti " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" +"Fil. esauriti" #MSG_FILAMENT_CLEAN c=20 r=2 "Filament extruding & with correct color?" @@ -598,7 +598,7 @@ "Measured skew" "Deviazione mis" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Fallimenti MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Caricamento MMU fallito" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Caricamenti MMU falliti" @@ -827,14 +827,14 @@ "Prego aggiornare." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Premete la manopola per preriscaldare l'ugello e continuare." #MSG_FS_PAUSE c=5 "Pause" "Pausa" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Mancanza corrente" @@ -858,7 +858,7 @@ "Print from SD" "Stampa da SD" -# +# c=20 "Press the knob" "Premere la manopola" @@ -1166,13 +1166,13 @@ "Total failures" "Totale fallimenti" -# +# c=20 "to load filament" -"per caricare il filamento" +"per caricare il fil." -# +# c=20 "to unload filament" -"per scaricare il filamento" +"per scaricare fil." #MSG_UNLOAD_FILAMENT c=17 "Unload filament" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code processato per una stampante diversa. Continuare?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code processato per una stampante diversa. Per favore esegui nuovamente lo slice del modello. Stampa annullata." diff --git a/lang/lang_en_pl.txt b/lang/lang_en_pl.txt index 38d1421f7..bbdf0aca1 100644 --- a/lang/lang_en_pl.txt +++ b/lang/lang_en_pl.txt @@ -338,8 +338,8 @@ "Fil. sensor" "Czuj. filam." -#MSG_FIL_RUNOUTS c=14 -"Fil. runouts " +#MSG_FIL_RUNOUTS c=15 +"Fil. runouts" "Konc.filamentu" #MSG_FILAMENT_CLEAN c=20 r=2 @@ -598,7 +598,7 @@ "Measured skew" "Zmierzony skos" -#MSG_MMU_FAILS c=14 +#MSG_MMU_FAILS c=15 "MMU fails" "Bledy MMU" @@ -606,7 +606,7 @@ "MMU load failed " "Blad ladowania MMU" -#MSG_MMU_LOAD_FAILS c=14 +#MSG_MMU_LOAD_FAILS c=15 "MMU load fails" "Bledy ladow. MMU" @@ -827,14 +827,14 @@ "Prosze zaktualizowac." #MSG_PRESS_TO_PREHEAT c=20 r=4 -"Press knob to preheat nozzle and continue." +"Press the knob to preheat nozzle and continue." "Wcisnij pokretlo aby rozgrzac dysze i kontynuowac." #MSG_FS_PAUSE c=5 "Pause" "Pauza" -#MSG_POWER_FAILURES c=14 +#MSG_POWER_FAILURES c=15 "Power failures" "Zaniki zasilania" @@ -858,7 +858,7 @@ "Print from SD" "Druk z karty SD" -# +# c=20 "Press the knob" "Wcisnij pokretlo" @@ -1166,11 +1166,11 @@ "Total failures" "Suma bledow" -# +# c=20 "to load filament" "aby zaladow. fil." -# +# c=20 "to unload filament" "aby rozlad. filament" @@ -1398,7 +1398,7 @@ "G-code sliced for a different printer type. Continue?" "G-code pociety dla innej drukarki. Kontynuowac?" -#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=6 +#MSG_GCODE_DIFF_PRINTER_CANCELLED c=20 r=7 "G-code sliced for a different printer type. Please re-slice the model again. Print cancelled." "G-code pociety dla drukarki innego typu. Potnij model ponownie. Druk anulowany."