0
0
Fork 0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2025-06-28 01:40:56 +00:00

[2.0.x] LIN_ADVANCE v1.5 ()

This commit is contained in:
Scott Lahteine 2018-02-23 00:53:29 -06:00 committed by GitHub
parent 90fa423737
commit 2bd252b501
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 890 additions and 1671 deletions
Marlin/src/module

View file

@ -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();