Merge pull request #9152 from thinkyhead/bf2_anti_stutter

[2.0.x] Ensure smooth printer movements
This commit is contained in:
Scott Lahteine 2018-01-14 23:34:01 -06:00 committed by GitHub
commit 3ae41e5f7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 43 deletions

View File

@ -139,6 +139,7 @@ extern "C" {
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) #define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) #define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B) #define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B) #define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)

View File

@ -112,23 +112,28 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
} }
void HAL_timer_enable_interrupt(const uint8_t timer_num) { void HAL_timer_enable_interrupt(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_IER = TC_IER_CPCS; pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_IER = TC_IER_CPCS;
} }
void HAL_timer_disable_interrupt(const uint8_t timer_num) { void HAL_timer_disable_interrupt(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_IDR = TC_IDR_CPCS; pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_IDR = TC_IDR_CPCS;
} }
void HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_IER == TC_IER_CPCS;
}
#if 0 #if 0
void HAL_timer_set_count(const uint8_t timer_num, const uint32_t count) { void HAL_timer_set_count(const uint8_t timer_num, const uint32_t count) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
TC_SetRC(pConfig->pTimerRegs, pConfig->channel, count); TC_SetRC(pConfig->pTimerRegs, pConfig->channel, count);
} }
void HAL_timer_isr_prologue(const uint8_t timer_num) { void HAL_timer_isr_prologue(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
TC_GetStatus(pConfig->pTimerRegs, pConfig->channel); TC_GetStatus(pConfig->pTimerRegs, pConfig->channel);
} }
#endif #endif

View File

@ -55,6 +55,7 @@ typedef uint32_t hal_timer_t;
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
@ -91,32 +92,33 @@ extern const tTimerConfig TimerConfig[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_count(const uint8_t timer_num, const hal_timer_t count) { FORCE_INLINE static void HAL_timer_set_count(const uint8_t timer_num, const hal_timer_t count) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = count; pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = count;
} }
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC; return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC;
} }
FORCE_INLINE static void HAL_timer_set_current_count(const uint8_t timer_num, const hal_timer_t count) { FORCE_INLINE static void HAL_timer_set_current_count(const uint8_t timer_num, const hal_timer_t count) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV = count; pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV = count;
} }
FORCE_INLINE static hal_timer_t HAL_timer_get_current_count(const uint8_t timer_num) { FORCE_INLINE static hal_timer_t HAL_timer_get_current_count(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV; return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV;
} }
void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
//void HAL_timer_isr_prologue(const uint8_t timer_num); //void HAL_timer_isr_prologue(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
const tTimerConfig *pConfig = &TimerConfig[timer_num]; const tTimerConfig * const pConfig = &TimerConfig[timer_num];
// Reading the status register clears the interrupt flag // Reading the status register clears the interrupt flag
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR; pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
} }

View File

@ -75,6 +75,14 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
} }
} }
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case 0: return NVIC_GetActive(TIMER0_IRQn);
case 1: return NVIC_GetActive(TIMER1_IRQn);
}
return false;
}
void HAL_timer_isr_prologue(const uint8_t timer_num) { void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) { switch (timer_num) {
case 0: SBI(LPC_TIM0->IR, 0); break; // Clear the Interrupt case 0: SBI(LPC_TIM0->IR, 0); break; // Clear the Interrupt

View File

@ -58,6 +58,8 @@ typedef uint32_t hal_timer_t;
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
@ -125,6 +127,7 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_current_count(const uint8_t timer_
void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num); void HAL_timer_isr_prologue(const uint8_t timer_num);
#endif // _HAL_TIMERS_DUE_H #endif // _HAL_TIMERS_DUE_H

View File

@ -93,7 +93,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
* TODO: Calculate Timer prescale value, so we get the 32bit to adjust * TODO: Calculate Timer prescale value, so we get the 32bit to adjust
*/ */
void HAL_timer_start(uint8_t timer_num, uint32_t frequency) { void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
nvic_irq_num irq_num; nvic_irq_num irq_num;
switch (timer_num) { switch (timer_num) {
case 1: irq_num = NVIC_TIMER1_CC; break; case 1: irq_num = NVIC_TIMER1_CC; break;
@ -135,7 +135,7 @@ void HAL_timer_start(uint8_t timer_num, uint32_t frequency) {
} }
} }
void HAL_timer_enable_interrupt(uint8_t timer_num) { void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN); timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN);
@ -148,7 +148,7 @@ void HAL_timer_enable_interrupt(uint8_t timer_num) {
} }
} }
void HAL_timer_disable_interrupt(uint8_t timer_num) { void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) { switch (timer_num) {
case STEP_TIMER_NUM: case STEP_TIMER_NUM:
timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN); timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN);
@ -161,4 +161,12 @@ void HAL_timer_disable_interrupt(uint8_t timer_num) {
} }
} }
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM: return bool(TIM_DIER(STEP_TIMER_DEV) & STEP_TIMER_CHAN);
case TEMP_TIMER_NUM: return bool(TIM_DIER(TEMP_TIMER_DEV) & TEMP_TIMER_CHAN);
}
return false;
}
#endif // __STM32F1__ #endif // __STM32F1__

View File

@ -62,8 +62,6 @@ typedef uint16_t hal_timer_t;
#define STEP_TIMER_DEV TIMER_DEV(STEP_TIMER_NUM) #define STEP_TIMER_DEV TIMER_DEV(STEP_TIMER_NUM)
#define TEMP_TIMER_DEV TIMER_DEV(TEMP_TIMER_NUM) #define TEMP_TIMER_DEV TIMER_DEV(TEMP_TIMER_NUM)
//STM32_HAVE_TIMER(n); //STM32_HAVE_TIMER(n);
#define HAL_TIMER_RATE (F_CPU) // frequency of timers peripherals #define HAL_TIMER_RATE (F_CPU) // frequency of timers peripherals
@ -79,6 +77,7 @@ typedef uint16_t hal_timer_t;
#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) #define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) #define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) #define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
#define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) #define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN)
@ -113,9 +112,10 @@ static HardwareTimer TempTimer(TEMP_TIMER_NUM);
// Public functions // Public functions
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void HAL_timer_start(uint8_t timer_num, uint32_t frequency); void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
void HAL_timer_enable_interrupt(uint8_t timer_num); void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
/** /**
* NOTE: By default libmaple sets ARPE = 1, which means the Auto reload register is preloaded (will only update with an update event) * NOTE: By default libmaple sets ARPE = 1, which means the Auto reload register is preloaded (will only update with an update event)

View File

@ -67,6 +67,14 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
} }
} }
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case 0: return NVIC_IS_ENABLED(IRQ_FTM0);
case 1: return NVIC_IS_ENABLED(IRQ_FTM1);
}
return false;
}
void HAL_timer_isr_prologue(const uint8_t timer_num) { void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch(timer_num) { switch(timer_num) {
case 0: case 0:

View File

@ -68,6 +68,8 @@ typedef uint32_t hal_timer_t;
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM) #define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM) #define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM) #define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM) #define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
@ -110,8 +112,8 @@ FORCE_INLINE static hal_timer_t HAL_timer_get_current_count(const uint8_t timer_
void HAL_timer_enable_interrupt(const uint8_t timer_num); void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num); void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
void HAL_timer_isr_prologue(const uint8_t timer_num); void HAL_timer_isr_prologue(const uint8_t timer_num);
#endif // _HAL_TIMERS_TEENSY_H #endif // _HAL_TIMERS_TEENSY_H

View File

@ -61,25 +61,6 @@ enum DebugFlags {
}; };
#endif #endif
//todo: HAL: breaks encapsulation
// For AVR only, define a serial interface based on configuration
#ifdef __AVR__
#ifdef USBCON
#include <HardwareSerial.h>
#if ENABLED(BLUETOOTH)
#define MYSERIAL0 bluetoothSerial
#else
#define MYSERIAL0 Serial
#endif // BLUETOOTH
#else
#include "../HAL/HAL_AVR/MarlinSerial.h"
#define MYSERIAL0 customizedSerial
#endif
#elif defined(ARDUINO_ARCH_SAM)
// To pull the Serial port definitions and overrides
#include "../HAL/HAL_DUE/MarlinSerial_Due.h"
#endif
extern uint8_t marlin_debug_flags; extern uint8_t marlin_debug_flags;
#define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F)) #define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F))

View File

@ -1352,7 +1352,9 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
// Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED. // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED.
const float v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters); const float v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters);
block->entry_speed = min(vmax_junction, v_allowable); // If stepper ISR is disabled, this indicates buffer_segment wants to add a split block.
// In this case start with the max. allowed speed to avoid an interrupted first move.
block->entry_speed = STEPPER_ISR_ENABLED() ? MINIMUM_PLANNER_SPEED : min(vmax_junction, v_allowable);
// Initialize planner efficiency flags // Initialize planner efficiency flags
// Set flag if block will always reach maximum junction speed regardless of entry/exit speeds. // Set flag if block will always reach maximum junction speed regardless of entry/exit speeds.
@ -1362,7 +1364,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
// block nominal speed limits both the current and next maximum junction speeds. Hence, in both // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
// the reverse and forward planners, the corresponding block junction speed will always be at the // the reverse and forward planners, the corresponding block junction speed will always be at the
// the maximum junction speed and may always be ignored for any speed reduction checks. // the maximum junction speed and may always be ignored for any speed reduction checks.
block->flag |= BLOCK_FLAG_RECALCULATE | (block->nominal_speed <= v_allowable ? BLOCK_FLAG_NOMINAL_LENGTH : 0); block->flag |= block->nominal_speed <= v_allowable ? BLOCK_FLAG_RECALCULATE | BLOCK_FLAG_NOMINAL_LENGTH : BLOCK_FLAG_RECALCULATE;
// Update previous path unit_vector and nominal speed // Update previous path unit_vector and nominal speed
COPY(previous_speed, current_speed); COPY(previous_speed, current_speed);
@ -1382,7 +1384,7 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
* In that case, the retract and move will be executed together. * In that case, the retract and move will be executed together.
* This leads to too many advance steps due to a huge e_acceleration. * This leads to too many advance steps due to a huge e_acceleration.
* The math is good, but we must avoid retract moves with advance! * The math is good, but we must avoid retract moves with advance!
* lin_dist_e > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) * lin_dist_e > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
*/ */
block->use_advance_lead = esteps && (block->steps[X_AXIS] || block->steps[Y_AXIS]) block->use_advance_lead = esteps && (block->steps[X_AXIS] || block->steps[Y_AXIS])
&& extruder_advance_k && extruder_advance_k
@ -1398,9 +1400,6 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE], float fr_mm_s, const
#endif // LIN_ADVANCE #endif // LIN_ADVANCE
const float bnsr = 1.0 / block->nominal_speed;
calculate_trapezoid_for_block(block, block->entry_speed * bnsr, safe_speed * bnsr);
// Move buffer head // Move buffer head
block_buffer_head = next_buffer_head; block_buffer_head = next_buffer_head;

View File

@ -534,6 +534,16 @@ class Planner {
static block_t* get_current_block() { static block_t* get_current_block() {
if (blocks_queued()) { if (blocks_queued()) {
block_t * const block = &block_buffer[block_buffer_tail]; block_t * const block = &block_buffer[block_buffer_tail];
// If the block has no trapezoid calculated, it's unsafe to execute.
if (movesplanned() > 1) {
const block_t * const next = &block_buffer[next_block_index(block_buffer_tail)];
if (TEST(block->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE))
return NULL;
}
else if (TEST(block->flag, BLOCK_BIT_RECALCULATE))
return NULL;
#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