Skip to content

Commit 460ece8

Browse files
committed
backport TMC2208 linear advance fix
MarlinFirmware/Marlin#24533
1 parent e7b2bad commit 460ece8

File tree

4 files changed

+231
-277
lines changed

4 files changed

+231
-277
lines changed

Marlin/src/module/planner.cpp

+37-38
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
784784
NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE));
785785
NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
786786

787-
#if ENABLED(S_CURVE_ACCELERATION)
787+
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
788788
uint32_t cruise_rate = initial_rate;
789789
#endif
790790

@@ -805,12 +805,12 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
805805
accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
806806
plateau_steps = 0;
807807

808-
#if ENABLED(S_CURVE_ACCELERATION)
808+
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
809809
// We won't reach the cruising rate. Let's calculate the speed we will reach
810810
cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
811811
#endif
812812
}
813-
#if ENABLED(S_CURVE_ACCELERATION)
813+
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
814814
else // We have some plateau time, so the cruise rate will be the nominal rate
815815
cruise_rate = block->nominal_rate;
816816
#endif
@@ -837,6 +837,14 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
837837
#endif
838838
block->final_rate = final_rate;
839839

840+
#if ENABLED(LIN_ADVANCE)
841+
if (block->la_advance_rate) {
842+
const float comp = extruder_advance_K[block->extruder] * block->steps.e / block->step_event_count;
843+
block->max_adv_steps = cruise_rate * comp;
844+
block->final_adv_steps = final_rate * comp;
845+
}
846+
#endif
847+
840848
/**
841849
* Laser trapezoid calculations
842850
*
@@ -1183,13 +1191,6 @@ void Planner::recalculate_trapezoids() {
11831191
const float current_nominal_speed = SQRT(block->nominal_speed_sqr),
11841192
nomr = 1.0f / current_nominal_speed;
11851193
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
1186-
#if ENABLED(LIN_ADVANCE)
1187-
if (block->use_advance_lead) {
1188-
const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
1189-
block->max_adv_steps = current_nominal_speed * comp;
1190-
block->final_adv_steps = next_entry_speed * comp;
1191-
}
1192-
#endif
11931194
}
11941195

11951196
// Reset current only to ensure next trapezoid is computed - The
@@ -1222,13 +1223,6 @@ void Planner::recalculate_trapezoids() {
12221223
const float next_nominal_speed = SQRT(next->nominal_speed_sqr),
12231224
nomr = 1.0f / next_nominal_speed;
12241225
calculate_trapezoid_for_block(next, next_entry_speed * nomr, float(MINIMUM_PLANNER_SPEED) * nomr);
1225-
#if ENABLED(LIN_ADVANCE)
1226-
if (next->use_advance_lead) {
1227-
const float comp = next->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
1228-
next->max_adv_steps = next_nominal_speed * comp;
1229-
next->final_adv_steps = (MINIMUM_PLANNER_SPEED) * comp;
1230-
}
1231-
#endif
12321226
}
12331227

12341228
// Reset next only to ensure its trapezoid is computed - The stepper is free to use
@@ -2282,9 +2276,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
22822276
// Compute and limit the acceleration rate for the trapezoid generator.
22832277
const float steps_per_mm = block->step_event_count * inverse_millimeters;
22842278
uint32_t accel;
2279+
#if ENABLED(LIN_ADVANCE)
2280+
bool use_advance_lead = false;
2281+
#endif
22852282
if (!block->steps.a && !block->steps.b && !block->steps.c) { // Is this a retract / recover move?
22862283
accel = CEIL(settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2
2287-
TERN_(LIN_ADVANCE, block->use_advance_lead = false); // No linear advance for simple retract/recover
22882284
}
22892285
else {
22902286
#define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
@@ -2317,27 +2313,23 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
23172313
*
23182314
* de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
23192315
*/
2320-
block->use_advance_lead = esteps
2321-
&& extruder_advance_K[active_extruder]
2322-
&& de > 0;
2323-
2324-
if (block->use_advance_lead) {
2325-
block->e_D_ratio = (target_float.e - position_float.e) /
2326-
#if IS_KINEMATIC
2327-
block->millimeters
2328-
#else
2316+
use_advance_lead = esteps && extruder_advance_K[extruder] && de > 0;
2317+
2318+
if (use_advance_lead) {
2319+
float e_D_ratio = (target_float.e - position_float.e) /
2320+
TERN(IS_KINEMATIC, block->millimeters,
23292321
SQRT(sq(target_float.x - position_float.x)
23302322
+ sq(target_float.y - position_float.y)
23312323
+ sq(target_float.z - position_float.z))
2332-
#endif
2333-
;
2324+
);
23342325

23352326
// 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!
23362327
// This assumes no one will use a retract length of 0mm < retr_length < ~0.2mm and no one will print 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
2337-
if (block->e_D_ratio > 3.0f)
2338-
block->use_advance_lead = false;
2328+
if (e_D_ratio > 3.0f)
2329+
use_advance_lead = false;
23392330
else {
2340-
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[active_extruder] * block->e_D_ratio) * steps_per_mm;
2331+
// Scale E acceleration so that it will be possible to jump to the advance speed.
2332+
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[extruder] * e_D_ratio) * steps_per_mm;
23412333
if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
23422334
SERIAL_ECHOLNPGM("Acceleration limited.");
23432335
NOMORE(accel, max_accel_steps_per_s2);
@@ -2365,13 +2357,20 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
23652357
block->acceleration_rate = (uint32_t)(accel * (sq(4096.0f) / (STEPPER_TIMER_RATE)));
23662358
#endif
23672359
#if ENABLED(LIN_ADVANCE)
2368-
if (block->use_advance_lead) {
2369-
block->advance_speed = (STEPPER_TIMER_RATE) / (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * settings.axis_steps_per_mm[E_AXIS_N(extruder)]);
2360+
block->la_advance_rate = 0;
2361+
block->la_scaling = 0;
2362+
2363+
if (use_advance_lead) {
2364+
// the Bresenham algorithm will convert this step rate into extruder steps
2365+
block->la_advance_rate = extruder_advance_K[extruder] * block->acceleration_steps_per_s2;
2366+
2367+
// reduce LA ISR frequency by calling it only often enough to ensure that there will
2368+
// never be more than four extruder steps per call
2369+
for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
2370+
block->la_scaling++;
23702371
#if ENABLED(LA_DEBUG)
2371-
if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio)
2372-
SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
2373-
if (block->advance_speed < 200)
2374-
SERIAL_ECHOLNPGM("eISR running at > 10kHz.");
2372+
if (block->la_advance_rate >> block->la_scaling > 10000)
2373+
SERIAL_ECHOLNPGM("eISR running at > 10kHz: ", block->la_advance_rate);
23752374
#endif
23762375
}
23772376
#endif

Marlin/src/module/planner.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,10 @@ typedef struct block_t {
210210

211211
// Advance extrusion
212212
#if ENABLED(LIN_ADVANCE)
213-
bool use_advance_lead;
214-
uint16_t advance_speed, // STEP timer value for extruder speed offset ISR
215-
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
216-
final_adv_steps; // advance steps due to exit speed
217-
float e_D_ratio;
213+
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
214+
uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
215+
uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure
216+
final_adv_steps; // Advance steps for exit speed pressure
218217
#endif
219218

220219
uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
@@ -977,7 +976,7 @@ class Planner
977976
return target_velocity_sqr - 2 * accel * distance;
978977
}
979978

980-
#if ENABLED(S_CURVE_ACCELERATION)
979+
#if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
981980
/**
982981
* Calculate the speed reached given initial speed, acceleration and distance
983982
*/

0 commit comments

Comments
 (0)