Merge pull request #2785 from wavexx/la15_acc_fixes
Linear Advance 1.5 Fixes
This commit is contained in:
commit
c0ea67abbf
|
|
@ -288,6 +288,7 @@
|
||||||
#define LA_K_DEF 0 // Default K factor (Unit: mm compression per 1mm/s extruder speed)
|
#define LA_K_DEF 0 // Default K factor (Unit: mm compression per 1mm/s extruder speed)
|
||||||
#define LA_K_MAX 10 // Maximum acceptable K factor (exclusive, see notes in planner.cpp:plan_buffer_line)
|
#define LA_K_MAX 10 // Maximum acceptable K factor (exclusive, see notes in planner.cpp:plan_buffer_line)
|
||||||
#define LA_LA10_MIN LA_K_MAX // Lin. Advance 1.0 threshold value (inclusive)
|
#define LA_LA10_MIN LA_K_MAX // Lin. Advance 1.0 threshold value (inclusive)
|
||||||
|
//#define LA_FLOWADJ // Adjust LA along with flow/M221 for uniform width
|
||||||
//#define LA_NOCOMPAT // Disable Linear Advance 1.0 compatibility
|
//#define LA_NOCOMPAT // Disable Linear Advance 1.0 compatibility
|
||||||
//#define LA_LIVE_K // Allow adjusting K in the Tune menu
|
//#define LA_LIVE_K // Allow adjusting K in the Tune menu
|
||||||
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
|
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@ extern float feedrate;
|
||||||
extern int feedmultiply;
|
extern int feedmultiply;
|
||||||
extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
|
extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
|
||||||
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
|
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
|
||||||
extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
|
extern float extruder_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
|
||||||
extern float current_position[NUM_AXIS] ;
|
extern float current_position[NUM_AXIS] ;
|
||||||
extern float destination[NUM_AXIS] ;
|
extern float destination[NUM_AXIS] ;
|
||||||
extern float min_pos[3];
|
extern float min_pos[3];
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,23 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
||||||
// Size of Plateau of Nominal Rate.
|
// Size of Plateau of Nominal Rate.
|
||||||
uint32_t plateau_steps = 0;
|
uint32_t plateau_steps = 0;
|
||||||
|
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
uint16_t final_adv_steps = 0;
|
||||||
|
uint16_t max_adv_steps = 0;
|
||||||
|
if (block->use_advance_lead) {
|
||||||
|
final_adv_steps = final_rate * block->adv_comp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will
|
// Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will
|
||||||
// have to use intersection_distance() to calculate when to abort acceleration and start braking
|
// have to use intersection_distance() to calculate when to abort acceleration and start braking
|
||||||
// in order to reach the final_rate exactly at the end of this block.
|
// in order to reach the final_rate exactly at the end of this block.
|
||||||
if (accel_decel_steps < block->step_event_count.wide) {
|
if (accel_decel_steps < block->step_event_count.wide) {
|
||||||
plateau_steps = block->step_event_count.wide - accel_decel_steps;
|
plateau_steps = block->step_event_count.wide - accel_decel_steps;
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
if (block->use_advance_lead)
|
||||||
|
max_adv_steps = block->nominal_rate * block->adv_comp;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
uint32_t acceleration_x4 = acceleration << 2;
|
uint32_t acceleration_x4 = acceleration << 2;
|
||||||
// Avoid negative numbers
|
// Avoid negative numbers
|
||||||
|
|
@ -263,14 +275,20 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
||||||
decelerate_steps = block->step_event_count.wide;
|
decelerate_steps = block->step_event_count.wide;
|
||||||
accelerate_steps = block->step_event_count.wide - decelerate_steps;
|
accelerate_steps = block->step_event_count.wide - decelerate_steps;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
uint16_t final_adv_steps = 0;
|
if (block->use_advance_lead) {
|
||||||
if (block->use_advance_lead) {
|
if(!accelerate_steps || !decelerate_steps) {
|
||||||
final_adv_steps = exit_speed * block->adv_comp;
|
// accelerate_steps=0: deceleration-only ramp, max_rate is effectively unused
|
||||||
}
|
// decelerate_steps=0: acceleration-only ramp, max_rate _is_ final_rate
|
||||||
|
max_adv_steps = final_adv_steps;
|
||||||
|
} else {
|
||||||
|
float max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr);
|
||||||
|
max_adv_steps = max_rate * block->adv_comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
|
||||||
// This block locks the interrupts globally for 4.38 us,
|
// This block locks the interrupts globally for 4.38 us,
|
||||||
|
|
@ -284,6 +302,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit
|
||||||
block->final_rate = final_rate;
|
block->final_rate = final_rate;
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
block->final_adv_steps = final_adv_steps;
|
block->final_adv_steps = final_adv_steps;
|
||||||
|
block->max_adv_steps = max_adv_steps;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
CRITICAL_SECTION_END;
|
CRITICAL_SECTION_END;
|
||||||
|
|
@ -1077,12 +1096,20 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
&& delta_mm[E_AXIS] >= 0
|
&& delta_mm[E_AXIS] >= 0
|
||||||
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
&& abs(delta_mm[Z_AXIS]) < 0.5;
|
||||||
if (block->use_advance_lead) {
|
if (block->use_advance_lead) {
|
||||||
|
#ifdef LA_FLOWADJ
|
||||||
|
// M221/FLOW should change uniformly the extrusion thickness
|
||||||
|
float delta_e = (e - position_float[E_AXIS]) / extruder_multiplier[extruder];
|
||||||
|
#else
|
||||||
|
// M221/FLOW only adjusts for an incorrect source diameter
|
||||||
|
float delta_e = (e - position_float[E_AXIS]);
|
||||||
|
#endif
|
||||||
|
float delta_D = sqrt(sq(x - position_float[X_AXIS])
|
||||||
|
+ sq(y - position_float[Y_AXIS])
|
||||||
|
+ sq(z - position_float[Z_AXIS]));
|
||||||
|
|
||||||
// all extrusion moves with LA require a compression which is proportional to the
|
// all extrusion moves with LA require a compression which is proportional to the
|
||||||
// extrusion_length to distance ratio (e/D)
|
// extrusion_length to distance ratio (e/D)
|
||||||
e_D_ratio = (e - position_float[E_AXIS]) /
|
e_D_ratio = delta_e / delta_D;
|
||||||
sqrt(sq(x - position_float[X_AXIS])
|
|
||||||
+ sq(y - position_float[Y_AXIS])
|
|
||||||
+ sq(z - position_float[Z_AXIS]));
|
|
||||||
|
|
||||||
// Check for unusual high e_D ratio to detect if a retract move was combined with the last
|
// Check for unusual high e_D ratio to detect if a retract move was combined with the last
|
||||||
// print move due to min. steps per segment. Never execute this with advance! This assumes
|
// print move due to min. steps per segment. Never execute this with advance! This assumes
|
||||||
|
|
@ -1134,52 +1161,6 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
|
|
||||||
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
|
||||||
if (block->use_advance_lead) {
|
|
||||||
// the nominal speed doesn't change past this point: calculate the compression ratio for the
|
|
||||||
// segment and the required advance steps
|
|
||||||
block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS];
|
|
||||||
block->max_adv_steps = block->nominal_speed * block->adv_comp;
|
|
||||||
|
|
||||||
float advance_speed;
|
|
||||||
if (e_D_ratio > 0)
|
|
||||||
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
|
||||||
else
|
|
||||||
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
|
|
||||||
|
|
||||||
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
|
||||||
// still need to replicate the *exact* same step grouping policy (see below)
|
|
||||||
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
|
||||||
float advance_rate = (F_CPU / 8.0) / advance_speed;
|
|
||||||
if (advance_speed > 20000) {
|
|
||||||
block->advance_rate = advance_rate * 4;
|
|
||||||
block->advance_step_loops = 4;
|
|
||||||
}
|
|
||||||
else if (advance_speed > 10000) {
|
|
||||||
block->advance_rate = advance_rate * 2;
|
|
||||||
block->advance_step_loops = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// never overflow the internal accumulator with very low rates
|
|
||||||
if (advance_rate < UINT16_MAX)
|
|
||||||
block->advance_rate = advance_rate;
|
|
||||||
else
|
|
||||||
block->advance_rate = UINT16_MAX;
|
|
||||||
block->advance_step_loops = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LA_DEBUG
|
|
||||||
if (block->advance_step_loops > 2)
|
|
||||||
// @wavexx: we should really check for the difference between step_loops and
|
|
||||||
// advance_step_loops instead. A difference of more than 1 will lead
|
|
||||||
// to uneven speed and *should* be adjusted here by furthermore
|
|
||||||
// reducing the speed.
|
|
||||||
SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Start with a safe speed.
|
// Start with a safe speed.
|
||||||
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
||||||
float safe_speed = block->nominal_speed;
|
float safe_speed = block->nominal_speed;
|
||||||
|
|
@ -1305,6 +1286,53 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
|
|
||||||
// Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated.
|
// Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated.
|
||||||
block->speed_factor = block->nominal_rate / block->nominal_speed;
|
block->speed_factor = block->nominal_rate / block->nominal_speed;
|
||||||
|
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
if (block->use_advance_lead) {
|
||||||
|
// calculate the compression ratio for the segment (the required advance steps are computed
|
||||||
|
// during trapezoid planning)
|
||||||
|
float adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; // (step/(mm/s))
|
||||||
|
block->adv_comp = adv_comp / block->speed_factor; // step/(step/min)
|
||||||
|
|
||||||
|
float advance_speed;
|
||||||
|
if (e_D_ratio > 0)
|
||||||
|
advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]);
|
||||||
|
else
|
||||||
|
advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS];
|
||||||
|
|
||||||
|
// to save more space we avoid another copy of calc_timer and go through slow division, but we
|
||||||
|
// still need to replicate the *exact* same step grouping policy (see below)
|
||||||
|
if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY;
|
||||||
|
float advance_rate = (F_CPU / 8.0) / advance_speed;
|
||||||
|
if (advance_speed > 20000) {
|
||||||
|
block->advance_rate = advance_rate * 4;
|
||||||
|
block->advance_step_loops = 4;
|
||||||
|
}
|
||||||
|
else if (advance_speed > 10000) {
|
||||||
|
block->advance_rate = advance_rate * 2;
|
||||||
|
block->advance_step_loops = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// never overflow the internal accumulator with very low rates
|
||||||
|
if (advance_rate < UINT16_MAX)
|
||||||
|
block->advance_rate = advance_rate;
|
||||||
|
else
|
||||||
|
block->advance_rate = UINT16_MAX;
|
||||||
|
block->advance_step_loops = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LA_DEBUG
|
||||||
|
if (block->advance_step_loops > 2)
|
||||||
|
// @wavexx: we should really check for the difference between step_loops and
|
||||||
|
// advance_step_loops instead. A difference of more than 1 will lead
|
||||||
|
// to uneven speed and *should* be adjusted here by furthermore
|
||||||
|
// reducing the speed.
|
||||||
|
SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
calculate_trapezoid_for_block(block, block->entry_speed, safe_speed);
|
calculate_trapezoid_for_block(block, block->entry_speed, safe_speed);
|
||||||
|
|
||||||
if (block->step_event_count.wide <= 32767)
|
if (block->step_event_count.wide <= 32767)
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1};
|
||||||
|
|
||||||
static uint16_t main_Rate;
|
static uint16_t main_Rate;
|
||||||
static uint16_t eISR_Rate;
|
static uint16_t eISR_Rate;
|
||||||
static uint16_t eISR_Err;
|
static uint32_t eISR_Err;
|
||||||
|
|
||||||
static uint16_t current_adv_steps;
|
static uint16_t current_adv_steps;
|
||||||
static uint16_t target_adv_steps;
|
static uint16_t target_adv_steps;
|
||||||
|
|
@ -348,10 +348,7 @@ FORCE_INLINE void stepper_next_block()
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
if (current_block->use_advance_lead) {
|
if (current_block->use_advance_lead) {
|
||||||
e_step_loops = current_block->advance_step_loops;
|
|
||||||
target_adv_steps = current_block->max_adv_steps;
|
target_adv_steps = current_block->max_adv_steps;
|
||||||
} else {
|
|
||||||
e_step_loops = 1;
|
|
||||||
}
|
}
|
||||||
e_steps = 0;
|
e_steps = 0;
|
||||||
nextAdvanceISR = ADV_NEVER;
|
nextAdvanceISR = ADV_NEVER;
|
||||||
|
|
@ -736,38 +733,30 @@ FORCE_INLINE uint16_t fastdiv(uint16_t q, uint8_t d)
|
||||||
|
|
||||||
FORCE_INLINE void advance_spread(uint16_t timer)
|
FORCE_INLINE void advance_spread(uint16_t timer)
|
||||||
{
|
{
|
||||||
if(eISR_Err > timer)
|
eISR_Err += timer;
|
||||||
|
|
||||||
|
uint8_t ticks = 0;
|
||||||
|
while(eISR_Err >= current_block->advance_rate)
|
||||||
|
{
|
||||||
|
++ticks;
|
||||||
|
eISR_Err -= current_block->advance_rate;
|
||||||
|
}
|
||||||
|
if(!ticks)
|
||||||
{
|
{
|
||||||
// advance-step skipped
|
|
||||||
eISR_Err -= timer;
|
|
||||||
eISR_Rate = timer;
|
eISR_Rate = timer;
|
||||||
nextAdvanceISR = timer;
|
nextAdvanceISR = timer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// at least one step
|
if (ticks <= 3)
|
||||||
uint8_t ticks = 1;
|
eISR_Rate = fastdiv(timer, ticks + 1);
|
||||||
uint32_t block = current_block->advance_rate;
|
|
||||||
uint16_t max_t = timer - eISR_Err;
|
|
||||||
while (block < max_t)
|
|
||||||
{
|
|
||||||
++ticks;
|
|
||||||
block += current_block->advance_rate;
|
|
||||||
}
|
|
||||||
if (block > timer)
|
|
||||||
eISR_Err += block - timer;
|
|
||||||
else
|
|
||||||
eISR_Err -= timer - block;
|
|
||||||
|
|
||||||
if (ticks <= 4)
|
|
||||||
eISR_Rate = fastdiv(timer, ticks);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// >4 ticks are still possible on slow moves
|
// >4 ticks are still possible on slow moves
|
||||||
eISR_Rate = timer / ticks;
|
eISR_Rate = timer / (ticks + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextAdvanceISR = eISR_Rate / 2;
|
nextAdvanceISR = eISR_Rate;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -812,8 +801,11 @@ FORCE_INLINE void isr() {
|
||||||
acceleration_time += timer;
|
acceleration_time += timer;
|
||||||
#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 | ADV_ACC_VARY;
|
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||||
|
if (e_extruding && current_adv_steps > target_adv_steps)
|
||||||
|
target_adv_steps = current_adv_steps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -835,6 +827,8 @@ FORCE_INLINE void isr() {
|
||||||
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) {
|
||||||
target_adv_steps = current_block->final_adv_steps;
|
target_adv_steps = current_block->final_adv_steps;
|
||||||
la_state = ADV_INIT | ADV_ACC_VARY;
|
la_state = ADV_INIT | ADV_ACC_VARY;
|
||||||
|
if (e_extruding && current_adv_steps < target_adv_steps)
|
||||||
|
target_adv_steps = current_adv_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -848,12 +842,12 @@ FORCE_INLINE void isr() {
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
if(current_block->use_advance_lead) {
|
if(current_block->use_advance_lead) {
|
||||||
if (!nextAdvanceISR) {
|
// Due to E-jerk, there can be discontinuities in pressure state where an
|
||||||
// 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.
|
||||||
// acceleration or deceleration can be skipped or joined with the previous block.
|
// If LA was not previously active, re-check the pressure level
|
||||||
// If LA was not previously active, re-check the pressure level
|
la_state = ADV_INIT;
|
||||||
la_state = ADV_INIT;
|
if (e_extruding)
|
||||||
}
|
target_adv_steps = current_adv_steps;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -865,14 +859,21 @@ 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) {
|
if (la_state & ADV_INIT) {
|
||||||
|
LA_phase = -1;
|
||||||
|
|
||||||
if (current_adv_steps == target_adv_steps) {
|
if (current_adv_steps == target_adv_steps) {
|
||||||
// nothing to be done in this phase
|
// nothing to be done in this phase, cancel any pending eisr
|
||||||
la_state = 0;
|
la_state = 0;
|
||||||
|
nextAdvanceISR = ADV_NEVER;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eISR_Err = current_block->advance_rate / 4;
|
// reset error and iterations per loop for this phase
|
||||||
|
eISR_Err = current_block->advance_rate;
|
||||||
|
e_step_loops = current_block->advance_step_loops;
|
||||||
|
|
||||||
if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) {
|
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 could reverse the direction of extrusion in this phase
|
||||||
|
eISR_Err += current_block->advance_rate;
|
||||||
LA_phase = 0;
|
LA_phase = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -882,11 +883,13 @@ FORCE_INLINE void isr() {
|
||||||
advance_spread(main_Rate);
|
advance_spread(main_Rate);
|
||||||
if (LA_phase >= 0) {
|
if (LA_phase >= 0) {
|
||||||
if (step_loops == e_step_loops)
|
if (step_loops == e_step_loops)
|
||||||
LA_phase = (eISR_Rate > main_Rate);
|
LA_phase = (current_block->advance_rate < main_Rate);
|
||||||
else {
|
else {
|
||||||
// avoid overflow through division. warning: we need to _guarantee_ step_loops
|
// avoid overflow through division. warning: we need to _guarantee_ step_loops
|
||||||
// and e_step_loops are <= 4 due to fastdiv's limit
|
// and e_step_loops are <= 4 due to fastdiv's limit
|
||||||
LA_phase = (fastdiv(eISR_Rate, step_loops) > fastdiv(main_Rate, e_step_loops));
|
auto adv_rate_n = fastdiv(current_block->advance_rate, step_loops);
|
||||||
|
auto main_rate_n = fastdiv(main_Rate, e_step_loops);
|
||||||
|
LA_phase = (adv_rate_n < main_rate_n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -928,26 +931,34 @@ FORCE_INLINE void isr() {
|
||||||
FORCE_INLINE void advance_isr() {
|
FORCE_INLINE void advance_isr() {
|
||||||
if (current_adv_steps > target_adv_steps) {
|
if (current_adv_steps > target_adv_steps) {
|
||||||
// decompression
|
// decompression
|
||||||
|
if (e_step_loops != 1) {
|
||||||
|
uint16_t d_steps = current_adv_steps - target_adv_steps;
|
||||||
|
if (d_steps < e_step_loops)
|
||||||
|
e_step_loops = d_steps;
|
||||||
|
}
|
||||||
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);
|
||||||
if(current_adv_steps > e_step_loops)
|
current_adv_steps -= e_step_loops;
|
||||||
current_adv_steps -= e_step_loops;
|
|
||||||
else
|
|
||||||
current_adv_steps = 0;
|
|
||||||
nextAdvanceISR = eISR_Rate;
|
|
||||||
}
|
}
|
||||||
else if (current_adv_steps < target_adv_steps) {
|
else if (current_adv_steps < target_adv_steps) {
|
||||||
// compression
|
// compression
|
||||||
|
if (e_step_loops != 1) {
|
||||||
|
uint16_t d_steps = target_adv_steps - current_adv_steps;
|
||||||
|
if (d_steps < e_step_loops)
|
||||||
|
e_step_loops = d_steps;
|
||||||
|
}
|
||||||
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);
|
||||||
current_adv_steps += e_step_loops;
|
current_adv_steps += e_step_loops;
|
||||||
nextAdvanceISR = eISR_Rate;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (current_adv_steps == target_adv_steps) {
|
||||||
// advance steps completed
|
// advance steps completed
|
||||||
nextAdvanceISR = ADV_NEVER;
|
nextAdvanceISR = ADV_NEVER;
|
||||||
LA_phase = -1;
|
}
|
||||||
e_step_loops = 1;
|
else {
|
||||||
|
// schedule another tick
|
||||||
|
nextAdvanceISR = eISR_Rate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1017,7 +1028,7 @@ FORCE_INLINE void advance_isr_scheduler() {
|
||||||
|
|
||||||
// Schedule the next closest tick, ignoring advance if scheduled too
|
// Schedule the next closest tick, ignoring advance if scheduled too
|
||||||
// soon in order to avoid skewing the regular stepper acceleration
|
// soon in order to avoid skewing the regular stepper acceleration
|
||||||
if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + TCNT1 + 40) < nextMainISR)
|
if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + 40) < nextMainISR)
|
||||||
OCR1A = nextAdvanceISR;
|
OCR1A = nextAdvanceISR;
|
||||||
else
|
else
|
||||||
OCR1A = nextMainISR;
|
OCR1A = nextMainISR;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue