| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -30,8 +30,6 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @brief Nozzle class
 | 
					 | 
					 | 
					 | 
					 * @brief Nozzle class
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 *
 | 
					 | 
					 | 
					 | 
					 *
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @todo: Do not ignore the end.z value and allow XYZ movements
 | 
					 | 
					 | 
					 | 
					 * @todo: Do not ignore the end.z value and allow XYZ movements
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * @todo: Currently this feature needs HAS_BED_PROBE to be active
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 *  due to the do_blocking_move_to*() functions.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 */
 | 
					 | 
					 | 
					 | 
					 */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class Nozzle {
 | 
					 | 
					 | 
					 | 
					class Nozzle {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  private:
 | 
					 | 
					 | 
					 | 
					  private:
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -43,34 +41,40 @@ class Nozzle {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param end point_t defining the ending point
 | 
					 | 
					 | 
					 | 
					     * @param end point_t defining the ending point
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param strokes number of strokes to execute
 | 
					 | 
					 | 
					 | 
					     * @param strokes number of strokes to execute
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     */
 | 
					 | 
					 | 
					 | 
					     */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static void stroke(point_t const &start, point_t const &end, uint8_t const &strokes)
 | 
					 | 
					 | 
					 | 
					    static void stroke(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    __attribute__ ((optimize ("Os"))) {
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) point_t const &start,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) point_t const &end,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &strokes
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Store the current coords
 | 
					 | 
					 | 
					 | 
					    ) __attribute__((optimize ("Os"))) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        point_t const initial = {
 | 
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_FEATURE)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[X_AXIS],
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[Y_AXIS],
 | 
					 | 
					 | 
					 | 
					        #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[Z_AXIS],
 | 
					 | 
					 | 
					 | 
					          // Store the current coords
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[E_AXIS]
 | 
					 | 
					 | 
					 | 
					          point_t const initial = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        };
 | 
					 | 
					 | 
					 | 
					            current_position[X_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #endif
 | 
					 | 
					 | 
					 | 
					            current_position[Y_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					            current_position[Z_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // Move to the starting point
 | 
					 | 
					 | 
					 | 
					            current_position[E_AXIS]
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      do_blocking_move_to_xy(start.x, start.y);
 | 
					 | 
					 | 
					 | 
					          };
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      do_blocking_move_to_z(start.z);
 | 
					 | 
					 | 
					 | 
					        #endif // NOZZLE_CLEAN_PARK
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // Start the stroke pattern
 | 
					 | 
					 | 
					 | 
					        // Move to the starting point
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      for (uint8_t i = 0; i < (strokes >>1); i++) {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(end.x, end.y);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(start.x, start.y);
 | 
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(start.x, start.y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }
 | 
					 | 
					 | 
					 | 
					        do_blocking_move_to_z(start.z);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
					 | 
					 | 
					 | 
					        // Start the stroke pattern
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Move the nozzle to the initial point
 | 
					 | 
					 | 
					 | 
					        for (uint8_t i = 0; i < (strokes >>1); i++) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_z(initial.z);
 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(end.x, end.y);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(initial.x, initial.y);
 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(start.x, start.y);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #endif
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          // Move the nozzle to the initial point
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_z(initial.z);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(initial.x, initial.y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        #endif // NOZZLE_CLEAN_PARK
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      #endif // NOZZLE_CLEAN_FEATURE
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    /**
 | 
					 | 
					 | 
					 | 
					    /**
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -82,47 +86,53 @@ class Nozzle {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param strokes number of strokes to execute
 | 
					 | 
					 | 
					 | 
					     * @param strokes number of strokes to execute
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param objects number of objects to create
 | 
					 | 
					 | 
					 | 
					     * @param objects number of objects to create
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     */
 | 
					 | 
					 | 
					 | 
					     */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static void zigzag(point_t const &start,
 | 
					 | 
					 | 
					 | 
					    static void zigzag(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      point_t const &end, uint8_t const &strokes, uint8_t const &objects)
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) point_t const &start,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    __attribute__ ((optimize ("Os"))) {
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) point_t const &end,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      float A = fabs(end.y - start.y); // [twice the] Amplitude
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &strokes,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      float P = fabs(end.x - start.x) / (objects << 1); // Period
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &objects
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					    ) __attribute__((optimize ("Os"))) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      // Don't allow impossible triangles
 | 
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_FEATURE)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if (A <= 0.0f || P <= 0.0f ) return;
 | 
					 | 
					 | 
					 | 
					        float A = fabs(end.y - start.y); // [twice the] Amplitude
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        float P = fabs(end.x - start.x) / (objects << 1); // Period
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Store the current coords
 | 
					 | 
					 | 
					 | 
					        // Don't allow impossible triangles
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        point_t const initial = {
 | 
					 | 
					 | 
					 | 
					        if (A <= 0.0f || P <= 0.0f ) return;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[X_AXIS],
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[Y_AXIS],
 | 
					 | 
					 | 
					 | 
					        #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[Z_AXIS],
 | 
					 | 
					 | 
					 | 
					          // Store the current coords
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          current_position[E_AXIS]
 | 
					 | 
					 | 
					 | 
					          point_t const initial = {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        };
 | 
					 | 
					 | 
					 | 
					            current_position[X_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #endif
 | 
					 | 
					 | 
					 | 
					            current_position[Y_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					            current_position[Z_AXIS],
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      for (uint8_t j = 0; j < strokes; j++) {
 | 
					 | 
					 | 
					 | 
					            current_position[E_AXIS]
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (uint8_t i = 0; i < (objects << 1); i++) {
 | 
					 | 
					 | 
					 | 
					          };
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          float const x = start.x + i * P;
 | 
					 | 
					 | 
					 | 
					        #endif // NOZZLE_CLEAN_PARK
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					        for (uint8_t j = 0; j < strokes; j++) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(x, y);
 | 
					 | 
					 | 
					 | 
					          for (uint8_t i = 0; i < (objects << 1); i++) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          if (i == 0) do_blocking_move_to_z(start.z);
 | 
					 | 
					 | 
					 | 
					            float const x = start.x + i * P;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            do_blocking_move_to_xy(x, y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (i == 0) do_blocking_move_to_z(start.z);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          for (int i = (objects << 1); i > -1; i--) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            float const x = start.x + i * P;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            do_blocking_move_to_xy(x, y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (int i = (objects << 1); i > -1; i--) {
 | 
					 | 
					 | 
					 | 
					        #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          float const x = start.x + i * P;
 | 
					 | 
					 | 
					 | 
					          // Move the nozzle to the initial point
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_z(initial.z);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(initial.x, initial.y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        #endif // NOZZLE_CLEAN_PARK
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          do_blocking_move_to_xy(x, y);
 | 
					 | 
					 | 
					 | 
					      #endif // NOZZLE_CLEAN_FEATURE
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_PARK)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        // Move the nozzle to the initial point
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_z(initial.z);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(initial.x, initial.y);
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      #endif
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  public:
 | 
					 | 
					 | 
					 | 
					  public:
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -133,21 +143,52 @@ class Nozzle {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param pattern one of the available patterns
 | 
					 | 
					 | 
					 | 
					     * @param pattern one of the available patterns
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     * @param argument depends on the cleaning pattern
 | 
					 | 
					 | 
					 | 
					     * @param argument depends on the cleaning pattern
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					     */
 | 
					 | 
					 | 
					 | 
					     */
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    static void clean(uint8_t const &pattern,
 | 
					 | 
					 | 
					 | 
					    static void clean(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      uint8_t const &strokes, uint8_t const &objects = 0)
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &pattern,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    __attribute__ ((optimize ("Os"))) {
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &strokes,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      switch (pattern) {
 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &objects = 0
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        case 1:
 | 
					 | 
					 | 
					 | 
					    ) __attribute__((optimize ("Os"))) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          Nozzle::zigzag(
 | 
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_CLEAN_FEATURE)
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            NOZZLE_CLEAN_START_PT,
 | 
					 | 
					 | 
					 | 
					        switch (pattern) {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            NOZZLE_CLEAN_END_PT, strokes, objects);
 | 
					 | 
					 | 
					 | 
					          case 1:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          break;
 | 
					 | 
					 | 
					 | 
					            Nozzle::zigzag(
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					              NOZZLE_CLEAN_START_PT,
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        default:
 | 
					 | 
					 | 
					 | 
					              NOZZLE_CLEAN_END_PT, strokes, objects);
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          Nozzle::stroke(
 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            NOZZLE_CLEAN_START_PT,
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            NOZZLE_CLEAN_END_PT, strokes);
 | 
					 | 
					 | 
					 | 
					          default:
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      }
 | 
					 | 
					 | 
					 | 
					            Nozzle::stroke(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					              NOZZLE_CLEAN_START_PT,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					              NOZZLE_CLEAN_END_PT, strokes);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      #endif // NOZZLE_CLEAN_FEATURE
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    static void park(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      __attribute__((unused)) uint8_t const &z_action
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    ) __attribute__((optimize ("Os"))) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      #if ENABLED(NOZZLE_PARK_FEATURE)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        float const z = current_position[Z_AXIS];
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        point_t const park = NOZZLE_PARK_POINT;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        switch(z_action) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          case 1: // force Z-park height
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            do_blocking_move_to_z(park.z);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          case 2: // Raise by Z-park height
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            do_blocking_move_to_z(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					              (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          default: // Raise to Z-park height if lower
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (current_position[Z_AXIS] < park.z)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					              do_blocking_move_to_z(park.z);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        do_blocking_move_to_xy(park.x, park.y);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      #endif // NOZZLE_PARK_FEATURE
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					};
 | 
					 | 
					 | 
					 | 
					};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |