|
@ -460,7 +460,7 @@ void Stepper::isr() { |
|
|
|
|
|
|
|
|
// Take multiple steps per interrupt (For high speed moves)
|
|
|
// Take multiple steps per interrupt (For high speed moves)
|
|
|
bool all_steps_done = false; |
|
|
bool all_steps_done = false; |
|
|
for (int8_t i = 0; i < step_loops; i++) { |
|
|
for (uint8_t i = step_loops; i--;) { |
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
|
|
|
|
|
|
counter_E += current_block->steps[E_AXIS]; |
|
|
counter_E += current_block->steps[E_AXIS]; |
|
@ -530,10 +530,34 @@ void Stepper::isr() { |
|
|
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ |
|
|
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define CYCLES_EATEN_BY_CODE 240 |
|
|
#if HAS_X_STEP |
|
|
|
|
|
#define _COUNT_STEPPERS_1 1 |
|
|
|
|
|
#else |
|
|
|
|
|
#define _COUNT_STEPPERS_1 0 |
|
|
|
|
|
#endif |
|
|
|
|
|
#if HAS_Y_STEP |
|
|
|
|
|
#define _COUNT_STEPPERS_2 _COUNT_STEPPERS_1 + 1 |
|
|
|
|
|
#else |
|
|
|
|
|
#define _COUNT_STEPPERS_2 _COUNT_STEPPERS_1 |
|
|
|
|
|
#endif |
|
|
|
|
|
#if HAS_Z_STEP |
|
|
|
|
|
#define _COUNT_STEPPERS_3 _COUNT_STEPPERS_2 + 1 |
|
|
|
|
|
#else |
|
|
|
|
|
#define _COUNT_STEPPERS_3 _COUNT_STEPPERS_2 |
|
|
|
|
|
#endif |
|
|
|
|
|
#if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE) |
|
|
|
|
|
#define _COUNT_STEPPERS_4 _COUNT_STEPPERS_3 + 1 |
|
|
|
|
|
#else |
|
|
|
|
|
#define _COUNT_STEPPERS_4 _COUNT_STEPPERS_3 |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#define CYCLES_EATEN_XYZE ((_COUNT_STEPPERS_4) * 5) |
|
|
|
|
|
#define EXTRA_CYCLES_XYZE (STEP_PULSE_CYCLES - (CYCLES_EATEN_XYZE)) |
|
|
|
|
|
|
|
|
// If a minimum pulse time was specified get the CPU clock
|
|
|
// If a minimum pulse time was specified get the timer 0 value
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE |
|
|
// which increments every 4µs on 16MHz and every 3.2µs on 20MHz.
|
|
|
|
|
|
// Two or 3 counts of TCNT0 should be a sufficient delay.
|
|
|
|
|
|
#if EXTRA_CYCLES_XYZE > 20 |
|
|
uint32_t pulse_start = TCNT0; |
|
|
uint32_t pulse_start = TCNT0; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
@ -564,9 +588,12 @@ void Stepper::isr() { |
|
|
#endif |
|
|
#endif |
|
|
#endif // !ADVANCE && !LIN_ADVANCE
|
|
|
#endif // !ADVANCE && !LIN_ADVANCE
|
|
|
|
|
|
|
|
|
// For a minimum pulse time wait before stopping pulses
|
|
|
// For minimum pulse time wait before stopping pulses
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE |
|
|
#if EXTRA_CYCLES_XYZE > 20 |
|
|
while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_CODE) { /* nada */ } |
|
|
while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } |
|
|
|
|
|
pulse_start = TCNT0; |
|
|
|
|
|
#elif EXTRA_CYCLES_XYZE > 0 |
|
|
|
|
|
DELAY_NOPS(EXTRA_CYCLES_XYZE); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if HAS_X_STEP |
|
|
#if HAS_X_STEP |
|
@ -601,7 +628,15 @@ void Stepper::isr() { |
|
|
all_steps_done = true; |
|
|
all_steps_done = true; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// For minimum pulse time wait before stopping pulses
|
|
|
|
|
|
#if EXTRA_CYCLES_XYZE > 20 |
|
|
|
|
|
if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } |
|
|
|
|
|
#elif EXTRA_CYCLES_XYZE > 0 |
|
|
|
|
|
if (i) DELAY_NOPS(EXTRA_CYCLES_XYZE); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
} // steps_loop
|
|
|
|
|
|
|
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
if (current_block->use_advance_lead) { |
|
|
if (current_block->use_advance_lead) { |
|
@ -765,6 +800,9 @@ void Stepper::isr() { |
|
|
|
|
|
|
|
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |
|
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |
|
|
|
|
|
|
|
|
|
|
|
#define CYCLES_EATEN_E (E_STEPPERS * 5) |
|
|
|
|
|
#define EXTRA_CYCLES_E (STEP_PULSE_CYCLES - (CYCLES_EATEN_E)) |
|
|
|
|
|
|
|
|
// Timer interrupt for E. e_steps is set in the main routine;
|
|
|
// Timer interrupt for E. e_steps is set in the main routine;
|
|
|
|
|
|
|
|
|
void Stepper::advance_isr() { |
|
|
void Stepper::advance_isr() { |
|
@ -794,12 +832,10 @@ void Stepper::isr() { |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#define CYCLES_EATEN_BY_E 60 |
|
|
|
|
|
|
|
|
|
|
|
// Step all E steppers that have steps
|
|
|
// Step all E steppers that have steps
|
|
|
for (uint8_t i = 0; i < step_loops; i++) { |
|
|
for (uint8_t i = step_loops; i--;) { |
|
|
|
|
|
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_E |
|
|
#if EXTRA_CYCLES_E > 20 |
|
|
uint32_t pulse_start = TCNT0; |
|
|
uint32_t pulse_start = TCNT0; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
@ -814,9 +850,12 @@ void Stepper::isr() { |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
// For a minimum pulse time wait before stopping pulses
|
|
|
// For minimum pulse time wait before stopping pulses
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_E |
|
|
#if EXTRA_CYCLES_E > 20 |
|
|
while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_E) { /* nada */ } |
|
|
while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } |
|
|
|
|
|
pulse_start = TCNT0; |
|
|
|
|
|
#elif EXTRA_CYCLES_E > 0 |
|
|
|
|
|
DELAY_NOPS(EXTRA_CYCLES_E); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
STOP_E_PULSE(0); |
|
|
STOP_E_PULSE(0); |
|
@ -829,8 +868,15 @@ void Stepper::isr() { |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// For minimum pulse time wait before looping
|
|
|
|
|
|
#if EXTRA_CYCLES_E > 20 |
|
|
|
|
|
if (i) while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } |
|
|
|
|
|
#elif EXTRA_CYCLES_E > 0 |
|
|
|
|
|
if (i) DELAY_NOPS(EXTRA_CYCLES_E); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
} // steps_loop
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Stepper::advance_isr_scheduler() { |
|
|
void Stepper::advance_isr_scheduler() { |
|
@ -1056,15 +1102,11 @@ void Stepper::init() { |
|
|
ENABLE_STEPPER_DRIVER_INTERRUPT(); |
|
|
ENABLE_STEPPER_DRIVER_INTERRUPT(); |
|
|
|
|
|
|
|
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |
|
|
#if ENABLED(ADVANCE) || ENABLED(LIN_ADVANCE) |
|
|
|
|
|
ZERO(e_steps); |
|
|
for (int i = 0; i < E_STEPPERS; i++) { |
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
e_steps[i] = 0; |
|
|
ZERO(current_adv_steps); |
|
|
#if ENABLED(LIN_ADVANCE) |
|
|
#endif |
|
|
current_adv_steps[i] = 0; |
|
|
#endif // ADVANCE || LIN_ADVANCE
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif // ADVANCE or LIN_ADVANCE
|
|
|
|
|
|
|
|
|
|
|
|
endstops.enable(true); // Start with endstops active. After homing they can be disabled
|
|
|
endstops.enable(true); // Start with endstops active. After homing they can be disabled
|
|
|
sei(); |
|
|
sei(); |
|
@ -1235,32 +1277,43 @@ void Stepper::report_positions() { |
|
|
|
|
|
|
|
|
#if ENABLED(BABYSTEPPING) |
|
|
#if ENABLED(BABYSTEPPING) |
|
|
|
|
|
|
|
|
#define CYCLES_EATEN_BY_BABYSTEP 60 |
|
|
#if ENABLED(DELTA) |
|
|
|
|
|
#define CYCLES_EATEN_BABYSTEP (2 * 15) |
|
|
|
|
|
#else |
|
|
|
|
|
#define CYCLES_EATEN_BABYSTEP 0 |
|
|
|
|
|
#endif |
|
|
|
|
|
#define EXTRA_CYCLES_BABYSTEP (STEP_PULSE_CYCLES - (CYCLES_EATEN_BABYSTEP)) |
|
|
|
|
|
|
|
|
#define _ENABLE(AXIS) enable_## AXIS() |
|
|
#define _ENABLE(AXIS) enable_## AXIS() |
|
|
#define _READ_DIR(AXIS) AXIS ##_DIR_READ |
|
|
#define _READ_DIR(AXIS) AXIS ##_DIR_READ |
|
|
#define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR |
|
|
#define _INVERT_DIR(AXIS) INVERT_## AXIS ##_DIR |
|
|
#define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true) |
|
|
#define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true) |
|
|
|
|
|
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP |
|
|
#if EXTRA_CYCLES_BABYSTEP > 20 |
|
|
#define _SAVE_START (pulse_start = TCNT0) |
|
|
#define _SAVE_START (pulse_start = TCNT0) |
|
|
#define _PULSE_WAIT while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ } |
|
|
#define _PULSE_WAIT while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ } |
|
|
#else |
|
|
#else |
|
|
#define _SAVE_START NOOP |
|
|
#define _SAVE_START NOOP |
|
|
#define _PULSE_WAIT NOOP |
|
|
#if EXTRA_CYCLES_BABYSTEP > 0 |
|
|
|
|
|
#define _PULSE_WAIT DELAY_NOPS(EXTRA_CYCLES_BABYSTEP) |
|
|
|
|
|
#elif STEP_PULSE_CYCLES > 0 |
|
|
|
|
|
#define _PULSE_WAIT NOOP |
|
|
|
|
|
#elif ENABLED(DELTA) |
|
|
|
|
|
#define _PULSE_WAIT delayMicroseconds(2); |
|
|
|
|
|
#else |
|
|
|
|
|
#define _PULSE_WAIT delayMicroseconds(4); |
|
|
|
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#define START_BABYSTEP_AXIS(AXIS, INVERT) { \ |
|
|
#define BABYSTEP_AXIS(AXIS, INVERT) { \ |
|
|
old_dir = _READ_DIR(AXIS); \ |
|
|
const uint8_t old_dir = _READ_DIR(AXIS); \ |
|
|
_SAVE_START; \ |
|
|
_ENABLE(AXIS); \ |
|
|
|
|
|
_SAVE_START; \ |
|
|
_APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \ |
|
|
_APPLY_DIR(AXIS, _INVERT_DIR(AXIS)^direction^INVERT); \ |
|
|
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \ |
|
|
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), true); \ |
|
|
} |
|
|
_PULSE_WAIT; \ |
|
|
|
|
|
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \ |
|
|
#define STOP_BABYSTEP_AXIS(AXIS) { \ |
|
|
_APPLY_DIR(AXIS, old_dir); \ |
|
|
_PULSE_WAIT; \ |
|
|
|
|
|
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), true); \ |
|
|
|
|
|
_APPLY_DIR(AXIS, old_dir); \ |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// MUST ONLY BE CALLED BY AN ISR,
|
|
|
// MUST ONLY BE CALLED BY AN ISR,
|
|
@ -1268,31 +1321,30 @@ void Stepper::report_positions() { |
|
|
void Stepper::babystep(const AxisEnum axis, const bool direction) { |
|
|
void Stepper::babystep(const AxisEnum axis, const bool direction) { |
|
|
cli(); |
|
|
cli(); |
|
|
uint8_t old_dir; |
|
|
uint8_t old_dir; |
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP |
|
|
|
|
|
|
|
|
#if EXTRA_CYCLES_BABYSTEP > 20 |
|
|
uint32_t pulse_start; |
|
|
uint32_t pulse_start; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
switch (axis) { |
|
|
switch (axis) { |
|
|
|
|
|
|
|
|
case X_AXIS: |
|
|
#if ENABLED(BABYSTEP_XY) |
|
|
_ENABLE(x); |
|
|
|
|
|
START_BABYSTEP_AXIS(X, false); |
|
|
case X_AXIS: |
|
|
STOP_BABYSTEP_AXIS(X); |
|
|
BABYSTEP_AXIS(X, false); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case Y_AXIS: |
|
|
case Y_AXIS: |
|
|
_ENABLE(y); |
|
|
BABYSTEP_AXIS(Y, false); |
|
|
START_BABYSTEP_AXIS(Y, false); |
|
|
break; |
|
|
STOP_BABYSTEP_AXIS(Y); |
|
|
|
|
|
break; |
|
|
#endif |
|
|
|
|
|
|
|
|
case Z_AXIS: { |
|
|
case Z_AXIS: { |
|
|
|
|
|
|
|
|
#if DISABLED(DELTA) |
|
|
#if DISABLED(DELTA) |
|
|
|
|
|
|
|
|
_ENABLE(z); |
|
|
BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z); |
|
|
START_BABYSTEP_AXIS(Z, BABYSTEP_INVERT_Z); |
|
|
|
|
|
STOP_BABYSTEP_AXIS(Z); |
|
|
|
|
|
|
|
|
|
|
|
#else // DELTA
|
|
|
#else // DELTA
|
|
|
|
|
|
|
|
@ -1305,24 +1357,24 @@ void Stepper::report_positions() { |
|
|
uint8_t old_x_dir_pin = X_DIR_READ, |
|
|
uint8_t old_x_dir_pin = X_DIR_READ, |
|
|
old_y_dir_pin = Y_DIR_READ, |
|
|
old_y_dir_pin = Y_DIR_READ, |
|
|
old_z_dir_pin = Z_DIR_READ; |
|
|
old_z_dir_pin = Z_DIR_READ; |
|
|
//setup new step
|
|
|
|
|
|
X_DIR_WRITE(INVERT_X_DIR ^ z_direction); |
|
|
X_DIR_WRITE(INVERT_X_DIR ^ z_direction); |
|
|
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction); |
|
|
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction); |
|
|
Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction); |
|
|
Z_DIR_WRITE(INVERT_Z_DIR ^ z_direction); |
|
|
//perform step
|
|
|
|
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP |
|
|
_SAVE_START; |
|
|
pulse_start = TCNT0; |
|
|
|
|
|
#endif |
|
|
|
|
|
X_STEP_WRITE(!INVERT_X_STEP_PIN); |
|
|
X_STEP_WRITE(!INVERT_X_STEP_PIN); |
|
|
Y_STEP_WRITE(!INVERT_Y_STEP_PIN); |
|
|
Y_STEP_WRITE(!INVERT_Y_STEP_PIN); |
|
|
Z_STEP_WRITE(!INVERT_Z_STEP_PIN); |
|
|
Z_STEP_WRITE(!INVERT_Z_STEP_PIN); |
|
|
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_BABYSTEP |
|
|
|
|
|
while ((uint32_t)(TCNT0 - pulse_start) < STEP_PULSE_CYCLES - CYCLES_EATEN_BY_BABYSTEP) { /* nada */ } |
|
|
_PULSE_WAIT; |
|
|
#endif |
|
|
|
|
|
X_STEP_WRITE(INVERT_X_STEP_PIN); |
|
|
X_STEP_WRITE(INVERT_X_STEP_PIN); |
|
|
Y_STEP_WRITE(INVERT_Y_STEP_PIN); |
|
|
Y_STEP_WRITE(INVERT_Y_STEP_PIN); |
|
|
Z_STEP_WRITE(INVERT_Z_STEP_PIN); |
|
|
Z_STEP_WRITE(INVERT_Z_STEP_PIN); |
|
|
//get old pin state back.
|
|
|
|
|
|
|
|
|
// Restore direction bits
|
|
|
X_DIR_WRITE(old_x_dir_pin); |
|
|
X_DIR_WRITE(old_x_dir_pin); |
|
|
Y_DIR_WRITE(old_y_dir_pin); |
|
|
Y_DIR_WRITE(old_y_dir_pin); |
|
|
Z_DIR_WRITE(old_z_dir_pin); |
|
|
Z_DIR_WRITE(old_z_dir_pin); |
|
|