Procházet zdrojové kódy

♻️ Planner flags refactor

Scott Lahteine před 1 rokem
rodič
revize
307dfb15ca

+ 1
- 1
Marlin/src/gcode/motion/G2_G3.cpp Zobrazit soubor

@@ -315,7 +315,7 @@ void plan_arc(
315 315
         // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
316 316
         // To reduce stuttering, the sin and cos could be computed at different times.
317 317
         // For now, compute both at the same time.
318
-        const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment);
318
+        const float Ti = i * theta_per_segment, cos_Ti = cos(Ti), sin_Ti = sin(Ti);
319 319
         rvec.a = -offset[0] * cos_Ti + offset[1] * sin_Ti;
320 320
         rvec.b = -offset[0] * sin_Ti - offset[1] * cos_Ti;
321 321
       }

+ 1
- 1
Marlin/src/gcode/motion/G6.cpp Zobrazit soubor

@@ -50,7 +50,7 @@ void GcodeSuite::G6() {
50 50
   // No speed is set, can't schedule the move
51 51
   if (!planner.last_page_step_rate) return;
52 52
 
53
-  const page_idx_t page_idx = (page_idx_t) parser.value_ulong();
53
+  const page_idx_t page_idx = (page_idx_t)parser.value_ulong();
54 54
 
55 55
   uint16_t num_steps = DirectStepping::Config::TOTAL_STEPS;
56 56
   if (parser.seen('S')) num_steps = parser.value_ushort();

+ 2
- 2
Marlin/src/gcode/temp/M106_M107.cpp Zobrazit soubor

@@ -90,7 +90,7 @@ void GcodeSuite::M106() {
90 90
   // Set speed, with constraint
91 91
   thermalManager.set_fan_speed(pfan, speed);
92 92
 
93
-  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
93
+  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_BIT_SYNC_FANS));
94 94
 
95 95
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
96 96
     thermalManager.set_fan_speed(1 - pfan, speed);
@@ -111,7 +111,7 @@ void GcodeSuite::M107() {
111 111
   if (TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()))  // pfan == 0 when duplicating
112 112
     thermalManager.set_fan_speed(1 - pfan, 0);
113 113
 
114
-  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_FLAG_SYNC_FANS));
114
+  TERN_(LASER_SYNCHRONOUS_M106_M107, planner.buffer_sync_block(BLOCK_BIT_SYNC_FANS));
115 115
 }
116 116
 
117 117
 #endif // HAS_FAN

+ 74
- 81
Marlin/src/module/planner.cpp Zobrazit soubor

@@ -739,7 +739,7 @@ block_t* Planner::get_current_block() {
739 739
     block_t * const block = &block_buffer[block_buffer_tail];
740 740
 
741 741
     // No trapezoid calculated? Don't execute yet.
742
-    if (TEST(block->flag, BLOCK_BIT_RECALCULATE)) return nullptr;
742
+    if (block->flag.recalculate) return nullptr;
743 743
 
744 744
     // We can't be sure how long an active block will take, so don't count it.
745 745
     TERN_(HAS_WIRED_LCD, block_buffer_runtime_us -= block->segment_time_us);
@@ -948,7 +948,7 @@ void Planner::reverse_pass_kernel(block_t * const current, const block_t * const
948 948
 
949 949
     // Compute maximum entry speed decelerating over the current block from its exit speed.
950 950
     // If not at the maximum entry speed, or the previous block entry speed changed
951
-    if (current->entry_speed_sqr != max_entry_speed_sqr || (next && TEST(next->flag, BLOCK_BIT_RECALCULATE))) {
951
+    if (current->entry_speed_sqr != max_entry_speed_sqr || (next && next->flag.recalculate)) {
952 952
 
953 953
       // If nominal length true, max junction speed is guaranteed to be reached.
954 954
       // If a block can de/ac-celerate from nominal speed to zero within the length of the block, then
@@ -958,14 +958,14 @@ void Planner::reverse_pass_kernel(block_t * const current, const block_t * const
958 958
       // the reverse and forward planners, the corresponding block junction speed will always be at the
959 959
       // the maximum junction speed and may always be ignored for any speed reduction checks.
960 960
 
961
-      const float new_entry_speed_sqr = TEST(current->flag, BLOCK_BIT_NOMINAL_LENGTH)
961
+      const float new_entry_speed_sqr = current->flag.nominal_length
962 962
         ? max_entry_speed_sqr
963 963
         : _MIN(max_entry_speed_sqr, max_allowable_speed_sqr(-current->acceleration, next ? next->entry_speed_sqr : sq(float(MINIMUM_PLANNER_SPEED)), current->millimeters));
964 964
       if (current->entry_speed_sqr != new_entry_speed_sqr) {
965 965
 
966 966
         // Need to recalculate the block speed - Mark it now, so the stepper
967 967
         // ISR does not consume the block before being recalculated
968
-        SBI(current->flag, BLOCK_BIT_RECALCULATE);
968
+        current->flag.recalculate = true;
969 969
 
970 970
         // But there is an inherent race condition here, as the block may have
971 971
         // become BUSY just before being marked RECALCULATE, so check for that!
@@ -973,7 +973,7 @@ void Planner::reverse_pass_kernel(block_t * const current, const block_t * const
973 973
           // Block became busy. Clear the RECALCULATE flag (no point in
974 974
           // recalculating BUSY blocks). And don't set its speed, as it can't
975 975
           // be updated at this time.
976
-          CBI(current->flag, BLOCK_BIT_RECALCULATE);
976
+          current->flag.recalculate = false;
977 977
         }
978 978
         else {
979 979
           // Block is not BUSY so this is ahead of the Stepper ISR:
@@ -1011,8 +1011,8 @@ void Planner::reverse_pass() {
1011 1011
     // Perform the reverse pass
1012 1012
     block_t *current = &block_buffer[block_index];
1013 1013
 
1014
-    // Only consider non sync-and-page blocks
1015
-    if (!(current->flag & BLOCK_MASK_SYNC) && !IS_PAGE(current)) {
1014
+    // Only process movement blocks
1015
+    if (current->is_move()) {
1016 1016
       reverse_pass_kernel(current, next);
1017 1017
       next = current;
1018 1018
     }
@@ -1041,8 +1041,7 @@ void Planner::forward_pass_kernel(const block_t * const previous, block_t * cons
1041 1041
     // change, adjust the entry speed accordingly. Entry speeds have already been reset,
1042 1042
     // maximized, and reverse-planned. If nominal length is set, max junction speed is
1043 1043
     // guaranteed to be reached. No need to recheck.
1044
-    if (!TEST(previous->flag, BLOCK_BIT_NOMINAL_LENGTH) &&
1045
-      previous->entry_speed_sqr < current->entry_speed_sqr) {
1044
+    if (!previous->flag.nominal_length && previous->entry_speed_sqr < current->entry_speed_sqr) {
1046 1045
 
1047 1046
       // Compute the maximum allowable speed
1048 1047
       const float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
@@ -1052,7 +1051,7 @@ void Planner::forward_pass_kernel(const block_t * const previous, block_t * cons
1052 1051
 
1053 1052
         // Mark we need to recompute the trapezoidal shape, and do it now,
1054 1053
         // so the stepper ISR does not consume the block before being recalculated
1055
-        SBI(current->flag, BLOCK_BIT_RECALCULATE);
1054
+        current->flag.recalculate = true;
1056 1055
 
1057 1056
         // But there is an inherent race condition here, as the block maybe
1058 1057
         // became BUSY, just before it was marked as RECALCULATE, so check
@@ -1061,7 +1060,7 @@ void Planner::forward_pass_kernel(const block_t * const previous, block_t * cons
1061 1060
           // Block became busy. Clear the RECALCULATE flag (no point in
1062 1061
           //  recalculating BUSY blocks and don't set its speed, as it can't
1063 1062
           //  be updated at this time.
1064
-          CBI(current->flag, BLOCK_BIT_RECALCULATE);
1063
+          current->flag.recalculate = false;
1065 1064
         }
1066 1065
         else {
1067 1066
           // Block is not BUSY, we won the race against the Stepper ISR:
@@ -1106,8 +1105,8 @@ void Planner::forward_pass() {
1106 1105
     // Perform the forward pass
1107 1106
     block = &block_buffer[block_index];
1108 1107
 
1109
-    // Skip SYNC and page blocks
1110
-    if (!(block->flag & BLOCK_MASK_SYNC) && !IS_PAGE(block)) {
1108
+    // Only process movement blocks
1109
+    if (block->is_move()) {
1111 1110
       // If there's no previous block or the previous block is not
1112 1111
       // BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
1113 1112
       // the previous block became BUSY, so assume the current block's
@@ -1131,9 +1130,10 @@ void Planner::recalculate_trapezoids() {
1131 1130
   // The tail may be changed by the ISR so get a local copy.
1132 1131
   uint8_t block_index = block_buffer_tail,
1133 1132
           head_block_index = block_buffer_head;
1134
-  // Since there could be a sync block in the head of the queue, and the
1133
+
1134
+  // Since there could be non-move blocks in the head of the queue, and the
1135 1135
   // next loop must not recalculate the head block (as it needs to be
1136
-  // specially handled), scan backwards to the first non-SYNC block.
1136
+  // specially handled), scan backwards to the first move block.
1137 1137
   while (head_block_index != block_index) {
1138 1138
 
1139 1139
     // Go back (head always point to the first free block)
@@ -1142,8 +1142,8 @@ void Planner::recalculate_trapezoids() {
1142 1142
     // Get the pointer to the block
1143 1143
     block_t *prev = &block_buffer[prev_index];
1144 1144
 
1145
-    // If not dealing with a sync block, we are done. The last block is not a SYNC block
1146
-    if (!(prev->flag & BLOCK_MASK_SYNC)) break;
1145
+    // It the block is a move, we're done with this loop
1146
+    if (prev->is_move()) break;
1147 1147
 
1148 1148
     // Examine the previous block. This and all following are SYNC blocks
1149 1149
     head_block_index = prev_index;
@@ -1156,18 +1156,17 @@ void Planner::recalculate_trapezoids() {
1156 1156
 
1157 1157
     next = &block_buffer[block_index];
1158 1158
 
1159
-    // Skip sync and page blocks
1160
-    if (!(next->flag & BLOCK_MASK_SYNC) && !IS_PAGE(next)) {
1159
+    // Only process movement blocks
1160
+    if (next->is_move()) {
1161 1161
       next_entry_speed = SQRT(next->entry_speed_sqr);
1162 1162
 
1163 1163
       if (block) {
1164
-        // Recalculate if current block entry or exit junction speed has changed.
1165
-        if (TEST(block->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE)) {
1166 1164
 
1167
-          // Mark the current block as RECALCULATE, to protect it from the Stepper ISR running it.
1168
-          // Note that due to the above condition, there's a chance the current block isn't marked as
1169
-          // RECALCULATE yet, but the next one is. That's the reason for the following line.
1170
-          SBI(block->flag, BLOCK_BIT_RECALCULATE);
1165
+        // If the next block is marked to RECALCULATE, also mark the previously-fetched one
1166
+        if (next->flag.recalculate) block->flag.recalculate = true;
1167
+
1168
+        // Recalculate if current block entry or exit junction speed has changed.
1169
+        if (block->flag.recalculate) {
1171 1170
 
1172 1171
           // But there is an inherent race condition here, as the block maybe
1173 1172
           // became BUSY, just before it was marked as RECALCULATE, so check
@@ -1190,7 +1189,7 @@ void Planner::recalculate_trapezoids() {
1190 1189
 
1191 1190
           // Reset current only to ensure next trapezoid is computed - The
1192 1191
           // stepper is free to use the block from now on.
1193
-          CBI(block->flag, BLOCK_BIT_RECALCULATE);
1192
+          block->flag.recalculate = false;
1194 1193
         }
1195 1194
       }
1196 1195
 
@@ -1204,10 +1203,10 @@ void Planner::recalculate_trapezoids() {
1204 1203
   // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
1205 1204
   if (next) {
1206 1205
 
1207
-    // Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it.
1206
+    // Mark the last block as RECALCULATE, to prevent the Stepper ISR running it.
1208 1207
     // As the last block is always recalculated here, there is a chance the block isn't
1209 1208
     // marked as RECALCULATE yet. That's the reason for the following line.
1210
-    SBI(next->flag, BLOCK_BIT_RECALCULATE);
1209
+    block->flag.recalculate = true;
1211 1210
 
1212 1211
     // But there is an inherent race condition here, as the block maybe
1213 1212
     // became BUSY, just before it was marked as RECALCULATE, so check
@@ -1229,7 +1228,7 @@ void Planner::recalculate_trapezoids() {
1229 1228
 
1230 1229
     // Reset next only to ensure its trapezoid is computed - The stepper is free to use
1231 1230
     // the block from now on.
1232
-    CBI(next->flag, BLOCK_BIT_RECALCULATE);
1231
+    next->flag.recalculate = false;
1233 1232
   }
1234 1233
 }
1235 1234
 
@@ -1460,7 +1459,7 @@ void Planner::check_axes_activity() {
1460 1459
     for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
1461 1460
       const block_t * const block = &block_buffer[b];
1462 1461
       if (NUM_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k, || block->steps.u, || block->steps.v, || block->steps.w)) {
1463
-        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
1462
+        const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec
1464 1463
         NOLESS(high, se);
1465 1464
       }
1466 1465
     }
@@ -1782,7 +1781,7 @@ void Planner::synchronize() { while (busy()) idle(); }
1782 1781
 bool Planner::_buffer_steps(const xyze_long_t &target
1783 1782
   OPTARG(HAS_POSITION_FLOAT, const xyze_pos_t &target_float)
1784 1783
   OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
1785
-  , feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters
1784
+  , feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters/*=0.0*/
1786 1785
 ) {
1787 1786
 
1788 1787
   // Wait for the next available block
@@ -1796,10 +1795,11 @@ bool Planner::_buffer_steps(const xyze_long_t &target
1796 1795
 
1797 1796
   // Fill the block with the specified movement
1798 1797
   if (!_populate_block(block, false, target
1799
-    OPTARG(HAS_POSITION_FLOAT, target_float)
1800
-    OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
1801
-    , fr_mm_s, extruder, millimeters
1802
-  )) {
1798
+        OPTARG(HAS_POSITION_FLOAT, target_float)
1799
+        OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
1800
+        , fr_mm_s, extruder, millimeters
1801
+      )
1802
+  ) {
1803 1803
     // Movement was not queued, probably because it was too short.
1804 1804
     //  Simply accept that as movement queued and done
1805 1805
     return true;
@@ -1856,36 +1856,8 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
1856 1856
   );
1857 1857
 
1858 1858
   /* <-- add a slash to enable
1859
-    SERIAL_ECHOLNPGM(
1860
-      "  _populate_block FR:", fr_mm_s,
1861
-      " A:", target.a, " (", da, " steps)"
1862
-      #if HAS_Y_AXIS
1863
-        " B:", target.b, " (", db, " steps)"
1864
-      #endif
1865
-      #if HAS_Z_AXIS
1866
-        " C:", target.c, " (", dc, " steps)"
1867
-      #endif
1868
-      #if HAS_I_AXIS
1869
-        " " STR_I ":", target.i, " (", di, " steps)"
1870
-      #endif
1871
-      #if HAS_J_AXIS
1872
-        " " STR_J ":", target.j, " (", dj, " steps)"
1873
-      #endif
1874
-      #if HAS_K_AXIS
1875
-        " " STR_K ":", target.k, " (", dk, " steps)"
1876
-      #endif
1877
-      #if HAS_U_AXIS
1878
-        " " STR_U ":", target.u, " (", du, " steps)"
1879
-      #endif
1880
-      #if HAS_V_AXIS
1881
-        " " STR_V ":", target.v, " (", dv, " steps)"
1882
-      #endif
1883
-      #if HAS_W_AXIS
1884
-        " " STR_W ":", target.w, " (", dw, " steps)"
1885
-      #if HAS_EXTRUDERS
1886
-        " E:", target.e, " (", de, " steps)"
1887
-      #endif
1888
-    );
1859
+    #define _ALINE(A) " " STR_##A  ":", target[_AXIS(A)], " (", int32_t(target[_AXIS(A)] - position[_AXIS(A)]), " steps)"
1860
+    SERIAL_ECHOLNPGM("  _populate_block FR:", fr_mm_s, LOGICAL_AXIS_MAP(_ALINE));
1889 1861
   //*/
1890 1862
 
1891 1863
   #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
@@ -1978,7 +1950,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
1978 1950
   #endif
1979 1951
 
1980 1952
   // Clear all flags, including the "busy" bit
1981
-  block->flag = 0x00;
1953
+  block->flag.clear();
1982 1954
 
1983 1955
   // Set direction bits
1984 1956
   block->direction_bits = dm;
@@ -2449,7 +2421,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2449 2421
   if (speed_factor < 1.0f) {
2450 2422
     current_speed *= speed_factor;
2451 2423
     block->nominal_rate *= speed_factor;
2452
-    block->nominal_speed_sqr = block->nominal_speed_sqr * sq(speed_factor);
2424
+    block->nominal_speed_sqr *= sq(speed_factor);
2453 2425
   }
2454 2426
 
2455 2427
   // Compute and limit the acceleration rate for the trapezoid generator.
@@ -2651,14 +2623,15 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2651 2623
         vmax_junction_sqr = sq(float(MINIMUM_PLANNER_SPEED));
2652 2624
       }
2653 2625
       else {
2654
-        NOLESS(junction_cos_theta, -0.999999f); // Check for numerical round-off to avoid divide by zero.
2655
-
2656 2626
         // Convert delta vector to unit vector
2657 2627
         xyze_float_t junction_unit_vec = unit_vec - prev_unit_vec;
2658 2628
         normalize_junction_vector(junction_unit_vec);
2659 2629
 
2660
-        const float junction_acceleration = limit_value_by_axis_maximum(block->acceleration, junction_unit_vec),
2661
-                    sin_theta_d2 = SQRT(0.5f * (1.0f - junction_cos_theta)); // Trig half angle identity. Always positive.
2630
+        const float junction_acceleration = limit_value_by_axis_maximum(block->acceleration, junction_unit_vec);
2631
+
2632
+        NOLESS(junction_cos_theta, -0.999999f); // Check for numerical round-off to avoid divide by zero.
2633
+
2634
+        const float sin_theta_d2 = SQRT(0.5f * (1.0f - junction_cos_theta)); // Trig half angle identity. Always positive.
2662 2635
 
2663 2636
         vmax_junction_sqr = junction_acceleration * junction_deviation_mm * sin_theta_d2 / (1.0f - sin_theta_d2);
2664 2637
 
@@ -2888,7 +2861,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2888 2861
   // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
2889 2862
   // the reverse and forward planners, the corresponding block junction speed will always be at the
2890 2863
   // the maximum junction speed and may always be ignored for any speed reduction checks.
2891
-  block->flag |= block->nominal_speed_sqr <= v_allowable_sqr ? BLOCK_FLAG_RECALCULATE | BLOCK_FLAG_NOMINAL_LENGTH : BLOCK_FLAG_RECALCULATE;
2864
+  block->flag.set_nominal(block->nominal_speed_sqr <= v_allowable_sqr);
2892 2865
 
2893 2866
   // Update previous path unit_vector and nominal speed
2894 2867
   previous_speed = current_speed;
@@ -2913,9 +2886,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
2913 2886
  * Add a block to the buffer that just updates the position,
2914 2887
  * or in case of LASER_SYNCHRONOUS_M106_M107 the fan PWM
2915 2888
  */
2916
-void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag)) {
2889
+void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, const BlockFlagBit sync_flag/*=BLOCK_BIT_SYNC_POSITION*/)) {
2917 2890
   #if DISABLED(LASER_SYNCHRONOUS_M106_M107)
2918
-    constexpr uint8_t sync_flag = BLOCK_FLAG_SYNC_POSITION;
2891
+    constexpr BlockFlagBit sync_flag = BLOCK_BIT_SYNC_POSITION;
2919 2892
   #endif
2920 2893
 
2921 2894
   // Wait for the next available block
@@ -2925,7 +2898,7 @@ void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_
2925 2898
   // Clear block
2926 2899
   memset(block, 0, sizeof(block_t));
2927 2900
 
2928
-  block->flag = sync_flag;
2901
+  block->flag.apply(sync_flag);
2929 2902
 
2930 2903
   block->position = position;
2931 2904
   #if ENABLED(BACKLASH_COMPENSATION)
@@ -3073,8 +3046,8 @@ bool Planner::buffer_segment(const abce_pos_t &abce
3073 3046
   if (!_buffer_steps(target
3074 3047
       OPTARG(HAS_POSITION_FLOAT, target_float)
3075 3048
       OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
3076
-      , fr_mm_s, extruder, millimeters)
3077
-  ) return false;
3049
+      , fr_mm_s, extruder, millimeters
3050
+  )) return false;
3078 3051
 
3079 3052
   stepper.wake_up();
3080 3053
   return true;
@@ -3141,6 +3114,14 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
3141 3114
 
3142 3115
 #if ENABLED(DIRECT_STEPPING)
3143 3116
 
3117
+  /**
3118
+   * @brief Add a direct stepping page block to the buffer
3119
+   *        and wake up the Stepper ISR to process it.
3120
+   *
3121
+   * @param page_idx Page index provided by G6 I<index>
3122
+   * @param extruder The extruder to use in the move
3123
+   * @param num_steps Number of steps to process in the ISR
3124
+   */
3144 3125
   void Planner::buffer_page(const page_idx_t page_idx, const uint8_t extruder, const uint16_t num_steps) {
3145 3126
     if (!last_page_step_rate) {
3146 3127
       kill(GET_TEXT_F(MSG_BAD_PAGE_SPEED));
@@ -3150,7 +3131,7 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
3150 3131
     uint8_t next_buffer_head;
3151 3132
     block_t * const block = get_next_free_block(next_buffer_head);
3152 3133
 
3153
-    block->flag = BLOCK_FLAG_IS_PAGE;
3134
+    block->flag.reset(BLOCK_BIT_PAGE);
3154 3135
 
3155 3136
     #if HAS_FAN
3156 3137
       FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
@@ -3238,6 +3219,12 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
3238 3219
   }
3239 3220
 }
3240 3221
 
3222
+/**
3223
+ * @brief Set the Planner position in mm
3224
+ * @details Set the Planner position from a native machine position in mm
3225
+ *
3226
+ * @param xyze A native (Cartesian) machine position
3227
+ */
3241 3228
 void Planner::set_position_mm(const xyze_pos_t &xyze) {
3242 3229
   xyze_pos_t machine = xyze;
3243 3230
   TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine, true));
@@ -3273,7 +3260,13 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) {
3273 3260
 
3274 3261
 #endif
3275 3262
 
3276
-// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
3263
+/**
3264
+ * @brief Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
3265
+ * @details Update planner movement factors after a change to certain settings:
3266
+ *          - max_acceleration_steps_per_s2 from settings max_acceleration_mm_per_s2 * axis_steps_per_mm (M201, M92)
3267
+ *          - acceleration_long_cutoff based on the largest max_acceleration_steps_per_s2 (M201)
3268
+ *          - max_e_jerk for all extruders based on junction_deviation_mm (M205 J)
3269
+ */
3277 3270
 void Planner::reset_acceleration_rates() {
3278 3271
   uint32_t highest_rate = 1;
3279 3272
   LOOP_DISTINCT_AXES(i) {
@@ -3286,8 +3279,8 @@ void Planner::reset_acceleration_rates() {
3286 3279
 }
3287 3280
 
3288 3281
 /**
3289
- * Recalculate 'position' and 'mm_per_step'.
3290
- * Must be called whenever settings.axis_steps_per_mm changes!
3282
+ * @brief Recalculate 'position' and 'mm_per_step'.
3283
+ * @details Required whenever settings.axis_steps_per_mm changes!
3291 3284
  */
3292 3285
 void Planner::refresh_positioning() {
3293 3286
   LOOP_DISTINCT_AXES(i) mm_per_step[i] = 1.0f / settings.axis_steps_per_mm[i];

+ 65
- 43
Marlin/src/module/planner.h Zobrazit soubor

@@ -70,9 +70,6 @@
70 70
 
71 71
 #if ENABLED(DIRECT_STEPPING)
72 72
   #include "../feature/direct_stepping.h"
73
-  #define IS_PAGE(B) TEST(B->flag, BLOCK_BIT_IS_PAGE)
74
-#else
75
-  #define IS_PAGE(B) false
76 73
 #endif
77 74
 
78 75
 #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
@@ -92,7 +89,34 @@
92 89
   #define HAS_DIST_MM_ARG 1
93 90
 #endif
94 91
 
95
-enum BlockFlagBit : char {
92
+#if ENABLED(LASER_POWER_INLINE)
93
+
94
+  typedef struct {
95
+    bool isPlanned:1;
96
+    bool isEnabled:1;
97
+    bool dir:1;
98
+    bool Reserved:6;
99
+  } power_status_t;
100
+
101
+  typedef struct {
102
+    power_status_t status;    // See planner settings for meaning
103
+    uint8_t power;            // Ditto; When in trapezoid mode this is nominal power
104
+    #if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
105
+      uint8_t   power_entry;  // Entry power for the laser
106
+      #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
107
+        uint8_t   power_exit; // Exit power for the laser
108
+        uint32_t  entry_per,  // Steps per power increment (to avoid floats in stepper calcs)
109
+                  exit_per;   // Steps per power decrement
110
+      #endif
111
+    #endif
112
+  } block_laser_t;
113
+
114
+#endif
115
+
116
+/**
117
+ * Planner block flags as boolean bit fields
118
+ */
119
+enum BlockFlagBit {
96 120
   // Recalculate trapezoids on entry junction. For optimization.
97 121
   BLOCK_BIT_RECALCULATE,
98 122
 
@@ -109,7 +133,7 @@ enum BlockFlagBit : char {
109 133
 
110 134
   // Direct stepping page
111 135
   #if ENABLED(DIRECT_STEPPING)
112
-    , BLOCK_BIT_IS_PAGE
136
+    , BLOCK_BIT_PAGE
113 137
   #endif
114 138
 
115 139
   // Sync the fan speeds from the block
@@ -118,57 +142,55 @@ enum BlockFlagBit : char {
118 142
   #endif
119 143
 };
120 144
 
121
-enum BlockFlag : char {
122
-    BLOCK_FLAG_RECALCULATE          = _BV(BLOCK_BIT_RECALCULATE)
123
-  , BLOCK_FLAG_NOMINAL_LENGTH       = _BV(BLOCK_BIT_NOMINAL_LENGTH)
124
-  , BLOCK_FLAG_CONTINUED            = _BV(BLOCK_BIT_CONTINUED)
125
-  , BLOCK_FLAG_SYNC_POSITION        = _BV(BLOCK_BIT_SYNC_POSITION)
126
-  #if ENABLED(DIRECT_STEPPING)
127
-    , BLOCK_FLAG_IS_PAGE            = _BV(BLOCK_BIT_IS_PAGE)
128
-  #endif
129
-  #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
130
-    , BLOCK_FLAG_SYNC_FANS          = _BV(BLOCK_BIT_SYNC_FANS)
131
-  #endif
132
-};
145
+/**
146
+ * Planner block flags as boolean bit fields
147
+ */
148
+typedef struct {
149
+  union {
150
+    uint8_t bits;
133 151
 
134
-#define BLOCK_MASK_SYNC ( BLOCK_FLAG_SYNC_POSITION | TERN0(LASER_SYNCHRONOUS_M106_M107, BLOCK_FLAG_SYNC_FANS) )
152
+    struct {
153
+      bool recalculate:1;
135 154
 
136
-#if ENABLED(LASER_POWER_INLINE)
155
+      bool nominal_length:1;
137 156
 
138
-  typedef struct {
139
-    bool isPlanned:1;
140
-    bool isEnabled:1;
141
-    bool dir:1;
142
-    bool Reserved:6;
143
-  } power_status_t;
157
+      bool continued:1;
144 158
 
145
-  typedef struct {
146
-    power_status_t status;    // See planner settings for meaning
147
-    uint8_t power;            // Ditto; When in trapezoid mode this is nominal power
148
-    #if ENABLED(LASER_POWER_INLINE_TRAPEZOID)
149
-      uint8_t   power_entry;  // Entry power for the laser
150
-      #if DISABLED(LASER_POWER_INLINE_TRAPEZOID_CONT)
151
-        uint8_t   power_exit; // Exit power for the laser
152
-        uint32_t  entry_per,  // Steps per power increment (to avoid floats in stepper calcs)
153
-                  exit_per;   // Steps per power decrement
159
+      bool sync_position:1;
160
+
161
+      #if ENABLED(DIRECT_STEPPING)
162
+        bool page:1;
154 163
       #endif
155
-    #endif
156
-  } block_laser_t;
157 164
 
158
-#endif
165
+      #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
166
+        bool sync_fans:1;
167
+      #endif
168
+    };
169
+  };
170
+
171
+  void clear() volatile { bits = 0; }
172
+  void apply(const uint8_t f) volatile { bits |= f; }
173
+  void apply(const BlockFlagBit b) volatile { SBI(bits, b); }
174
+  void reset(const BlockFlagBit b) volatile { bits = _BV(b); }
175
+  void set_nominal(const bool n) volatile { recalculate = true; if (n) nominal_length = true; }
176
+
177
+} block_flags_t;
159 178
 
160 179
 /**
161
- * struct block_t
162
- *
163
- * A single entry in the planner buffer.
164
- * Tracks linear movement over multiple axes.
180
+ * A single entry in the planner buffer, used to set up and
181
+ * track a coordinated linear motion for one or more axes.
165 182
  *
166 183
  * The "nominal" values are as-specified by G-code, and
167 184
  * may never actually be reached due to acceleration limits.
168 185
  */
169 186
 typedef struct block_t {
170 187
 
171
-  volatile uint8_t flag;                    // Block flags (See BlockFlag enum above) - Modified by ISR and main thread!
188
+  volatile block_flags_t flag;              // Block flags
189
+
190
+  volatile bool is_fan_sync() { return TERN0(LASER_SYNCHRONOUS_M106_M107, flag.sync_fans); }
191
+  volatile bool is_sync() { return flag.sync_position || is_fan_sync(); }
192
+  volatile bool is_page() { return TERN0(DIRECT_STEPPING, flag.page); }
193
+  volatile bool is_move() { return !(is_sync() || is_page()); }
172 194
 
173 195
   // Fields used by the motion planner to manage acceleration
174 196
   float nominal_speed_sqr,                  // The nominal speed for this block in (mm/sec)^2
@@ -759,7 +781,7 @@ class Planner {
759 781
      * case of LASER_SYNCHRONOUS_M106_M107 the fan pwm
760 782
      */
761 783
     static void buffer_sync_block(
762
-      TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_flag=BLOCK_FLAG_SYNC_POSITION)
784
+      TERN_(LASER_SYNCHRONOUS_M106_M107, const BlockFlagBit flag=BLOCK_BIT_SYNC_POSITION)
763 785
     );
764 786
 
765 787
   #if IS_KINEMATIC

+ 9
- 12
Marlin/src/module/stepper.cpp Zobrazit soubor

@@ -1699,7 +1699,7 @@ void Stepper::pulse_phase_isr() {
1699 1699
     }while(0)
1700 1700
 
1701 1701
     // Direct Stepping page?
1702
-    const bool is_page = IS_PAGE(current_block);
1702
+    const bool is_page = current_block->is_page();
1703 1703
 
1704 1704
     #if ENABLED(DIRECT_STEPPING)
1705 1705
       // Direct stepping is currently not ready for HAS_I_AXIS
@@ -1977,7 +1977,7 @@ uint32_t Stepper::block_phase_isr() {
1977 1977
             count_position[_AXIS(AXIS)] += page_step_state.bd[_AXIS(AXIS)] * count_direction[_AXIS(AXIS)];
1978 1978
         #endif
1979 1979
 
1980
-        if (IS_PAGE(current_block)) {
1980
+        if (current_block->is_page()) {
1981 1981
           PAGE_SEGMENT_UPDATE_POS(X);
1982 1982
           PAGE_SEGMENT_UPDATE_POS(Y);
1983 1983
           PAGE_SEGMENT_UPDATE_POS(Z);
@@ -2167,16 +2167,13 @@ uint32_t Stepper::block_phase_isr() {
2167 2167
     if ((current_block = planner.get_current_block())) {
2168 2168
 
2169 2169
       // Sync block? Sync the stepper counts or fan speeds and return
2170
-      while (current_block->flag & BLOCK_MASK_SYNC) {
2170
+      while (current_block->is_sync()) {
2171 2171
 
2172
-        #if ENABLED(LASER_SYNCHRONOUS_M106_M107)
2173
-          const bool is_sync_fans = TEST(current_block->flag, BLOCK_BIT_SYNC_FANS);
2174
-          if (is_sync_fans) planner.sync_fan_speeds(current_block->fan_speed);
2175
-        #else
2176
-          constexpr bool is_sync_fans = false;
2177
-        #endif
2178
-
2179
-        if (!is_sync_fans) _set_position(current_block->position);
2172
+        if (current_block->is_fan_sync()) {
2173
+          TERN_(LASER_SYNCHRONOUS_M106_M107, planner.sync_fan_speeds(current_block->fan_speed));
2174
+        }
2175
+        else
2176
+          _set_position(current_block->position);
2180 2177
 
2181 2178
         discard_current_block();
2182 2179
 
@@ -2196,7 +2193,7 @@ uint32_t Stepper::block_phase_isr() {
2196 2193
       #endif
2197 2194
 
2198 2195
       #if ENABLED(DIRECT_STEPPING)
2199
-        if (IS_PAGE(current_block)) {
2196
+        if (current_block->is_page()) {
2200 2197
           page_step_state.segment_steps = 0;
2201 2198
           page_step_state.segment_idx = 0;
2202 2199
           page_step_state.page = page_manager.get_page(current_block->page_idx);

+ 1
- 2
Marlin/src/module/stepper.h Zobrazit soubor

@@ -524,8 +524,7 @@ class Stepper {
524 524
     // Discard current block and free any resources
525 525
     FORCE_INLINE static void discard_current_block() {
526 526
       #if ENABLED(DIRECT_STEPPING)
527
-        if (IS_PAGE(current_block))
528
-          page_manager.free_page(current_block->page_idx);
527
+        if (current_block->is_page()) page_manager.free_page(current_block->page_idx);
529 528
       #endif
530 529
       current_block = nullptr;
531 530
       axis_did_move = 0;

Loading…
Zrušit
Uložit