Browse Source

Step timing cleanup and rounding fix (#16258)

Jason Smith 5 years ago
parent
commit
d5bc5547ee
2 changed files with 27 additions and 12 deletions
  1. 9
    2
      Marlin/src/module/stepper.cpp
  2. 18
    10
      Marlin/src/module/stepper.h

+ 9
- 2
Marlin/src/module/stepper.cpp View File

338
 #if DISABLED(MIXING_EXTRUDER)
338
 #if DISABLED(MIXING_EXTRUDER)
339
   #define E_APPLY_STEP(v,Q) E_STEP_WRITE(stepper_extruder, v)
339
   #define E_APPLY_STEP(v,Q) E_STEP_WRITE(stepper_extruder, v)
340
 #endif
340
 #endif
341
+
342
+#define CYCLES_TO_NS(CYC) (1000UL * (CYC) / ((F_CPU) / 1000000))
343
+constexpr uint32_t NS_PER_PULSE_TIMER_TICK = 1000000000UL / (STEPPER_TIMER_RATE);
344
+
345
+// Round up when converting from ns to timer ticks
346
+constexpr uint32_t NS_TO_PULSE_TIMER_TICKS(uint32_t NS) { return (NS + (NS_PER_PULSE_TIMER_TICK) / 2) / (NS_PER_PULSE_TIMER_TICK); }
347
+
341
 #define TIMER_SETUP_NS (CYCLES_TO_NS(TIMER_READ_ADD_AND_STORE_CYCLES))
348
 #define TIMER_SETUP_NS (CYCLES_TO_NS(TIMER_READ_ADD_AND_STORE_CYCLES))
342
 
349
 
343
 #define PULSE_HIGH_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_HIGH_NS - _MIN(_MIN_PULSE_HIGH_NS, TIMER_SETUP_NS)))
350
 #define PULSE_HIGH_TICK_COUNT hal_timer_t(NS_TO_PULSE_TIMER_TICKS(_MIN_PULSE_HIGH_NS - _MIN(_MIN_PULSE_HIGH_NS, TIMER_SETUP_NS)))
1430
   // Take multiple steps per interrupt (For high speed moves)
1437
   // Take multiple steps per interrupt (For high speed moves)
1431
   bool firstStep = true;
1438
   bool firstStep = true;
1432
   xyze_bool_t step_needed{0};
1439
   xyze_bool_t step_needed{0};
1433
-  hal_timer_t end_tick_count;
1440
+  hal_timer_t end_tick_count = 0;
1434
 
1441
 
1435
   do {
1442
   do {
1436
     #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
1443
     #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
1941
 
1948
 
1942
     // Step E stepper if we have steps
1949
     // Step E stepper if we have steps
1943
     bool firstStep = true;
1950
     bool firstStep = true;
1944
-    hal_timer_t end_tick_count;
1951
+    hal_timer_t end_tick_count = 0;
1945
 
1952
 
1946
     while (LA_steps) {
1953
     while (LA_steps) {
1947
       #if (MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE) && DISABLED(I2S_STEPPER_STREAM)
1954
       #if (MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE) && DISABLED(I2S_STEPPER_STREAM)

+ 18
- 10
Marlin/src/module/stepper.h View File

56
 // Estimate the amount of time the Stepper ISR will take to execute
56
 // Estimate the amount of time the Stepper ISR will take to execute
57
 //
57
 //
58
 
58
 
59
+/**
60
+ * The method of calculating these cycle-constants is unclear.
61
+ * Most of them are no longer used directly for pulse timing, and exist
62
+ * only to estimate a maximum step rate based on the user's configuration.
63
+ * As 32-bit processors continue to diverge, maintaining cycle counts
64
+ * will become increasingly difficult and error-prone.
65
+ */
66
+
59
 #ifdef CPU_32_BIT
67
 #ifdef CPU_32_BIT
68
+  /**
69
+   * Duration of START_TIMED_PULSE
70
+   * 
71
+   * ...as measured on an LPC1768 with a scope and converted to cycles.
72
+   * Not applicable to other 32-bit processors, but as long as others
73
+   * take longer, pulses will be longer. For example the SKR Pro
74
+   * (stm32f407zgt6) requires ~60 cyles.
75
+   */
60
   #define TIMER_READ_ADD_AND_STORE_CYCLES 34UL
76
   #define TIMER_READ_ADD_AND_STORE_CYCLES 34UL
61
 
77
 
62
   // The base ISR takes 792 cycles
78
   // The base ISR takes 792 cycles
86
   #define ISR_STEPPER_CYCLES 16UL
102
   #define ISR_STEPPER_CYCLES 16UL
87
 
103
 
88
 #else
104
 #else
105
+  // Cycles to perform actions in START_TIMED_PULSE
89
   #define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
106
   #define TIMER_READ_ADD_AND_STORE_CYCLES 13UL
90
 
107
 
91
   // The base ISR takes 752 cycles
108
   // The base ISR takes 752 cycles
157
   #define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1UL)
174
   #define MIN_STEPPER_PULSE_CYCLES _MIN_STEPPER_PULSE_CYCLES(1UL)
158
 #endif
175
 #endif
159
 
176
 
160
-// Calculate the minimum ticks of the PULSE timer that must elapse with the step pulse enabled
161
-// adding the "start stepper pulse" code section execution cycles to account for that not all
162
-// pulses start at the beginning of the loop, so an extra time must be added to compensate so
163
-// the last generated pulse (usually the extruder stepper) has the right length
177
+// Calculate the minimum pulse times (high and low)
164
 #if MINIMUM_STEPPER_PULSE && MAXIMUM_STEPPER_RATE
178
 #if MINIMUM_STEPPER_PULSE && MAXIMUM_STEPPER_RATE
165
   constexpr uint32_t _MIN_STEP_PERIOD_NS = 1000000000UL / MAXIMUM_STEPPER_RATE;
179
   constexpr uint32_t _MIN_STEP_PERIOD_NS = 1000000000UL / MAXIMUM_STEPPER_RATE;
166
   constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
180
   constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
167
   constexpr uint32_t _MIN_PULSE_LOW_NS = _MAX((_MIN_STEP_PERIOD_NS - _MIN(_MIN_STEP_PERIOD_NS, _MIN_PULSE_HIGH_NS)), _MIN_PULSE_HIGH_NS);
181
   constexpr uint32_t _MIN_PULSE_LOW_NS = _MAX((_MIN_STEP_PERIOD_NS - _MIN(_MIN_STEP_PERIOD_NS, _MIN_PULSE_HIGH_NS)), _MIN_PULSE_HIGH_NS);
168
 #elif MINIMUM_STEPPER_PULSE
182
 #elif MINIMUM_STEPPER_PULSE
169
   // Assume 50% duty cycle
183
   // Assume 50% duty cycle
170
-  constexpr uint32_t _MIN_STEP_PERIOD_NS = 1000000000UL / MAXIMUM_STEPPER_RATE;
171
   constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
184
   constexpr uint32_t _MIN_PULSE_HIGH_NS = 1000UL * MINIMUM_STEPPER_PULSE;
172
   constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
185
   constexpr uint32_t _MIN_PULSE_LOW_NS = _MIN_PULSE_HIGH_NS;
173
 #elif MAXIMUM_STEPPER_RATE
186
 #elif MAXIMUM_STEPPER_RATE
178
   #error "Expected at least one of MINIMUM_STEPPER_PULSE or MAXIMUM_STEPPER_RATE to be defined"
191
   #error "Expected at least one of MINIMUM_STEPPER_PULSE or MAXIMUM_STEPPER_RATE to be defined"
179
 #endif
192
 #endif
180
 
193
 
181
-// TODO: NS_TO_PULSE_TIMER_TICKS has some rounding issues:
182
-//   1. PULSE_TIMER_TICKS_PER_US rounds to an integer, which loses 20% of the count for a 2.5 MHz pulse tick (such as for LPC1768)
183
-//   2. The math currently rounds down to the closes tick. Perhaps should round up.
184
-constexpr uint32_t NS_TO_PULSE_TIMER_TICKS(uint32_t NS) { return PULSE_TIMER_TICKS_PER_US * (NS) / 1000UL; }
185
-#define CYCLES_TO_NS(CYC) (1000UL * (CYC) / ((F_CPU) / 1000000))
186
 
194
 
187
 // But the user could be enforcing a minimum time, so the loop time is
195
 // But the user could be enforcing a minimum time, so the loop time is
188
 #define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + _MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES))
196
 #define ISR_LOOP_CYCLES (ISR_LOOP_BASE_CYCLES + _MAX(MIN_STEPPER_PULSE_CYCLES, MIN_ISR_LOOP_CYCLES))

Loading…
Cancel
Save