diff --git a/gcode_parse.c b/gcode_parse.c index e6f811d..fdcd9e6 100644 --- a/gcode_parse.c +++ b/gcode_parse.c @@ -85,13 +85,14 @@ const int32_t rounding[DECFLOAT_EXP_MAX] = {0, 5, 50, 500}; /// convert a floating point input value into an integer with appropriate scaling. /// \param *df pointer to floating point structure that holds fp value to convert /// \param multiplicand multiply by this amount during conversion to integer -/// \param denominator divide by this amount during conversion to integer +/// \param divide_by_1000 divide by 1000 during conversion to integer /// /// lots of work has been done in exploring this function's limitations in terms of overflow and rounding /// this work may not be finished -static int32_t decfloat_to_int(decfloat *df, uint32_t multiplicand, uint32_t denominator) { +static int32_t decfloat_to_int(decfloat *df, uint32_t multiplicand, uint8_t divide_by_1000) { uint32_t r = df->mantissa; uint8_t e = df->exponent; + uint32_t denominator = divide_by_1000 ? 1000 : 1; // e=1 means we've seen a decimal point but no digits after it, and e=2 means we've seen a decimal point with one digit so it's too high by one if not zero if (e) @@ -139,42 +140,42 @@ void gcode_parse_char(uint8_t c) { break; case 'X': if (next_target.option_inches) - next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_IN_X, 1); + next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_IN_X, 0); else - next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_M_X, 1000); + next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_M_X, 1); if (debug_flags & DEBUG_ECHO) serwrite_int32(next_target.target.X); break; case 'Y': if (next_target.option_inches) - next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_IN_Y, 1); + next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_IN_Y, 0); else - next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_M_Y, 1000); + next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_M_Y, 1); if (debug_flags & DEBUG_ECHO) serwrite_int32(next_target.target.Y); break; case 'Z': if (next_target.option_inches) - next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_IN_Z, 1); + next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_IN_Z, 0); else - next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_M_Z, 1000); + next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_M_Z, 1); if (debug_flags & DEBUG_ECHO) serwrite_int32(next_target.target.Z); break; case 'E': if (next_target.option_inches) - next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_IN_E, 1); + next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_IN_E, 0); else - next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_M_E, 1000); + next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_M_E, 1); if (debug_flags & DEBUG_ECHO) serwrite_uint32(next_target.target.E); break; case 'F': // just use raw integer, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it if (next_target.option_inches) - next_target.target.F = decfloat_to_int(&read_digit, 254, 10); + next_target.target.F = decfloat_to_int(&read_digit, 25400, 1); else - next_target.target.F = decfloat_to_int(&read_digit, 1, 1); + next_target.target.F = decfloat_to_int(&read_digit, 1, 0); if (debug_flags & DEBUG_ECHO) serwrite_uint32(next_target.target.F); break; @@ -183,17 +184,17 @@ void gcode_parse_char(uint8_t c) { // cosmetically this should be done in the temperature section, // but it takes less code, less memory and loses no precision if we do it here instead if ((next_target.M == 104) || (next_target.M == 109) || (next_target.M == 140)) - next_target.S = decfloat_to_int(&read_digit, 4, 1); + next_target.S = decfloat_to_int(&read_digit, 4, 0); // if this is heater PID stuff, multiply by PID_SCALE because we divide by PID_SCALE later on else if ((next_target.M >= 130) && (next_target.M <= 132)) - next_target.S = decfloat_to_int(&read_digit, PID_SCALE, 1); + next_target.S = decfloat_to_int(&read_digit, PID_SCALE, 0); else - next_target.S = decfloat_to_int(&read_digit, 1, 1); + next_target.S = decfloat_to_int(&read_digit, 1, 0); if (debug_flags & DEBUG_ECHO) serwrite_uint16(next_target.S); break; case 'P': - next_target.P = decfloat_to_int(&read_digit, 1, 1); + next_target.P = decfloat_to_int(&read_digit, 1, 0); if (debug_flags & DEBUG_ECHO) serwrite_uint16(next_target.P); break; @@ -203,12 +204,12 @@ void gcode_parse_char(uint8_t c) { serwrite_uint8(next_target.T); break; case 'N': - next_target.N = decfloat_to_int(&read_digit, 1, 1); + next_target.N = decfloat_to_int(&read_digit, 1, 0); if (debug_flags & DEBUG_ECHO) serwrite_uint32(next_target.N); break; case '*': - next_target.checksum_read = decfloat_to_int(&read_digit, 1, 1); + next_target.checksum_read = decfloat_to_int(&read_digit, 1, 0); if (debug_flags & DEBUG_ECHO) serwrite_uint8(next_target.checksum_read); break;