|
@@ -117,8 +117,8 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
|
void advance_isr();
|
|
void advance_isr();
|
|
|
|
|
|
static const uint16_t ADV_NEVER = 0xFFFF;
|
|
static const uint16_t ADV_NEVER = 0xFFFF;
|
|
- static const uint8_t ADV_INIT = 0b01;
|
|
|
|
- static const uint8_t ADV_DECELERATE = 0b10;
|
|
|
|
|
|
+ static const uint8_t ADV_INIT = 0b01; // initialize LA
|
|
|
|
+ static const uint8_t ADV_ACC_VARY = 0b10; // varying acceleration phase
|
|
|
|
|
|
static uint16_t nextMainISR;
|
|
static uint16_t nextMainISR;
|
|
static uint16_t nextAdvanceISR;
|
|
static uint16_t nextAdvanceISR;
|
|
@@ -128,13 +128,12 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
|
static uint16_t eISR_Err;
|
|
static uint16_t eISR_Err;
|
|
|
|
|
|
static uint16_t current_adv_steps;
|
|
static uint16_t current_adv_steps;
|
|
- static uint16_t final_adv_steps;
|
|
|
|
- static uint16_t max_adv_steps;
|
|
|
|
- static uint32_t LA_decelerate_after;
|
|
|
|
|
|
+ static uint16_t target_adv_steps;
|
|
|
|
|
|
- static int8_t e_steps;
|
|
|
|
- static uint8_t e_step_loops;
|
|
|
|
- static int8_t LA_phase;
|
|
|
|
|
|
+ static int8_t e_steps; // scheduled e-steps during each isr loop
|
|
|
|
+ static uint8_t e_step_loops; // e-steps to execute at most in each isr loop
|
|
|
|
+ static uint8_t e_extruding; // current move is an extrusion move
|
|
|
|
+ static int8_t LA_phase; // LA compensation phase
|
|
|
|
|
|
#define _NEXT_ISR(T) main_Rate = nextMainISR = T
|
|
#define _NEXT_ISR(T) main_Rate = nextMainISR = T
|
|
#else
|
|
#else
|
|
@@ -349,15 +348,12 @@ FORCE_INLINE void stepper_next_block()
|
|
|
|
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
if (current_block->use_advance_lead) {
|
|
if (current_block->use_advance_lead) {
|
|
- LA_decelerate_after = current_block->decelerate_after;
|
|
|
|
- final_adv_steps = current_block->final_adv_steps;
|
|
|
|
- max_adv_steps = current_block->max_adv_steps;
|
|
|
|
e_step_loops = current_block->advance_step_loops;
|
|
e_step_loops = current_block->advance_step_loops;
|
|
|
|
+ target_adv_steps = current_block->max_adv_steps;
|
|
} else {
|
|
} else {
|
|
- e_steps = 0;
|
|
|
|
e_step_loops = 1;
|
|
e_step_loops = 1;
|
|
- current_adv_steps = 0;
|
|
|
|
}
|
|
}
|
|
|
|
+ e_steps = 0;
|
|
nextAdvanceISR = ADV_NEVER;
|
|
nextAdvanceISR = ADV_NEVER;
|
|
LA_phase = -1;
|
|
LA_phase = -1;
|
|
#endif
|
|
#endif
|
|
@@ -371,11 +367,17 @@ FORCE_INLINE void stepper_next_block()
|
|
counter_y.lo = counter_x.lo;
|
|
counter_y.lo = counter_x.lo;
|
|
counter_z.lo = counter_x.lo;
|
|
counter_z.lo = counter_x.lo;
|
|
counter_e.lo = counter_x.lo;
|
|
counter_e.lo = counter_x.lo;
|
|
|
|
+#ifdef LIN_ADVANCE
|
|
|
|
+ e_extruding = current_block->steps_e.lo != 0;
|
|
|
|
+#endif
|
|
} else {
|
|
} else {
|
|
counter_x.wide = -(current_block->step_event_count.wide >> 1);
|
|
counter_x.wide = -(current_block->step_event_count.wide >> 1);
|
|
counter_y.wide = counter_x.wide;
|
|
counter_y.wide = counter_x.wide;
|
|
counter_z.wide = counter_x.wide;
|
|
counter_z.wide = counter_x.wide;
|
|
counter_e.wide = counter_x.wide;
|
|
counter_e.wide = counter_x.wide;
|
|
|
|
+#ifdef LIN_ADVANCE
|
|
|
|
+ e_extruding = current_block->steps_e.wide != 0;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
step_events_completed.wide = 0;
|
|
step_events_completed.wide = 0;
|
|
// Set directions.
|
|
// Set directions.
|
|
@@ -811,7 +813,7 @@ FORCE_INLINE void isr() {
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
if (current_block->use_advance_lead) {
|
|
if (current_block->use_advance_lead) {
|
|
if (step_events_completed.wide <= (unsigned long int)step_loops)
|
|
if (step_events_completed.wide <= (unsigned long int)step_loops)
|
|
- la_state = ADV_INIT;
|
|
|
|
|
|
+ la_state = ADV_INIT | ADV_ACC_VARY;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
@@ -827,11 +829,13 @@ FORCE_INLINE void isr() {
|
|
uint16_t timer = calc_timer(step_rate, step_loops);
|
|
uint16_t timer = calc_timer(step_rate, step_loops);
|
|
_NEXT_ISR(timer);
|
|
_NEXT_ISR(timer);
|
|
deceleration_time += timer;
|
|
deceleration_time += timer;
|
|
|
|
+
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
if (current_block->use_advance_lead) {
|
|
if (current_block->use_advance_lead) {
|
|
- la_state = ADV_DECELERATE;
|
|
|
|
- if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops)
|
|
|
|
- la_state |= ADV_INIT;
|
|
|
|
|
|
+ if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
|
|
|
+ target_adv_steps = current_block->final_adv_steps;
|
|
|
|
+ la_state = ADV_INIT | ADV_ACC_VARY;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
@@ -841,6 +845,17 @@ FORCE_INLINE void isr() {
|
|
// the initial interrupt blocking.
|
|
// the initial interrupt blocking.
|
|
OCR1A_nominal = calc_timer(uint16_t(current_block->nominal_rate), step_loops);
|
|
OCR1A_nominal = calc_timer(uint16_t(current_block->nominal_rate), step_loops);
|
|
step_loops_nominal = step_loops;
|
|
step_loops_nominal = step_loops;
|
|
|
|
+
|
|
|
|
+#ifdef LIN_ADVANCE
|
|
|
|
+ if(current_block->use_advance_lead) {
|
|
|
|
+ if (!nextAdvanceISR) {
|
|
|
|
+ // Due to E-jerk, there can be discontinuities in pressure state where an
|
|
|
|
+ // acceleration or deceleration can be skipped or joined with the previous block.
|
|
|
|
+ // If LA was not previously active, re-check the pressure level
|
|
|
|
+ la_state = ADV_INIT;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
_NEXT_ISR(OCR1A_nominal);
|
|
_NEXT_ISR(OCR1A_nominal);
|
|
}
|
|
}
|
|
@@ -849,10 +864,23 @@ FORCE_INLINE void isr() {
|
|
|
|
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
// avoid multiple instances or function calls to advance_spread
|
|
// avoid multiple instances or function calls to advance_spread
|
|
- if (la_state & ADV_INIT) eISR_Err = current_block->advance_rate / 4;
|
|
|
|
|
|
+ if (la_state & ADV_INIT) {
|
|
|
|
+ if (current_adv_steps == target_adv_steps) {
|
|
|
|
+ // nothing to be done in this phase
|
|
|
|
+ la_state = 0;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ eISR_Err = current_block->advance_rate / 4;
|
|
|
|
+ if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
|
|
|
|
+ // LA could reverse the direction of extrusion in this phase
|
|
|
|
+ LA_phase = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
if (la_state & ADV_INIT || nextAdvanceISR != ADV_NEVER) {
|
|
if (la_state & ADV_INIT || nextAdvanceISR != ADV_NEVER) {
|
|
|
|
+ // update timers & phase for the next iteration
|
|
advance_spread(main_Rate);
|
|
advance_spread(main_Rate);
|
|
- if (la_state & ADV_DECELERATE) {
|
|
|
|
|
|
+ if (LA_phase >= 0) {
|
|
if (step_loops == e_step_loops)
|
|
if (step_loops == e_step_loops)
|
|
LA_phase = (eISR_Rate > main_Rate);
|
|
LA_phase = (eISR_Rate > main_Rate);
|
|
else {
|
|
else {
|
|
@@ -898,7 +926,7 @@ FORCE_INLINE void isr() {
|
|
// Timer interrupt for E. e_steps is set in the main routine.
|
|
// Timer interrupt for E. e_steps is set in the main routine.
|
|
|
|
|
|
FORCE_INLINE void advance_isr() {
|
|
FORCE_INLINE void advance_isr() {
|
|
- if (step_events_completed.wide > LA_decelerate_after && current_adv_steps > final_adv_steps) {
|
|
|
|
|
|
+ if (current_adv_steps > target_adv_steps) {
|
|
// decompression
|
|
// decompression
|
|
e_steps -= e_step_loops;
|
|
e_steps -= e_step_loops;
|
|
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
|
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
|
@@ -908,7 +936,7 @@ FORCE_INLINE void advance_isr() {
|
|
current_adv_steps = 0;
|
|
current_adv_steps = 0;
|
|
nextAdvanceISR = eISR_Rate;
|
|
nextAdvanceISR = eISR_Rate;
|
|
}
|
|
}
|
|
- else if (step_events_completed.wide < LA_decelerate_after && current_adv_steps < max_adv_steps) {
|
|
|
|
|
|
+ else if (current_adv_steps < target_adv_steps) {
|
|
// compression
|
|
// compression
|
|
e_steps += e_step_loops;
|
|
e_steps += e_step_loops;
|
|
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
|
if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR);
|
|
@@ -1233,9 +1261,6 @@ void st_init()
|
|
nextMainISR = 0;
|
|
nextMainISR = 0;
|
|
nextAdvanceISR = ADV_NEVER;
|
|
nextAdvanceISR = ADV_NEVER;
|
|
main_Rate = ADV_NEVER;
|
|
main_Rate = ADV_NEVER;
|
|
- e_steps = 0;
|
|
|
|
- e_step_loops = 1;
|
|
|
|
- LA_phase = -1;
|
|
|
|
current_adv_steps = 0;
|
|
current_adv_steps = 0;
|
|
#endif
|
|
#endif
|
|
|
|
|