Fix stepper/planner block handling, race conditions (#11098)
- Allow planner to alter the deceleration phase of the currently executing block. - Remove BUSY flag, as it is NON ATOMIC to set bits in the Stepper ISR and Planner at the same time.
This commit is contained in:
		
				
					committed by
					
						 Scott Lahteine
						Scott Lahteine
					
				
			
			
				
	
			
			
			
						parent
						
							4d3a9930c5
						
					
				
				
					commit
					edb21f349a
				
			| @@ -107,8 +107,6 @@ Stepper stepper; // Singleton | ||||
|  | ||||
| // public: | ||||
|  | ||||
| block_t* Stepper::current_block = NULL;  // A pointer to the block currently being traced | ||||
|  | ||||
| #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) | ||||
|   bool Stepper::homing_dual_axis = false; | ||||
| #endif | ||||
| @@ -119,6 +117,8 @@ block_t* Stepper::current_block = NULL;  // A pointer to the block currently bei | ||||
|  | ||||
| // private: | ||||
|  | ||||
| block_t* Stepper::current_block = NULL; // A pointer to the block currently being traced | ||||
|  | ||||
| uint8_t Stepper::last_direction_bits = 0, | ||||
|         Stepper::axis_did_move; | ||||
|  | ||||
| @@ -1665,6 +1665,7 @@ uint32_t Stepper::stepper_block_phase_isr() { | ||||
|       acceleration_time = deceleration_time = 0; | ||||
|  | ||||
|       uint8_t oversampling = 0;                         // Assume we won't use it | ||||
|  | ||||
|       #if ENABLED(ADAPTIVE_STEP_SMOOTHING) | ||||
|         // At this point, we must decide if we can use Stepper movement axis smoothing. | ||||
|         uint32_t max_rate = current_block->nominal_rate;  // Get the maximum rate (maximum event speed) | ||||
| @@ -1874,6 +1875,34 @@ uint32_t Stepper::stepper_block_phase_isr() { | ||||
|   } | ||||
| #endif // LIN_ADVANCE | ||||
|  | ||||
| // Check if the given block is busy or not - Must not be called from ISR contexts | ||||
| // The current_block could change in the middle of the read by an Stepper ISR, so | ||||
| // we must explicitly prevent that! | ||||
| bool Stepper::is_block_busy(const block_t* const block) { | ||||
|   #ifdef __AVR__ | ||||
|     // A SW memory barrier, to ensure GCC does not overoptimize loops | ||||
|     #define sw_barrier() asm volatile("": : :"memory"); | ||||
|  | ||||
|     // Keep reading until 2 consecutive reads return the same value, | ||||
|     // meaning there was no update in-between caused by an interrupt. | ||||
|     // This works because stepper ISRs happen at a slower rate than | ||||
|     // successive reads of a variable, so 2 consecutive reads with | ||||
|     // the same value means no interrupt updated it. | ||||
|     block_t* vold, *vnew = current_block; | ||||
|     sw_barrier(); | ||||
|     do { | ||||
|       vold = vnew; | ||||
|       vnew = current_block; | ||||
|       sw_barrier(); | ||||
|     } while (vold != vnew); | ||||
|   #else | ||||
|     block_t *vnew = current_block; | ||||
|   #endif | ||||
|  | ||||
|   // Return if the block is busy or not | ||||
|   return block == vnew; | ||||
| } | ||||
|  | ||||
| void Stepper::init() { | ||||
|  | ||||
|   // Init Digipot Motor Current | ||||
|   | ||||
		Reference in New Issue
	
	Block a user