|
@@ -758,7 +758,11 @@ void Planner::calculate_trapezoid_for_block(block_t* const block, const float &e
|
758
|
758
|
const bool was_enabled = STEPPER_ISR_ENABLED();
|
759
|
759
|
if (was_enabled) DISABLE_STEPPER_DRIVER_INTERRUPT();
|
760
|
760
|
|
761
|
|
- // Don't update variables if block is busy: It is being interpreted by the planner
|
|
761
|
+ // Don't update variables if block is busy; it is being interpreted by the planner.
|
|
762
|
+ // If this happens, there's a problem... The block speed is inconsistent. Some values
|
|
763
|
+ // have already been updated, but the Stepper ISR is already using the block. Fortunately,
|
|
764
|
+ // the values being used by the Stepper ISR weren't touched, so just stop here...
|
|
765
|
+ // TODO: There may be a way to update a running block, depending on the stepper ISR position.
|
762
|
766
|
if (!TEST(block->flag, BLOCK_BIT_BUSY)) {
|
763
|
767
|
block->accelerate_until = accelerate_steps;
|
764
|
768
|
block->decelerate_after = accelerate_steps + plateau_steps;
|
|
@@ -862,10 +866,13 @@ void Planner::reverse_pass_kernel(block_t* const current, const block_t * const
|
862
|
866
|
? max_entry_speed_sqr
|
863
|
867
|
: MIN(max_entry_speed_sqr, max_allowable_speed_sqr(-current->acceleration, next ? next->entry_speed_sqr : sq(MINIMUM_PLANNER_SPEED), current->millimeters));
|
864
|
868
|
if (current->entry_speed_sqr != new_entry_speed_sqr) {
|
865
|
|
- current->entry_speed_sqr = new_entry_speed_sqr;
|
866
|
869
|
|
867
|
|
- // Need to recalculate the block speed
|
|
870
|
+ // Need to recalculate the block speed - Mark it now, so the stepper
|
|
871
|
+ // ISR does not consume the block before being recalculated
|
868
|
872
|
SBI(current->flag, BLOCK_BIT_RECALCULATE);
|
|
873
|
+
|
|
874
|
+ // Set the new entry speed
|
|
875
|
+ current->entry_speed_sqr = new_entry_speed_sqr;
|
869
|
876
|
}
|
870
|
877
|
}
|
871
|
878
|
}
|
|
@@ -925,14 +932,15 @@ void Planner::forward_pass_kernel(const block_t* const previous, block_t* const
|
925
|
932
|
// If true, current block is full-acceleration and we can move the planned pointer forward.
|
926
|
933
|
if (new_entry_speed_sqr < current->entry_speed_sqr) {
|
927
|
934
|
|
|
935
|
+ // Mark we need to recompute the trapezoidal shape, and do it now,
|
|
936
|
+ // so the stepper ISR does not consume the block before being recalculated
|
|
937
|
+ SBI(current->flag, BLOCK_BIT_RECALCULATE);
|
|
938
|
+
|
928
|
939
|
// Always <= max_entry_speed_sqr. Backward pass sets this.
|
929
|
940
|
current->entry_speed_sqr = new_entry_speed_sqr; // Always <= max_entry_speed_sqr. Backward pass sets this.
|
930
|
941
|
|
931
|
942
|
// Set optimal plan pointer.
|
932
|
943
|
block_buffer_planned = block_index;
|
933
|
|
-
|
934
|
|
- // And mark we need to recompute the trapezoidal shape
|
935
|
|
- SBI(current->flag, BLOCK_BIT_RECALCULATE);
|
936
|
944
|
}
|
937
|
945
|
}
|
938
|
946
|
|
|
@@ -1019,6 +1027,12 @@ void Planner::recalculate_trapezoids() {
|
1019
|
1027
|
if (current) {
|
1020
|
1028
|
// Recalculate if current block entry or exit junction speed has changed.
|
1021
|
1029
|
if (TEST(current->flag, BLOCK_BIT_RECALCULATE) || TEST(next->flag, BLOCK_BIT_RECALCULATE)) {
|
|
1030
|
+
|
|
1031
|
+ // Mark the current block as RECALCULATE, to protect it from the Stepper ISR running it.
|
|
1032
|
+ // Note that due to the above condition, there's a chance the current block isn't marked as
|
|
1033
|
+ // RECALCULATE yet, but the next one is. That's the reason for the following line.
|
|
1034
|
+ SBI(current->flag, BLOCK_BIT_RECALCULATE);
|
|
1035
|
+
|
1022
|
1036
|
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
1023
|
1037
|
const float current_nominal_speed = SQRT(current->nominal_speed_sqr),
|
1024
|
1038
|
nomr = 1.0 / current_nominal_speed;
|
|
@@ -1030,7 +1044,10 @@ void Planner::recalculate_trapezoids() {
|
1030
|
1044
|
current->final_adv_steps = next_entry_speed * comp;
|
1031
|
1045
|
}
|
1032
|
1046
|
#endif
|
1033
|
|
- CBI(current->flag, BLOCK_BIT_RECALCULATE); // Reset current only to ensure next trapezoid is computed
|
|
1047
|
+
|
|
1048
|
+ // Reset current only to ensure next trapezoid is computed - The
|
|
1049
|
+ // stepper is free to use the block from now on.
|
|
1050
|
+ CBI(current->flag, BLOCK_BIT_RECALCULATE);
|
1034
|
1051
|
}
|
1035
|
1052
|
}
|
1036
|
1053
|
|
|
@@ -1043,6 +1060,12 @@ void Planner::recalculate_trapezoids() {
|
1043
|
1060
|
|
1044
|
1061
|
// Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
|
1045
|
1062
|
if (next) {
|
|
1063
|
+
|
|
1064
|
+ // Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it.
|
|
1065
|
+ // As the last block is always recalculated here, there is a chance the block isn't
|
|
1066
|
+ // marked as RECALCULATE yet. That's the reason for the following line.
|
|
1067
|
+ SBI(next->flag, BLOCK_BIT_RECALCULATE);
|
|
1068
|
+
|
1046
|
1069
|
const float next_nominal_speed = SQRT(next->nominal_speed_sqr),
|
1047
|
1070
|
nomr = 1.0 / next_nominal_speed;
|
1048
|
1071
|
calculate_trapezoid_for_block(next, next_entry_speed * nomr, (MINIMUM_PLANNER_SPEED) * nomr);
|
|
@@ -1053,6 +1076,9 @@ void Planner::recalculate_trapezoids() {
|
1053
|
1076
|
next->final_adv_steps = (MINIMUM_PLANNER_SPEED) * comp;
|
1054
|
1077
|
}
|
1055
|
1078
|
#endif
|
|
1079
|
+
|
|
1080
|
+ // Reset next only to ensure its trapezoid is computed - The stepper is free to use
|
|
1081
|
+ // the block from now on.
|
1056
|
1082
|
CBI(next->flag, BLOCK_BIT_RECALCULATE);
|
1057
|
1083
|
}
|
1058
|
1084
|
}
|