瀏覽代碼

Fix, improve Linear Advance (#24533)

tombrazier 2 年之前
父節點
當前提交
232a104a92
沒有連結到貢獻者的電子郵件帳戶。
共有 4 個檔案被更改,包括 305 行新增351 行删除
  1. 110
    109
      Marlin/src/module/planner.cpp
  2. 5
    6
      Marlin/src/module/planner.h
  3. 180
    171
      Marlin/src/module/stepper.cpp
  4. 10
    65
      Marlin/src/module/stepper.h

+ 110
- 109
Marlin/src/module/planner.cpp 查看文件

788
   NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE));
788
   NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE));
789
   NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
789
   NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
790
 
790
 
791
-  #if ENABLED(S_CURVE_ACCELERATION)
791
+  #if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
792
     // If we have some plateau time, the cruise rate will be the nominal rate
792
     // If we have some plateau time, the cruise rate will be the nominal rate
793
     uint32_t cruise_rate = block->nominal_rate;
793
     uint32_t cruise_rate = block->nominal_rate;
794
   #endif
794
   #endif
820
       accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
820
       accelerate_steps = _MIN(uint32_t(_MAX(accelerate_steps_float, 0)), block->step_event_count);
821
       decelerate_steps = block->step_event_count - accelerate_steps;
821
       decelerate_steps = block->step_event_count - accelerate_steps;
822
 
822
 
823
-      #if ENABLED(S_CURVE_ACCELERATION)
823
+      #if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
824
         // We won't reach the cruising rate. Let's calculate the speed we will reach
824
         // We won't reach the cruising rate. Let's calculate the speed we will reach
825
         cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
825
         cruise_rate = final_speed(initial_rate, accel, accelerate_steps);
826
       #endif
826
       #endif
849
   #endif
849
   #endif
850
   block->final_rate = final_rate;
850
   block->final_rate = final_rate;
851
 
851
 
852
+  #if ENABLED(LIN_ADVANCE)
853
+    if (block->la_advance_rate) {
854
+      const float comp = extruder_advance_K[block->extruder] * block->steps.e / block->step_event_count;
855
+      block->max_adv_steps = cruise_rate * comp;
856
+      block->final_adv_steps = final_rate * comp;
857
+    }
858
+  #endif
859
+
852
   #if ENABLED(LASER_POWER_TRAP)
860
   #if ENABLED(LASER_POWER_TRAP)
853
     /**
861
     /**
854
      * Laser Trapezoid Calculations
862
      * Laser Trapezoid Calculations
899
   #endif // LASER_POWER_TRAP
907
   #endif // LASER_POWER_TRAP
900
 }
908
 }
901
 
909
 
902
-/*                            PLANNER SPEED DEFINITION
903
-                                     +--------+   <- current->nominal_speed
904
-                                    /          \
905
-         current->entry_speed ->   +            \
906
-                                   |             + <- next->entry_speed (aka exit speed)
907
-                                   +-------------+
908
-                                       time -->
909
-
910
-  Recalculates the motion plan according to the following basic guidelines:
911
-
912
-    1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
913
-        (i.e. current->entry_speed) such that:
914
-      a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
915
-         neighboring blocks.
916
-      b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
917
-         with a maximum allowable deceleration over the block travel distance.
918
-      c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
919
-    2. Go over every block in chronological (forward) order and dial down junction speed values if
920
-      a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
921
-         acceleration over the block travel distance.
922
-
923
-  When these stages are complete, the planner will have maximized the velocity profiles throughout the all
924
-  of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
925
-  other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
926
-  are possible. If a new block is added to the buffer, the plan is recomputed according to the said
927
-  guidelines for a new optimal plan.
928
-
929
-  To increase computational efficiency of these guidelines, a set of planner block pointers have been
930
-  created to indicate stop-compute points for when the planner guidelines cannot logically make any further
931
-  changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
932
-  planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
933
-  bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
934
-  added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
935
-  them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
936
-  point) are all accelerating, they are all optimal and can not be altered by a new block added to the
937
-  planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
938
-  junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
939
-  used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
940
-  recomputed as stated in the general guidelines.
941
-
942
-  Planner buffer index mapping:
943
-  - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
944
-  - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
945
-      the buffer is full or empty. As described for standard ring buffers, this block is always empty.
946
-  - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
947
-      streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
948
-      planner buffer that don't change with the addition of a new block, as describe above. In addition,
949
-      this block can never be less than block_buffer_tail and will always be pushed forward and maintain
950
-      this requirement when encountered by the Planner::release_current_block() routine during a cycle.
951
-
952
-  NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
953
-        segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
954
-        enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and
955
-        then decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this
956
-        happens and becomes an annoyance, there are a few simple solutions:
957
-
958
-    - Maximize the machine acceleration. The planner will be able to compute higher velocity profiles
959
-      within the same combined distance.
960
-
961
-    - Maximize line motion(s) distance per block to a desired tolerance. The more combined distance the
962
-      planner has to use, the faster it can go.
963
-
964
-    - Maximize the planner buffer size. This also will increase the combined distance for the planner to
965
-      compute over. It also increases the number of computations the planner has to perform to compute an
966
-      optimal plan, so select carefully.
967
-
968
-    - Use G2/G3 arcs instead of many short segments. Arcs inform the planner of a safe exit speed at the
969
-      end of the last segment, which alleviates this problem.
970
-*/
910
+/**
911
+ *                              PLANNER SPEED DEFINITION
912
+ *                                     +--------+   <- current->nominal_speed
913
+ *                                    /          \
914
+ *         current->entry_speed ->   +            \
915
+ *                                   |             + <- next->entry_speed (aka exit speed)
916
+ *                                   +-------------+
917
+ *                                       time -->
918
+ *
919
+ *  Recalculates the motion plan according to the following basic guidelines:
920
+ *
921
+ *    1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
922
+ *        (i.e. current->entry_speed) such that:
923
+ *      a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
924
+ *         neighboring blocks.
925
+ *      b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
926
+ *         with a maximum allowable deceleration over the block travel distance.
927
+ *      c. The last (or newest appended) block is planned from a complete stop (an exit speed of zero).
928
+ *    2. Go over every block in chronological (forward) order and dial down junction speed values if
929
+ *      a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
930
+ *         acceleration over the block travel distance.
931
+ *
932
+ *  When these stages are complete, the planner will have maximized the velocity profiles throughout the all
933
+ *  of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
934
+ *  other words, for all of the blocks in the planner, the plan is optimal and no further speed improvements
935
+ *  are possible. If a new block is added to the buffer, the plan is recomputed according to the said
936
+ *  guidelines for a new optimal plan.
937
+ *
938
+ *  To increase computational efficiency of these guidelines, a set of planner block pointers have been
939
+ *  created to indicate stop-compute points for when the planner guidelines cannot logically make any further
940
+ *  changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
941
+ *  planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
942
+ *  bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
943
+ *  added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
944
+ *  them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
945
+ *  point) are all accelerating, they are all optimal and can not be altered by a new block added to the
946
+ *  planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
947
+ *  junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
948
+ *  used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
949
+ *  recomputed as stated in the general guidelines.
950
+ *
951
+ *  Planner buffer index mapping:
952
+ *  - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
953
+ *  - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
954
+ *      the buffer is full or empty. As described for standard ring buffers, this block is always empty.
955
+ *  - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
956
+ *      streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
957
+ *      planner buffer that don't change with the addition of a new block, as describe above. In addition,
958
+ *      this block can never be less than block_buffer_tail and will always be pushed forward and maintain
959
+ *      this requirement when encountered by the Planner::release_current_block() routine during a cycle.
960
+ *
961
+ *  NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
962
+ *        segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
963
+ *        enough combined distance traveled in the entire buffer to accelerate up to the nominal speed and
964
+ *        then decelerate to a complete stop at the end of the buffer, as stated by the guidelines. If this
965
+ *        happens and becomes an annoyance, there are a few simple solutions:
966
+ *
967
+ *    - Maximize the machine acceleration. The planner will be able to compute higher velocity profiles
968
+ *      within the same combined distance.
969
+ *
970
+ *    - Maximize line motion(s) distance per block to a desired tolerance. The more combined distance the
971
+ *      planner has to use, the faster it can go.
972
+ *
973
+ *    - Maximize the planner buffer size. This also will increase the combined distance for the planner to
974
+ *      compute over. It also increases the number of computations the planner has to perform to compute an
975
+ *      optimal plan, so select carefully.
976
+ *
977
+ *    - Use G2/G3 arcs instead of many short segments. Arcs inform the planner of a safe exit speed at the
978
+ *      end of the last segment, which alleviates this problem.
979
+ */
971
 
980
 
972
 // The kernel called by recalculate() when scanning the plan from last to first entry.
981
 // The kernel called by recalculate() when scanning the plan from last to first entry.
973
 void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next
982
 void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next
1211
             // NOTE: Entry and exit factors always > 0 by all previous logic operations.
1220
             // NOTE: Entry and exit factors always > 0 by all previous logic operations.
1212
             const float nomr = 1.0f / block->nominal_speed;
1221
             const float nomr = 1.0f / block->nominal_speed;
1213
             calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
1222
             calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
1214
-            #if ENABLED(LIN_ADVANCE)
1215
-              if (block->use_advance_lead) {
1216
-                const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
1217
-                block->max_adv_steps = block->nominal_speed * comp;
1218
-                block->final_adv_steps = next_entry_speed * comp;
1219
-              }
1220
-            #endif
1221
           }
1223
           }
1222
 
1224
 
1223
           // Reset current only to ensure next trapezoid is computed - The
1225
           // Reset current only to ensure next trapezoid is computed - The
1251
 
1253
 
1252
       const float nomr = 1.0f / block->nominal_speed;
1254
       const float nomr = 1.0f / block->nominal_speed;
1253
       calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
1255
       calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
1254
-      #if ENABLED(LIN_ADVANCE)
1255
-        if (block->use_advance_lead) {
1256
-          const float comp = block->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
1257
-          block->max_adv_steps = block->nominal_speed * comp;
1258
-          block->final_adv_steps = next_entry_speed * comp;
1259
-        }
1260
-      #endif
1261
     }
1256
     }
1262
 
1257
 
1263
     // Reset block to ensure its trapezoid is computed - The stepper is free to use
1258
     // Reset block to ensure its trapezoid is computed - The stepper is free to use
2502
   // Compute and limit the acceleration rate for the trapezoid generator.
2497
   // Compute and limit the acceleration rate for the trapezoid generator.
2503
   const float steps_per_mm = block->step_event_count * inverse_millimeters;
2498
   const float steps_per_mm = block->step_event_count * inverse_millimeters;
2504
   uint32_t accel;
2499
   uint32_t accel;
2500
+  #if ENABLED(LIN_ADVANCE)
2501
+    bool use_advance_lead = false;
2502
+  #endif
2505
   if (NUM_AXIS_GANG(
2503
   if (NUM_AXIS_GANG(
2506
          !block->steps.a, && !block->steps.b, && !block->steps.c,
2504
          !block->steps.a, && !block->steps.b, && !block->steps.c,
2507
       && !block->steps.i, && !block->steps.j, && !block->steps.k,
2505
       && !block->steps.i, && !block->steps.j, && !block->steps.k,
2508
       && !block->steps.u, && !block->steps.v, && !block->steps.w)
2506
       && !block->steps.u, && !block->steps.v, && !block->steps.w)
2509
   ) {                                                             // Is this a retract / recover move?
2507
   ) {                                                             // Is this a retract / recover move?
2510
     accel = CEIL(settings.retract_acceleration * steps_per_mm);   // Convert to: acceleration steps/sec^2
2508
     accel = CEIL(settings.retract_acceleration * steps_per_mm);   // Convert to: acceleration steps/sec^2
2511
-    TERN_(LIN_ADVANCE, block->use_advance_lead = false);          // No linear advance for simple retract/recover
2512
   }
2509
   }
2513
   else {
2510
   else {
2514
     #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
2511
     #define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
2535
       /**
2532
       /**
2536
        * Use LIN_ADVANCE for blocks if all these are true:
2533
        * Use LIN_ADVANCE for blocks if all these are true:
2537
        *
2534
        *
2538
-       * esteps             : This is a print move, because we checked for A, B, C steps before.
2535
+       * esteps                       : This is a print move, because we checked for A, B, C steps before.
2539
        *
2536
        *
2540
-       * extruder_advance_K[active_extruder] : There is an advance factor set for this extruder.
2537
+       * extruder_advance_K[extruder] : There is an advance factor set for this extruder.
2541
        *
2538
        *
2542
-       * de > 0             : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
2539
+       * de > 0                       : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
2543
        */
2540
        */
2544
-      block->use_advance_lead =  esteps
2545
-                              && extruder_advance_K[active_extruder]
2546
-                              && de > 0;
2547
-
2548
-      if (block->use_advance_lead) {
2549
-        block->e_D_ratio = (target_float.e - position_float.e) /
2550
-          #if IS_KINEMATIC
2551
-            block->millimeters
2552
-          #else
2541
+      use_advance_lead = esteps && extruder_advance_K[extruder] && de > 0;
2542
+
2543
+      if (use_advance_lead) {
2544
+        float e_D_ratio = (target_float.e - position_float.e) /
2545
+          TERN(IS_KINEMATIC, block->millimeters,
2553
             SQRT(sq(target_float.x - position_float.x)
2546
             SQRT(sq(target_float.x - position_float.x)
2554
                + sq(target_float.y - position_float.y)
2547
                + sq(target_float.y - position_float.y)
2555
                + sq(target_float.z - position_float.z))
2548
                + sq(target_float.z - position_float.z))
2556
-          #endif
2557
-        ;
2549
+          );
2558
 
2550
 
2559
         // 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!
2551
         // 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!
2560
         // 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.
2552
         // 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.
2561
-        if (block->e_D_ratio > 3.0f)
2562
-          block->use_advance_lead = false;
2553
+        if (e_D_ratio > 3.0f)
2554
+          use_advance_lead = false;
2563
         else {
2555
         else {
2564
-          const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[active_extruder] * block->e_D_ratio) * steps_per_mm;
2556
+          // Scale E acceleration so that it will be possible to jump to the advance speed.
2557
+          const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[extruder] * e_D_ratio) * steps_per_mm;
2565
           if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
2558
           if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
2566
             SERIAL_ECHOLNPGM("Acceleration limited.");
2559
             SERIAL_ECHOLNPGM("Acceleration limited.");
2567
           NOMORE(accel, max_accel_steps_per_s2);
2560
           NOMORE(accel, max_accel_steps_per_s2);
2593
     block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
2586
     block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
2594
   #endif
2587
   #endif
2595
   #if ENABLED(LIN_ADVANCE)
2588
   #if ENABLED(LIN_ADVANCE)
2596
-    if (block->use_advance_lead) {
2597
-      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)]);
2589
+    block->la_advance_rate = 0;
2590
+    block->la_scaling = 0;
2591
+
2592
+    if (use_advance_lead) {
2593
+      // the Bresenham algorithm will convert this step rate into extruder steps
2594
+      block->la_advance_rate = extruder_advance_K[extruder] * block->acceleration_steps_per_s2;
2595
+
2596
+      // reduce LA ISR frequency by calling it only often enough to ensure that there will
2597
+      // never be more than four extruder steps per call
2598
+      for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
2599
+        block->la_scaling++;
2600
+
2598
       #if ENABLED(LA_DEBUG)
2601
       #if ENABLED(LA_DEBUG)
2599
-        if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < block->nominal_speed * block->e_D_ratio)
2600
-          SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
2601
-        if (block->advance_speed < 200)
2602
-          SERIAL_ECHOLNPGM("eISR running at > 10kHz.");
2602
+        if (block->la_advance_rate >> block->la_scaling > 10000)
2603
+          SERIAL_ECHOLNPGM("eISR running at > 10kHz: ", block->la_advance_rate);
2603
       #endif
2604
       #endif
2604
     }
2605
     }
2605
   #endif
2606
   #endif

+ 5
- 6
Marlin/src/module/planner.h 查看文件

239
 
239
 
240
   // Advance extrusion
240
   // Advance extrusion
241
   #if ENABLED(LIN_ADVANCE)
241
   #if ENABLED(LIN_ADVANCE)
242
-    bool use_advance_lead;
243
-    uint16_t advance_speed,                 // STEP timer value for extruder speed offset ISR
244
-             max_adv_steps,                 // max. advance steps to get cruising speed pressure (not always nominal_speed!)
245
-             final_adv_steps;               // advance steps due to exit speed
246
-    float e_D_ratio;
242
+    uint32_t la_advance_rate;               // The rate at which steps are added whilst accelerating
243
+    uint8_t  la_scaling;                    // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
244
+    uint16_t max_adv_steps,                 // Max advance steps to get cruising speed pressure
245
+             final_adv_steps;               // Advance steps for exit speed pressure
247
   #endif
246
   #endif
248
 
247
 
249
   uint32_t nominal_rate,                    // The nominal step rate for this block in step_events/sec
248
   uint32_t nominal_rate,                    // The nominal step rate for this block in step_events/sec
1018
       return target_velocity_sqr - 2 * accel * distance;
1017
       return target_velocity_sqr - 2 * accel * distance;
1019
     }
1018
     }
1020
 
1019
 
1021
-    #if ENABLED(S_CURVE_ACCELERATION)
1020
+    #if EITHER(S_CURVE_ACCELERATION, LIN_ADVANCE)
1022
       /**
1021
       /**
1023
        * Calculate the speed reached given initial speed, acceleration and distance
1022
        * Calculate the speed reached given initial speed, acceleration and distance
1024
        */
1023
        */

+ 180
- 171
Marlin/src/module/stepper.cpp 查看文件

217
 #endif
217
 #endif
218
 
218
 
219
 #if ENABLED(LIN_ADVANCE)
219
 #if ENABLED(LIN_ADVANCE)
220
-
221
   uint32_t Stepper::nextAdvanceISR = LA_ADV_NEVER,
220
   uint32_t Stepper::nextAdvanceISR = LA_ADV_NEVER,
222
-           Stepper::LA_isr_rate = LA_ADV_NEVER;
223
-  uint16_t Stepper::LA_current_adv_steps = 0,
224
-           Stepper::LA_final_adv_steps,
225
-           Stepper::LA_max_adv_steps;
226
-
227
-  int8_t   Stepper::LA_steps = 0;
228
-
229
-  bool Stepper::LA_use_advance_lead;
230
-
231
-#endif // LIN_ADVANCE
221
+           Stepper::la_interval = LA_ADV_NEVER;
222
+  int32_t  Stepper::la_delta_error = 0,
223
+           Stepper::la_dividend = 0,
224
+           Stepper::la_advance_steps = 0;
225
+#endif
232
 
226
 
233
 #if ENABLED(INTEGRATED_BABYSTEPPING)
227
 #if ENABLED(INTEGRATED_BABYSTEPPING)
234
   uint32_t Stepper::nextBabystepISR = BABYSTEP_NEVER;
228
   uint32_t Stepper::nextBabystepISR = BABYSTEP_NEVER;
588
   TERN_(HAS_V_DIR, SET_STEP_DIR(V));
582
   TERN_(HAS_V_DIR, SET_STEP_DIR(V));
589
   TERN_(HAS_W_DIR, SET_STEP_DIR(W));
583
   TERN_(HAS_W_DIR, SET_STEP_DIR(W));
590
 
584
 
591
-  #if DISABLED(LIN_ADVANCE)
592
-    #if ENABLED(MIXING_EXTRUDER)
593
-       // Because this is valid for the whole block we don't know
594
-       // what E steppers will step. Likely all. Set all.
595
-      if (motor_direction(E_AXIS)) {
596
-        MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
597
-        count_direction.e = -1;
598
-      }
599
-      else {
600
-        MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
601
-        count_direction.e = 1;
602
-      }
603
-    #elif HAS_EXTRUDERS
604
-      if (motor_direction(E_AXIS)) {
605
-        REV_E_DIR(stepper_extruder);
606
-        count_direction.e = -1;
607
-      }
608
-      else {
609
-        NORM_E_DIR(stepper_extruder);
610
-        count_direction.e = 1;
611
-      }
612
-    #endif
613
-  #endif // !LIN_ADVANCE
585
+  #if ENABLED(MIXING_EXTRUDER)
586
+     // Because this is valid for the whole block we don't know
587
+     // what E steppers will step. Likely all. Set all.
588
+    if (motor_direction(E_AXIS)) {
589
+      MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
590
+      count_direction.e = -1;
591
+    }
592
+    else {
593
+      MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
594
+      count_direction.e = 1;
595
+    }
596
+  #elif HAS_EXTRUDERS
597
+    if (motor_direction(E_AXIS)) {
598
+      REV_E_DIR(stepper_extruder);
599
+      count_direction.e = -1;
600
+    }
601
+    else {
602
+      NORM_E_DIR(stepper_extruder);
603
+      count_direction.e = 1;
604
+    }
605
+  #endif
614
 
606
 
615
   DIR_WAIT_AFTER();
607
   DIR_WAIT_AFTER();
616
 }
608
 }
1467
     // Enable ISRs to reduce USART processing latency
1459
     // Enable ISRs to reduce USART processing latency
1468
     hal.isr_on();
1460
     hal.isr_on();
1469
 
1461
 
1470
-    if (!nextMainISR) pulse_phase_isr();                    // 0 = Do coordinated axes Stepper pulses
1462
+    if (!nextMainISR) pulse_phase_isr();                // 0 = Do coordinated axes Stepper pulses
1471
 
1463
 
1472
     #if ENABLED(LIN_ADVANCE)
1464
     #if ENABLED(LIN_ADVANCE)
1473
-      if (!nextAdvanceISR) nextAdvanceISR = advance_isr();  // 0 = Do Linear Advance E Stepper pulses
1465
+      if (!nextAdvanceISR) {                            // 0 = Do Linear Advance E Stepper pulses
1466
+        advance_isr();
1467
+        nextAdvanceISR = la_interval;
1468
+      }
1469
+      else if (nextAdvanceISR == LA_ADV_NEVER)          // Start LA steps if necessary
1470
+        nextAdvanceISR = la_interval;
1474
     #endif
1471
     #endif
1475
 
1472
 
1476
     #if ENABLED(INTEGRATED_BABYSTEPPING)
1473
     #if ENABLED(INTEGRATED_BABYSTEPPING)
1477
-      const bool is_babystep = (nextBabystepISR == 0);      // 0 = Do Babystepping (XY)Z pulses
1474
+      const bool is_babystep = (nextBabystepISR == 0);  // 0 = Do Babystepping (XY)Z pulses
1478
       if (is_babystep) nextBabystepISR = babystepping_isr();
1475
       if (is_babystep) nextBabystepISR = babystepping_isr();
1479
     #endif
1476
     #endif
1480
 
1477
 
1796
         PULSE_PREP(W);
1793
         PULSE_PREP(W);
1797
       #endif
1794
       #endif
1798
 
1795
 
1799
-      #if EITHER(LIN_ADVANCE, MIXING_EXTRUDER)
1800
-        delta_error.e += advance_dividend.e;
1801
-        if (delta_error.e >= 0) {
1802
-          #if ENABLED(LIN_ADVANCE)
1803
-            delta_error.e -= advance_divisor;
1804
-            // Don't step E here - But remember the number of steps to perform
1805
-            motor_direction(E_AXIS) ? --LA_steps : ++LA_steps;
1806
-          #else
1807
-            count_position.e += count_direction.e;
1808
-            step_needed.e = true;
1809
-          #endif
1810
-        }
1811
-      #elif HAS_E0_STEP
1796
+      #if EITHER(HAS_E0_STEP, MIXING_EXTRUDER)
1812
         PULSE_PREP(E);
1797
         PULSE_PREP(E);
1798
+
1799
+        #if ENABLED(LIN_ADVANCE)
1800
+          if (step_needed.e && current_block->la_advance_rate) {
1801
+            // don't actually step here, but do subtract movements steps
1802
+            // from the linear advance step count
1803
+            step_needed.e = false;
1804
+            count_position.e -= count_direction.e;
1805
+            la_advance_steps--;
1806
+          }
1807
+        #endif
1813
       #endif
1808
       #endif
1814
     }
1809
     }
1815
 
1810
 
1849
       PULSE_START(W);
1844
       PULSE_START(W);
1850
     #endif
1845
     #endif
1851
 
1846
 
1852
-    #if DISABLED(LIN_ADVANCE)
1853
-      #if ENABLED(MIXING_EXTRUDER)
1854
-        if (step_needed.e) E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
1855
-      #elif HAS_E0_STEP
1856
-        PULSE_START(E);
1857
-      #endif
1847
+    #if ENABLED(MIXING_EXTRUDER)
1848
+      if (step_needed.e) E_STEP_WRITE(mixer.get_next_stepper(), !INVERT_E_STEP_PIN);
1849
+    #elif HAS_E0_STEP
1850
+      PULSE_START(E);
1858
     #endif
1851
     #endif
1859
 
1852
 
1860
     TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
1853
     TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
1894
       PULSE_STOP(W);
1887
       PULSE_STOP(W);
1895
     #endif
1888
     #endif
1896
 
1889
 
1897
-    #if DISABLED(LIN_ADVANCE)
1898
-      #if ENABLED(MIXING_EXTRUDER)
1899
-        if (delta_error.e >= 0) {
1900
-          delta_error.e -= advance_divisor;
1901
-          E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
1902
-        }
1903
-      #elif HAS_E0_STEP
1904
-        PULSE_STOP(E);
1905
-      #endif
1890
+    #if ENABLED(MIXING_EXTRUDER)
1891
+      if (step_needed.e) E_STEP_WRITE(mixer.get_stepper(), INVERT_E_STEP_PIN);
1892
+    #elif HAS_E0_STEP
1893
+      PULSE_STOP(E);
1906
     #endif
1894
     #endif
1907
 
1895
 
1908
     #if ISR_MULTI_STEPS
1896
     #if ISR_MULTI_STEPS
1912
   } while (--events_to_do);
1900
   } while (--events_to_do);
1913
 }
1901
 }
1914
 
1902
 
1903
+// Calculate timer interval, with all limits applied.
1904
+uint32_t Stepper::calc_timer_interval(uint32_t step_rate) {
1905
+  #ifdef CPU_32_BIT
1906
+    // In case of high-performance processor, it is able to calculate in real-time
1907
+    return uint32_t(STEPPER_TIMER_RATE) / step_rate;
1908
+  #else
1909
+    // AVR is able to keep up at 30khz Stepping ISR rate.
1910
+    constexpr uint32_t min_step_rate = (F_CPU) / 500000U;
1911
+    if (step_rate <= min_step_rate) {
1912
+      step_rate = 0;
1913
+      uintptr_t table_address = (uintptr_t)&speed_lookuptable_slow[0][0];
1914
+      return uint16_t(pgm_read_word(table_address));
1915
+    }
1916
+    else {
1917
+      step_rate -= min_step_rate; // Correct for minimal speed
1918
+      if (step_rate >= 0x0800) {  // higher step rate
1919
+        const uint8_t rate_mod_256 = (step_rate & 0x00FF);
1920
+        const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)][0]),
1921
+                        gain = uint16_t(pgm_read_word(table_address + 2));
1922
+        return uint16_t(pgm_read_word(table_address)) - MultiU16X8toH16(rate_mod_256, gain);
1923
+      }
1924
+      else { // lower step rates
1925
+        uintptr_t table_address = uintptr_t(&speed_lookuptable_slow[0][0]);
1926
+        table_address += (step_rate >> 1) & 0xFFFC;
1927
+        return uint16_t(pgm_read_word(table_address))
1928
+               - ((uint16_t(pgm_read_word(table_address + 2)) * uint8_t(step_rate & 0x0007)) >> 3);
1929
+      }
1930
+    }
1931
+  #endif
1932
+}
1933
+
1934
+// Get the timer interval and the number of loops to perform per tick
1935
+uint32_t Stepper::calc_timer_interval(uint32_t step_rate, uint8_t &loops) {
1936
+  uint8_t multistep = 1;
1937
+  #if DISABLED(DISABLE_MULTI_STEPPING)
1938
+
1939
+    // The stepping frequency limits for each multistepping rate
1940
+    static const uint32_t limit[] PROGMEM = {
1941
+      (  MAX_STEP_ISR_FREQUENCY_1X     ),
1942
+      (  MAX_STEP_ISR_FREQUENCY_2X >> 1),
1943
+      (  MAX_STEP_ISR_FREQUENCY_4X >> 2),
1944
+      (  MAX_STEP_ISR_FREQUENCY_8X >> 3),
1945
+      ( MAX_STEP_ISR_FREQUENCY_16X >> 4),
1946
+      ( MAX_STEP_ISR_FREQUENCY_32X >> 5),
1947
+      ( MAX_STEP_ISR_FREQUENCY_64X >> 6),
1948
+      (MAX_STEP_ISR_FREQUENCY_128X >> 7)
1949
+    };
1950
+
1951
+    // Select the proper multistepping
1952
+    uint8_t idx = 0;
1953
+    while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
1954
+      step_rate >>= 1;
1955
+      multistep <<= 1;
1956
+      ++idx;
1957
+    };
1958
+  #else
1959
+    NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
1960
+  #endif
1961
+  loops = multistep;
1962
+
1963
+  return calc_timer_interval(step_rate);
1964
+}
1965
+
1915
 // This is the last half of the stepper interrupt: This one processes and
1966
 // This is the last half of the stepper interrupt: This one processes and
1916
 // properly schedules blocks from the planner. This is executed after creating
1967
 // properly schedules blocks from the planner. This is executed after creating
1917
 // the step pulses, so it is not time critical, as pulses are already done.
1968
 // the step pulses, so it is not time critical, as pulses are already done.
1964
         // acc_step_rate is in steps/second
2015
         // acc_step_rate is in steps/second
1965
 
2016
 
1966
         // step_rate to timer interval and steps per stepper isr
2017
         // step_rate to timer interval and steps per stepper isr
1967
-        interval = calc_timer_interval(acc_step_rate, &steps_per_isr);
2018
+        interval = calc_timer_interval(acc_step_rate << oversampling_factor, steps_per_isr);
1968
         acceleration_time += interval;
2019
         acceleration_time += interval;
1969
 
2020
 
1970
         #if ENABLED(LIN_ADVANCE)
2021
         #if ENABLED(LIN_ADVANCE)
1971
-          if (LA_use_advance_lead) {
1972
-            // Fire ISR if final adv_rate is reached
1973
-            if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
2022
+          if (current_block->la_advance_rate) {
2023
+            const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
2024
+            la_interval = calc_timer_interval(acc_step_rate + la_step_rate) << current_block->la_scaling;
1974
           }
2025
           }
1975
-          else if (LA_steps) nextAdvanceISR = 0;
1976
         #endif
2026
         #endif
1977
 
2027
 
1978
         /**
2028
         /**
2035
         #endif
2085
         #endif
2036
 
2086
 
2037
         // step_rate to timer interval and steps per stepper isr
2087
         // step_rate to timer interval and steps per stepper isr
2038
-        interval = calc_timer_interval(step_rate, &steps_per_isr);
2088
+        interval = calc_timer_interval(step_rate << oversampling_factor, steps_per_isr);
2039
         deceleration_time += interval;
2089
         deceleration_time += interval;
2040
 
2090
 
2041
         #if ENABLED(LIN_ADVANCE)
2091
         #if ENABLED(LIN_ADVANCE)
2042
-          if (LA_use_advance_lead) {
2043
-            // Wake up eISR on first deceleration loop and fire ISR if final adv_rate is reached
2044
-            if (step_events_completed <= decelerate_after + steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
2045
-              initiateLA();
2046
-              LA_isr_rate = current_block->advance_speed;
2092
+          if (current_block->la_advance_rate) {
2093
+            const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
2094
+            if (la_step_rate != step_rate) {
2095
+              bool reverse_e = la_step_rate > step_rate;
2096
+              la_interval = calc_timer_interval(reverse_e ? la_step_rate - step_rate : step_rate - la_step_rate) << current_block->la_scaling;
2097
+
2098
+              if (reverse_e != motor_direction(E_AXIS)) {
2099
+                TBI(last_direction_bits, E_AXIS);
2100
+                count_direction.e = -count_direction.e;
2101
+
2102
+                DIR_WAIT_BEFORE();
2103
+
2104
+                if (reverse_e) {
2105
+                  #if ENABLED(MIXING_EXTRUDER)
2106
+                    MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
2107
+                  #else
2108
+                    REV_E_DIR(stepper_extruder);
2109
+                  #endif
2110
+                }
2111
+                else {
2112
+                  #if ENABLED(MIXING_EXTRUDER)
2113
+                    MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
2114
+                  #else
2115
+                    NORM_E_DIR(stepper_extruder);
2116
+                  #endif
2117
+                }
2118
+
2119
+                DIR_WAIT_AFTER();
2120
+              }
2047
             }
2121
             }
2048
           }
2122
           }
2049
-          else if (LA_steps) nextAdvanceISR = 0;
2050
         #endif // LIN_ADVANCE
2123
         #endif // LIN_ADVANCE
2051
 
2124
 
2052
         /*
2125
         /*
2069
       }
2142
       }
2070
       else {  // Must be in cruise phase otherwise
2143
       else {  // Must be in cruise phase otherwise
2071
 
2144
 
2072
-        #if ENABLED(LIN_ADVANCE)
2073
-          // If there are any esteps, fire the next advance_isr "now"
2074
-          if (LA_steps && LA_isr_rate != current_block->advance_speed) initiateLA();
2075
-        #endif
2076
-
2077
         // Calculate the ticks_nominal for this nominal speed, if not done yet
2145
         // Calculate the ticks_nominal for this nominal speed, if not done yet
2078
         if (ticks_nominal < 0) {
2146
         if (ticks_nominal < 0) {
2079
           // step_rate to timer interval and loops for the nominal speed
2147
           // step_rate to timer interval and loops for the nominal speed
2080
-          ticks_nominal = calc_timer_interval(current_block->nominal_rate, &steps_per_isr);
2148
+          ticks_nominal = calc_timer_interval(current_block->nominal_rate << oversampling_factor, steps_per_isr);
2149
+
2150
+          #if ENABLED(LIN_ADVANCE)
2151
+            if (current_block->la_advance_rate)
2152
+              la_interval = calc_timer_interval(current_block->nominal_rate) << current_block->la_scaling;
2153
+          #endif
2081
         }
2154
         }
2082
 
2155
 
2083
         // The timer interval is just the nominal value for the nominal speed
2156
         // The timer interval is just the nominal value for the nominal speed
2291
       step_event_count = current_block->step_event_count << oversampling;
2364
       step_event_count = current_block->step_event_count << oversampling;
2292
 
2365
 
2293
       // Initialize Bresenham delta errors to 1/2
2366
       // Initialize Bresenham delta errors to 1/2
2294
-      delta_error = -int32_t(step_event_count);
2367
+      delta_error = TERN_(LIN_ADVANCE, la_delta_error =) -int32_t(step_event_count);
2295
 
2368
 
2296
       // Calculate Bresenham dividends and divisors
2369
       // Calculate Bresenham dividends and divisors
2297
       advance_dividend = current_block->steps << 1;
2370
       advance_dividend = current_block->steps << 1;
2312
       #if ENABLED(LIN_ADVANCE)
2385
       #if ENABLED(LIN_ADVANCE)
2313
         #if DISABLED(MIXING_EXTRUDER) && E_STEPPERS > 1
2386
         #if DISABLED(MIXING_EXTRUDER) && E_STEPPERS > 1
2314
           // If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
2387
           // If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
2315
-          if (stepper_extruder != last_moved_extruder) LA_current_adv_steps = 0;
2388
+          if (stepper_extruder != last_moved_extruder) la_advance_steps = 0;
2316
         #endif
2389
         #endif
2317
-
2318
-        if ((LA_use_advance_lead = current_block->use_advance_lead)) {
2319
-          LA_final_adv_steps = current_block->final_adv_steps;
2320
-          LA_max_adv_steps = current_block->max_adv_steps;
2321
-          initiateLA(); // Start the ISR
2322
-          LA_isr_rate = current_block->advance_speed;
2390
+        if (current_block->la_advance_rate) {
2391
+          // apply LA scaling and discount the effect of frequency scaling
2392
+          la_dividend = (advance_dividend.e << current_block->la_scaling) << oversampling;
2323
         }
2393
         }
2324
-        else LA_isr_rate = LA_ADV_NEVER;
2325
       #endif
2394
       #endif
2326
 
2395
 
2327
       if ( ENABLED(DUAL_X_CARRIAGE) // TODO: Find out why this fixes "jittery" small circles
2396
       if ( ENABLED(DUAL_X_CARRIAGE) // TODO: Find out why this fixes "jittery" small circles
2375
       #endif
2444
       #endif
2376
 
2445
 
2377
       // Calculate the initial timer interval
2446
       // Calculate the initial timer interval
2378
-      interval = calc_timer_interval(current_block->initial_rate, &steps_per_isr);
2447
+      interval = calc_timer_interval(current_block->initial_rate << oversampling_factor, steps_per_isr);
2448
+      acceleration_time += interval;
2449
+
2450
+      #if ENABLED(LIN_ADVANCE)
2451
+        if (current_block->la_advance_rate) {
2452
+          const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
2453
+          la_interval = calc_timer_interval(current_block->initial_rate + la_step_rate) << current_block->la_scaling;
2454
+        }
2455
+      #endif
2379
     }
2456
     }
2380
   }
2457
   }
2381
 
2458
 
2386
 #if ENABLED(LIN_ADVANCE)
2463
 #if ENABLED(LIN_ADVANCE)
2387
 
2464
 
2388
   // Timer interrupt for E. LA_steps is set in the main routine
2465
   // Timer interrupt for E. LA_steps is set in the main routine
2389
-  uint32_t Stepper::advance_isr() {
2390
-    uint32_t interval;
2391
-
2392
-    if (LA_use_advance_lead) {
2393
-      if (step_events_completed > decelerate_after && LA_current_adv_steps > LA_final_adv_steps) {
2394
-        LA_steps--;
2395
-        LA_current_adv_steps--;
2396
-        interval = LA_isr_rate;
2397
-      }
2398
-      else if (step_events_completed < decelerate_after && LA_current_adv_steps < LA_max_adv_steps) {
2399
-        LA_steps++;
2400
-        LA_current_adv_steps++;
2401
-        interval = LA_isr_rate;
2402
-      }
2403
-      else
2404
-        interval = LA_isr_rate = LA_ADV_NEVER;
2405
-    }
2406
-    else
2407
-      interval = LA_ADV_NEVER;
2408
-
2409
-    if (!LA_steps) return interval; // Leave pins alone if there are no steps!
2410
-
2411
-    DIR_WAIT_BEFORE();
2412
-
2413
-    #if ENABLED(MIXING_EXTRUDER)
2414
-      // We don't know which steppers will be stepped because LA loop follows,
2415
-      // with potentially multiple steps. Set all.
2416
-      if (LA_steps > 0) {
2417
-        MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
2418
-        count_direction.e = 1;
2419
-      }
2420
-      else if (LA_steps < 0) {
2421
-        MIXER_STEPPER_LOOP(j) REV_E_DIR(j);
2422
-        count_direction.e = -1;
2423
-      }
2424
-    #else
2425
-      if (LA_steps > 0) {
2426
-        NORM_E_DIR(stepper_extruder);
2427
-        count_direction.e = 1;
2428
-      }
2429
-      else if (LA_steps < 0) {
2430
-        REV_E_DIR(stepper_extruder);
2431
-        count_direction.e = -1;
2432
-      }
2433
-    #endif
2434
-
2435
-    DIR_WAIT_AFTER();
2436
-
2437
-    //const hal_timer_t added_step_ticks = hal_timer_t(ADDED_STEP_TICKS);
2438
-
2439
-    // Step E stepper if we have steps
2440
-    #if ISR_MULTI_STEPS
2441
-      bool firstStep = true;
2442
-      USING_TIMED_PULSE();
2443
-    #endif
2444
-
2445
-    while (LA_steps) {
2446
-      #if ISR_MULTI_STEPS
2447
-        if (firstStep)
2448
-          firstStep = false;
2449
-        else
2450
-          AWAIT_LOW_PULSE();
2451
-      #endif
2452
-
2466
+  void Stepper::advance_isr() {
2467
+    // Apply Bresenham algorithm so that linear advance can piggy back on
2468
+    // the acceleration and speed values calculated in block_phase_isr().
2469
+    // This helps keep LA in sync with, for example, S_CURVE_ACCELERATION.
2470
+    la_delta_error += la_dividend;
2471
+    if (la_delta_error >= 0) {
2453
       count_position.e += count_direction.e;
2472
       count_position.e += count_direction.e;
2473
+      la_advance_steps += count_direction.e;
2474
+      la_delta_error -= advance_divisor;
2454
 
2475
 
2455
       // Set the STEP pulse ON
2476
       // Set the STEP pulse ON
2456
       #if ENABLED(MIXING_EXTRUDER)
2477
       #if ENABLED(MIXING_EXTRUDER)
2461
 
2482
 
2462
       // Enforce a minimum duration for STEP pulse ON
2483
       // Enforce a minimum duration for STEP pulse ON
2463
       #if ISR_PULSE_CONTROL
2484
       #if ISR_PULSE_CONTROL
2485
+        USING_TIMED_PULSE();
2464
         START_HIGH_PULSE();
2486
         START_HIGH_PULSE();
2465
-      #endif
2466
-
2467
-      LA_steps < 0 ? ++LA_steps : --LA_steps;
2468
-
2469
-      #if ISR_PULSE_CONTROL
2470
         AWAIT_HIGH_PULSE();
2487
         AWAIT_HIGH_PULSE();
2471
       #endif
2488
       #endif
2472
 
2489
 
2476
       #else
2493
       #else
2477
         E_STEP_WRITE(stepper_extruder, INVERT_E_STEP_PIN);
2494
         E_STEP_WRITE(stepper_extruder, INVERT_E_STEP_PIN);
2478
       #endif
2495
       #endif
2479
-
2480
-      // For minimum pulse time wait before looping
2481
-      // Just wait for the requested pulse duration
2482
-      #if ISR_PULSE_CONTROL
2483
-        if (LA_steps) START_LOW_PULSE();
2484
-      #endif
2485
-    } // LA_steps
2486
-
2487
-    return interval;
2496
+    }
2488
   }
2497
   }
2489
 
2498
 
2490
 #endif // LIN_ADVANCE
2499
 #endif // LIN_ADVANCE

+ 10
- 65
Marlin/src/module/stepper.h 查看文件

417
 
417
 
418
     #if ENABLED(LIN_ADVANCE)
418
     #if ENABLED(LIN_ADVANCE)
419
       static constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF;
419
       static constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF;
420
-      static uint32_t nextAdvanceISR, LA_isr_rate;
421
-      static uint16_t LA_current_adv_steps, LA_final_adv_steps, LA_max_adv_steps; // Copy from current executed block. Needed because current_block is set to NULL "too early".
422
-      static int8_t LA_steps;
423
-      static bool LA_use_advance_lead;
420
+      static uint32_t nextAdvanceISR,
421
+                      la_interval;      // Interval between ISR calls for LA
422
+      static int32_t  la_delta_error,   // Analogue of delta_error.e for E steps in LA ISR
423
+                      la_dividend,      // Analogue of advance_dividend.e for E steps in LA ISR
424
+                      la_advance_steps; // Count of steps added to increase nozzle pressure
424
     #endif
425
     #endif
425
 
426
 
426
     #if ENABLED(INTEGRATED_BABYSTEPPING)
427
     #if ENABLED(INTEGRATED_BABYSTEPPING)
475
 
476
 
476
     #if ENABLED(LIN_ADVANCE)
477
     #if ENABLED(LIN_ADVANCE)
477
       // The Linear advance ISR phase
478
       // The Linear advance ISR phase
478
-      static uint32_t advance_isr();
479
-      FORCE_INLINE static void initiateLA() { nextAdvanceISR = 0; }
479
+      static void advance_isr();
480
     #endif
480
     #endif
481
 
481
 
482
     #if ENABLED(INTEGRATED_BABYSTEPPING)
482
     #if ENABLED(INTEGRATED_BABYSTEPPING)
512
       current_block = nullptr;
512
       current_block = nullptr;
513
       axis_did_move = 0;
513
       axis_did_move = 0;
514
       planner.release_current_block();
514
       planner.release_current_block();
515
+      TERN_(LIN_ADVANCE, la_interval = nextAdvanceISR = LA_ADV_NEVER);
515
     }
516
     }
516
 
517
 
517
     // Quickly stop all steppers
518
     // Quickly stop all steppers
631
     // Set the current position in steps
632
     // Set the current position in steps
632
     static void _set_position(const abce_long_t &spos);
633
     static void _set_position(const abce_long_t &spos);
633
 
634
 
634
-    FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t *loops) {
635
-      uint32_t timer;
636
-
637
-      // Scale the frequency, as requested by the caller
638
-      step_rate <<= oversampling_factor;
639
-
640
-      uint8_t multistep = 1;
641
-      #if DISABLED(DISABLE_MULTI_STEPPING)
642
-
643
-        // The stepping frequency limits for each multistepping rate
644
-        static const uint32_t limit[] PROGMEM = {
645
-          (  MAX_STEP_ISR_FREQUENCY_1X     ),
646
-          (  MAX_STEP_ISR_FREQUENCY_2X >> 1),
647
-          (  MAX_STEP_ISR_FREQUENCY_4X >> 2),
648
-          (  MAX_STEP_ISR_FREQUENCY_8X >> 3),
649
-          ( MAX_STEP_ISR_FREQUENCY_16X >> 4),
650
-          ( MAX_STEP_ISR_FREQUENCY_32X >> 5),
651
-          ( MAX_STEP_ISR_FREQUENCY_64X >> 6),
652
-          (MAX_STEP_ISR_FREQUENCY_128X >> 7)
653
-        };
654
-
655
-        // Select the proper multistepping
656
-        uint8_t idx = 0;
657
-        while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
658
-          step_rate >>= 1;
659
-          multistep <<= 1;
660
-          ++idx;
661
-        };
662
-      #else
663
-        NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
664
-      #endif
665
-      *loops = multistep;
666
-
667
-      #ifdef CPU_32_BIT
668
-        // In case of high-performance processor, it is able to calculate in real-time
669
-        timer = uint32_t(STEPPER_TIMER_RATE) / step_rate;
670
-      #else
671
-        constexpr uint32_t min_step_rate = (F_CPU) / 500000U;
672
-        NOLESS(step_rate, min_step_rate);
673
-        step_rate -= min_step_rate; // Correct for minimal speed
674
-        if (step_rate >= (8 * 256)) { // higher step rate
675
-          const uint8_t tmp_step_rate = (step_rate & 0x00FF);
676
-          const uint16_t table_address = (uint16_t)&speed_lookuptable_fast[(uint8_t)(step_rate >> 8)][0],
677
-                         gain = (uint16_t)pgm_read_word(table_address + 2);
678
-          timer = MultiU16X8toH16(tmp_step_rate, gain);
679
-          timer = (uint16_t)pgm_read_word(table_address) - timer;
680
-        }
681
-        else { // lower step rates
682
-          uint16_t table_address = (uint16_t)&speed_lookuptable_slow[0][0];
683
-          table_address += ((step_rate) >> 1) & 0xFFFC;
684
-          timer = (uint16_t)pgm_read_word(table_address)
685
-                - (((uint16_t)pgm_read_word(table_address + 2) * (uint8_t)(step_rate & 0x0007)) >> 3);
686
-        }
687
-        // (there is no need to limit the timer value here. All limits have been
688
-        // applied above, and AVR is able to keep up at 30khz Stepping ISR rate)
689
-      #endif
690
-
691
-      return timer;
692
-    }
635
+    // Calculate timing interval for the given step rate
636
+    static uint32_t calc_timer_interval(uint32_t step_rate);
637
+    static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t &loops);
693
 
638
 
694
     #if ENABLED(S_CURVE_ACCELERATION)
639
     #if ENABLED(S_CURVE_ACCELERATION)
695
       static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);
640
       static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);

Loading…
取消
儲存