void GCode::resetFatalError() {
	TemperatureController::resetAllErrorStates();
	fatalErrorMsg = NULL;
	UI_ERROR("");
	EVENT_CONTINUE_FROM_FATAL_ERROR
	Com::printFLN(PSTR("info:Continue from fatal state"));
}
Exemple #2
0
/** \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
}