mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-06-28 01:40:56 +00:00
[2.0.x] LIN_ADVANCE v1.5 (#9712)
This commit is contained in:
parent
90fa423737
commit
2bd252b501
52 changed files with 890 additions and 1671 deletions
Marlin/src/module
|
@ -111,31 +111,21 @@ volatile uint32_t Stepper::step_events_completed = 0; // The number of step even
|
|||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
uint32_t Stepper::LA_decelerate_after;
|
||||
|
||||
constexpr hal_timer_t ADV_NEVER = HAL_TIMER_TYPE_MAX;
|
||||
|
||||
hal_timer_t Stepper::nextMainISR = 0,
|
||||
Stepper::nextAdvanceISR = ADV_NEVER,
|
||||
Stepper::eISR_Rate = ADV_NEVER;
|
||||
uint16_t Stepper::current_adv_steps = 0,
|
||||
Stepper::final_adv_steps,
|
||||
Stepper::max_adv_steps;
|
||||
|
||||
volatile int Stepper::e_steps[E_STEPPERS];
|
||||
int Stepper::final_estep_rate,
|
||||
Stepper::current_estep_rate[E_STEPPERS],
|
||||
Stepper::current_adv_steps[E_STEPPERS];
|
||||
int8_t Stepper::e_steps = 0,
|
||||
Stepper::LA_active_extruder; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
|
||||
/**
|
||||
* See https://github.com/MarlinFirmware/Marlin/issues/5699#issuecomment-309264382
|
||||
*
|
||||
* This fix isn't perfect and may lose steps - but better than locking up completely
|
||||
* in future the planner should slow down if advance stepping rate would be too high
|
||||
*/
|
||||
FORCE_INLINE hal_timer_t adv_rate(const int steps, const hal_timer_t timer, const uint8_t loops) {
|
||||
if (steps) {
|
||||
const hal_timer_t rate = (timer * loops) / abs(steps);
|
||||
//return constrain(rate, 1, ADV_NEVER - 1)
|
||||
return rate ? rate : 1;
|
||||
}
|
||||
return ADV_NEVER;
|
||||
}
|
||||
bool Stepper::use_advance_lead;
|
||||
|
||||
#endif // LIN_ADVANCE
|
||||
|
||||
|
@ -461,7 +451,7 @@ void Stepper::isr() {
|
|||
#if DISABLED(MIXING_EXTRUDER)
|
||||
// Don't step E here for mixing extruder
|
||||
count_position[E_AXIS] += count_direction[E_AXIS];
|
||||
motor_direction(E_AXIS) ? --e_steps[TOOL_E_INDEX] : ++e_steps[TOOL_E_INDEX];
|
||||
motor_direction(E_AXIS) ? --e_steps : ++e_steps;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -640,25 +630,6 @@ void Stepper::isr() {
|
|||
|
||||
} // steps_loop
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
if (current_block->use_advance_lead) {
|
||||
const int delta_adv_steps = current_estep_rate[TOOL_E_INDEX] - current_adv_steps[TOOL_E_INDEX];
|
||||
current_adv_steps[TOOL_E_INDEX] += delta_adv_steps;
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
// Mixing extruders apply advance lead proportionally
|
||||
MIXING_STEPPERS_LOOP(j)
|
||||
e_steps[j] += delta_adv_steps * current_block->step_event_count / current_block->mix_event_count[j];
|
||||
#else
|
||||
// For most extruders, advance the single E stepper
|
||||
e_steps[TOOL_E_INDEX] += delta_adv_steps;
|
||||
#endif
|
||||
}
|
||||
// If we have esteps to execute, fire the next advance_isr "now"
|
||||
if (e_steps[TOOL_E_INDEX]) nextAdvanceISR = 0;
|
||||
|
||||
#endif // LIN_ADVANCE
|
||||
|
||||
// Calculate new timer value
|
||||
if (step_events_completed <= (uint32_t)current_block->accelerate_until) {
|
||||
|
||||
|
@ -683,14 +654,15 @@ void Stepper::isr() {
|
|||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
if (current_block->use_advance_lead) {
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j)
|
||||
current_estep_rate[j] = ((uint32_t)acc_step_rate * current_block->abs_adv_steps_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 17;
|
||||
#else
|
||||
current_estep_rate[TOOL_E_INDEX] = ((uint32_t)acc_step_rate * current_block->abs_adv_steps_multiplier8) >> 17;
|
||||
#endif
|
||||
if (step_events_completed == step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
|
||||
nextAdvanceISR = 0; // Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
|
||||
eISR_Rate = current_block->advance_speed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eISR_Rate = ADV_NEVER;
|
||||
if (e_steps) nextAdvanceISR = 0;
|
||||
}
|
||||
eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], interval, step_loops);
|
||||
|
||||
#endif // LIN_ADVANCE
|
||||
}
|
||||
|
@ -719,14 +691,15 @@ void Stepper::isr() {
|
|||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
if (current_block->use_advance_lead) {
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j)
|
||||
current_estep_rate[j] = ((uint32_t)step_rate * current_block->abs_adv_steps_multiplier8 * current_block->step_event_count / current_block->mix_event_count[j]) >> 17;
|
||||
#else
|
||||
current_estep_rate[TOOL_E_INDEX] = ((uint32_t)step_rate * current_block->abs_adv_steps_multiplier8) >> 17;
|
||||
#endif
|
||||
if (step_events_completed <= (uint32_t)current_block->decelerate_after + step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
|
||||
nextAdvanceISR = 0; // Wake up eISR on first deceleration loop
|
||||
eISR_Rate = current_block->advance_speed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eISR_Rate = ADV_NEVER;
|
||||
if (e_steps) nextAdvanceISR = 0;
|
||||
}
|
||||
eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], interval, step_loops);
|
||||
|
||||
#endif // LIN_ADVANCE
|
||||
}
|
||||
|
@ -734,10 +707,8 @@ void Stepper::isr() {
|
|||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
if (current_block->use_advance_lead)
|
||||
current_estep_rate[TOOL_E_INDEX] = final_estep_rate;
|
||||
|
||||
eISR_Rate = adv_rate(e_steps[TOOL_E_INDEX], OCR1A_nominal, step_loops_nominal);
|
||||
// If we have esteps to execute, fire the next advance_isr "now"
|
||||
if (e_steps && eISR_Rate != current_block->advance_speed) nextAdvanceISR = 0;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -781,55 +752,79 @@ void Stepper::isr() {
|
|||
#if ENABLED(MK2_MULTIPLEXER)
|
||||
// Even-numbered steppers are reversed
|
||||
#define SET_E_STEP_DIR(INDEX) \
|
||||
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0))
|
||||
if (e_steps) E## INDEX ##_DIR_WRITE(e_steps < 0 ? !INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0) : INVERT_E## INDEX ##_DIR ^ TEST(INDEX, 0))
|
||||
#else
|
||||
#define SET_E_STEP_DIR(INDEX) \
|
||||
if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
|
||||
if (e_steps) E## INDEX ##_DIR_WRITE(e_steps < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
|
||||
#endif
|
||||
|
||||
#define START_E_PULSE(INDEX) \
|
||||
if (e_steps[INDEX]) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN)
|
||||
if (e_steps) E## INDEX ##_STEP_WRITE(!INVERT_E_STEP_PIN)
|
||||
|
||||
#define STOP_E_PULSE(INDEX) \
|
||||
if (e_steps[INDEX]) { \
|
||||
e_steps[INDEX] < 0 ? ++e_steps[INDEX] : --e_steps[INDEX]; \
|
||||
if (e_steps) { \
|
||||
e_steps < 0 ? ++e_steps : --e_steps; \
|
||||
E## INDEX ##_STEP_WRITE(INVERT_E_STEP_PIN); \
|
||||
}
|
||||
|
||||
SET_E_STEP_DIR(0);
|
||||
#if E_STEPPERS > 1
|
||||
SET_E_STEP_DIR(1);
|
||||
#if E_STEPPERS > 2
|
||||
SET_E_STEP_DIR(2);
|
||||
#if E_STEPPERS > 3
|
||||
SET_E_STEP_DIR(3);
|
||||
#if E_STEPPERS > 4
|
||||
SET_E_STEP_DIR(4);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed > LA_decelerate_after && current_adv_steps > final_adv_steps) {
|
||||
e_steps--;
|
||||
current_adv_steps--;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
else if (step_events_completed < LA_decelerate_after && current_adv_steps < max_adv_steps) {
|
||||
//step_events_completed <= (uint32_t)current_block->accelerate_until) {
|
||||
e_steps++;
|
||||
current_adv_steps++;
|
||||
nextAdvanceISR = eISR_Rate;
|
||||
}
|
||||
else {
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
eISR_Rate = ADV_NEVER;
|
||||
}
|
||||
}
|
||||
else
|
||||
nextAdvanceISR = ADV_NEVER;
|
||||
|
||||
// Step all E steppers that have steps
|
||||
for (uint8_t i = step_loops; i--;) {
|
||||
switch(LA_active_extruder) {
|
||||
case 0: SET_E_STEP_DIR(0); break;
|
||||
#if EXTRUDERS > 1
|
||||
case 1: SET_E_STEP_DIR(1); break;
|
||||
#if EXTRUDERS > 2
|
||||
case 2: SET_E_STEP_DIR(2); break;
|
||||
#if EXTRUDERS > 3
|
||||
case 3: SET_E_STEP_DIR(3); break;
|
||||
#if EXTRUDERS > 4
|
||||
case 4: SET_E_STEP_DIR(4); break;
|
||||
#endif // EXTRUDERS > 4
|
||||
#endif // EXTRUDERS > 3
|
||||
#endif // EXTRUDERS > 2
|
||||
#endif // EXTRUDERS > 1
|
||||
}
|
||||
|
||||
// Step E stepper if we have steps
|
||||
while (e_steps) {
|
||||
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
|
||||
#endif
|
||||
|
||||
START_E_PULSE(0);
|
||||
#if E_STEPPERS > 1
|
||||
START_E_PULSE(1);
|
||||
#if E_STEPPERS > 2
|
||||
START_E_PULSE(2);
|
||||
#if E_STEPPERS > 3
|
||||
START_E_PULSE(3);
|
||||
#if E_STEPPERS > 4
|
||||
START_E_PULSE(4);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
switch(LA_active_extruder) {
|
||||
case 0: START_E_PULSE(0); break;
|
||||
#if EXTRUDERS > 1
|
||||
case 1: START_E_PULSE(1); break;
|
||||
#if EXTRUDERS > 2
|
||||
case 2: START_E_PULSE(2); break;
|
||||
#if EXTRUDERS > 3
|
||||
case 3: START_E_PULSE(3); break;
|
||||
#if EXTRUDERS > 4
|
||||
case 4: START_E_PULSE(4); break;
|
||||
#endif // EXTRUDERS > 4
|
||||
#endif // EXTRUDERS > 3
|
||||
#endif // EXTRUDERS > 2
|
||||
#endif // EXTRUDERS > 1
|
||||
}
|
||||
|
||||
// For minimum pulse time wait before stopping pulses
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
|
@ -839,19 +834,21 @@ void Stepper::isr() {
|
|||
DELAY_NOPS(EXTRA_CYCLES_E);
|
||||
#endif
|
||||
|
||||
STOP_E_PULSE(0);
|
||||
#if E_STEPPERS > 1
|
||||
STOP_E_PULSE(1);
|
||||
#if E_STEPPERS > 2
|
||||
STOP_E_PULSE(2);
|
||||
#if E_STEPPERS > 3
|
||||
STOP_E_PULSE(3);
|
||||
#if E_STEPPERS > 4
|
||||
STOP_E_PULSE(4);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
switch(LA_active_extruder) {
|
||||
case 0: STOP_E_PULSE(0); break;
|
||||
#if EXTRUDERS > 1
|
||||
case 1: STOP_E_PULSE(1); break;
|
||||
#if EXTRUDERS > 2
|
||||
case 2: STOP_E_PULSE(2); break;
|
||||
#if EXTRUDERS > 3
|
||||
case 3: STOP_E_PULSE(3); break;
|
||||
#if EXTRUDERS > 4
|
||||
case 4: STOP_E_PULSE(4); break;
|
||||
#endif // EXTRUDERS > 4
|
||||
#endif // EXTRUDERS > 3
|
||||
#endif // EXTRUDERS > 2
|
||||
#endif // EXTRUDERS > 1
|
||||
}
|
||||
|
||||
// For minimum pulse time wait before looping
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
|
@ -1116,11 +1113,6 @@ void Stepper::init() {
|
|||
|
||||
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
for (uint8_t i = 0; i < COUNT(e_steps); i++) e_steps[i] = 0;
|
||||
ZERO(current_adv_steps);
|
||||
#endif
|
||||
|
||||
endstops.enable(true); // Start with endstops active. After homing they can be disabled
|
||||
sei();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue