Пример #1
0
/**
  Check if result is plausible. If it is, an ok is send and the command is stored in queue.
  If not, a resend and ok is send.
*/
void GCode::checkAndPushCommand()
{
    if(hasM())
    {
        if(M==110)   // Reset line number
        {
            lastLineNumber = actLineNumber;
            Com::printFLN(Com::tOk);
            waitingForResend = -1;
            return;
        }
        if(M==112)   // Emergency kill - freeze printer
        {
            Commands::emergencyStop();
        }
#ifdef DEBUG_COM_ERRORS
        if(M==666)
        {
            lastLineNumber++;
            return;
        }
#endif // DEBUG_COM_ERRORS
    }
    if(hasN())
    {
        if((((lastLineNumber+1) & 0xffff)!=(actLineNumber&0xffff)))
        {
            if(waitingForResend<0)   // after a resend, we have to skip the garbage in buffers, no message for this
            {
                if(Printer::debugErrors())
                {
                    Com::printF(Com::tExpectedLine,lastLineNumber+1);
                    Com::printFLN(Com::tGot,actLineNumber);
                }
                requestResend(); // Line missing, force resend
            }
            else
            {
                --waitingForResend;
                commandsReceivingWritePosition = 0;
                Com::printFLN(Com::tSkip,actLineNumber);
                Com::printFLN(Com::tOk);
            }
            return;
        }
        lastLineNumber = actLineNumber;
    }
    pushCommand();
#ifdef ACK_WITH_LINENUMBER
    Com::printFLN(Com::tOkSpace,actLineNumber);
#else
    Com::printFLN(Com::tOk);
#endif
    wasLastCommandReceivedAsBinary = sendAsBinary;
    waitingForResend = -1; // everything is ok.
}
Пример #2
0
/*
    Start updating.
    Implementation of VariableNameManager's virtual funtion to establish a connection to a PV as the variable name has changed.
    This function may also be used to initiate updates when loaded as a plugin.
*/
void QELineEdit::establishConnection( unsigned int variableIndex ) {

    // Create a connection.
    // If successfull, the QCaObject object that will supply data update signals will be returned
    qcaobject::QCaObject* qca = createConnection( variableIndex );

    // If a QCaObject object is now available to supply data update signals, connect it to the appropriate slots
    if(  qca ) {
        QObject::connect( qca,  SIGNAL( stringChanged( const QString&, QCaAlarmInfo&, QCaDateTime&, const unsigned int& ) ),
                          this, SLOT( setTextIfNoFocus( const QString&, QCaAlarmInfo&, QCaDateTime&, const unsigned int& ) ) );
        QObject::connect( qca,  SIGNAL( connectionChanged( QCaConnectionInfo& ) ),
                          this, SLOT( connectionChanged( QCaConnectionInfo& ) ) );
        QObject::connect( this, SIGNAL( requestResend() ),
                          qca, SLOT( resendLastData() ) );
    }
}
Пример #3
0
/*
    Start updating.
    Implementation of VariableNameManager's virtual funtion to establish a connection to a PV as the variable name has changed.
    This function may also be used to initiate updates when loaded as a plugin.
*/
void QEPeriodic::establishConnection( unsigned int variableIndex ) {

    // Create a connection.
    // If successfull, the QCaObject object that will supply data update signals will be returned
    qcaobject::QCaObject* qca = createConnection( variableIndex );

    // If a QCaObject object is now available to supply data update signals, connect it to the appropriate slots
    if(  qca ) {
        QObject::connect( qca,  SIGNAL( floatingChanged( const double&, QCaAlarmInfo&, QCaDateTime&, const unsigned int& ) ),
                          this, SLOT( setElement( const double&, QCaAlarmInfo&, QCaDateTime&, const unsigned int& ) ) );

        // Get conection status changes always (subscribing or not)
        QObject::connect( qca,  SIGNAL( connectionChanged( QCaConnectionInfo&, const unsigned int&  ) ),
                          this, SLOT( connectionChanged( QCaConnectionInfo&, const unsigned int&  ) ) );
        QObject::connect( this, SIGNAL( requestResend() ),
                          qca, SLOT( resendLastData() ) );

    }
}
void DtmfDataLinkLayer::checkFrameReceiveList()
{
	//initialize variable to hold EOT, goes and nogoes
	int request = 0;
	int listLength = 0;

	//iterate through list to find list length
	for(int i=0;i<8;i++)
		if(frameRecList[i].eot == 1)
			listLength = i+1;

#ifdef DEBUG
	DEBUG_OUT << "Checking list of " << listLength << " entries..." << std::endl;
	for(int i=0;i<listLength;i++)
	{
		DEBUG_OUT << i << " - ";
		for(int j=7;j>=0;j--)
			DEBUG_OUT << (bool)(frameRecList[i].dataByte&(1<<j));
		if(frameRecList[i].flag==1)
			DEBUG_OUT << " - received";
		else
			DEBUG_OUT << " - missing";
		if(frameRecList[i].eot == 1)
			DEBUG_OUT << " - End of transmission";
		DEBUG_OUT << std::endl;
	}
#endif

	//iterate through list and and set request variable according to flagbits
	for(int j=0;j<listLength;j++)
	{
		for(int i=0;i<j+1;i++)
			request |= ((bool)(frameRecList[i].flag)<<i);
	}

	//pass upwards if list is complete
	if(request == (pow(2.,listLength)-1) && listLength > 0)
		passDataUpwards(listLength);
	else
		//request resends
		requestResend(request);
}
Пример #5
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
}
Пример #6
0
// Parse and use an XML string representing the widget's user info.
// The user info includes attributes for each element in the table such as
// if the element is selectable, and what the user defined values are for an element.
void QEPeriodic::setUserInfo( QString inStr )
{
    QXmlStreamReader xml( inStr );

    // Set all element info to default as only non default is saved in the XML
    for( int i = 0; i < NUM_ELEMENTS; i++ )
    {
        userInfo[i].enable = false;
        userInfo[i].value1 = 0.0;
        userInfo[i].value2 = 0.0;
        userInfo[i].elementText.clear();
    }

    // Step over initial document start
    if( xml.readNext() == QXmlStreamReader::StartDocument )
    {
        // Parse all elements
        while (!xml.atEnd())
        {
            // Ignore all but 'elements' elements
            if( xml.readNext() == QXmlStreamReader::StartElement &&
                xml.name().compare( "elements" ) == 0 )
            {
                // Found an 'elements' element
                // Parse all elements in the 'elements' element
                while (!xml.atEnd())
                {
                    // Ignore all but 'element' elements
                    if( xml.readNext() == QXmlStreamReader::StartElement &&
                        xml.name().compare( "element" ) == 0 )
                    {

                        // Found an 'element' element, get any attributes
                        bool ok;
                        QXmlStreamAttributes attributes = xml.attributes();

                        // Only use the element if it includes a valid element number attribute
                        int i = attributes.value( "number" ).toString().toInt( &ok );
                        if( i >= 1 && i <= NUM_ELEMENTS )
                        {
                            // Element number is good, so extract any other attributes.
                            // Note, the presence of each attribute is not checked.
                            // If not present or valid then the returned 0.0 or empty strings are used
                            i--;
                            if( attributes.value( "enable" ).toString().compare( "yes" ) == 0 )
                                userInfo[i].enable = true;
                            else
                                userInfo[i].enable = false;
                            userInfo[i].value1 = attributes.value( "value1" ).toString().toDouble( &ok );
                            userInfo[i].value2 = attributes.value( "value2" ).toString().toDouble( &ok );
                            userInfo[i].elementText = attributes.value( "text" ).toString();
                        }
                    }
                }
            }
        }
    }
//    if (xml.hasError()) {
//        qDebug() << xml.errorString();
//    }

    emit requestResend();
}
Пример #7
0
// variable 2 tolerance
void QEPeriodic::setVariableTolerance2( double variableTolerance2In )
{
    variableTolerance2 = variableTolerance2In;
    emit requestResend();
}
Пример #8
0
// variable 2 type
void QEPeriodic::setVariableType2( variableTypes variableType2In )
{
    variableType2 = variableType2In;
    emit requestResend();
}
Пример #9
0
// presentation options
void QEPeriodic::setPresentationOption( presentationOptions presentationOptionIn )
{
    presentationOption = presentationOptionIn;
    updatePresentationOptions();
    emit requestResend();
}
Пример #10
0
// subscribe
void QEPeriodic::setSubscribe( bool subscribeIn )
{
    subscribe = subscribeIn;
    emit requestResend();
}
Пример #11
0
/**
  Check if result is plausible. If it is, an ok is send and the command is stored in queue.
  If not, a resend and ok is send.
*/
void GCode::checkAndPushCommand()
{
    if(hasM())
    {
        if(M == 110)   // Reset line number
        {
            lastLineNumber = actLineNumber;
            Com::printFLN(Com::tOk);
            waitingForResend = -1;
            return;
        }
        if(M == 112)   // Emergency kill - freeze printer
        {
            Commands::emergencyStop();
        }
#ifdef DEBUG_COM_ERRORS
        if(M == 666) // force an communication error
        {
            lastLineNumber++;
            return;
        } else if(M == 668) {
            lastLineNumber = 0;  // simulate a reset so lines are out of resend buffer
        }
#endif // DEBUG_COM_ERRORS
    }
    if(hasN())
    {
        if((((lastLineNumber + 1) & 0xffff) != (actLineNumber & 0xffff)))
        {
            if(static_cast<uint16_t>(lastLineNumber - actLineNumber) < 40)
            {
                // we have seen that line already. So we assume it is a repeated resend and we ignore it
                commandsReceivingWritePosition = 0;
                Com::printFLN(Com::tSkip,actLineNumber);
                Com::printFLN(Com::tOk);
            }
            else if(waitingForResend < 0)  // after a resend, we have to skip the garbage in buffers, no message for this
            {
                if(Printer::debugErrors())
                {
                    Com::printF(Com::tExpectedLine, lastLineNumber + 1);
                    Com::printFLN(Com::tGot, actLineNumber);
                }
                requestResend(); // Line missing, force resend
            }
            else
            {
                --waitingForResend;
                commandsReceivingWritePosition = 0;
                Com::printFLN(Com::tSkip, actLineNumber);
                Com::printFLN(Com::tOk);
            }
            return;
        }
        lastLineNumber = actLineNumber;
    } /*
	This test is not compatible with all hosts. Replaced by forbidding backward switch of protocols.
	else if(lastLineNumber && !(hasM() && M == 117)) { // once line number always line number!
		if(Printer::debugErrors())
        {
			Com::printErrorFLN(PSTR("Missing linenumber"));
		}
		requestResend();
		return;
	}*/
	if(GCode::hasFatalError() && !(hasM() && M==999)) {
		GCode::reportFatalError();
	} else {
		pushCommand();
	}
#ifdef DEBUG_COM_ERRORS
    if(hasM() && M == 667)
        return; // omit ok
#endif
#if ACK_WITH_LINENUMBER
    Com::printFLN(Com::tOkSpace, actLineNumber);
#else
    Com::printFLN(Com::tOk);
#endif
    wasLastCommandReceivedAsBinary = sendAsBinary;
	keepAlive(NotBusy);
    waitingForResend = -1; // everything is ok.
}