Discard all "continued" blocks on interrupted move
This commit is contained in:
parent
4e891e9fb7
commit
85c6ffbe0d
3 changed files with 33 additions and 14 deletions
|
@ -789,7 +789,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
|
||||||
block_t* block = &block_buffer[block_buffer_head];
|
block_t* block = &block_buffer[block_buffer_head];
|
||||||
|
|
||||||
// Clear all flags, including the "busy" bit
|
// Clear all flags, including the "busy" bit
|
||||||
block->flag = 0;
|
block->flag = 0x00;
|
||||||
|
|
||||||
// Set direction bits
|
// Set direction bits
|
||||||
block->direction_bits = dm;
|
block->direction_bits = dm;
|
||||||
|
@ -1435,7 +1435,9 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
|
||||||
const int32_t between[XYZE] = { _BETWEEN(X), _BETWEEN(Y), _BETWEEN(Z), _BETWEEN(E) };
|
const int32_t between[XYZE] = { _BETWEEN(X), _BETWEEN(Y), _BETWEEN(Z), _BETWEEN(E) };
|
||||||
DISABLE_STEPPER_DRIVER_INTERRUPT();
|
DISABLE_STEPPER_DRIVER_INTERRUPT();
|
||||||
_buffer_steps(between, fr_mm_s, extruder);
|
_buffer_steps(between, fr_mm_s, extruder);
|
||||||
|
const uint8_t next = block_buffer_head;
|
||||||
_buffer_steps(target, fr_mm_s, extruder);
|
_buffer_steps(target, fr_mm_s, extruder);
|
||||||
|
SBI(block_buffer[next].flag, BLOCK_BIT_CONTINUED);
|
||||||
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -57,14 +57,18 @@ enum BlockFlagBit {
|
||||||
BLOCK_BIT_START_FROM_FULL_HALT,
|
BLOCK_BIT_START_FROM_FULL_HALT,
|
||||||
|
|
||||||
// The block is busy
|
// The block is busy
|
||||||
BLOCK_BIT_BUSY
|
BLOCK_BIT_BUSY,
|
||||||
|
|
||||||
|
// The block is segment 2+ of a longer move
|
||||||
|
BLOCK_BIT_CONTINUED
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlockFlag {
|
enum BlockFlag {
|
||||||
BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE),
|
BLOCK_FLAG_RECALCULATE = _BV(BLOCK_BIT_RECALCULATE),
|
||||||
BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH),
|
BLOCK_FLAG_NOMINAL_LENGTH = _BV(BLOCK_BIT_NOMINAL_LENGTH),
|
||||||
BLOCK_FLAG_START_FROM_FULL_HALT = _BV(BLOCK_BIT_START_FROM_FULL_HALT),
|
BLOCK_FLAG_START_FROM_FULL_HALT = _BV(BLOCK_BIT_START_FROM_FULL_HALT),
|
||||||
BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY)
|
BLOCK_FLAG_BUSY = _BV(BLOCK_BIT_BUSY),
|
||||||
|
BLOCK_FLAG_CONTINUED = _BV(BLOCK_BIT_CONTINUED)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -454,14 +458,24 @@ class Planner {
|
||||||
static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
|
static bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Discards" the block and "releases" the memory.
|
* "Discard" the block and "release" the memory.
|
||||||
* Called when the current block is no longer needed.
|
* Called when the current block is no longer needed.
|
||||||
*/
|
*/
|
||||||
static void discard_current_block() {
|
FORCE_INLINE static void discard_current_block() {
|
||||||
if (blocks_queued())
|
if (blocks_queued())
|
||||||
block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
|
block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Discard" the next block if it's continued.
|
||||||
|
* Called after an interrupted move to throw away the rest of the move.
|
||||||
|
*/
|
||||||
|
FORCE_INLINE static bool discard_continued_block() {
|
||||||
|
const bool discard = blocks_queued() && TEST(block_buffer[block_buffer_tail].flag, BLOCK_BIT_CONTINUED);
|
||||||
|
if (discard) discard_current_block();
|
||||||
|
return discard;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current block. NULL if the buffer is empty.
|
* The current block. NULL if the buffer is empty.
|
||||||
* This also marks the block as busy.
|
* This also marks the block as busy.
|
||||||
|
@ -469,7 +483,7 @@ class Planner {
|
||||||
*/
|
*/
|
||||||
static block_t* get_current_block() {
|
static block_t* get_current_block() {
|
||||||
if (blocks_queued()) {
|
if (blocks_queued()) {
|
||||||
block_t* block = &block_buffer[block_buffer_tail];
|
block_t * const block = &block_buffer[block_buffer_tail];
|
||||||
#if ENABLED(ULTRA_LCD)
|
#if ENABLED(ULTRA_LCD)
|
||||||
block_buffer_runtime_us -= block->segment_time_us; // We can't be sure how long an active block will take, so don't count it.
|
block_buffer_runtime_us -= block->segment_time_us; // We can't be sure how long an active block will take, so don't count it.
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -388,18 +388,21 @@ void Stepper::isr() {
|
||||||
// When cleaning, discard the current block and run fast
|
// When cleaning, discard the current block and run fast
|
||||||
//
|
//
|
||||||
if (cleaning_buffer_counter) {
|
if (cleaning_buffer_counter) {
|
||||||
if (cleaning_buffer_counter < 0)
|
if (cleaning_buffer_counter < 0) { // Count up for endstop hit
|
||||||
++cleaning_buffer_counter; // Count up for endstop hit
|
if (current_block) planner.discard_current_block(); // Discard the active block that led to the trigger
|
||||||
|
if (!planner.discard_continued_block()) // Discard next CONTINUED block
|
||||||
|
cleaning_buffer_counter = 0; // Keep discarding until non-CONTINUED
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
planner.discard_current_block();
|
||||||
--cleaning_buffer_counter; // Count down for abort print
|
--cleaning_buffer_counter; // Count down for abort print
|
||||||
#ifdef SD_FINISHED_RELEASECOMMAND
|
#ifdef SD_FINISHED_RELEASECOMMAND
|
||||||
if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
current_block = NULL;
|
current_block = NULL; // Prep to get a new block after cleaning
|
||||||
planner.discard_current_block();
|
|
||||||
_NEXT_ISR(HAL_STEPPER_TIMER_RATE / 10000); // Run at max speed - 10 KHz
|
_NEXT_ISR(HAL_STEPPER_TIMER_RATE / 10000); // Run at max speed - 10 KHz
|
||||||
HAL_ENABLE_ISRs(); // Re-enable ISRs
|
HAL_ENABLE_ISRs();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,9 +1122,9 @@ void Stepper::init() {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block until all buffered steps are executed
|
* Block until all buffered steps are executed / cleaned
|
||||||
*/
|
*/
|
||||||
void Stepper::synchronize() { while (planner.blocks_queued()) idle(); }
|
void Stepper::synchronize() { while (planner.blocks_queued() || cleaning_buffer_counter) idle(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the stepper positions directly in steps
|
* Set the stepper positions directly in steps
|
||||||
|
@ -1245,7 +1248,7 @@ void Stepper::endstop_triggered(AxisEnum axis) {
|
||||||
#endif // !COREXY && !COREXZ && !COREYZ
|
#endif // !COREXY && !COREXZ && !COREYZ
|
||||||
|
|
||||||
kill_current_block();
|
kill_current_block();
|
||||||
cleaning_buffer_counter = -(BLOCK_BUFFER_SIZE - 1); // Ignore remaining blocks
|
cleaning_buffer_counter = -1; // Discard the rest of the move
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stepper::report_positions() {
|
void Stepper::report_positions() {
|
||||||
|
|
Reference in a new issue