Esempio n. 1
0
/****************************************************************************
*                                                                           *
* Character Received - add it to our command                                *
*                                                                           *
****************************************************************************/
void gcode_parse_char(uint8_t c) 
{
  uint8_t save_ch;

  #ifdef ASTERISK_IN_CHECKSUM_INCLUDED
  if (next_target.seen_checksum == 0)
  {
    next_target.checksum_calculated = crc(next_target.checksum_calculated, c);
  }
  #endif

  save_ch = c;

  // uppercase
  if (c >= 'a' && c <= 'z')
  {
    c &= ~32;
  }

  // process previous field
  if (last_field)
  {
    // check if we're seeing a new field or end of line
    // any character will start a new field, even invalid/unknown ones
    if ((c >= 'A' && c <= 'Z') || c == '*' || (c == 10) || (c == 13))
    {
      // before using value, apply the sign
      if (read_digit.sign)
      {
        value = -value;
      }

      switch (last_field)
      {
        case 'G':
        next_target.G = value;
        break;

        case 'M':
        next_target.M = value;
        // this is a bit hacky since string parameters don't fit in general G code syntax
        // NB: filename MUST start with a letter and MUST NOT contain spaces
        // letters will also be converted to uppercase
        if ((next_target.M == 23) || (next_target.M == 28))
        {
          next_target.getting_string = 1;
        }
        break;

        case 'X':
        if (next_target.option_inches)
        {
          next_target.target.x = inch_to_mm(value);
        }
        else
        {
          next_target.target.x = value;
        }
        break;

        case 'Y':
        if (next_target.option_inches)
        {
          next_target.target.y = inch_to_mm(value);
        }
        else
        {
          next_target.target.y = value;
        }
        break;

        case 'Z':
        if (next_target.option_inches)
        {
          next_target.target.z = inch_to_mm(value);
        }
        else
        {
          next_target.target.z = value;
        }
        break;

        case 'E':
        if (next_target.option_inches)
        {
          next_target.target.e = inch_to_mm(value);
        }
        else
        {
          next_target.target.e = value;
        }
        break;

        case 'F':
        if (next_target.option_inches)
        {
          next_target.target.feed_rate = inch_to_mm(value);
        }
        else
        {
          next_target.target.feed_rate = value;
        }
        break;

        case 'S':
        next_target.S = value;
        break;

        case 'P':
        // if this is dwell, multiply by 1000 to convert seconds to milliseconds
        if (next_target.G == 4)
        {
          next_target.P = value * 1000.0;
        }
        else
        {
          next_target.P = value;
        }
        break;

        case 'N':
        next_target.N = value;
        break;

        case '*':
        next_target.checksum_read = value;
        break;
      }

      // reset for next field
      last_field = 0;
      read_digit.sign = read_digit.exponent = 0;
      value = 0;
    }
  }

  if (next_target.getting_string)
  {
    if ((c == 10) || (c == 13) || ( c == ' ')  || ( c == '*'))
    {
      next_target.getting_string = 0;
    }
    else
    {
      if (next_target.chpos < sizeof(next_target.filename))
      {
        next_target.filename [next_target.chpos++] = c;
        next_target.filename [next_target.chpos] = 0;
      }
    }      
  }

  // skip comments, filenames
  if (next_target.seen_semi_comment == 0 && next_target.seen_parens_comment == 0 && next_target.getting_string == 0)
  {
    // new field?
    if ((c >= 'A' && c <= 'Z') || c == '*')
    {
      last_field = c;
    }

    // process character
    switch (c)
    {
      // each currently known command is either G or M, so preserve previous G/M unless a new one has appeared
      // FIXME: same for T command
      case 'G':
      next_target.seen_G = 1;
      next_target.seen_M = 0;
      next_target.M = 0;
      break;

      case 'M':
      next_target.seen_M = 1;
      next_target.seen_G = 0;
      next_target.G = 0;
      break;

      case 'X':
      next_target.seen_X = 1;
      break;

      case 'Y':
      next_target.seen_Y = 1;
      break;

      case 'Z':
      next_target.seen_Z = 1;
      break;

      case 'E':
      next_target.seen_E = 1;
      break;

      case 'F':
      next_target.seen_F = 1;
      break;

      case 'S':
      next_target.seen_S = 1;
      break;

      case 'P':
      next_target.seen_P = 1;
      break;

      case 'N':
      next_target.seen_N = 1;
      break;

      case '*':
      next_target.seen_checksum = 1;
      break;

      // comments
      case ';':
      case '^':
      next_target.seen_semi_comment = 1;
      break;

      case '(':
      next_target.seen_parens_comment = 1;
      break;

      // now for some numeracy
      case '-':
      read_digit.sign = 1;
      // force sign to be at start of number, so 1-2 = -2 instead of -12
      read_digit.exponent = 0;
      break;

      case '.':
      if (read_digit.exponent == 0)
      {
        read_digit.exponent = 1;
      }
      break;

      default:
      // can't do ranges in switch..case, so process actual digits here
      if (c >= '0' && c <= '9')
      {
        if (read_digit.exponent == 0)
        {
          value = value * 10 + (c - '0');
        }
        else
        {
          value += (double)(c - '0') / power(10, read_digit.exponent);
        }

        if (read_digit.exponent)
        {
          read_digit.exponent++;
        }
      }
    }
  }
  else if (next_target.seen_parens_comment == 1 && c == ')')
  {
    next_target.seen_parens_comment = 0; // recognize stuff after a (comment)
  }

  #ifndef ASTERISK_IN_CHECKSUM_INCLUDED
  if (next_target.seen_checksum == 0)
  {
    next_target.checksum_calculated = crc(next_target.checksum_calculated, save_ch);
  }
  #endif
}
Esempio n. 2
0
static char* convert_page_size_name( char *pValue )
{

	int i;
	char *pOptName = NULL;
	char *pDup = NULL;

	for( i=0; gluecode_page_name_table[i].glue_name!=NULL; i++ ){
		if( !strcmp(gluecode_page_name_table[i].glue_name, pValue) ){
			pOptName = &gluecode_page_name_table[i].opt_name[0];
			return pOptName;
		}
	}

	if( !strncmp(pValue, "custom", 6) ){
		char *pTemp;
		char *pWidth, *pHeight;
		int width_mm, height_mm;
		short flgInch;

		pDup = strdup(pValue);

		pTemp = strrchr(pDup, '_');
		if( pTemp ){
			pTemp++;
			pWidth = pTemp;
			while( *pTemp != '\0' && *pTemp != 'x')
				pTemp++;

			if( *pTemp	 == 'x' ){
				*pTemp = '\0';pTemp++;

				pHeight = pTemp;
				while( isdigit(*pTemp) )
					pTemp++;

				if( !strcmp(pTemp, "in") ){
					flgInch = 1;
				}else if( !strcmp(pTemp, "mm") ){
					flgInch = 0;
				}else{
					goto opt_error;
				}
				*pTemp = '\0';

				if( flgInch ){
					int width_in, height_in;
					width_in = atoi(pWidth);
					height_in = atoi(pHeight);
					width_mm = inch_to_mm(width_in);
					height_mm = inch_to_mm(height_in);
				}else{
					width_mm = atoi(pWidth);
					height_mm = atoi(pHeight);
				}

				for( i=0; gluecode_page_size_table[i].opt_name!=NULL; i++ ){
					if( width_mm == gluecode_page_size_table[i].width &&
						height_mm == gluecode_page_size_table[i].height ){
						pOptName = &gluecode_page_size_table[i].opt_name[0];
						break;
					}
				}
				return pOptName;
			}
		}
	}

 opt_error:

	if( pDup )
		free(pDup);

	return NULL;
}