Selaa lähdekoodia

Fix STM32F1 motor shocks (stepper timer issue) (#14030)

Tanguy Pruvot 6 vuotta sitten
vanhempi
commit
19aafb9050

+ 16
- 27
Marlin/src/HAL/HAL_STM32F1/HAL_timers_STM32F1.cpp Näytä tiedosto

42
 // Local defines
42
 // Local defines
43
 // --------------------------------------------------------------------------
43
 // --------------------------------------------------------------------------
44
 
44
 
45
-#define NUM_HARDWARE_TIMERS 4
46
-
47
-//#define PRESCALER 1
48
 // --------------------------------------------------------------------------
45
 // --------------------------------------------------------------------------
49
 // Types
46
 // Types
50
 // --------------------------------------------------------------------------
47
 // --------------------------------------------------------------------------
51
 
48
 
52
-
53
 // --------------------------------------------------------------------------
49
 // --------------------------------------------------------------------------
54
 // Public Variables
50
 // Public Variables
55
 // --------------------------------------------------------------------------
51
 // --------------------------------------------------------------------------
57
 // --------------------------------------------------------------------------
53
 // --------------------------------------------------------------------------
58
 // Private Variables
54
 // Private Variables
59
 // --------------------------------------------------------------------------
55
 // --------------------------------------------------------------------------
60
-/* VGPV
61
-const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
62
-  { TC0, 0, TC0_IRQn, 0},  // 0 - [servo timer5]
63
-  { TC0, 1, TC1_IRQn, 0},  // 1
64
-  { TC0, 2, TC2_IRQn, 0},  // 2
65
-  { TC1, 0, TC3_IRQn, 2},  // 3 - stepper
66
-  { TC1, 1, TC4_IRQn, 15}, // 4 - temperature
67
-  { TC1, 2, TC5_IRQn, 0},  // 5 - [servo timer3]
68
-  { TC2, 0, TC6_IRQn, 0},  // 6
69
-  { TC2, 1, TC7_IRQn, 0},  // 7
70
-  { TC2, 2, TC8_IRQn, 0},  // 8
71
-};
72
-*/
56
+
73
 // --------------------------------------------------------------------------
57
 // --------------------------------------------------------------------------
74
 // Function prototypes
58
 // Function prototypes
75
 // --------------------------------------------------------------------------
59
 // --------------------------------------------------------------------------
101
     case 3: irq_num = NVIC_TIMER3; break;
85
     case 3: irq_num = NVIC_TIMER3; break;
102
     case 4: irq_num = NVIC_TIMER4; break;
86
     case 4: irq_num = NVIC_TIMER4; break;
103
     case 5: irq_num = NVIC_TIMER5; break;
87
     case 5: irq_num = NVIC_TIMER5; break;
88
+    #ifdef STM32_HIGH_DENSITY
89
+      // 6 & 7 are basic timers, avoid them
90
+      case 8: irq_num = NVIC_TIMER8_CC; break;
91
+    #endif
104
     default:
92
     default:
105
       /**
93
       /**
106
-       *  We should not get here, add Sanitycheck for timer number. Should be a general timer
107
-       *  since basic timers do not have CC channels.
108
-       *  Advanced timers should be skipped if possible too, and are not listed above.
94
+       * This should never happen. Add a Sanitycheck for timer number.
95
+       * Should be a general timer since basic timers have no CC channels.
109
        */
96
        */
110
       break;
97
       break;
111
   }
98
   }
118
   switch (timer_num) {
105
   switch (timer_num) {
119
     case STEP_TIMER_NUM:
106
     case STEP_TIMER_NUM:
120
       timer_pause(STEP_TIMER_DEV);
107
       timer_pause(STEP_TIMER_DEV);
108
+      timer_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OUTPUT_COMPARE); // counter
121
       timer_set_count(STEP_TIMER_DEV, 0);
109
       timer_set_count(STEP_TIMER_DEV, 0);
122
       timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1));
110
       timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1));
123
       timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
111
       timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
112
+      timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change
124
       timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE / frequency)));
113
       timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE / frequency)));
114
+      timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register
125
       timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
115
       timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
126
-      nvic_irq_set_priority(irq_num, 1);
116
+      nvic_irq_set_priority(irq_num, STEP_TIMER_IRQ_PRIO);
127
       timer_generate_update(STEP_TIMER_DEV);
117
       timer_generate_update(STEP_TIMER_DEV);
128
       timer_resume(STEP_TIMER_DEV);
118
       timer_resume(STEP_TIMER_DEV);
129
       break;
119
       break;
130
     case TEMP_TIMER_NUM:
120
     case TEMP_TIMER_NUM:
131
       timer_pause(TEMP_TIMER_DEV);
121
       timer_pause(TEMP_TIMER_DEV);
122
+      timer_set_mode(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, TIMER_OUTPUT_COMPARE);
132
       timer_set_count(TEMP_TIMER_DEV, 0);
123
       timer_set_count(TEMP_TIMER_DEV, 0);
133
       timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1));
124
       timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1));
134
       timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
125
       timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
135
       timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
126
       timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
136
       timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
127
       timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
137
-      nvic_irq_set_priority(irq_num, 2);
128
+      nvic_irq_set_priority(irq_num, TEMP_TIMER_IRQ_PRIO);
138
       timer_generate_update(TEMP_TIMER_DEV);
129
       timer_generate_update(TEMP_TIMER_DEV);
139
       timer_resume(TEMP_TIMER_DEV);
130
       timer_resume(TEMP_TIMER_DEV);
140
       break;
131
       break;
145
   switch (timer_num) {
136
   switch (timer_num) {
146
     case STEP_TIMER_NUM: ENABLE_STEPPER_DRIVER_INTERRUPT(); break;
137
     case STEP_TIMER_NUM: ENABLE_STEPPER_DRIVER_INTERRUPT(); break;
147
     case TEMP_TIMER_NUM: ENABLE_TEMPERATURE_INTERRUPT(); break;
138
     case TEMP_TIMER_NUM: ENABLE_TEMPERATURE_INTERRUPT(); break;
148
-    default: break;
149
   }
139
   }
150
 }
140
 }
151
 
141
 
153
   switch (timer_num) {
143
   switch (timer_num) {
154
     case STEP_TIMER_NUM: DISABLE_STEPPER_DRIVER_INTERRUPT(); break;
144
     case STEP_TIMER_NUM: DISABLE_STEPPER_DRIVER_INTERRUPT(); break;
155
     case TEMP_TIMER_NUM: DISABLE_TEMPERATURE_INTERRUPT(); break;
145
     case TEMP_TIMER_NUM: DISABLE_TEMPERATURE_INTERRUPT(); break;
156
-    default: break;
157
   }
146
   }
158
 }
147
 }
159
 
148
 
160
 static inline bool timer_irq_enabled(const timer_dev * const dev, const uint8_t interrupt) {
149
 static inline bool timer_irq_enabled(const timer_dev * const dev, const uint8_t interrupt) {
161
-  return bool(*bb_perip(&(dev->regs).adv->DIER, interrupt));
150
+  return bool(*bb_perip(&(dev->regs).gen->DIER, interrupt));
162
 }
151
 }
163
 
152
 
164
 bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
153
 bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
208
       case 12: return &timer12;
197
       case 12: return &timer12;
209
     #endif
198
     #endif
210
     #if STM32_HAVE_TIMER(13)
199
     #if STM32_HAVE_TIMER(13)
211
-      case 13: return &timer14;
200
+      case 13: return &timer13;
212
     #endif
201
     #endif
213
     #if STM32_HAVE_TIMER(14)
202
     #if STM32_HAVE_TIMER(14)
214
       case 14: return &timer14;
203
       case 14: return &timer14;
215
     #endif
204
     #endif
216
-      default: return nullptr;
205
+    default: return nullptr;
217
   }
206
   }
218
 }
207
 }
219
 
208
 

+ 19
- 21
Marlin/src/HAL/HAL_STM32F1/HAL_timers_STM32F1.h Näytä tiedosto

45
 typedef uint16_t hal_timer_t;
45
 typedef uint16_t hal_timer_t;
46
 #define HAL_TIMER_TYPE_MAX 0xFFFF
46
 #define HAL_TIMER_TYPE_MAX 0xFFFF
47
 
47
 
48
-#define HAL_TIMER_RATE         (F_CPU)  // frequency of timers peripherals
48
+#define HAL_TIMER_RATE uint32_t(F_CPU)  // frequency of timers peripherals
49
 
49
 
50
 #define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
50
 #define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
51
 #define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
51
 #define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
60
 #define PULSE_TIMER_NUM STEP_TIMER_NUM
60
 #define PULSE_TIMER_NUM STEP_TIMER_NUM
61
 #define SERVO0_TIMER_NUM 1  // SERVO0 or BLTOUCH
61
 #define SERVO0_TIMER_NUM 1  // SERVO0 or BLTOUCH
62
 
62
 
63
+#define STEP_TIMER_IRQ_PRIO 1
64
+#define TEMP_TIMER_IRQ_PRIO 2
65
+
63
 #define TEMP_TIMER_PRESCALE     1000 // prescaler for setting Temp timer, 72Khz
66
 #define TEMP_TIMER_PRESCALE     1000 // prescaler for setting Temp timer, 72Khz
64
 #define TEMP_TIMER_FREQUENCY    1000 // temperature interrupt frequency
67
 #define TEMP_TIMER_FREQUENCY    1000 // temperature interrupt frequency
65
 
68
 
126
  */
129
  */
127
 
130
 
128
 FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
131
 FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
129
-  //compare = MIN(compare, HAL_TIMER_TYPE_MAX);
130
   switch (timer_num) {
132
   switch (timer_num) {
131
   case STEP_TIMER_NUM:
133
   case STEP_TIMER_NUM:
132
-    timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, compare);
133
-    return;
134
+    // NOTE: WE have set ARPE = 0, which means the Auto reload register is not preloaded
135
+    // and there is no need to use any compare, as in the timer mode used, setting ARR to the compare value
136
+    // will result in exactly the same effect, ie trigerring an interrupt, and on top, set counter to 0
137
+    timer_set_reload(STEP_TIMER_DEV, compare); // We reload direct ARR as needed during counting up
138
+    break;
134
   case TEMP_TIMER_NUM:
139
   case TEMP_TIMER_NUM:
135
     timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, compare);
140
     timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, compare);
136
-    return;
137
-  default:
138
-    return;
139
-  }
140
-}
141
-
142
-FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
143
-  switch (timer_num) {
144
-  case STEP_TIMER_NUM:
145
-    return timer_get_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN);
146
-  case TEMP_TIMER_NUM:
147
-    return timer_get_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN);
148
-  default:
149
-    return 0;
141
+    break;
150
   }
142
   }
151
 }
143
 }
152
 
144
 
153
 FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
145
 FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
154
   switch (timer_num) {
146
   switch (timer_num) {
155
   case STEP_TIMER_NUM:
147
   case STEP_TIMER_NUM:
156
-    timer_set_count(STEP_TIMER_DEV, 0);
148
+    // No counter to clear
157
     timer_generate_update(STEP_TIMER_DEV);
149
     timer_generate_update(STEP_TIMER_DEV);
158
     return;
150
     return;
159
   case TEMP_TIMER_NUM:
151
   case TEMP_TIMER_NUM:
160
     timer_set_count(TEMP_TIMER_DEV, 0);
152
     timer_set_count(TEMP_TIMER_DEV, 0);
161
     timer_generate_update(TEMP_TIMER_DEV);
153
     timer_generate_update(TEMP_TIMER_DEV);
162
     return;
154
     return;
163
-  default:
164
-    return;
165
   }
155
   }
166
 }
156
 }
167
 
157
 
168
 #define HAL_timer_isr_epilogue(TIMER_NUM)
158
 #define HAL_timer_isr_epilogue(TIMER_NUM)
159
+
160
+// No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple.
161
+// Needed here to reset ARPE=0 for stepper timer
162
+FORCE_INLINE static void timer_no_ARR_preload_ARPE(timer_dev *dev) {
163
+  bb_peri_set_bit(&(dev->regs).gen->CR1, TIMER_CR1_ARPE_BIT, 0);
164
+}
165
+
166
+#define TIMER_OC_NO_PRELOAD 0 // Need to disable preload also on compare registers.

+ 1
- 1
Marlin/src/module/stepper.cpp Näytä tiedosto

1262
   // Program timer compare for the maximum period, so it does NOT
1262
   // Program timer compare for the maximum period, so it does NOT
1263
   // flag an interrupt while this ISR is running - So changes from small
1263
   // flag an interrupt while this ISR is running - So changes from small
1264
   // periods to big periods are respected and the timer does not reset to 0
1264
   // periods to big periods are respected and the timer does not reset to 0
1265
-  HAL_timer_set_compare(STEP_TIMER_NUM, HAL_TIMER_TYPE_MAX);
1265
+  HAL_timer_set_compare(STEP_TIMER_NUM, hal_timer_t(HAL_TIMER_TYPE_MAX));
1266
 
1266
 
1267
   // Count of ticks for the next ISR
1267
   // Count of ticks for the next ISR
1268
   hal_timer_t next_isr_ticks = 0;
1268
   hal_timer_t next_isr_ticks = 0;

Loading…
Peruuta
Tallenna