diff --git a/Marlin/src/feature/I2CPositionEncoder.cpp b/Marlin/src/feature/I2CPositionEncoder.cpp index 7c80ff3a39..9d7e4bddb8 100644 --- a/Marlin/src/feature/I2CPositionEncoder.cpp +++ b/Marlin/src/feature/I2CPositionEncoder.cpp @@ -358,7 +358,7 @@ bool I2CPositionEncoder::test_axis() { stepper.synchronize(); - planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS], + planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS], stepper.get_axis_position_mm(E_AXIS), feedrate, 0); stepper.synchronize(); @@ -415,10 +415,10 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) { startCoord[encoderAxis] = startDistance; endCoord[encoderAxis] = endDistance; - LOOP_L_N(i, iter) { - stepper.synchronize(); + stepper.synchronize(); - planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS], + LOOP_L_N(i, iter) { + planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS], stepper.get_axis_position_mm(E_AXIS), feedrate, 0); stepper.synchronize(); @@ -427,7 +427,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) { //do_blocking_move_to(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS]); - planner.buffer_line(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS], + planner.buffer_line(endCoord[X_AXIS], endCoord[Y_AXIS], endCoord[Z_AXIS], stepper.get_axis_position_mm(E_AXIS), feedrate, 0); stepper.synchronize(); diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp index 06065f2631..efd916f381 100644 --- a/Marlin/src/feature/fwretract.cpp +++ b/Marlin/src/feature/fwretract.cpp @@ -108,7 +108,7 @@ void FWRetract::retract(const bool retracting // G11 priority to recover the long retract if activated if (!retracting) swapping = retracted_swap[active_extruder]; #else - const bool swapping = false; + constexpr bool swapping = false; #endif /* // debugging @@ -118,62 +118,57 @@ void FWRetract::retract(const bool retracting for (uint8_t i = 0; i < EXTRUDERS; ++i) { SERIAL_ECHOPAIR("retracted[", i); SERIAL_ECHOLNPAIR("] ", retracted[i]); - SERIAL_ECHOPAIR("retracted_swap[", i); - SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + #if EXTRUDERS > 1 + SERIAL_ECHOPAIR("retracted_swap[", i); + SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + #endif } SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]); SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]); SERIAL_ECHOLNPAIR("hop_amount ", hop_amount); //*/ - const float old_feedrate_mm_s = feedrate_mm_s; + const float old_feedrate_mm_s = feedrate_mm_s, + renormalize = RECIPROCAL(planner.e_factor[active_extruder]), + base_retract = swapping ? swap_retract_length : retract_length, + old_z = current_position[Z_AXIS], + old_e = current_position[E_AXIS]; // The current position will be the destination for E and Z moves set_destination_from_current(); - stepper.synchronize(); // Wait for buffered moves to complete - - const float renormalize = 1.0 / planner.e_factor[active_extruder]; if (retracting) { // Retract by moving from a faux E position back to the current E position feedrate_mm_s = retract_feedrate_mm_s; - current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize; - sync_plan_position_e(); - prepare_move_to_destination(); // set_current_to_destination + destination[E_AXIS] -= base_retract * renormalize; + prepare_move_to_destination(); // set_current_to_destination // Is a Z hop set, and has the hop not yet been done? - // No double zlifting - // Feedrate to the max if (retract_zlift > 0.01 && !hop_amount) { // Apply hop only once - const float old_z = current_position[Z_AXIS]; hop_amount += retract_zlift; // Add to the hop total (again, only once) destination[Z_AXIS] += retract_zlift; // Raise Z by the zlift (M207 Z) amount feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Maximum Z feedrate prepare_move_to_destination(); // Raise up, set_current_to_destination - current_position[Z_AXIS] = old_z; // Spoof the Z position in the planner - SYNC_PLAN_POSITION_KINEMATIC(); } } else { // If a hop was done and Z hasn't changed, undo the Z hop if (hop_amount) { - current_position[Z_AXIS] += hop_amount; // Set actual Z (due to the prior hop) - SYNC_PLAN_POSITION_KINEMATIC(); // Spoof the Z position in the planner + destination[Z_AXIS] -= hop_amount; // Move back down by the total hop amount feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max prepare_move_to_destination(); // Lower Z, set_current_to_destination hop_amount = 0.0; // Clear the hop amount } - // A retract multiplier has been added here to get faster swap recovery + destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize; feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s; - - current_position[E_AXIS] -= (swapping ? swap_retract_length + swap_retract_recover_length - : retract_length + retract_recover_length) * renormalize; - sync_plan_position_e(); prepare_move_to_destination(); // Recover E, set_current_to_destination } feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate + current_position[Z_AXIS] = old_z; // Restore Z and E positions + current_position[E_AXIS] = old_e; + SYNC_PLAN_POSITION_KINEMATIC(); // As if the move never took place retracted[active_extruder] = retracting; // Active extruder now retracted / recovered @@ -189,8 +184,10 @@ void FWRetract::retract(const bool retracting for (uint8_t i = 0; i < EXTRUDERS; ++i) { SERIAL_ECHOPAIR("retracted[", i); SERIAL_ECHOLNPAIR("] ", retracted[i]); - SERIAL_ECHOPAIR("retracted_swap[", i); - SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + #if EXTRUDERS > 1 + SERIAL_ECHOPAIR("retracted_swap[", i); + SERIAL_ECHOLNPAIR("] ", retracted_swap[i]); + #endif } SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]); SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]); diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 9666366544..913316ecf9 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -121,8 +121,8 @@ static void do_pause_e_move(const float &length, const float &fr) { set_destination_from_current(); destination[E_AXIS] += length / planner.e_factor[active_extruder]; planner.buffer_line_kinematic(destination, fr, active_extruder); - stepper.synchronize(); set_current_from_destination(); + stepper.synchronize(); } /** @@ -366,12 +366,12 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u #endif print_job_timer.pause(); - // Wait for synchronize steppers - stepper.synchronize(); - // Save current position COPY(resume_position, current_position); + // Wait for buffered blocks to complete + stepper.synchronize(); + // Initial retract before move to filament change position if (retract && thermalManager.hotEnoughToExtrude(active_extruder)) do_pause_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 616cc58ee4..9f3f4c03c8 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -240,8 +240,6 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de destination[E_AXIS] = current_position[E_AXIS]; G26_line_to_destination(feed_value); - - stepper.synchronize(); set_destination_from_current(); } @@ -256,8 +254,6 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de destination[E_AXIS] += e_delta; G26_line_to_destination(feed_value); - - stepper.synchronize(); set_destination_from_current(); } @@ -499,13 +495,11 @@ inline bool prime_nozzle() { if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR; #endif G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); - + set_destination_from_current(); stepper.synchronize(); // Without this synchronize, the purge is more consistent, // but because the planner has a buffer, we won't be able // to stop as quickly. So we put up with the less smooth // action to give the user a more responsive 'Stop'. - set_destination_from_current(); - idle(); } wait_for_release(); @@ -526,7 +520,6 @@ inline bool prime_nozzle() { set_destination_from_current(); destination[E_AXIS] += g26_prime_length; G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); - stepper.synchronize(); set_destination_from_current(); retract_filament(destination); } @@ -700,7 +693,6 @@ void GcodeSuite::G26() { if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) { do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - stepper.synchronize(); set_current_from_destination(); } diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 49b1fa7cb1..8f33033af9 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -949,8 +949,8 @@ void GcodeSuite::G29() { #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT); #endif - enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT)); stepper.synchronize(); + enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT)); #endif // Auto Bed Leveling is complete! Enable if possible. diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp index eb300b01db..eae35d1c4e 100644 --- a/Marlin/src/gcode/control/M80_M81.cpp +++ b/Marlin/src/gcode/control/M80_M81.cpp @@ -108,7 +108,6 @@ void GcodeSuite::M81() { safe_delay(1000); // Wait 1 second before switching off #if HAS_SUICIDE - stepper.synchronize(); suicide(); #elif HAS_POWER_SWITCH PSU_OFF(); diff --git a/Marlin/src/gcode/geometry/G92.cpp b/Marlin/src/gcode/geometry/G92.cpp index 0b10aab5b8..933a6e1cdb 100644 --- a/Marlin/src/gcode/geometry/G92.cpp +++ b/Marlin/src/gcode/geometry/G92.cpp @@ -33,8 +33,6 @@ */ void GcodeSuite::G92() { - stepper.synchronize(); - #if ENABLED(CNC_COORDINATE_SYSTEMS) switch (parser.subcode) { case 1: @@ -94,10 +92,8 @@ void GcodeSuite::G92() { COPY(coordinate_system[active_coordinate_system], position_shift); #endif - if (didXYZ) - SYNC_PLAN_POSITION_KINEMATIC(); - else if (didE) - sync_plan_position_e(); + if (didXYZ) SYNC_PLAN_POSITION_KINEMATIC(); + else if (didE) sync_plan_position_e(); report_current_position(); } diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp index 5ca83eedaa..af50da5656 100644 --- a/Marlin/src/gcode/host/M114.cpp +++ b/Marlin/src/gcode/host/M114.cpp @@ -43,8 +43,6 @@ void report_current_position_detail() { - stepper.synchronize(); - SERIAL_PROTOCOLPGM("\nLogical:"); const float logical[XYZ] = { LOGICAL_X_POSITION(current_position[X_AXIS]), @@ -79,6 +77,8 @@ report_xyz(delta); #endif + stepper.synchronize(); + SERIAL_PROTOCOLPGM("Stepper:"); LOOP_XYZE(i) { SERIAL_CHAR(' '); diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp index bd41673f35..453d02cd03 100644 --- a/Marlin/src/gcode/lcd/M0_M1.cpp +++ b/Marlin/src/gcode/lcd/M0_M1.cpp @@ -58,6 +58,8 @@ void GcodeSuite::M0_M1() { const bool has_message = !hasP && !hasS && args && *args; + stepper.synchronize(); + #if ENABLED(ULTIPANEL) if (has_message) @@ -81,8 +83,6 @@ void GcodeSuite::M0_M1() { KEEPALIVE_STATE(PAUSED_FOR_USER); wait_for_user = true; - stepper.synchronize(); - if (ms > 0) { ms += millis(); // wait until this time for a click while (PENDING(millis(), ms) && wait_for_user) idle(); diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 66da413741..fdb92fb03e 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -396,13 +396,13 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f #endif - stepper.synchronize(); - feedrate_mm_s = old_feedrate_mm_s; #if ENABLED(DEBUG_LEVELING_FEATURE) if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to"); #endif + + stepper.synchronize(); } void do_blocking_move_to_x(const float &rx, const float &fr_mm_s/*=0.0*/) { do_blocking_move_to(rx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s); @@ -881,8 +881,8 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS }, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1 ); - SYNC_PLAN_POSITION_KINEMATIC(); stepper.synchronize(); + SYNC_PLAN_POSITION_KINEMATIC(); extruder_duplication_enabled = true; active_extruder_parked = false; #if ENABLED(DEBUG_LEVELING_FEATURE) @@ -1106,7 +1106,7 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder); #else sync_plan_position(); - current_position[axis] = distance; + current_position[axis] = distance; // Set delta/cartesian axes directly planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder); #endif diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index 8aa08cd54b..4be4b2af59 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1382,15 +1382,9 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE] const float esteps_float = de * e_factor[extruder]; const int32_t esteps = abs(esteps_float) + 0.5; - // Calculate the buffer head after we push this byte - const uint8_t next_buffer_head = next_block_index(block_buffer_head); - - // If the buffer is full: good! That means we are well ahead of the robot. - // Rest here until there is room in the buffer. - while (block_buffer_tail == next_buffer_head) idle(); - - // Prepare to set up new block - block_t* block = &block_buffer[block_buffer_head]; + // Wait for the next available block + uint8_t next_buffer_head; + block_t * const block = get_next_free_block(next_buffer_head); // Clear all flags, including the "busy" bit block->flag = 0x00; @@ -2032,6 +2026,26 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE] } // _buffer_steps() +/** + * Planner::buffer_sync_block + * Add a block to the buffer that just updates the position + */ +void Planner::buffer_sync_block() { + // Wait for the next available block + uint8_t next_buffer_head; + block_t * const block = get_next_free_block(next_buffer_head); + + block->steps[A_AXIS] = position[A_AXIS]; + block->steps[B_AXIS] = position[B_AXIS]; + block->steps[C_AXIS] = position[C_AXIS]; + block->steps[E_AXIS] = position[E_AXIS]; + + block->flag = BLOCK_FLAG_SYNC_POSITION; + + block_buffer_head = next_buffer_head; + stepper.wake_up(); +} // buffer_sync_block() + /** * Planner::buffer_segment * @@ -2160,19 +2174,19 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c #else #define _EINDEX E_AXIS #endif - const int32_t na = position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]), - nb = position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]), - nc = position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]), - ne = position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); + position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]), + position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]), + position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]), + position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); #if HAS_POSITION_FLOAT - position_float[X_AXIS] = a; - position_float[Y_AXIS] = b; - position_float[Z_AXIS] = c; + position_float[A_AXIS] = a; + position_float[B_AXIS] = b; + position_float[C_AXIS] = c; position_float[E_AXIS] = e; #endif - stepper.set_position(na, nb, nc, ne); previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest. ZERO(previous_speed); + buffer_sync_block(); } void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) { @@ -2220,23 +2234,23 @@ void Planner::set_position_mm(const AxisEnum axis, const float &v) { #if HAS_POSITION_FLOAT position_float[axis] = v; #endif - stepper.set_position(axis, position[axis]); previous_speed[axis] = 0.0; + buffer_sync_block(); } // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2 void Planner::reset_acceleration_rates() { #if ENABLED(DISTINCT_E_FACTORS) - #define HIGHEST_CONDITION (i < E_AXIS || i == E_AXIS + active_extruder) + #define AXIS_CONDITION (i < E_AXIS || i == E_AXIS + active_extruder) #else - #define HIGHEST_CONDITION true + #define AXIS_CONDITION true #endif uint32_t highest_rate = 1; LOOP_XYZE_N(i) { max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i]; - if (HIGHEST_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); + if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); } - cutoff_long = 4294967295UL / highest_rate; + cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL } // Recalculate position, steps_to_mm if axis_steps_per_mm changes! diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index 031cee7451..eceb31f3a1 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -57,14 +57,18 @@ enum BlockFlagBit : char { BLOCK_BIT_BUSY, // The block is segment 2+ of a longer move - BLOCK_BIT_CONTINUED + BLOCK_BIT_CONTINUED, + + // Sync the stepper counts from the block + BLOCK_BIT_SYNC_POSITION }; enum BlockFlag : char { BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE), BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH), BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY), - BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED) + BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED), + BLOCK_FLAG_SYNC_POSITION = _BV(BLOCK_BIT_SYNC_POSITION) }; /** @@ -422,6 +426,20 @@ class Planner { #endif + + /** + * Planner::get_next_free_block + * + * - Get the next head index (passed by reference) + * - Wait for a space to open up in the planner + * - Return the head block + */ + FORCE_INLINE static block_t* get_next_free_block(uint8_t &next_buffer_head) { + next_buffer_head = next_block_index(block_buffer_head); + while (block_buffer_tail == next_buffer_head) idle(); // while (is_full) + return &block_buffer[block_buffer_head]; + } + /** * Planner::_buffer_steps * @@ -439,6 +457,12 @@ class Planner { , float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0 ); + /** + * Planner::buffer_sync_block + * Add a block to the buffer that just updates the position + */ + static void buffer_sync_block(); + /** * Planner::buffer_segment * @@ -518,7 +542,7 @@ class Planner { static void set_position_mm_kinematic(const float (&cart)[XYZE]); static void set_position_mm(const AxisEnum axis, const float &v); FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); } - FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); } + FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(E_AXIS, e); } /** * Sync from the stepper positions. (e.g., after an interrupted move) @@ -528,7 +552,7 @@ class Planner { /** * Does the buffer have any blocks queued? */ - static bool has_blocks_queued() { return (block_buffer_head != block_buffer_tail); } + FORCE_INLINE static bool has_blocks_queued() { return (block_buffer_head != block_buffer_tail); } /** * "Discard" the block and "release" the memory. diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 04c6c270f5..4e6747a124 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -109,10 +109,10 @@ int16_t Stepper::cleaning_buffer_counter = 0; bool Stepper::locked_z_motor = false, Stepper::locked_z2_motor = false; #endif -long Stepper::counter_X = 0, - Stepper::counter_Y = 0, - Stepper::counter_Z = 0, - Stepper::counter_E = 0; +int32_t Stepper::counter_X = 0, + Stepper::counter_Y = 0, + Stepper::counter_Z = 0, + Stepper::counter_E = 0; volatile uint32_t Stepper::step_events_completed = 0; // The number of step events executed in the current block @@ -159,7 +159,7 @@ volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 }; volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; #if ENABLED(MIXING_EXTRUDER) - long Stepper::counter_m[MIXING_STEPPERS]; + int32_t Stepper::counter_m[MIXING_STEPPERS]; #endif uint8_t Stepper::step_loops, Stepper::step_loops_nominal; @@ -169,7 +169,7 @@ hal_timer_t Stepper::OCR1A_nominal; hal_timer_t Stepper::acc_step_rate; // needed for deceleration start point #endif -volatile long Stepper::endstops_trigsteps[XYZ]; +volatile int32_t Stepper::endstops_trigsteps[XYZ]; #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) #define LOCKED_X_MOTOR locked_x_motor @@ -1217,6 +1217,16 @@ void Stepper::isr() { // Anything in the buffer? if ((current_block = planner.get_current_block())) { + // Sync block? Sync the stepper counts and return + while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) { + _set_position( + current_block->steps[A_AXIS], current_block->steps[B_AXIS], + current_block->steps[C_AXIS], current_block->steps[E_AXIS] + ); + planner.discard_current_block(); + if (!(current_block = planner.get_current_block())) return; + } + // Initialize the trapezoid generator from the current block. static int8_t last_extruder = -1; @@ -1976,12 +1986,7 @@ void Stepper::synchronize() { while (planner.has_blocks_queued() || cleaning_buf * This allows get_axis_position_mm to correctly * derive the current XYZ position later on. */ -void Stepper::set_position(const long &a, const long &b, const long &c, const long &e) { - - synchronize(); // Bad to set stepper counts in the middle of a move - - CRITICAL_SECTION_START; - +void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) { #if CORE_IS_XY // corexy positioning // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html @@ -2004,29 +2009,15 @@ void Stepper::set_position(const long &a, const long &b, const long &c, const lo count_position[Y_AXIS] = b; count_position[Z_AXIS] = c; #endif - - count_position[E_AXIS] = e; - CRITICAL_SECTION_END; -} - -void Stepper::set_position(const AxisEnum &axis, const long &v) { - CRITICAL_SECTION_START; - count_position[axis] = v; - CRITICAL_SECTION_END; -} - -void Stepper::set_e_position(const long &e) { - CRITICAL_SECTION_START; count_position[E_AXIS] = e; - CRITICAL_SECTION_END; } /** * Get a stepper's position in steps. */ -long Stepper::position(const AxisEnum axis) { +int32_t Stepper::position(const AxisEnum axis) { CRITICAL_SECTION_START; - const long count_pos = count_position[axis]; + const int32_t count_pos = count_position[axis]; CRITICAL_SECTION_END; return count_pos; } @@ -2095,9 +2086,9 @@ void Stepper::endstop_triggered(const AxisEnum axis) { void Stepper::report_positions() { CRITICAL_SECTION_START; - const long xpos = count_position[X_AXIS], - ypos = count_position[Y_AXIS], - zpos = count_position[Z_AXIS]; + const int32_t xpos = count_position[X_AXIS], + ypos = count_position[Y_AXIS], + zpos = count_position[Z_AXIS]; CRITICAL_SECTION_END; #if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 88bbab8743..19bfeec685 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -94,7 +94,7 @@ class Stepper { #endif // Counter variables for the Bresenham line tracer - static long counter_X, counter_Y, counter_Z, counter_E; + static int32_t counter_X, counter_Y, counter_Z, counter_E; static volatile uint32_t step_events_completed; // The number of step events executed in the current block #if ENABLED(BEZIER_JERK_CONTROL) @@ -137,8 +137,8 @@ class Stepper { static hal_timer_t acc_step_rate; // needed for deceleration start point #endif - static volatile long endstops_trigsteps[XYZ]; - static volatile long endstops_stepsTotal, endstops_stepsDone; + static volatile int32_t endstops_trigsteps[XYZ]; + static volatile int32_t endstops_stepsTotal, endstops_stepsDone; // // Positions of stepper motors, in step units @@ -154,7 +154,7 @@ class Stepper { // Mixing extruder mix counters // #if ENABLED(MIXING_EXTRUDER) - static long counter_m[MIXING_STEPPERS]; + static int32_t counter_m[MIXING_STEPPERS]; #define MIXING_STEPPERS_LOOP(VAR) \ for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) \ if (current_block->mix_event_count[VAR]) @@ -191,9 +191,32 @@ class Stepper { // // Set the current position in steps // - static void set_position(const long &a, const long &b, const long &c, const long &e); - static void set_position(const AxisEnum &a, const long &v); - static void set_e_position(const long &e); + static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e); + + FORCE_INLINE static void _set_position(const AxisEnum a, const int32_t &v) { count_position[a] = v; } + + FORCE_INLINE static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) { + synchronize(); + CRITICAL_SECTION_START; + _set_position(a, b, c, e); + CRITICAL_SECTION_END; + } + + static void set_position(const AxisEnum a, const int32_t &v) { + synchronize(); + CRITICAL_SECTION_START; + count_position[a] = v; + CRITICAL_SECTION_END; + } + + FORCE_INLINE static void _set_e_position(const int32_t &e) { count_position[E_AXIS] = e; } + + static void set_e_position(const int32_t &e) { + synchronize(); + CRITICAL_SECTION_START; + count_position[E_AXIS] = e; + CRITICAL_SECTION_END; + } // // Set direction bits for all steppers @@ -203,7 +226,7 @@ class Stepper { // // Get the position of a stepper, in steps // - static long position(const AxisEnum axis); + static int32_t position(const AxisEnum axis); // // Report the positions of the steppers, in steps