mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-26 13:25:54 +00:00
Adaptive multiaxis step smoothing
- Stepper bugs fixed - Support MIXING_EXTRUDER with Linear Advance - Miscellaneous cleanup Co-Authored-By: ejtagle <ejtagle@hotmail.com>
This commit is contained in:
parent
aab9cb0bbe
commit
1cdcc6adfa
@ -205,15 +205,6 @@
|
||||
#define MAX_AUTORETRACT 99
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MAX_STEP_FREQUENCY differs for TOSHIBA
|
||||
*/
|
||||
#if ENABLED(CONFIG_STEPPERS_TOSHIBA)
|
||||
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
|
||||
#else
|
||||
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
|
||||
#endif
|
||||
|
||||
// MS1 MS2 Stepper Driver Microstepping mode table
|
||||
#define MICROSTEP1 LOW,LOW
|
||||
#if ENABLED(HEROIC_STEPPER_DRIVERS)
|
||||
@ -1320,4 +1311,109 @@
|
||||
#define HAS_FOLDER_SORTING (FOLDER_SORTING || ENABLED(SDSORT_GCODE))
|
||||
#endif
|
||||
|
||||
// Calculate a default maximum stepper rate, if not supplied
|
||||
#ifndef MAXIMUM_STEPPER_RATE
|
||||
#define MAXIMUM_STEPPER_RATE (1000000UL / (2UL * (MINIMUM_STEPPER_PULSE)))
|
||||
#endif
|
||||
|
||||
//
|
||||
// Estimate the amount of time the ISR will take to execute
|
||||
//
|
||||
|
||||
// The base ISR takes 752 cycles
|
||||
#define ISR_BASE_CYCLES 752UL
|
||||
|
||||
// Linear advance base time is 32 cycles
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#define ISR_LA_BASE_CYCLES 32UL
|
||||
#else
|
||||
#define ISR_LA_BASE_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// S curve interpolation adds 160 cycles
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
#define ISR_S_CURVE_CYCLES 160UL
|
||||
#else
|
||||
#define ISR_S_CURVE_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// Stepper Loop base cycles
|
||||
#define ISR_LOOP_BASE_CYCLES 32UL
|
||||
|
||||
// And each stepper takes 88 cycles
|
||||
#define ISR_STEPPER_CYCLES 88UL
|
||||
|
||||
// For each stepper, we add its time
|
||||
#ifdef HAS_X_STEP
|
||||
#define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_X_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// For each stepper, we add its time
|
||||
#ifdef HAS_Y_STEP
|
||||
#define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_Y_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// For each stepper, we add its time
|
||||
#ifdef HAS_Z_STEP
|
||||
#define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#else
|
||||
#define ISR_Z_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// E is always interpolated, even for mixing extruders
|
||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
|
||||
// If linear advance is disabled, then the loop also handles them
|
||||
#if DISABLED(LIN_ADVANCE) && ENABLED(MIXING_EXTRUDER)
|
||||
#define ISR_MIXING_STEPPER_CYCLES ((MIXING_STEPPERS) * ISR_STEPPER_CYCLES)
|
||||
#else
|
||||
#define ISR_MIXING_STEPPER_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// And the total minimum loop time is, without including the base
|
||||
#define MIN_ISR_LOOP_CYCLES (ISR_X_STEPPER_CYCLES + ISR_Y_STEPPER_CYCLES + ISR_Z_STEPPER_CYCLES + ISR_E_STEPPER_CYCLES + ISR_MIXING_STEPPER_CYCLES)
|
||||
|
||||
// But the user could be enforcing a minimum time, so the loop time is
|
||||
#define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES))
|
||||
|
||||
// If linear advance is enabled, then it is handled separately
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
// Estimate the minimum LA loop time
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ((MIXING_STEPPERS) * (ISR_STEPPER_CYCLES))
|
||||
#else
|
||||
#define MIN_ISR_LA_LOOP_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
|
||||
// And the real loop time
|
||||
#define ISR_LA_LOOP_CYCLES MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LA_LOOP_CYCLES)
|
||||
|
||||
#else
|
||||
#define ISR_LA_LOOP_CYCLES 0UL
|
||||
#endif
|
||||
|
||||
// Now estimate the total ISR execution time in cycles given a step per ISR multiplier
|
||||
#define ISR_EXECUTION_CYCLES(rate) (((ISR_BASE_CYCLES + (ISR_LOOP_CYCLES * rate) + ISR_LA_BASE_CYCLES + ISR_LA_LOOP_CYCLES)) / rate)
|
||||
|
||||
// The maximum allowable stepping frequency when doing x128-x1 stepping (in Hz)
|
||||
#define MAX_128X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(128))
|
||||
#define MAX_64X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(64))
|
||||
#define MAX_32X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(32))
|
||||
#define MAX_16X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(16))
|
||||
#define MAX_8X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(8))
|
||||
#define MAX_4X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(4))
|
||||
#define MAX_2X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(2))
|
||||
#define MAX_1X_STEP_ISR_FREQUENCY (F_CPU / ISR_EXECUTION_CYCLES(1))
|
||||
|
||||
// The minimum allowable frequency for step smoothing will be 1/10 of the maximum nominal frequency (in Hz)
|
||||
#define MIN_STEP_ISR_FREQUENCY MAX_1X_STEP_ISR_FREQUENCY
|
||||
|
||||
// Disable multiple steps per ISR
|
||||
//#define DISABLE_MULTI_STEPPING
|
||||
|
||||
#endif // CONDITIONALS_POST_H
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 4, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -453,6 +453,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -457,6 +457,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -452,6 +452,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -450,6 +450,14 @@
|
||||
//#define JUNCTION_DEVIATION_INCLUDE_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
* below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
|
||||
#define MICROSTEP_MODES { 16, 16, 16, 16, 16 } // [1,2,4,8,16]
|
||||
|
||||
|
@ -1628,10 +1628,16 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Bail if this is a zero-length block
|
||||
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
|
||||
|
||||
// For a mixing extruder, get a magnified step_event_count for each
|
||||
// For a mixing extruder, get a magnified esteps for each
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
for (uint8_t i = 0; i < MIXING_STEPPERS; i++)
|
||||
block->mix_event_count[i] = mixing_factor[i] * block->step_event_count;
|
||||
block->mix_steps[i] = mixing_factor[i] * (
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
esteps
|
||||
#else
|
||||
block->step_event_count
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
|
||||
#if FAN_COUNT > 0
|
||||
|
@ -103,7 +103,7 @@ typedef struct {
|
||||
uint8_t active_extruder; // The extruder to move (if E move)
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
uint32_t mix_event_count[MIXING_STEPPERS]; // Scaled step_event_count for the mixing steppers
|
||||
uint32_t mix_steps[MIXING_STEPPERS]; // Scaled steps[E_AXIS] for the mixing steppers
|
||||
#endif
|
||||
|
||||
// Settings for the trapezoid generator
|
||||
@ -125,7 +125,7 @@ typedef struct {
|
||||
// Advance extrusion
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
bool use_advance_lead;
|
||||
uint16_t advance_speed, // Timer value for extruder speed offset
|
||||
uint16_t advance_speed, // STEP timer value for extruder speed offset ISR
|
||||
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
|
||||
final_adv_steps; // advance steps due to exit speed
|
||||
float e_D_ratio;
|
||||
|
@ -46,6 +46,29 @@
|
||||
* and Philipp Tiefenbacher.
|
||||
*/
|
||||
|
||||
/**
|
||||
* __________________________
|
||||
* /| |\ _________________ ^
|
||||
* / | | \ /| |\ |
|
||||
* / | | \ / | | \ s
|
||||
* / | | | | | \ p
|
||||
* / | | | | | \ e
|
||||
* +-----+------------------------+---+--+---------------+----+ e
|
||||
* | BLOCK 1 | BLOCK 2 | d
|
||||
*
|
||||
* time ----->
|
||||
*
|
||||
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
||||
* first block->accelerate_until step_events_completed, then keeps going at constant speed until
|
||||
* step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
|
||||
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marlin uses the Bresenham algorithm. For a detailed explanation of theory and
|
||||
* method see https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Jerk controlled movements planner added Apr 2018 by Eduardo José Tagle.
|
||||
* Equations based on Synthethos TinyG2 sources, but the fixed-point
|
||||
@ -86,10 +109,14 @@ block_t* Stepper::current_block = NULL; // A pointer to the block currently bei
|
||||
// private:
|
||||
|
||||
uint8_t Stepper::last_direction_bits = 0,
|
||||
Stepper::last_movement_extruder = 0xFF,
|
||||
Stepper::axis_did_move;
|
||||
|
||||
bool Stepper::abort_current_block;
|
||||
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
uint8_t Stepper::last_moved_extruder = 0xFF;
|
||||
#endif
|
||||
|
||||
#if ENABLED(X_DUAL_ENDSTOPS)
|
||||
bool Stepper::locked_X_motor = false, Stepper::locked_X2_motor = false;
|
||||
#endif
|
||||
@ -100,19 +127,30 @@ bool Stepper::abort_current_block;
|
||||
bool Stepper::locked_Z_motor = false, Stepper::locked_Z2_motor = false;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Marlin uses the Bresenham algorithm. For a detailed explanation of theory and
|
||||
* method see https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html
|
||||
*
|
||||
* The implementation used here additionally rounds up the starting seed.
|
||||
*/
|
||||
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
|
||||
uint8_t Stepper::steps_per_isr;
|
||||
|
||||
int32_t Stepper::counter_X = 0,
|
||||
Stepper::counter_Y = 0,
|
||||
Stepper::counter_Z = 0,
|
||||
Stepper::counter_E = 0;
|
||||
#if DISABLED(ADAPTIVE_STEP_SMOOTHING)
|
||||
constexpr
|
||||
#endif
|
||||
uint8_t Stepper::oversampling_factor;
|
||||
|
||||
uint32_t Stepper::step_events_completed = 0; // The number of step events executed in the current block
|
||||
int32_t Stepper::delta_error[XYZE] = { 0 };
|
||||
|
||||
uint32_t Stepper::advance_dividend[XYZE] = { 0 },
|
||||
Stepper::advance_divisor = 0,
|
||||
Stepper::step_events_completed = 0, // The number of step events executed in the current block
|
||||
Stepper::accelerate_until, // The point from where we need to stop acceleration
|
||||
Stepper::decelerate_after, // The point from where we need to start decelerating
|
||||
Stepper::step_event_count; // The total event count for the current block
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
int32_t Stepper::delta_error_m[MIXING_STEPPERS];
|
||||
uint32_t Stepper::advance_dividend_m[MIXING_STEPPERS],
|
||||
Stepper::advance_divisor_m;
|
||||
#else
|
||||
int8_t Stepper::active_extruder; // Active extruder
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
int32_t __attribute__((used)) Stepper::bezier_A __asm__("bezier_A"); // A coefficient in Bézier speed curve with alias for assembler
|
||||
@ -125,49 +163,32 @@ uint32_t Stepper::step_events_completed = 0; // The number of step events execut
|
||||
#endif
|
||||
|
||||
uint32_t Stepper::nextMainISR = 0;
|
||||
bool Stepper::all_steps_done = false;
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
uint32_t Stepper::LA_decelerate_after;
|
||||
constexpr uint32_t LA_ADV_NEVER = 0xFFFFFFFF;
|
||||
uint32_t Stepper::nextAdvanceISR = LA_ADV_NEVER,
|
||||
Stepper::LA_isr_rate = LA_ADV_NEVER;
|
||||
uint16_t Stepper::LA_current_adv_steps = 0,
|
||||
Stepper::LA_final_adv_steps,
|
||||
Stepper::LA_max_adv_steps;
|
||||
|
||||
constexpr uint32_t ADV_NEVER = 0xFFFFFFFF;
|
||||
uint32_t Stepper::nextAdvanceISR = ADV_NEVER,
|
||||
Stepper::eISR_Rate = ADV_NEVER;
|
||||
uint16_t Stepper::current_adv_steps = 0,
|
||||
Stepper::final_adv_steps,
|
||||
Stepper::max_adv_steps;
|
||||
int8_t Stepper::LA_steps = 0;
|
||||
|
||||
int8_t Stepper::e_steps = 0;
|
||||
|
||||
#if E_STEPPERS > 1
|
||||
int8_t Stepper::LA_active_extruder; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
#else
|
||||
constexpr int8_t Stepper::LA_active_extruder;
|
||||
#endif
|
||||
|
||||
bool Stepper::use_advance_lead;
|
||||
bool Stepper::LA_use_advance_lead;
|
||||
|
||||
#endif // LIN_ADVANCE
|
||||
|
||||
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
|
||||
|
||||
volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
|
||||
int8_t Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
int32_t Stepper::counter_m[MIXING_STEPPERS];
|
||||
#endif
|
||||
|
||||
uint32_t Stepper::ticks_nominal;
|
||||
uint8_t Stepper::step_loops, Stepper::step_loops_nominal;
|
||||
|
||||
int32_t Stepper::ticks_nominal = -1;
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
|
||||
#endif
|
||||
|
||||
volatile int32_t Stepper::endstops_trigsteps[XYZ];
|
||||
|
||||
volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
|
||||
int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
|
||||
|
||||
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
|
||||
#define DUAL_ENDSTOP_APPLY_STEP(A,V) \
|
||||
if (homing_dual_axis) { \
|
||||
@ -200,7 +221,7 @@ volatile int32_t Stepper::endstops_trigsteps[XYZ];
|
||||
X2_DIR_WRITE(v); \
|
||||
} \
|
||||
else { \
|
||||
if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
|
||||
if (movement_extruder()) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
|
||||
}
|
||||
#define X_APPLY_STEP(v,ALWAYS) \
|
||||
if (extruder_duplication_enabled || ALWAYS) { \
|
||||
@ -208,7 +229,7 @@ volatile int32_t Stepper::endstops_trigsteps[XYZ];
|
||||
X2_STEP_WRITE(v); \
|
||||
} \
|
||||
else { \
|
||||
if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
|
||||
if (movement_extruder()) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
|
||||
}
|
||||
#else
|
||||
#define X_APPLY_DIR(v,Q) X_DIR_WRITE(v)
|
||||
@ -240,7 +261,7 @@ volatile int32_t Stepper::endstops_trigsteps[XYZ];
|
||||
#endif
|
||||
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(current_block->active_extruder, v)
|
||||
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(active_extruder, v)
|
||||
#endif
|
||||
|
||||
// intRes = longIn1 * longIn2 >> 24
|
||||
@ -303,25 +324,6 @@ static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
|
||||
return intRes;
|
||||
}
|
||||
|
||||
// Some useful constants
|
||||
|
||||
/**
|
||||
* __________________________
|
||||
* /| |\ _________________ ^
|
||||
* / | | \ /| |\ |
|
||||
* / | | \ / | | \ s
|
||||
* / | | | | | \ p
|
||||
* / | | | | | \ e
|
||||
* +-----+------------------------+---+--+---------------+----+ e
|
||||
* | BLOCK 1 | BLOCK 2 | d
|
||||
*
|
||||
* time ----->
|
||||
*
|
||||
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
||||
* first block->accelerate_until step_events_completed, then keeps going at constant speed until
|
||||
* step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset.
|
||||
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
|
||||
*/
|
||||
void Stepper::wake_up() {
|
||||
// TCNT1 = 0;
|
||||
ENABLE_STEPPER_DRIVER_INTERRUPT();
|
||||
@ -357,14 +359,25 @@ void Stepper::set_directions() {
|
||||
#endif
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
if (motor_direction(E_AXIS)) {
|
||||
REV_E_DIR(current_block->active_extruder);
|
||||
MIXING_STEPPERS_LOOP(j) REV_E_DIR(j);
|
||||
count_direction[E_AXIS] = -1;
|
||||
}
|
||||
else {
|
||||
NORM_E_DIR(current_block->active_extruder);
|
||||
MIXING_STEPPERS_LOOP(j) NORM_E_DIR(j);
|
||||
count_direction[E_AXIS] = 1;
|
||||
}
|
||||
#else
|
||||
if (motor_direction(E_AXIS)) {
|
||||
REV_E_DIR(active_extruder);
|
||||
count_direction[E_AXIS] = -1;
|
||||
}
|
||||
else {
|
||||
NORM_E_DIR(active_extruder);
|
||||
count_direction[E_AXIS] = 1;
|
||||
}
|
||||
#endif
|
||||
#endif // !LIN_ADVANCE
|
||||
}
|
||||
|
||||
@ -1097,15 +1110,6 @@ void Stepper::set_directions() {
|
||||
* Stepper Driver Interrupt
|
||||
*
|
||||
* Directly pulses the stepper motors at high frequency.
|
||||
* Timer 1 runs at a base frequency of 2MHz, with this ISR using OCR1A compare mode.
|
||||
*
|
||||
* OCR1A Frequency
|
||||
* 1 2 MHz
|
||||
* 50 40 KHz
|
||||
* 100 20 KHz - capped max rate
|
||||
* 200 10 KHz - nominal max rate
|
||||
* 2000 1 KHz - sleep rate
|
||||
* 4000 500 Hz - init rate
|
||||
*/
|
||||
|
||||
HAL_STEP_TIMER_ISR {
|
||||
@ -1119,10 +1123,6 @@ HAL_STEP_TIMER_ISR {
|
||||
#define STEP_MULTIPLY(A,B) MultiU24X32toH16(A, B)
|
||||
|
||||
void Stepper::isr() {
|
||||
|
||||
// Disable interrupts, to avoid ISR preemption while we reprogram the period
|
||||
DISABLE_ISRS();
|
||||
|
||||
// Program timer compare for the maximum period, so it does NOT
|
||||
// flag an interrupt while this ISR is running - So changes from small
|
||||
// periods to big periods are respected and the timer does not reset to 0
|
||||
@ -1169,7 +1169,7 @@ void Stepper::isr() {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
// Compute the time remaining for the advance isr
|
||||
if (nextAdvanceISR != ADV_NEVER) nextAdvanceISR -= interval;
|
||||
if (nextAdvanceISR != LA_ADV_NEVER) nextAdvanceISR -= interval;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1211,10 +1211,8 @@ void Stepper::isr() {
|
||||
/**
|
||||
* Get the current tick value + margin
|
||||
* Assuming at least 6µs between calls to this ISR...
|
||||
* On AVR the ISR epilogue is estimated at 40 instructions - close to 2.5µS.
|
||||
* On ARM the ISR epilogue is estimated at 10 instructions - close to 200nS.
|
||||
* In either case leave at least 8µS for other tasks to execute - That allows
|
||||
* up to 100khz stepping rates
|
||||
* On AVR the ISR epilogue+prologue is estimated at 100 instructions - Give 8µs as margin
|
||||
* On ARM the ISR epilogue+prologue is estimated at 20 instructions - Give 1µs as margin
|
||||
*/
|
||||
min_ticks = HAL_timer_get_count(STEP_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * 8); // ISR never takes more than 1ms, so this shouldn't cause trouble
|
||||
|
||||
@ -1262,97 +1260,34 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
if (!current_block) return;
|
||||
|
||||
// Take multiple steps per interrupt (For high speed moves)
|
||||
all_steps_done = false;
|
||||
for (uint8_t i = step_loops; i--;) {
|
||||
for (uint8_t i = steps_per_isr; i--;) {
|
||||
|
||||
#define _COUNTER(AXIS) counter_## AXIS
|
||||
#define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
|
||||
#define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN
|
||||
|
||||
// Advance the Bresenham counter; start a pulse if the axis needs a step
|
||||
// Start an active pulse, if Bresenham says so, and update position
|
||||
#define PULSE_START(AXIS) do{ \
|
||||
_COUNTER(AXIS) += current_block->steps[_AXIS(AXIS)]; \
|
||||
if (_COUNTER(AXIS) >= 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); } \
|
||||
}while(0)
|
||||
|
||||
// Advance the Bresenham counter; start a pulse if the axis needs a step
|
||||
#define STEP_TICK(AXIS) do { \
|
||||
if (_COUNTER(AXIS) >= 0) { \
|
||||
_COUNTER(AXIS) -= current_block->step_event_count; \
|
||||
delta_error[_AXIS(AXIS)] += advance_dividend[_AXIS(AXIS)]; \
|
||||
if (delta_error[_AXIS(AXIS)] >= 0) { \
|
||||
_APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS), 0); \
|
||||
count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
// Stop an active pulse, if any
|
||||
#define PULSE_STOP(AXIS) _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), 0)
|
||||
// Stop an active pulse, if any, and adjust error term
|
||||
#define PULSE_STOP(AXIS) do { \
|
||||
if (delta_error[_AXIS(AXIS)] >= 0) { \
|
||||
delta_error[_AXIS(AXIS)] -= advance_divisor; \
|
||||
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS), 0); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
/**
|
||||
* Estimate the number of cycles that the stepper logic already takes
|
||||
* up between the start and stop of the X stepper pulse.
|
||||
*
|
||||
* Currently this uses very modest estimates of around 5 cycles.
|
||||
* True values may be derived by careful testing.
|
||||
*
|
||||
* Once any delay is added, the cost of the delay code itself
|
||||
* may be subtracted from this value to get a more accurate delay.
|
||||
* Delays under 20 cycles (1.25µs) will be very accurate, using NOPs.
|
||||
* Longer delays use a loop. The resolution is 8 cycles.
|
||||
*/
|
||||
#if HAS_X_STEP
|
||||
#define _CYCLE_APPROX_1 5
|
||||
#else
|
||||
#define _CYCLE_APPROX_1 0
|
||||
#endif
|
||||
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
|
||||
#define _CYCLE_APPROX_2 _CYCLE_APPROX_1 + 4
|
||||
#else
|
||||
#define _CYCLE_APPROX_2 _CYCLE_APPROX_1
|
||||
#endif
|
||||
#if HAS_Y_STEP
|
||||
#define _CYCLE_APPROX_3 _CYCLE_APPROX_2 + 5
|
||||
#else
|
||||
#define _CYCLE_APPROX_3 _CYCLE_APPROX_2
|
||||
#endif
|
||||
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
|
||||
#define _CYCLE_APPROX_4 _CYCLE_APPROX_3 + 4
|
||||
#else
|
||||
#define _CYCLE_APPROX_4 _CYCLE_APPROX_3
|
||||
#endif
|
||||
#if HAS_Z_STEP
|
||||
#define _CYCLE_APPROX_5 _CYCLE_APPROX_4 + 5
|
||||
#else
|
||||
#define _CYCLE_APPROX_5 _CYCLE_APPROX_4
|
||||
#endif
|
||||
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
|
||||
#define _CYCLE_APPROX_6 _CYCLE_APPROX_5 + 4
|
||||
#else
|
||||
#define _CYCLE_APPROX_6 _CYCLE_APPROX_5
|
||||
#endif
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
#define _CYCLE_APPROX_7 _CYCLE_APPROX_6 + (MIXING_STEPPERS) * 6
|
||||
#else
|
||||
#define _CYCLE_APPROX_7 _CYCLE_APPROX_6 + 5
|
||||
#endif
|
||||
#else
|
||||
#define _CYCLE_APPROX_7 _CYCLE_APPROX_6
|
||||
#endif
|
||||
|
||||
#define CYCLES_EATEN_XYZE _CYCLE_APPROX_7
|
||||
#define EXTRA_CYCLES_XYZE (STEP_PULSE_CYCLES - (CYCLES_EATEN_XYZE))
|
||||
|
||||
/**
|
||||
* If a minimum pulse time was specified get the timer 0 value.
|
||||
*
|
||||
* On AVR the TCNT0 timer has an 8x prescaler, so it increments every 8 cycles.
|
||||
* That's every 0.5µs on 16MHz and every 0.4µs on 20MHz.
|
||||
* 20 counts of TCNT0 -by itself- is a good pulse delay.
|
||||
* 10µs = 160 or 200 cycles.
|
||||
*/
|
||||
#if EXTRA_CYCLES_XYZE > 20
|
||||
hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
// Get the timer count and estimate the end of the pulse
|
||||
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
||||
#endif
|
||||
|
||||
// Pulse start
|
||||
#if HAS_X_STEP
|
||||
PULSE_START(X);
|
||||
#endif
|
||||
@ -1363,64 +1298,48 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
PULSE_START(Z);
|
||||
#endif
|
||||
|
||||
// Pulse E/Mixing extruders
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
counter_E += current_block->steps[E_AXIS];
|
||||
if (counter_E >= 0) {
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
// Don't step E here for mixing extruder
|
||||
motor_direction(E_AXIS) ? --e_steps : ++e_steps;
|
||||
#endif
|
||||
}
|
||||
// Tick the E axis, correct error term and update position
|
||||
delta_error[E_AXIS] += advance_dividend[E_AXIS];
|
||||
if (delta_error[E_AXIS] >= 0) {
|
||||
count_position[E_AXIS] += count_direction[E_AXIS];
|
||||
delta_error[E_AXIS] -= advance_divisor;
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
// Step mixing steppers proportionally
|
||||
const bool dir = motor_direction(E_AXIS);
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
counter_m[j] += current_block->steps[E_AXIS];
|
||||
if (counter_m[j] >= 0) {
|
||||
counter_m[j] -= current_block->mix_event_count[j];
|
||||
dir ? --e_steps[j] : ++e_steps[j];
|
||||
// Don't step E here - But remember the number of steps to perform
|
||||
motor_direction(E_AXIS) ? --LA_steps : ++LA_steps;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // !LIN_ADVANCE - use linear interpolation for E also
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
// Keep updating the single E axis
|
||||
counter_E += current_block->steps[E_AXIS];
|
||||
// Tick the counters used for this mix
|
||||
|
||||
// Tick the E axis
|
||||
delta_error[E_AXIS] += advance_dividend[E_AXIS];
|
||||
if (delta_error[E_AXIS] >= 0) {
|
||||
count_position[E_AXIS] += count_direction[E_AXIS];
|
||||
delta_error[E_AXIS] -= advance_divisor;
|
||||
}
|
||||
|
||||
// Tick the counters used for this mix in proper proportion
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
// Step mixing steppers (proportionally)
|
||||
counter_m[j] += current_block->steps[E_AXIS];
|
||||
delta_error_m[j] += advance_dividend_m[j];
|
||||
// Step when the counter goes over zero
|
||||
if (counter_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
|
||||
if (delta_error_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
|
||||
}
|
||||
|
||||
#else // !MIXING_EXTRUDER
|
||||
PULSE_START(E);
|
||||
#endif
|
||||
#endif // !LIN_ADVANCE
|
||||
|
||||
#if HAS_X_STEP
|
||||
STEP_TICK(X);
|
||||
#endif
|
||||
#if HAS_Y_STEP
|
||||
STEP_TICK(Y);
|
||||
#endif
|
||||
#if HAS_Z_STEP
|
||||
STEP_TICK(Z);
|
||||
#endif
|
||||
|
||||
STEP_TICK(E); // Always tick the single E axis
|
||||
|
||||
// For minimum pulse time wait before stopping pulses
|
||||
#if EXTRA_CYCLES_XYZE > 20
|
||||
while (EXTRA_CYCLES_XYZE > (uint32_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
|
||||
#elif EXTRA_CYCLES_XYZE > 0
|
||||
DELAY_NS(EXTRA_CYCLES_XYZE * NANOSECONDS_PER_CYCLE);
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
// Just wait for the requested pulse duration
|
||||
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||
// Get the timer count and estimate the end of the pulse for the OFF phase
|
||||
pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
||||
#endif
|
||||
|
||||
// Pulse stop
|
||||
#if HAS_X_STEP
|
||||
PULSE_STOP(X);
|
||||
#endif
|
||||
@ -1434,8 +1353,8 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
if (counter_m[j] >= 0) {
|
||||
counter_m[j] -= current_block->mix_event_count[j];
|
||||
if (delta_error_m[j] >= 0) {
|
||||
delta_error_m[j] -= advance_divisor_m;
|
||||
E_STEP_WRITE(j, INVERT_E_STEP_PIN);
|
||||
}
|
||||
}
|
||||
@ -1444,18 +1363,14 @@ void Stepper::stepper_pulse_phase_isr() {
|
||||
#endif
|
||||
#endif // !LIN_ADVANCE
|
||||
|
||||
if (++step_events_completed >= current_block->step_event_count) {
|
||||
all_steps_done = true;
|
||||
break;
|
||||
}
|
||||
// If all events done, break loop now
|
||||
if (++step_events_completed >= step_event_count) break;
|
||||
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
// For minimum pulse time wait after stopping pulses also
|
||||
#if EXTRA_CYCLES_XYZE > 20
|
||||
if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#elif EXTRA_CYCLES_XYZE > 0
|
||||
if (i) DELAY_NS(EXTRA_CYCLES_XYZE * NANOSECONDS_PER_CYCLE);
|
||||
// Just wait for the requested pulse duration
|
||||
if (i) while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||
#endif
|
||||
|
||||
} // steps_loop
|
||||
}
|
||||
|
||||
@ -1471,8 +1386,17 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
// If there is a current block
|
||||
if (current_block) {
|
||||
|
||||
// Calculate new timer value
|
||||
if (step_events_completed <= current_block->accelerate_until) {
|
||||
// If current block is finished, reset pointer
|
||||
if (step_events_completed >= step_event_count) {
|
||||
axis_did_move = 0;
|
||||
current_block = NULL;
|
||||
planner.discard_current_block();
|
||||
}
|
||||
else {
|
||||
// Step events not completed yet...
|
||||
|
||||
// Are we in acceleration phase ?
|
||||
if (step_events_completed <= accelerate_until) { // Calculate new timer value
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
// Get the next speed to use (Jerk limited!)
|
||||
@ -1485,24 +1409,28 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
NOMORE(acc_step_rate, current_block->nominal_rate);
|
||||
#endif
|
||||
|
||||
// step_rate to timer interval
|
||||
interval = calc_timer_interval(acc_step_rate);
|
||||
// acc_step_rate is in steps/second
|
||||
|
||||
// step_rate to timer interval and steps per stepper isr
|
||||
interval = calc_timer_interval(acc_step_rate, oversampling_factor, &steps_per_isr);
|
||||
acceleration_time += interval;
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed == step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
|
||||
nextAdvanceISR = 0; // Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
|
||||
eISR_Rate = current_block->advance_speed;
|
||||
if (LA_use_advance_lead) {
|
||||
// Wake up eISR on first acceleration loop and fire ISR if final adv_rate is reached
|
||||
if (step_events_completed == steps_per_isr || (LA_steps && LA_isr_rate != current_block->advance_speed)) {
|
||||
nextAdvanceISR = 0;
|
||||
LA_isr_rate = current_block->advance_speed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eISR_Rate = ADV_NEVER;
|
||||
if (e_steps) nextAdvanceISR = 0;
|
||||
LA_isr_rate = LA_ADV_NEVER;
|
||||
if (LA_steps) nextAdvanceISR = 0;
|
||||
}
|
||||
#endif // LIN_ADVANCE
|
||||
}
|
||||
else if (step_events_completed > current_block->decelerate_after) {
|
||||
// Are we in Deceleration phase ?
|
||||
else if (step_events_completed > decelerate_after) {
|
||||
uint32_t step_rate;
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
@ -1511,12 +1439,15 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
// Initialize the Bézier speed curve
|
||||
_calc_bezier_curve_coeffs(current_block->cruise_rate, current_block->final_rate, current_block->deceleration_time_inverse);
|
||||
bezier_2nd_half = true;
|
||||
// The first point starts at cruise rate. Just save evaluation of the Bézier curve
|
||||
step_rate = current_block->cruise_rate;
|
||||
}
|
||||
|
||||
else {
|
||||
// Calculate the next speed to use
|
||||
step_rate = deceleration_time < current_block->deceleration_time
|
||||
? _eval_bezier_curve(deceleration_time)
|
||||
: current_block->final_rate;
|
||||
}
|
||||
#else
|
||||
|
||||
// Using the old trapezoidal control
|
||||
@ -1529,42 +1460,44 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
step_rate = current_block->final_rate;
|
||||
#endif
|
||||
|
||||
// step_rate to timer interval
|
||||
interval = calc_timer_interval(step_rate);
|
||||
// step_rate is in steps/second
|
||||
|
||||
// step_rate to timer interval and steps per stepper isr
|
||||
interval = calc_timer_interval(step_rate, oversampling_factor, &steps_per_isr);
|
||||
deceleration_time += interval;
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
if (current_block->use_advance_lead) {
|
||||
if (step_events_completed <= current_block->decelerate_after + step_loops || (e_steps && eISR_Rate != current_block->advance_speed)) {
|
||||
if (LA_use_advance_lead) {
|
||||
if (step_events_completed <= decelerate_after + steps_per_isr ||
|
||||
(LA_steps && LA_isr_rate != current_block->advance_speed)
|
||||
) {
|
||||
nextAdvanceISR = 0; // Wake up eISR on first deceleration loop
|
||||
eISR_Rate = current_block->advance_speed;
|
||||
LA_isr_rate = current_block->advance_speed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eISR_Rate = ADV_NEVER;
|
||||
if (e_steps) nextAdvanceISR = 0;
|
||||
LA_isr_rate = LA_ADV_NEVER;
|
||||
if (LA_steps) nextAdvanceISR = 0;
|
||||
}
|
||||
#endif // LIN_ADVANCE
|
||||
}
|
||||
// We must be in cruise phase otherwise
|
||||
else {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
// If there are any esteps, fire the next advance_isr "now"
|
||||
if (e_steps && eISR_Rate != current_block->advance_speed) nextAdvanceISR = 0;
|
||||
if (LA_steps && LA_isr_rate != current_block->advance_speed) nextAdvanceISR = 0;
|
||||
#endif
|
||||
|
||||
// Calculate the ticks_nominal for this nominal speed, if not done yet
|
||||
if (ticks_nominal < 0) {
|
||||
// step_rate to timer interval and loops for the nominal speed
|
||||
ticks_nominal = calc_timer_interval(current_block->nominal_rate, oversampling_factor, &steps_per_isr);
|
||||
}
|
||||
|
||||
// The timer interval is just the nominal value for the nominal speed
|
||||
interval = ticks_nominal;
|
||||
|
||||
// Ensure this runs at the correct step rate, even if it just came off an acceleration
|
||||
step_loops = step_loops_nominal;
|
||||
}
|
||||
|
||||
// If current block is finished, reset pointer
|
||||
if (all_steps_done) {
|
||||
axis_did_move = 0;
|
||||
current_block = NULL;
|
||||
planner.discard_current_block();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1660,25 +1593,82 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
//if (!!current_block->steps[C_AXIS]) SBI(axis_bits, Z_HEAD);
|
||||
axis_did_move = axis_bits;
|
||||
|
||||
// No acceleration / deceleration time elapsed so far
|
||||
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)
|
||||
while (max_rate < MIN_STEP_ISR_FREQUENCY) {
|
||||
max_rate <<= 1;
|
||||
if (max_rate >= MAX_1X_STEP_ISR_FREQUENCY) break;
|
||||
++oversampling;
|
||||
}
|
||||
oversampling_factor = oversampling;
|
||||
#endif
|
||||
|
||||
// Based on the oversampling factor, do the calculations
|
||||
step_event_count = current_block->step_event_count << oversampling;
|
||||
|
||||
// Initialize Bresenham delta errors to 1/2
|
||||
delta_error[X_AXIS] = delta_error[Y_AXIS] = delta_error[Z_AXIS] = delta_error[E_AXIS] = -int32_t(step_event_count);
|
||||
|
||||
// Calculate Bresenham dividends
|
||||
advance_dividend[X_AXIS] = current_block->steps[X_AXIS] << 1;
|
||||
advance_dividend[Y_AXIS] = current_block->steps[Y_AXIS] << 1;
|
||||
advance_dividend[Z_AXIS] = current_block->steps[Z_AXIS] << 1;
|
||||
advance_dividend[E_AXIS] = current_block->steps[E_AXIS] << 1;
|
||||
|
||||
// Calculate Bresenham divisor
|
||||
advance_divisor = step_event_count << 1;
|
||||
|
||||
// No step events completed so far
|
||||
step_events_completed = 0;
|
||||
|
||||
// Compute the acceleration and deceleration points
|
||||
accelerate_until = current_block->accelerate_until << oversampling;
|
||||
decelerate_after = current_block->decelerate_after << oversampling;
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
const uint32_t e_steps = (
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
current_block->steps[E_AXIS]
|
||||
#else
|
||||
step_event_count
|
||||
#endif
|
||||
);
|
||||
MIXING_STEPPERS_LOOP(i) {
|
||||
delta_error_m[i] = -int32_t(e_steps);
|
||||
advance_dividend_m[i] = current_block->mix_steps[i] << 1;
|
||||
}
|
||||
advance_divisor_m = e_steps << 1;
|
||||
#else
|
||||
active_extruder = current_block->active_extruder;
|
||||
#endif
|
||||
|
||||
// Initialize the trapezoid generator from the current block.
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if E_STEPPERS > 1
|
||||
if (current_block->active_extruder != last_movement_extruder) {
|
||||
current_adv_steps = 0; // If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
|
||||
LA_active_extruder = current_block->active_extruder;
|
||||
#if DISABLED(MIXING_EXTRUDER) && E_STEPPERS > 1
|
||||
// If the now active extruder wasn't in use during the last move, its pressure is most likely gone.
|
||||
if (active_extruder != last_moved_extruder) LA_current_adv_steps = 0;
|
||||
#endif
|
||||
|
||||
if ((LA_use_advance_lead = current_block->use_advance_lead)) {
|
||||
LA_final_adv_steps = current_block->final_adv_steps;
|
||||
LA_max_adv_steps = current_block->max_adv_steps;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((use_advance_lead = current_block->use_advance_lead)) {
|
||||
LA_decelerate_after = current_block->decelerate_after;
|
||||
final_adv_steps = current_block->final_adv_steps;
|
||||
max_adv_steps = current_block->max_adv_steps;
|
||||
}
|
||||
if (current_block->direction_bits != last_direction_bits
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
|| active_extruder != last_moved_extruder
|
||||
#endif
|
||||
|
||||
if (current_block->direction_bits != last_direction_bits || current_block->active_extruder != last_movement_extruder) {
|
||||
) {
|
||||
last_direction_bits = current_block->direction_bits;
|
||||
last_movement_extruder = current_block->active_extruder;
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
last_moved_extruder = active_extruder;
|
||||
#endif
|
||||
set_directions();
|
||||
}
|
||||
|
||||
@ -1691,17 +1681,15 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
// on the next call to this ISR, will be discarded.
|
||||
endstops.check_possible_change();
|
||||
|
||||
// No acceleration / deceleration time elapsed so far
|
||||
acceleration_time = deceleration_time = 0;
|
||||
#if ENABLED(Z_LATE_ENABLE)
|
||||
// If delayed Z enable, enable it now. This option will severely interfere with
|
||||
// timing between pulses when chaining motion between blocks, and it could lead
|
||||
// to lost steps in both X and Y axis, so avoid using it unless strictly necessary!!
|
||||
if (current_block->steps[Z_AXIS]) enable_Z();
|
||||
#endif
|
||||
|
||||
// No step events completed so far
|
||||
step_events_completed = 0;
|
||||
|
||||
// step_rate to timer interval for the nominal speed
|
||||
ticks_nominal = calc_timer_interval(current_block->nominal_rate);
|
||||
|
||||
// make a note of the number of step loops required at nominal speed
|
||||
step_loops_nominal = step_loops;
|
||||
// Mark the time_nominal as not calculated yet
|
||||
ticks_nominal = -1;
|
||||
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
// Set as deceleration point the initial rate of the block
|
||||
@ -1711,24 +1699,12 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
// Initialize the Bézier speed curve
|
||||
_calc_bezier_curve_coeffs(current_block->initial_rate, current_block->cruise_rate, current_block->acceleration_time_inverse);
|
||||
|
||||
// We have not started the 2nd half of the trapezoid
|
||||
// We haven't started the 2nd half of the trapezoid
|
||||
bezier_2nd_half = false;
|
||||
#endif
|
||||
|
||||
// Initialize Bresenham counters to 1/2 the ceiling, with proper roundup (as explained in the article linked above)
|
||||
counter_X = counter_Y = counter_Z = counter_E = -int32_t((current_block->step_event_count + 1) >> 1);
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(i)
|
||||
counter_m[i] = -int32_t((current_block->mix_event_count[i] + 1) >> 1);
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_LATE_ENABLE)
|
||||
// If delayed Z enable, enable it now. This option will severely interfere with
|
||||
// timing between pulses when chaining motion between blocks, and it could lead
|
||||
// to lost steps in both X and Y axis, so avoid using it unless strictly necessary!!
|
||||
if (current_block->steps[Z_AXIS]) enable_Z();
|
||||
#endif
|
||||
// Calculate the initial timer interval
|
||||
interval = calc_timer_interval(current_block->initial_rate, oversampling_factor, &steps_per_isr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1738,65 +1714,85 @@ uint32_t Stepper::stepper_block_phase_isr() {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
#define CYCLES_EATEN_E (E_STEPPERS * 5)
|
||||
#define EXTRA_CYCLES_E (STEP_PULSE_CYCLES - (CYCLES_EATEN_E))
|
||||
|
||||
// Timer interrupt for E. e_steps is set in the main routine;
|
||||
// Timer interrupt for E. LA_steps is set in the main routine
|
||||
uint32_t Stepper::advance_isr() {
|
||||
uint32_t interval;
|
||||
|
||||
if (use_advance_lead) {
|
||||
if (step_events_completed > LA_decelerate_after && current_adv_steps > final_adv_steps) {
|
||||
e_steps--;
|
||||
current_adv_steps--;
|
||||
interval = eISR_Rate;
|
||||
if (LA_use_advance_lead) {
|
||||
if (step_events_completed > decelerate_after && LA_current_adv_steps > LA_final_adv_steps) {
|
||||
LA_steps--;
|
||||
LA_current_adv_steps--;
|
||||
interval = LA_isr_rate;
|
||||
}
|
||||
else if (step_events_completed < LA_decelerate_after && current_adv_steps < max_adv_steps) {
|
||||
//step_events_completed <= (uint32_t)current_block->accelerate_until) {
|
||||
e_steps++;
|
||||
current_adv_steps++;
|
||||
interval = eISR_Rate;
|
||||
else if (step_events_completed < decelerate_after && LA_current_adv_steps < LA_max_adv_steps) {
|
||||
//step_events_completed <= (uint32_t)accelerate_until) {
|
||||
LA_steps++;
|
||||
LA_current_adv_steps++;
|
||||
interval = LA_isr_rate;
|
||||
}
|
||||
else
|
||||
interval = eISR_Rate = ADV_NEVER;
|
||||
interval = LA_isr_rate = LA_ADV_NEVER;
|
||||
}
|
||||
else
|
||||
interval = ADV_NEVER;
|
||||
interval = LA_ADV_NEVER;
|
||||
|
||||
if (e_steps >= 0)
|
||||
NORM_E_DIR(LA_active_extruder);
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
if (LA_steps >= 0)
|
||||
MIXING_STEPPERS_LOOP(j) NORM_E_DIR(j);
|
||||
else
|
||||
REV_E_DIR(LA_active_extruder);
|
||||
MIXING_STEPPERS_LOOP(j) REV_E_DIR(j);
|
||||
#else
|
||||
if (LA_steps >= 0)
|
||||
NORM_E_DIR(active_extruder);
|
||||
else
|
||||
REV_E_DIR(active_extruder);
|
||||
#endif
|
||||
|
||||
// Step E stepper if we have steps
|
||||
while (e_steps) {
|
||||
while (LA_steps) {
|
||||
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
hal_timer_t pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
||||
#endif
|
||||
|
||||
E_STEP_WRITE(LA_active_extruder, !INVERT_E_STEP_PIN);
|
||||
|
||||
// For minimum pulse time wait before stopping pulses
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
while (EXTRA_CYCLES_E > (hal_timer_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM);
|
||||
#elif EXTRA_CYCLES_E > 0
|
||||
DELAY_NS(EXTRA_CYCLES_E * NANOSECONDS_PER_CYCLE);
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
// Step mixing steppers (proportionally)
|
||||
delta_error_m[j] += advance_dividend_m[j];
|
||||
// Step when the counter goes over zero
|
||||
if (delta_error_m[j] >= 0) E_STEP_WRITE(j, !INVERT_E_STEP_PIN);
|
||||
}
|
||||
#else
|
||||
E_STEP_WRITE(active_extruder, !INVERT_E_STEP_PIN);
|
||||
#endif
|
||||
|
||||
e_steps < 0 ? ++e_steps : --e_steps;
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
// Just wait for the requested pulse duration
|
||||
while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||
// Get the timer count and estimate the end of the pulse for the OFF phase
|
||||
pulse_end = HAL_timer_get_count(PULSE_TIMER_NUM) + hal_timer_t((HAL_TICKS_PER_US) * (MINIMUM_STEPPER_PULSE));
|
||||
#endif
|
||||
|
||||
E_STEP_WRITE(LA_active_extruder, INVERT_E_STEP_PIN);
|
||||
LA_steps < 0 ? ++LA_steps : --LA_steps;
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
MIXING_STEPPERS_LOOP(j) {
|
||||
if (delta_error_m[j] >= 0) {
|
||||
delta_error_m[j] -= advance_divisor_m;
|
||||
E_STEP_WRITE(j, INVERT_E_STEP_PIN);
|
||||
}
|
||||
}
|
||||
#else
|
||||
E_STEP_WRITE(active_extruder, INVERT_E_STEP_PIN);
|
||||
#endif
|
||||
|
||||
#if MINIMUM_STEPPER_PULSE > 0
|
||||
// For minimum pulse time wait before looping
|
||||
#if EXTRA_CYCLES_E > 20
|
||||
if (e_steps) while (EXTRA_CYCLES_E > (hal_timer_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#elif EXTRA_CYCLES_E > 0
|
||||
if (e_steps) DELAY_NS(EXTRA_CYCLES_E * NANOSECONDS_PER_CYCLE);
|
||||
// Just wait for the requested pulse duration
|
||||
if (LA_steps) while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
|
||||
#endif
|
||||
|
||||
} // e_steps
|
||||
} // LA_steps
|
||||
|
||||
return interval;
|
||||
}
|
||||
@ -2104,8 +2100,8 @@ void Stepper::report_positions() {
|
||||
#define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true)
|
||||
|
||||
#if EXTRA_CYCLES_BABYSTEP > 20
|
||||
#define _SAVE_START const hal_timer_t pulse_start = HAL_timer_get_count(STEP_TIMER_NUM)
|
||||
#define _PULSE_WAIT while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(HAL_timer_get_count(STEP_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#define _SAVE_START const hal_timer_t pulse_start = HAL_timer_get_count(PULSE_TIMER_NUM)
|
||||
#define _PULSE_WAIT while (EXTRA_CYCLES_BABYSTEP > (uint32_t)(HAL_timer_get_count(PULSE_TIMER_NUM) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#else
|
||||
#define _SAVE_START NOOP
|
||||
#if EXTRA_CYCLES_BABYSTEP > 0
|
||||
|
132
Marlin/stepper.h
132
Marlin/stepper.h
@ -99,10 +99,14 @@ class Stepper {
|
||||
private:
|
||||
|
||||
static uint8_t last_direction_bits, // The next stepping-bits to be output
|
||||
last_movement_extruder, // Last movement extruder, as computed when the last movement was fetched from planner
|
||||
axis_did_move; // Last Movement in the given direction is not null, as computed when the last movement was fetched from planner
|
||||
|
||||
static bool abort_current_block; // Signals to the stepper that current block should be aborted
|
||||
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
static uint8_t last_moved_extruder; // Last-moved extruder, as set when the last movement was fetched from planner
|
||||
#endif
|
||||
|
||||
#if ENABLED(X_DUAL_ENDSTOPS)
|
||||
static bool locked_X_motor, locked_X2_motor;
|
||||
#endif
|
||||
@ -113,9 +117,34 @@ class Stepper {
|
||||
static bool locked_Z_motor, locked_Z2_motor;
|
||||
#endif
|
||||
|
||||
// Counter variables for the Bresenham line tracer
|
||||
static int32_t counter_X, counter_Y, counter_Z, counter_E;
|
||||
static uint32_t step_events_completed; // The number of step events executed in the current block
|
||||
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
|
||||
static uint8_t steps_per_isr; // Count of steps to perform per Stepper ISR call
|
||||
|
||||
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
|
||||
static uint8_t oversampling_factor; // Oversampling factor (log2(multiplier)) to increase temporal resolution of axis
|
||||
#else
|
||||
static constexpr uint8_t oversampling_factor = 0;
|
||||
#endif
|
||||
|
||||
// Delta error variables for the Bresenham line tracer
|
||||
static int32_t delta_error[XYZE];
|
||||
static uint32_t advance_dividend[XYZE],
|
||||
advance_divisor,
|
||||
step_events_completed, // The number of step events executed in the current block
|
||||
accelerate_until, // The point from where we need to stop acceleration
|
||||
decelerate_after, // The point from where we need to start decelerating
|
||||
step_event_count; // The total event count for the current block
|
||||
|
||||
// Mixing extruder mix delta_errors for bresenham tracing
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
static int32_t delta_error_m[MIXING_STEPPERS];
|
||||
static uint32_t advance_dividend_m[MIXING_STEPPERS],
|
||||
advance_divisor_m;
|
||||
#define MIXING_STEPPERS_LOOP(VAR) \
|
||||
for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++)
|
||||
#else
|
||||
static int8_t active_extruder; // Active extruder
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
static int32_t bezier_A, // A coefficient in Bézier speed curve
|
||||
@ -128,33 +157,19 @@ class Stepper {
|
||||
#endif
|
||||
|
||||
static uint32_t nextMainISR; // time remaining for the next Step ISR
|
||||
static bool all_steps_done; // all steps done
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
|
||||
static uint32_t LA_decelerate_after; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
static uint32_t nextAdvanceISR, eISR_Rate;
|
||||
static uint16_t current_adv_steps, final_adv_steps, max_adv_steps; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
static int8_t e_steps;
|
||||
static bool use_advance_lead;
|
||||
#if E_STEPPERS > 1
|
||||
static int8_t LA_active_extruder; // Copy from current executed block. Needed because current_block is set to NULL "too early".
|
||||
#else
|
||||
static constexpr int8_t LA_active_extruder = 0;
|
||||
#endif
|
||||
|
||||
static uint32_t nextAdvanceISR, LA_isr_rate;
|
||||
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".
|
||||
static int8_t LA_steps;
|
||||
static bool LA_use_advance_lead;
|
||||
#endif // LIN_ADVANCE
|
||||
|
||||
static uint32_t acceleration_time, deceleration_time;
|
||||
static uint8_t step_loops, step_loops_nominal;
|
||||
|
||||
static uint32_t ticks_nominal;
|
||||
static int32_t ticks_nominal;
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
static uint32_t acc_step_rate; // needed for deceleration start point
|
||||
#endif
|
||||
|
||||
static volatile int32_t endstops_trigsteps[XYZ];
|
||||
static volatile int32_t endstops_stepsTotal, endstops_stepsDone;
|
||||
|
||||
//
|
||||
// Positions of stepper motors, in step units
|
||||
@ -166,16 +181,6 @@ class Stepper {
|
||||
//
|
||||
static int8_t count_direction[NUM_AXIS];
|
||||
|
||||
//
|
||||
// Mixing extruder mix counters
|
||||
//
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
static int32_t counter_m[MIXING_STEPPERS];
|
||||
#define MIXING_STEPPERS_LOOP(VAR) \
|
||||
for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) \
|
||||
if (current_block->mix_event_count[VAR])
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
@ -222,7 +227,15 @@ class Stepper {
|
||||
FORCE_INLINE static bool axis_is_moving(const AxisEnum axis) { return TEST(axis_did_move, axis); }
|
||||
|
||||
// The extruder associated to the last movement
|
||||
FORCE_INLINE static uint8_t movement_extruder() { return last_movement_extruder; }
|
||||
FORCE_INLINE static uint8_t movement_extruder() {
|
||||
return
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
0
|
||||
#else
|
||||
last_moved_extruder
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
// Handle a triggered endstop
|
||||
static void endstop_triggered(const AxisEnum axis);
|
||||
@ -290,25 +303,42 @@ class Stepper {
|
||||
// Set direction bits for all steppers
|
||||
static void set_directions();
|
||||
|
||||
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate) {
|
||||
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t scale, uint8_t* loops) {
|
||||
uint32_t timer;
|
||||
|
||||
NOMORE(step_rate, uint32_t(MAX_STEP_FREQUENCY));
|
||||
// Scale the frequency, as requested by the caller
|
||||
step_rate <<= scale;
|
||||
|
||||
if (step_rate > 20000) { // If steprate > 20kHz >> step 4 times
|
||||
step_rate >>= 2;
|
||||
step_loops = 4;
|
||||
}
|
||||
else if (step_rate > 10000) { // If steprate > 10kHz >> step 2 times
|
||||
uint8_t multistep = 1;
|
||||
#if DISABLED(DISABLE_MULTI_STEPPING)
|
||||
|
||||
// The stepping frequency limits for each multistepping rate
|
||||
static const uint32_t limit[] PROGMEM = {
|
||||
( MAX_1X_STEP_ISR_FREQUENCY ),
|
||||
( MAX_2X_STEP_ISR_FREQUENCY >> 1),
|
||||
( MAX_4X_STEP_ISR_FREQUENCY >> 2),
|
||||
( MAX_8X_STEP_ISR_FREQUENCY >> 3),
|
||||
( MAX_16X_STEP_ISR_FREQUENCY >> 4),
|
||||
( MAX_32X_STEP_ISR_FREQUENCY >> 5),
|
||||
( MAX_64X_STEP_ISR_FREQUENCY >> 6),
|
||||
(MAX_128X_STEP_ISR_FREQUENCY >> 7)
|
||||
};
|
||||
|
||||
// Select the proper multistepping
|
||||
uint8_t idx = 0;
|
||||
while (idx < 7 && step_rate > (uint32_t)pgm_read_dword(&limit[idx])) {
|
||||
step_rate >>= 1;
|
||||
step_loops = 2;
|
||||
}
|
||||
else {
|
||||
step_loops = 1;
|
||||
}
|
||||
multistep <<= 1;
|
||||
++idx;
|
||||
};
|
||||
#else
|
||||
NOMORE(step_rate, uint32_t(MAX_1X_STEP_ISR_FREQUENCY));
|
||||
#endif
|
||||
*loops = multistep;
|
||||
|
||||
NOLESS(step_rate, uint32_t(F_CPU / 500000U));
|
||||
step_rate -= F_CPU / 500000; // Correct for minimal speed
|
||||
constexpr uint32_t min_step_rate = F_CPU / 500000U;
|
||||
NOLESS(step_rate, min_step_rate);
|
||||
step_rate -= min_step_rate; // Correct for minimal speed
|
||||
if (step_rate >= (8 * 256)) { // higher step rate
|
||||
const uint8_t tmp_step_rate = (step_rate & 0x00FF);
|
||||
const uint16_t table_address = (uint16_t)&speed_lookuptable_fast[(uint8_t)(step_rate >> 8)][0],
|
||||
@ -322,10 +352,8 @@ class Stepper {
|
||||
timer = (uint16_t)pgm_read_word_near(table_address)
|
||||
- (((uint16_t)pgm_read_word_near(table_address + 2) * (uint8_t)(step_rate & 0x0007)) >> 3);
|
||||
}
|
||||
if (timer < 100) { // (20kHz - this should never happen)
|
||||
timer = 100;
|
||||
SERIAL_ECHOLNPAIR(MSG_STEPPER_TOO_HIGH, step_rate);
|
||||
}
|
||||
// (there is no need to limit the timer value here. All limits have been
|
||||
// applied above, and AVR is able to keep up at 30khz Stepping ISR rate)
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user