Fix MINIMUM_STEPPER_PULSE maths

This commit is contained in:
Scott Lahteine 2017-04-11 11:11:17 -05:00
parent 68773f4486
commit 6a9b008044
2 changed files with 117 additions and 64 deletions

View File

@ -36,8 +36,9 @@
#define CRITICAL_SECTION_END SREG = _sreg; #define CRITICAL_SECTION_END SREG = _sreg;
#endif #endif
// Clock speed factor // Clock speed factors
#define CYCLES_PER_MICROSECOND (F_CPU / 1000000UL) // 16 or 20 #define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20
#define INT0_PRESCALER 8
// Highly granular delays for step pulses, etc. // Highly granular delays for step pulses, etc.
#define DELAY_0_NOP NOOP #define DELAY_0_NOP NOOP

View File

@ -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
// If a minimum pulse time was specified get the CPU clock #define CYCLES_EATEN_XYZE ((_COUNT_STEPPERS_4) * 5)
#if STEP_PULSE_CYCLES > CYCLES_EATEN_BY_CODE #define EXTRA_CYCLES_XYZE (STEP_PULSE_CYCLES - (CYCLES_EATEN_XYZE))
// If a minimum pulse time was specified get the timer 0 value
// 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);
STOP_BABYSTEP_AXIS(X);
break;
case Y_AXIS: case X_AXIS:
_ENABLE(y); BABYSTEP_AXIS(X, false);
START_BABYSTEP_AXIS(Y, false); break;
STOP_BABYSTEP_AXIS(Y);
break; case Y_AXIS:
BABYSTEP_AXIS(Y, false);
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);