void GCode::resetFatalError() { TemperatureController::resetAllErrorStates(); fatalErrorMsg = NULL; UI_ERROR(""); EVENT_CONTINUE_FROM_FATAL_ERROR Com::printFLN(PSTR("info:Continue from fatal state")); }
/** \brief Read from serial console or sdcard. This function is the main function to read the commands from serial console or from sdcard. It must be called frequently to empty the incoming buffer. */ void GCode::readFromSerial() { if(bufferLength>=GCODE_BUFFER_SIZE) return; // all buffers full if(waitUntilAllCommandsAreParsed && bufferLength) return; waitUntilAllCommandsAreParsed=false; millis_t time = HAL::timeInMilliseconds(); if(!HAL::serialByteAvailable()) { if((waitingForResend>=0 || commandsReceivingWritePosition>0) && time-timeOfLastDataPacket>200) { requestResend(); // Something is wrong, a started line was not continued in the last second timeOfLastDataPacket = time; } #ifdef WAITING_IDENTIFIER else if(bufferLength == 0 && time-timeOfLastDataPacket>1000) // Don't do it if buffer is not empty. It may be a slow executing command. { #if !SUPPORT_CURA Com::printFLN(Com::tWait); // Unblock communication in case the last ok was not received correct. #endif // !SUPPORT_CURA timeOfLastDataPacket = time; } #endif } while(HAL::serialByteAvailable() && commandsReceivingWritePosition < MAX_CMD_SIZE) // consume data until no data or buffer full { #if FEATURE_WATCHDOG HAL::pingWatchdog(); #endif // FEATURE_WATCHDOG timeOfLastDataPacket = time; //HAL::timeInMilliseconds(); commandReceiving[commandsReceivingWritePosition++] = HAL::serialReadByte(); // first lets detect, if we got an old type ascii command if(commandsReceivingWritePosition==1) { if(waitingForResend>=0 && wasLastCommandReceivedAsBinary) { if(!commandReceiving[0]) waitingForResend--; // Skip 30 zeros to get in sync else waitingForResend = 30; commandsReceivingWritePosition = 0; continue; } if(!commandReceiving[0]) // Ignore zeros { commandsReceivingWritePosition = 0; continue; } sendAsBinary = (commandReceiving[0] & 128)!=0; } if(sendAsBinary) { if(commandsReceivingWritePosition < 2 ) continue; if(commandsReceivingWritePosition == 5 || commandsReceivingWritePosition == 4) binaryCommandSize = computeBinarySize((char*)commandReceiving); if(commandsReceivingWritePosition == binaryCommandSize) { GCode *act = &commandsBuffered[bufferWriteIndex]; if(act->parseBinary(commandReceiving,true)) // Success act->checkAndPushCommand(); else requestResend(); commandsReceivingWritePosition = 0; return; } } else // Ascii command { char ch = commandReceiving[commandsReceivingWritePosition-1]; if(ch == 0 || ch == '\n' || ch == '\r' || (!commentDetected && ch == ':')) // complete line read { //Com::printF(PSTR("Parse ascii"));Com::print((char*)commandReceiving);Com::println(); commandReceiving[commandsReceivingWritePosition-1]=0; commentDetected = false; if(commandsReceivingWritePosition==1) // empty line ignore { commandsReceivingWritePosition = 0; continue; } GCode *act = &commandsBuffered[bufferWriteIndex]; if(act->parseAscii((char *)commandReceiving,true)) // Success act->checkAndPushCommand(); else requestResend(); commandsReceivingWritePosition = 0; return; } else { if(ch == ';') commentDetected = true; // ignore new data until lineend if(commentDetected) commandsReceivingWritePosition--; } } if(commandsReceivingWritePosition == MAX_CMD_SIZE) { requestResend(); return; } } #if SDSUPPORT if(!sd.sdmode || commandsReceivingWritePosition!=0) // not reading or incoming serial command return; while( sd.filesize > sd.sdpos && commandsReceivingWritePosition < MAX_CMD_SIZE) // consume data until no data or buffer full { #if FEATURE_WATCHDOG HAL::pingWatchdog(); #endif // FEATURE_WATCHDOG timeOfLastDataPacket = HAL::timeInMilliseconds(); int n = sd.file.read(); #if FEATURE_WATCHDOG HAL::pingWatchdog(); #endif // FEATURE_WATCHDOG if(n==-1) { Com::printFLN(Com::tSDReadError); UI_ERROR("SD Read Error"); // Second try in case of recoverable errors sd.file.seekSet(sd.sdpos); n = sd.file.read(); #if FEATURE_WATCHDOG HAL::pingWatchdog(); #endif // FEATURE_WATCHDOG if(n==-1) { Com::printErrorFLN(PSTR("SD error did not recover!")); sd.sdmode = false; break; } UI_ERROR("SD error fixed"); } sd.sdpos++; // = file.curPosition(); commandReceiving[commandsReceivingWritePosition++] = (uint8_t)n; // first lets detect, if we got an old type ascii command if(commandsReceivingWritePosition==1) { sendAsBinary = (commandReceiving[0] & 128)!=0; } if(sendAsBinary) { if(commandsReceivingWritePosition < 2 ) continue; if(commandsReceivingWritePosition == 4 || commandsReceivingWritePosition == 5) binaryCommandSize = computeBinarySize((char*)commandReceiving); if(commandsReceivingWritePosition==binaryCommandSize) { GCode *act = &commandsBuffered[bufferWriteIndex]; if(act->parseBinary(commandReceiving,false)) // Success, silently ignore illegal commands pushCommand(); commandsReceivingWritePosition = 0; return; } } else { char ch = commandReceiving[commandsReceivingWritePosition-1]; bool returnChar = ch == '\n' || ch == '\r'; if(returnChar || sd.filesize == sd.sdpos || (!commentDetected && ch == ':') || commandsReceivingWritePosition >= (MAX_CMD_SIZE - 1) ) // complete line read { if(returnChar || ch == ':') commandReceiving[commandsReceivingWritePosition-1]=0; else commandReceiving[commandsReceivingWritePosition]=0; commentDetected = false; if(commandsReceivingWritePosition==1) // empty line ignore { commandsReceivingWritePosition = 0; continue; } GCode *act = &commandsBuffered[bufferWriteIndex]; if(act->parseAscii((char *)commandReceiving,false)) // Success pushCommand(); commandsReceivingWritePosition = 0; return; } else { if(ch == ';') commentDetected = true; // ignore new data until lineend if(commentDetected) commandsReceivingWritePosition--; } } } sd.sdmode = false; Com::printFLN(Com::tDonePrinting); commandsReceivingWritePosition = 0; commentDetected = false; Printer::setMenuMode(MENU_MODE_SD_PRINTING,false); BEEP_STOP_PRINTING #endif }