Esempio n. 1
0
/**
  Converts a ascii GCode line into a GCode structure.
*/
bool GCode::parseAscii(char *line,bool fromSerial)
{
    char *pos = line;
    params = 0;
    params2 = 0;
    internalCommand = !fromSerial;
	bool hasChecksum = false;
    char c;
    while ( (c = *(pos++)) )
    {
        if(c == '(' || c == '%') break; // alternative comment or program block
        switch(c)
        {
        case 'N':
        case 'n':
        {
            actLineNumber = parseLongValue(pos);
            params |=1;
            N = actLineNumber;
            break;
        }
        case 'G':
        case 'g':
        {
            G = parseLongValue(pos) & 0xffff;
            params |= 4;
            if(G > 255) params |= 4096;
            break;
        }
        case 'M':
        case 'm':
        {
            M = parseLongValue(pos) & 0xffff;
            params |= 2;
            if(M > 255) params |= 4096;
            // handle non standard text arguments that some M codes have
            if (M == 20 || M == 23 || M == 28 || M == 29 || M == 30 || M == 32 || M == 36 || M == 117)
            {
                // after M command we got a filename or text
                char digit;
                while( (digit = *pos) )
                {
                    if (digit < '0' || digit > '9') break;
                    pos++;
                }
                while( (digit = *pos) )
                {
                    if (digit != ' ') break;
                    pos++;
                    // skip leading whitespaces (may be no white space)
                }
                text = pos;
                while (*pos)
                {
                    if((M != 117 && M != 20 && *pos==' ') || *pos=='*') break;
                    pos++; // find a space as file name end
                }
                *pos = 0; // truncate filename by erasing space with nul, also skips checksum
                waitUntilAllCommandsAreParsed = true; // don't risk string be deleted
                params |= 32768;
            }
            break;
        }
        case 'X':
        case 'x':
        {
            X = parseFloatValue(pos);
            params |= 8;
            break;
        }
        case 'Y':
        case 'y':
        {
            Y = parseFloatValue(pos);
            params |= 16;
            break;
        }
        case 'Z':
        case 'z':
        {
            Z = parseFloatValue(pos);
            params |= 32;
            break;
        }
        case 'E':
        case 'e':
        {
            E = parseFloatValue(pos);
            params |= 64;
            break;
        }
        case 'F':
        case 'f':
        {
            F = parseFloatValue(pos);
            params |= 256;
            break;
        }
        case 'T':
        case 't':
        {
            T = parseLongValue(pos) & 0xff;
            params |= 512;
            break;
        }
        case 'S':
        case 's':
        {
            S = parseLongValue(pos);
            params |= 1024;
            break;
        }
        case 'P':
        case 'p':
        {
            P = parseLongValue(pos);
            params |= 2048;
            break;
        }
        case 'I':
        case 'i':
        {
            I = parseFloatValue(pos);
            params2 |= 1;
            params |= 4096; // Needs V2 for saving
            break;
        }
        case 'J':
        case 'j':
        {
            J = parseFloatValue(pos);
            params2 |= 2;
            params |= 4096; // Needs V2 for saving
            break;
        }
        case 'R':
        case 'r':
        {
            R = parseFloatValue(pos);
            params2 |= 4;
            params |= 4096; // Needs V2 for saving
            break;
        }
        case 'D':
        case 'd':
        {
            D = parseFloatValue(pos);
            params2 |= 8;
            params |= 4096; // Needs V2 for saving
            break;
        }
        case 'C':
        case 'c':
        {
	        D = parseFloatValue(pos);
	        params2 |= 16;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'H':
        case 'h':
        {
	        D = parseFloatValue(pos);
	        params2 |= 32;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'A':
        case 'a':
        {
	        D = parseFloatValue(pos);
	        params2 |= 64;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'B':
        case 'b':
        {
	        D = parseFloatValue(pos);
	        params2 |= 128;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'K':
        case 'k':
        {
	        D = parseFloatValue(pos);
	        params2 |= 256;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'L':
        case 'l':
        {
	        D = parseFloatValue(pos);
	        params2 |= 512;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case 'O':
        case 'o':
        {
	        D = parseFloatValue(pos);
	        params2 |= 1024;
	        params |= 4096; // Needs V2 for saving
	        break;
        }
        case '*' : //checksum
        {
            uint8_t checksum_given = parseLongValue(pos);
            uint8_t checksum = 0;
            while(line != (pos - 1)) checksum ^= *line++;
#if FEATURE_CHECKSUM_FORCED
            Printer::flag0 |= PRINTER_FLAG0_FORCE_CHECKSUM;
#endif
            if(checksum != checksum_given)
            {
                if(Printer::debugErrors())
                {
                    Com::printErrorFLN(Com::tWrongChecksum);
                }
                return false; // mismatch
            }
			hasChecksum = true;
            break;
        }
        default:
            break;
        }// end switch
    }// end while
	if(wasLastCommandReceivedAsBinary && !hasChecksum) {
		Com::printErrorFLN("Checksum required when switching back to ASCII protocol.");
		return false;
	}
    if(hasFormatError() || (params & 518) == 0)   // Must contain G, M or T command and parameter need to have variables!
    {
        formatErrors++;
        if(Printer::debugErrors())
            Com::printErrorFLN(Com::tFormatError);
        if(formatErrors < 3) return false;
    }
    else formatErrors = 0;
    return true;
}
Esempio n. 2
0
/**
  Converts a ascii GCode line into a GCode structure.
*/
bool GCode::parseAscii(char *line,bool fromSerial)
{
    bool has_checksum = false;
    char *pos;
    params = 0;
    params2 = 0;
    if((pos = strchr(line,'N'))!=0)   // Line number detected
    {
        actLineNumber = parseLongValue(++pos);
        params |=1;
        N = actLineNumber & 0xffff;
    }
    if((pos = strchr(line,'M'))!=0)   // M command
    {
        M = parseLongValue(++pos) & 0xffff;
        params |= 2;
        if(M>255) params |= 4096;
    }
    if(hasM() && (M == 23 || M == 28 || M == 29 || M == 30 || M == 32 || M == 117))
    {
        // after M command we got a filename for sd card management
        char *sp = line;
        while(*sp!='M') sp++; // Search M command
        while(*sp!=' ') sp++; // search next whitespace
        while(*sp==' ') sp++; // skip leading whitespaces
        text = sp;
        while(*sp)
        {
            if((M != 117 && *sp==' ') || *sp=='*') break; // end of filename reached
            sp++;
        }
        *sp = 0; // Removes checksum, but we don't care. Could also be part of the string.
        waitUntilAllCommandsAreParsed = true; // don't risk string be deleted
        params |= 32768;
    }
    else
    {
        if((pos = strchr(line,'G'))!=0)   // G command
        {
            G = parseLongValue(++pos) & 0xffff;
            params |= 4;
            if(G>255) params |= 4096;
        }
        if((pos = strchr(line,'X'))!=0)
        {
            X = parseFloatValue(++pos);
            params |= 8;
        }
        if((pos = strchr(line,'Y'))!=0)
        {
            Y = parseFloatValue(++pos);
            params |= 16;
        }
        if((pos = strchr(line,'Z'))!=0)
        {
            Z = parseFloatValue(++pos);
            params |= 32;
        }
        if((pos = strchr(line,'E'))!=0)
        {
            E = parseFloatValue(++pos);
            params |= 64;
        }
        if((pos = strchr(line,'F'))!=0)
        {
            F = parseFloatValue(++pos);
            params |= 256;
        }
        if((pos = strchr(line,'T'))!=0)   // M command
        {
            T = parseLongValue(++pos) & 0xff;
            params |= 512;
        }
        if((pos = strchr(line,'S'))!=0)   // M command
        {
            S = parseLongValue(++pos);
            params |= 1024;
        }
        if((pos = strchr(line,'P'))!=0)   // M command
        {
            P = parseLongValue(++pos);
            params |= 2048;
        }
        if((pos = strchr(line,'I'))!=0)
        {
            I = parseFloatValue(++pos);
            params2 |= 1;
            params |= 4096; // Needs V2 for saving
        }
        if((pos = strchr(line,'J'))!=0)
        {
            J = parseFloatValue(++pos);
            params2 |= 2;
            params |= 4096; // Needs V2 for saving
        }
        if((pos = strchr(line,'R'))!=0)
        {
            R = parseFloatValue(++pos);
            params2 |= 4;
            params |= 4096; // Needs V2 for saving
        }
    }
    if((pos = strchr(line,'*'))!=0)   // checksum
    {
        uint8_t checksum_given = parseLongValue(pos+1);
        uint8_t checksum = 0;
        while(line!=pos) checksum ^= *line++;
#if FEATURE_CHECKSUM_FORCED
        Printer::flag0 |= PRINTER_FLAG0_FORCE_CHECKSUM;
#endif
        if(checksum!=checksum_given)
        {
            if(Printer::debugErrors())
            {
                Com::printErrorFLN(Com::tWrongChecksum);
            }
            return false; // mismatch
        }
    }
#if FEATURE_CHECKSUM_FORCED
    else
    {
        if(!fromSerial) return true;
        if(hasM() && (M == 110 || hasString())) return true;
        if(Printer::debugErrors())
        {
            Com::printErrorFLN(Com::tMissingChecksum);
        }
        return false;
    }
#endif
    if(hasFormatError() || (params & 518)==0)   // Must contain G, M or T command and parameter need to have variables!
    {
        formatErrors++;
        if(Printer::debugErrors())
            Com::printErrorFLN(Com::tFormatError);
        if(formatErrors<3) return false;
    }
    else formatErrors = 0;
    return true;
}
bool CompactQik2s9v1::hasFormatError()
{
	return hasFormatError(false);
}