diff --git a/dda.c b/dda.c index 48630d9..bb122b6 100644 --- a/dda.c +++ b/dda.c @@ -222,28 +222,55 @@ void dda_create(DDA *dda, TARGET *target) { // we end at the passed target memcpy(&(dda->endpoint), target, sizeof(TARGET)); - x_delta_um = (uint32_t)labs(target->X - startpoint.X); - y_delta_um = (uint32_t)labs(target->Y - startpoint.Y); - z_delta_um = (uint32_t)labs(target->Z - startpoint.Z); - e_delta_um = (uint32_t)labs(target->E - startpoint.E); +// TODO TODO: We should really make up a loop for all axes. +// Think of what happens when a sixth axis (multi colour extruder) +// appears? + if (target->all_relative) { + x_delta_um = labs(target->X); + um_to_steps_x(dda->x_delta, x_delta_um); + dda->x_direction = (target->X < 0)?1:0; - um_to_steps_x(steps, target->X); - dda->x_delta = labs(steps - startpoint_steps.X); - startpoint_steps.X = steps; - um_to_steps_y(steps, target->Y); - dda->y_delta = labs(steps - startpoint_steps.Y); - startpoint_steps.Y = steps; - um_to_steps_z(steps, target->Z); - dda->z_delta = labs(steps - startpoint_steps.Z); - startpoint_steps.Z = steps; - um_to_steps_e(steps, target->E); - dda->e_delta = labs(steps - startpoint_steps.E); - startpoint_steps.E = steps; + y_delta_um = labs(target->Y); + um_to_steps_y(dda->y_delta, y_delta_um); + dda->y_direction = (target->Y < 0)?1:0; - dda->x_direction = (target->X >= startpoint.X)?1:0; - dda->y_direction = (target->Y >= startpoint.Y)?1:0; - dda->z_direction = (target->Z >= startpoint.Z)?1:0; - dda->e_direction = (target->E >= startpoint.E)?1:0; + z_delta_um = labs(target->Z); + um_to_steps_z(dda->z_delta, z_delta_um); + dda->z_direction = (target->Z < 0)?1:0; + } + else { + x_delta_um = (uint32_t)labs(target->X - startpoint.X); + y_delta_um = (uint32_t)labs(target->Y - startpoint.Y); + z_delta_um = (uint32_t)labs(target->Z - startpoint.Z); + + um_to_steps_x(steps, target->X); + dda->x_delta = labs(steps - startpoint_steps.X); + startpoint_steps.X = steps; + um_to_steps_y(steps, target->Y); + dda->y_delta = labs(steps - startpoint_steps.Y); + startpoint_steps.Y = steps; + um_to_steps_z(steps, target->Z); + dda->z_delta = labs(steps - startpoint_steps.Z); + startpoint_steps.Z = steps; + + dda->x_direction = (target->X >= startpoint.X)?1:0; + dda->y_direction = (target->Y >= startpoint.Y)?1:0; + dda->z_direction = (target->Z >= startpoint.Z)?1:0; + } + + // This if() matches Sprinter's behaviour as of March 2012. + if (target->all_relative || target->e_relative) { + e_delta_um = labs(target->E); + um_to_steps_e(dda->e_delta, e_delta_um); + dda->e_direction = (target->E < 0)?1:0; + } + else { + e_delta_um = (uint32_t)labs(target->E - startpoint.E); + um_to_steps_e(steps, target->E); + dda->e_delta = labs(steps - startpoint_steps.E); + startpoint_steps.E = steps; + dda->e_direction = (target->E >= startpoint.E)?1:0; + } if (DEBUG_DDA && (debug_flags & DEBUG_DDA)) sersendf_P(PSTR("%ld,%ld,%ld,%ld] ["), target->X - startpoint.X, target->Y - startpoint.Y, target->Z - startpoint.Z, target->E - startpoint.E); @@ -455,10 +482,6 @@ void dda_create(DDA *dda, TARGET *target) { // next dda starts where we finish memcpy(&startpoint, target, sizeof(TARGET)); - // if E is relative, reset it here - #ifndef E_ABSOLUTE - startpoint.E = startpoint_steps.E = 0; - #endif } /*! Start a prepared DDA diff --git a/dda.h b/dda.h index 463d452..508893f 100644 --- a/dda.h +++ b/dda.h @@ -97,11 +97,17 @@ X, Y, Z and E are in micrometers unless explcitely stated. F is in mm/min. */ typedef struct { +// TODO TODO: We should really make up a loop for all axes. +// Think of what happens when a sixth axis (multi colour extruder) +// appears? int32_t X; int32_t Y; int32_t Z; int32_t E; uint32_t F; + + uint8_t all_relative :1; ///< bool: relative coordinates? + uint8_t e_relative :1; ///< bool: e axis relative? Overrides all_relative } TARGET; /** diff --git a/gcode_parse.c b/gcode_parse.c index e2c16f7..2c63649 100644 --- a/gcode_parse.c +++ b/gcode_parse.c @@ -75,6 +75,8 @@ static int32_t decfloat_to_int(decfloat *df, uint32_t multiplicand) { return df->sign ? -(int32_t)r : (int32_t)r; } +// TODO TODO: write a gcode_init(), next_target is used uninitialised. For a hint on what to do, see line 340ff. + /// Character Received - add it to our command /// \param c the next character to process void gcode_parse_char(uint8_t c) { @@ -344,16 +346,12 @@ void gcode_parse_char(uint8_t c) { next_target.seen_G = 1; next_target.G = 1; - if (next_target.option_relative) { + if (next_target.target.all_relative) { next_target.target.X = next_target.target.Y = next_target.target.Z = 0; - #ifdef E_ABSOLUTE - next_target.target.E = 0; - #endif } - #ifndef E_ABSOLUTE - // E always relative + if (next_target.target.all_relative || next_target.target.e_relative) { next_target.target.E = 0; - #endif + } } } diff --git a/gcode_parse.h b/gcode_parse.h index 749cf3d..298eb17 100644 --- a/gcode_parse.h +++ b/gcode_parse.h @@ -40,7 +40,6 @@ typedef struct { uint8_t seen_checksum :1; ///< seen a checksum? uint8_t seen_semi_comment :1; ///< seen a semicolon? uint8_t seen_parens_comment :1; ///< seen an open parenthesis - uint8_t option_relative :1; ///< relative or absolute coordinates? uint8_t option_inches :1; ///< inches or millimeters? }; uint16_t flags; diff --git a/gcode_process.c b/gcode_process.c index c5e28dd..8941bf7 100644 --- a/gcode_process.c +++ b/gcode_process.c @@ -41,9 +41,7 @@ uint8_t next_tool; #if E_STARTSTOP_STEPS > 0 /// move E by a certain amount at a certain speed static void SpecialMoveE(int32_t e, uint32_t f) { - TARGET t = startpoint; - t.E += e; - t.F = f; + TARGET t = { 0L, 0L, 0L, e, f, 1, 1 }; enqueue(&t); } #endif /* E_STARTSTOP_STEPS > 0 */ @@ -61,45 +59,66 @@ static void SpecialMoveE(int32_t e, uint32_t f) { void process_gcode_command() { uint32_t backup_f; - // convert relative to absolute - if (next_target.option_relative) { - next_target.target.X += startpoint.X; - next_target.target.Y += startpoint.Y; - next_target.target.Z += startpoint.Z; - #ifdef E_ABSOLUTE - next_target.target.E += startpoint.E; - #endif - } - // E ALWAYS relative, otherwise we overflow our registers after only a few layers - // next_target.target.E += startpoint.E; - // easier way to do this - // startpoint.E = 0; - // moved to dda.c, end of dda_create() and dda_queue.c, next_move() - // implement axis limits #ifdef X_MIN - if (next_target.target.X < X_MIN * 1000.) - next_target.target.X = X_MIN * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.X += startpoint.X < X_MIN * 1000.) + next_target.target.X = X_MIN * 1000. + startpoint.X; + } + else { + if (next_target.target.X < X_MIN * 1000.) + next_target.target.X = X_MIN * 1000.; + } #endif #ifdef X_MAX - if (next_target.target.X > X_MAX * 1000.) - next_target.target.X = X_MAX * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.X += startpoint.X > X_MAX * 1000.) + next_target.target.X = X_MIN * 1000. - startpoint.X; + } + else { + if (next_target.target.X > X_MAX * 1000.) + next_target.target.X = X_MAX * 1000.; + } #endif #ifdef Y_MIN - if (next_target.target.Y < Y_MIN * 1000.) - next_target.target.Y = Y_MIN * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.Y += startpoint.Y < Y_MIN * 1000.) + next_target.target.Y = Y_MIN * 1000. + startpoint.Y; + } + else { + if (next_target.target.Y < Y_MIN * 1000.) + next_target.target.Y = Y_MIN * 1000.; + } #endif #ifdef Y_MAX - if (next_target.target.Y > Y_MAX * 1000.) - next_target.target.Y = Y_MAX * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.Y += startpoint.Y > Y_MAX * 1000.) + next_target.target.Y = Y_MIN * 1000. - startpoint.Y; + } + else { + if (next_target.target.Y > Y_MAX * 1000.) + next_target.target.Y = Y_MAX * 1000.; + } #endif #ifdef Z_MIN - if (next_target.target.Z < Z_MIN * 1000.) - next_target.target.Z = Z_MIN * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.Z += startpoint.Z < Z_MIN * 1000.) + next_target.target.Z = Z_MIN * 1000. + startpoint.Z; + } + else { + if (next_target.target.Z < Z_MIN * 1000.) + next_target.target.Z = Z_MIN * 1000.; + } #endif #ifdef Z_MAX - if (next_target.target.Z > Z_MAX * 1000.) - next_target.target.Z = Z_MAX * 1000.; + if (next_target.target.all_relative) { + if (next_target.target.Z += startpoint.Z > Z_MAX * 1000.) + next_target.target.Z = Z_MIN * 1000. - startpoint.Z; + } + else { + if (next_target.target.Z > Z_MAX * 1000.) + next_target.target.Z = Z_MAX * 1000.; + } #endif @@ -115,6 +134,7 @@ void process_gcode_command() { next_tool = next_target.T; } +// TODO TODO: really? // if we didn't see an axis word, set it to startpoint. this fixes incorrect moves after homing if (next_target.seen_X == 0) next_target.target.X = startpoint.X; @@ -253,9 +273,15 @@ void process_gcode_command() { //? //? Example: G90 //? - //? All coordinates from now on are absolute relative to the origin of the machine. (This is the RepRap default.) + //? All coordinates from now on are absolute relative to the origin + //? of the machine. This is the RepRap default. //? - next_target.option_relative = 0; + + // No queue_wait() needed. + next_target.target.all_relative = 0; + // TODO: What's about startpoint, next_target an friends? + // What should a machine do when returning from relative + // to absolute mode? break; case 91: @@ -265,7 +291,9 @@ void process_gcode_command() { //? //? All coordinates from now on are relative to the last position. //? - next_target.option_relative = 1; + + // No queue_wait() needed. + next_target.target.all_relative = 1; break; case 92: @@ -393,11 +421,25 @@ void process_gcode_command() { tool = next_tool; break; - // M82 - Set E codes absolute (default) - // not implemented + case 82: + //? --- M82 - Set E codes absolute --- + //? + //? This is the default. M82/M82 is not documented in the + //? RepRap wiki, behaviours was taken from Strinter as of March 2012. + + // No wait_queue() needed. + next_target.target.e_relative = 0; + break; // M83 - Set E codes relative while in Absolute Coordinates (G90) mode - // not implemented + case 83: + //? --- M83 - Set E codes relative --- + //? + //? Counterpart to M82. + + // No wait_queue() needed. + next_target.target.e_relative = 1; + break; // M84- stop idle hold case 84: @@ -407,6 +449,7 @@ void process_gcode_command() { z_disable(); e_disable(); break; + // M3/M101- extruder on case 3: case 101: diff --git a/home.c b/home.c index 325b1c3..443b72a 100644 --- a/home.c +++ b/home.c @@ -34,7 +34,7 @@ void home() { /// find X MIN endstop void home_x_negative() { #if defined X_MIN_PIN - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.X = -1000000; #ifdef SLOW_HOMING @@ -70,7 +70,7 @@ void home_x_positive() { #warning X_MAX_PIN defined, but not X_MAX. home_x_positive() disabled. #endif #if defined X_MAX_PIN && defined X_MAX - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.X = +1000000; #ifdef SLOW_HOMING @@ -104,7 +104,7 @@ void home_x_positive() { /// fund Y MIN endstop void home_y_negative() { #if defined Y_MIN_PIN - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.Y = -1000000; #ifdef SLOW_HOMING @@ -140,7 +140,7 @@ void home_y_positive() { #warning Y_MAX_PIN defined, but not Y_MAX. home_y_positive() disabled. #endif #if defined Y_MAX_PIN && defined Y_MAX - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.Y = +1000000; #ifdef SLOW_HOMING @@ -174,7 +174,7 @@ void home_y_positive() { /// find Z MIN endstop void home_z_negative() { #if defined Z_MIN_PIN - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.Z = -1000000; #ifdef SLOW_HOMING @@ -211,7 +211,7 @@ void home_z_positive() { #warning Z_MAX_PIN defined, but not Z_MAX. home_z_positive() disabled. #endif #if defined Z_MAX_PIN && defined Z_MAX - TARGET t = startpoint; + TARGET t = { 0L, 0L, 0L, 0L, 0L, 1, 1 }; t.Z = +1000000; #ifdef SLOW_HOMING diff --git a/mendel.c b/mendel.c index efbfcd4..8282164 100644 --- a/mendel.c +++ b/mendel.c @@ -274,6 +274,9 @@ void init(void) { // set up serial serial_init(); + // set up G-code parsing + // gcode_init(); + // set up inputs and outputs io_init();