Skip to content

Commit a49da45

Browse files
committed
initial version of comprehensive timer synchornisation for truly center aligned PWM for stm32 (when using more than one timer)
1 parent 813917a commit a49da45

File tree

1 file changed

+99
-19
lines changed

1 file changed

+99
-19
lines changed

src/drivers/hardware_specific/stm32/stm32_mcu.cpp

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#if defined(_STM32_DEF_)
66

7+
#define SIMPLEFOC_STM32_DEBUG
78
#pragma message("")
89
#pragma message("SimpleFOC: compiling for STM32")
910
#pragma message("")
@@ -204,25 +205,43 @@ void _stopTimers(HardwareTimer **timers_to_stop, int timer_num)
204205
}
205206
}
206207

207-
// align the timers to end the init
208-
void _startTimers(HardwareTimer **timers_to_start, int timer_num)
209-
{
210-
// TODO - sart each timer only once
211-
// sart timers
212-
for (int i=0; i < timer_num; i++) {
213-
if(timers_to_start[i] == NP) return;
214-
timers_to_start[i]->resume();
215-
#ifdef SIMPLEFOC_STM32_DEBUG
216-
SIMPLEFOC_DEBUG("STM32-DRV: Starting timer ", getTimerNumber(get_timer_index(timers_to_start[i]->getHandle()->Instance)));
217-
#endif
218-
}
208+
209+
// function finds the appropriate timer source trigger for the master timer index provided
210+
// returns -1 if no trigger source is found
211+
// currently supports the master timers to be from TIM1 to TIM8
212+
int _getTriggerSourceRegister(HardwareTimer* timer) {
213+
#if defined(TIM1) && TIM_TS_ITR0
214+
if (timer->getHandle()->Instance == TIM1) return LL_TIM_TS_ITR0;// return TIM_TS_ITR0;
215+
#endif
216+
#if defined(TIM2) && TIM_TS_ITR1
217+
if (timer->getHandle()->Instance == TIM2) return LL_TIM_TS_ITR1;//return TIM_TS_ITR1;
218+
#endif
219+
#if defined(TIM3) && TIM_TS_ITR2
220+
if (timer->getHandle()->Instance == TIM3) return LL_TIM_TS_ITR2;//return TIM_TS_ITR2;
221+
#endif
222+
#if defined(TIM4) && TIM_TS_ITR3
223+
if (timer->getHandle()->Instance == TIM4) return LL_TIM_TS_ITR3;//return TIM_TS_ITR3;
224+
#endif
225+
#if defined(TIM5) && TIM_TS_ITR4
226+
if (timer->getHandle()->Instance == TIM5) return LL_TIM_TS_ITR4;//return TIM_TS_ITR4;
227+
#endif
228+
#if defined(TIM6) && TIM_TS_ITR5
229+
if (timer->getHandle()->Instance == TIM6) return LL_TIM_TS_ITR5;//return TIM_TS_ITR5;
230+
#endif
231+
#if defined(TIM7) && TIM_TS_ITR6
232+
if (timer->getHandle()->Instance == TIM7) return LL_TIM_TS_ITR6;//return TIM_TS_ITR6;
233+
#endif
234+
#if defined(TIM8) && TIM_TS_ITR7
235+
if (timer->getHandle()->Instance == TIM8) return LL_TIM_TS_ITR7;// return TIM_TS_ITR7;
236+
#endif
237+
return -1;
219238
}
220239

221240
void _alignTimersNew() {
222241
int numTimers = 0;
223242
HardwareTimer *timers[numTimerPinsUsed];
224243

225-
// reset timer counters
244+
// find the timers used
226245
for (int i=0; i<numTimerPinsUsed; i++) {
227246
uint32_t index = get_timer_index((TIM_TypeDef*)timerPinsUsed[i]->peripheral);
228247
HardwareTimer *timer = (HardwareTimer *)(HardwareTimer_Handle[index]->__this);
@@ -237,6 +256,55 @@ void _alignTimersNew() {
237256
timers[numTimers++] = timer;
238257
}
239258

259+
// see if there is more then 1 timers used for the pwm
260+
// if yes, try to align timers
261+
if(numTimers > 1){
262+
// find the master timer
263+
uint8_t masterTimerIndex = 0;
264+
int triggerEvent = -1;
265+
for (int i=0; i<numTimers; i++) {
266+
// check if timer can be master
267+
if(IS_TIM_MASTER_INSTANCE(timers[i]->getHandle()->Instance)) {
268+
// check if timer already configured in TRGO update mode (used for ADC triggering)
269+
// in that case we should not change its TRGO configuration
270+
if(timers[i]->getHandle()->Instance->CR2 & LL_TIM_TRGO_UPDATE) continue;
271+
// check if it has the supported internal trigger
272+
triggerEvent = _getTriggerSourceRegister(timers[i]);
273+
if(triggerEvent == -1) continue; // not supported keep searching
274+
masterTimerIndex = i; // found the master timer
275+
break;
276+
}
277+
}
278+
279+
#ifdef SIMPLEFOC_STM32_DEBUG
280+
SIMPLEFOC_DEBUG("STM32-DRV: aligning!");
281+
#endif
282+
283+
// if no master timer found do not perform alignment
284+
if (triggerEvent == -1) {
285+
#ifdef SIMPLEFOC_STM32_DEBUG
286+
SIMPLEFOC_DEBUG("STM32-DRV: ERR: No master timer found, cannot align timers!");
287+
#endif
288+
}else{
289+
#ifdef SIMPLEFOC_STM32_DEBUG
290+
SIMPLEFOC_DEBUG("STM32-DRV: Aligning PWM to master timer: ", getTimerNumber(get_timer_index(timers[masterTimerIndex]->getHandle()->Instance)));
291+
#endif
292+
// make the master timer generate ITRGx event
293+
// if it was already configured in slave mode
294+
LL_TIM_SetSlaveMode(timers[masterTimerIndex]->getHandle()->Instance, LL_TIM_SLAVEMODE_DISABLED );
295+
// Configure the master timer to send a trigger signal on enable
296+
LL_TIM_SetTriggerOutput(timers[masterTimerIndex]->getHandle()->Instance, LL_TIM_TRGO_ENABLE);
297+
// configure other timers to get the input trigger from the master timer
298+
for (int i=0; i<numTimers; i++) {
299+
if (i==masterTimerIndex)
300+
continue;
301+
// Configure the slave timer to be triggered by the master enable signal
302+
LL_TIM_SetTriggerInput(timers[i]->getHandle()->Instance, triggerEvent);
303+
LL_TIM_SetSlaveMode(timers[i]->getHandle()->Instance, LL_TIM_SLAVEMODE_TRIGGER);
304+
}
305+
}
306+
}
307+
240308
// enable timer clock
241309
for (int i=0; i<numTimers; i++) {
242310
timers[i]->pause();
@@ -254,6 +322,20 @@ void _alignTimersNew() {
254322

255323

256324

325+
// align the timers to end the init
326+
void _startTimers(HardwareTimer **timers_to_start, int timer_num)
327+
{
328+
// // TODO - start each timer only once
329+
// // start timers
330+
// for (int i=0; i < timer_num; i++) {
331+
// if(timers_to_start[i] == NP) return;
332+
// timers_to_start[i]->resume();
333+
// #ifdef SIMPLEFOC_STM32_DEBUG
334+
// SIMPLEFOC_DEBUG("STM32-DRV: Starting timer ", getTimerNumber(get_timer_index(timers_to_start[i]->getHandle()->Instance)));
335+
// #endif
336+
// }
337+
_alignTimersNew();
338+
}
257339

258340

259341
// configure hardware 6pwm for a complementary pair of channels
@@ -540,7 +622,7 @@ void* _configure1PWM(long pwm_frequency, const int pinA) {
540622
return (STM32DriverParams*)SIMPLEFOC_DRIVER_INIT_FAILED;
541623

542624
HardwareTimer* HT1 = _initPinPWM(pwm_frequency, pinTimers[0]);\
543-
// allign the timers
625+
// align the timers
544626
_alignTimersNew();
545627

546628
uint32_t channel1 = STM_PIN_CHANNEL(pinTimers[0]->function);
@@ -598,6 +680,8 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
598680

599681

600682

683+
TIM_MasterConfigTypeDef sMasterConfig;
684+
TIM_SlaveConfigTypeDef sSlaveConfig;
601685

602686
// function setting the high pwm frequency to the supplied pins
603687
// - BLDC motor - 3PWM setting
@@ -620,7 +704,7 @@ void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const in
620704
HardwareTimer* HT1 = _initPinPWM(pwm_frequency, pinTimers[0]);
621705
HardwareTimer* HT2 = _initPinPWM(pwm_frequency, pinTimers[1]);
622706
HardwareTimer* HT3 = _initPinPWM(pwm_frequency, pinTimers[2]);
623-
707+
624708
uint32_t channel1 = STM_PIN_CHANNEL(pinTimers[0]->function);
625709
uint32_t channel2 = STM_PIN_CHANNEL(pinTimers[1]->function);
626710
uint32_t channel3 = STM_PIN_CHANNEL(pinTimers[2]->function);
@@ -945,8 +1029,4 @@ void printTimerCombination(int numPins, PinMap* timers[], int score) {
9451029

9461030
#endif
9471031

948-
949-
950-
951-
9521032
#endif

0 commit comments

Comments
 (0)