Skip to content

Commit 1ae389a

Browse files
authored
Merge pull request #374 from simplefoc/feat_stm32_synctimers
Feat stm32 synctimers
2 parents 412642d + 3ad11ee commit 1ae389a

File tree

1 file changed

+175
-21
lines changed

1 file changed

+175
-21
lines changed

src/drivers/hardware_specific/stm32/stm32_mcu.cpp

Lines changed: 175 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
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("")
1011

1112

12-
//#define SIMPLEFOC_STM32_DEBUG
13-
1413
#ifdef SIMPLEFOC_STM32_DEBUG
1514
void printTimerCombination(int numPins, PinMap* timers[], int score);
1615
int getTimerNumber(int timerIndex);
@@ -204,25 +203,112 @@ void _stopTimers(HardwareTimer **timers_to_stop, int timer_num)
204203
}
205204
}
206205

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-
}
206+
207+
#if defined(STM32G4xx)
208+
// function finds the appropriate timer source trigger for the master/slave timer combination
209+
// returns -1 if no trigger source is found
210+
// currently supports the master timers to be from TIM1 to TIM4 and TIM8
211+
int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) { // put master and slave in temp variables to avoid arrows
212+
TIM_TypeDef *TIM_master = master->getHandle()->Instance;
213+
#if defined(TIM1) && defined(LL_TIM_TS_ITR0)
214+
if (TIM_master == TIM1) return LL_TIM_TS_ITR0;// return TIM_TS_ITR0;
215+
#endif
216+
#if defined(TIM2) && defined(LL_TIM_TS_ITR1)
217+
else if (TIM_master == TIM2) return LL_TIM_TS_ITR1;//return TIM_TS_ITR1;
218+
#endif
219+
#if defined(TIM3) && defined(LL_TIM_TS_ITR2)
220+
else if (TIM_master == TIM3) return LL_TIM_TS_ITR2;//return TIM_TS_ITR2;
221+
#endif
222+
#if defined(TIM4) && defined(LL_TIM_TS_ITR3)
223+
else if (TIM_master == TIM4) return LL_TIM_TS_ITR3;//return TIM_TS_ITR3;
224+
#endif
225+
#if defined(TIM5) && defined(LL_TIM_TS_ITR4)
226+
else if (TIM_master == TIM5) return LL_TIM_TS_ITR4;//return TIM_TS_ITR4;
227+
#endif
228+
#if defined(TIM8) && defined(LL_TIM_TS_ITR5)
229+
else if (TIM_master == TIM8) return LL_TIM_TS_ITR5;//return TIM_TS_ITR5;
230+
#endif
231+
return -1;
232+
}
233+
#elif defined(STM32F4xx) || defined(STM32F1xx) || defined(STM32L4xx)
234+
235+
// function finds the appropriate timer source trigger for the master/slave timer combination
236+
// returns -1 if no trigger source is found
237+
// currently supports the master timers to be from TIM1 to TIM4 and TIM8
238+
int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) {
239+
// put master and slave in temp variables to avoid arrows
240+
TIM_TypeDef *TIM_master = master->getHandle()->Instance;
241+
TIM_TypeDef *TIM_slave = slave->getHandle()->Instance;
242+
#if defined(TIM1) && defined(LL_TIM_TS_ITR0)
243+
if (TIM_master == TIM1){
244+
if(TIM_slave == TIM2 || TIM_slave == TIM3 || TIM_slave == TIM4) return LL_TIM_TS_ITR0;
245+
#if defined(TIM8)
246+
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR0;
247+
#endif
248+
}
249+
#endif
250+
#if defined(TIM2) && defined(LL_TIM_TS_ITR1)
251+
else if (TIM_master == TIM2){
252+
if(TIM_slave == TIM1 || TIM_slave == TIM3 || TIM_slave == TIM4) return LL_TIM_TS_ITR1;
253+
#if defined(TIM8)
254+
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR1;
255+
#endif
256+
#if defined(TIM5)
257+
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR0;
258+
#endif
259+
}
260+
#endif
261+
#if defined(TIM3) && defined(LL_TIM_TS_ITR2)
262+
else if (TIM_master == TIM3){
263+
if(TIM_slave== TIM1 || TIM_slave == TIM2 || TIM_slave == TIM4) return LL_TIM_TS_ITR2;
264+
#if defined(TIM5)
265+
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR1;
266+
#endif
267+
}
268+
#endif
269+
#if defined(TIM4) && defined(LL_TIM_TS_ITR3)
270+
else if (TIM_master == TIM4){
271+
if(TIM_slave == TIM1 || TIM_slave == TIM2 || TIM_slave == TIM3) return LL_TIM_TS_ITR3;
272+
#if defined(TIM8)
273+
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR2;
274+
#endif
275+
#if defined(TIM5)
276+
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR1;
277+
#endif
278+
}
279+
#endif
280+
#if defined(TIM5)
281+
else if (TIM_master == TIM5){
282+
#if !defined(STM32L4xx) // only difference between F4,F1 and L4
283+
if(TIM_slave == TIM1) return LL_TIM_TS_ITR0;
284+
else if(TIM_slave == TIM3) return LL_TIM_TS_ITR2;
285+
#endif
286+
#if defined(TIM8)
287+
if(TIM_slave == TIM8) return LL_TIM_TS_ITR3;
288+
#endif
289+
}
290+
#endif
291+
#if defined(TIM8)
292+
else if (TIM_master == TIM8){
293+
if(TIM_slave==TIM2) return LL_TIM_TS_ITR1;
294+
else if(TIM_slave ==TIM4 || TIM_slave ==TIM5) return LL_TIM_TS_ITR3;
295+
}
296+
#endif
297+
return -1; // combination not supported
298+
}
299+
#else
300+
// Alignment not supported for this architecture
301+
int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) {
302+
return -1;
219303
}
304+
#endif
305+
220306

221307
void _alignTimersNew() {
222308
int numTimers = 0;
223309
HardwareTimer *timers[numTimerPinsUsed];
224310

225-
// reset timer counters
311+
// find the timers used
226312
for (int i=0; i<numTimerPinsUsed; i++) {
227313
uint32_t index = get_timer_index((TIM_TypeDef*)timerPinsUsed[i]->peripheral);
228314
HardwareTimer *timer = (HardwareTimer *)(HardwareTimer_Handle[index]->__this);
@@ -237,6 +323,62 @@ void _alignTimersNew() {
237323
timers[numTimers++] = timer;
238324
}
239325

326+
#ifdef SIMPLEFOC_STM32_DEBUG
327+
SIMPLEFOC_DEBUG("STM32-DRV: Syncronising timers! Timer no. ", numTimers);
328+
#endif
329+
330+
// see if there is more then 1 timers used for the pwm
331+
// if yes, try to align timers
332+
if(numTimers > 1){
333+
// find the master timer
334+
int16_t master_index = -1;
335+
int triggerEvent = -1;
336+
for (int i=0; i<numTimers; i++) {
337+
// check if timer can be master
338+
if(IS_TIM_MASTER_INSTANCE(timers[i]->getHandle()->Instance)) {
339+
// check if timer already configured in TRGO update mode (used for ADC triggering)
340+
// in that case we should not change its TRGO configuration
341+
if(timers[i]->getHandle()->Instance->CR2 & LL_TIM_TRGO_UPDATE) continue;
342+
// check if the timer has the supported internal trigger for other timers
343+
for (int slave_i=0; slave_i<numTimers; slave_i++) {
344+
if (i==slave_i) continue; // skip self
345+
// check if it has the supported internal trigger
346+
triggerEvent = _getInternalSourceTrigger(timers[i],timers[slave_i]);
347+
if(triggerEvent == -1) break; // not supported keep searching
348+
}
349+
if(triggerEvent == -1) continue; // cannot be master, keep searching
350+
// otherwise the master has been found, remember the index
351+
master_index = i; // found the master timer
352+
break;
353+
}
354+
}
355+
356+
357+
// if no master timer found do not perform alignment
358+
if (master_index == -1) {
359+
#ifdef SIMPLEFOC_STM32_DEBUG
360+
SIMPLEFOC_DEBUG("STM32-DRV: ERR: No master timer found, cannot align timers!");
361+
#endif
362+
}else{
363+
#ifdef SIMPLEFOC_STM32_DEBUG
364+
SIMPLEFOC_DEBUG("STM32-DRV: Aligning PWM to master timer: ", getTimerNumber(get_timer_index(timers[master_index]->getHandle()->Instance)));
365+
#endif
366+
// make the master timer generate ITRGx event
367+
// if it was already configured in slave mode
368+
LL_TIM_SetSlaveMode(timers[master_index]->getHandle()->Instance, LL_TIM_SLAVEMODE_DISABLED );
369+
// Configure the master timer to send a trigger signal on enable
370+
LL_TIM_SetTriggerOutput(timers[master_index]->getHandle()->Instance, LL_TIM_TRGO_ENABLE);
371+
// configure other timers to get the input trigger from the master timer
372+
for (int slave_index=0; slave_index < numTimers; slave_index++) {
373+
if (slave_index == master_index)
374+
continue;
375+
// Configure the slave timer to be triggered by the master enable signal
376+
LL_TIM_SetTriggerInput(timers[slave_index]->getHandle()->Instance, _getInternalSourceTrigger(timers[master_index], timers[slave_index]));
377+
LL_TIM_SetSlaveMode(timers[slave_index]->getHandle()->Instance, LL_TIM_SLAVEMODE_TRIGGER);
378+
}
379+
}
380+
}
381+
240382
// enable timer clock
241383
for (int i=0; i<numTimers; i++) {
242384
timers[i]->pause();
@@ -254,6 +396,20 @@ void _alignTimersNew() {
254396

255397

256398

399+
// align the timers to end the init
400+
void _startTimers(HardwareTimer **timers_to_start, int timer_num)
401+
{
402+
// // TODO - start each timer only once
403+
// // start timers
404+
// for (int i=0; i < timer_num; i++) {
405+
// if(timers_to_start[i] == NP) return;
406+
// timers_to_start[i]->resume();
407+
// #ifdef SIMPLEFOC_STM32_DEBUG
408+
// SIMPLEFOC_DEBUG("STM32-DRV: Starting timer ", getTimerNumber(get_timer_index(timers_to_start[i]->getHandle()->Instance)));
409+
// #endif
410+
// }
411+
_alignTimersNew();
412+
}
257413

258414

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

542698
HardwareTimer* HT1 = _initPinPWM(pwm_frequency, pinTimers[0]);\
543-
// allign the timers
699+
// align the timers
544700
_alignTimersNew();
545701

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

599755

600756

757+
TIM_MasterConfigTypeDef sMasterConfig;
758+
TIM_SlaveConfigTypeDef sSlaveConfig;
601759

602760
// function setting the high pwm frequency to the supplied pins
603761
// - BLDC motor - 3PWM setting
@@ -620,7 +778,7 @@ void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const in
620778
HardwareTimer* HT1 = _initPinPWM(pwm_frequency, pinTimers[0]);
621779
HardwareTimer* HT2 = _initPinPWM(pwm_frequency, pinTimers[1]);
622780
HardwareTimer* HT3 = _initPinPWM(pwm_frequency, pinTimers[2]);
623-
781+
624782
uint32_t channel1 = STM_PIN_CHANNEL(pinTimers[0]->function);
625783
uint32_t channel2 = STM_PIN_CHANNEL(pinTimers[1]->function);
626784
uint32_t channel3 = STM_PIN_CHANNEL(pinTimers[2]->function);
@@ -945,8 +1103,4 @@ void printTimerCombination(int numPins, PinMap* timers[], int score) {
9451103

9461104
#endif
9471105

948-
949-
950-
951-
9521106
#endif

0 commit comments

Comments
 (0)