Skip to content

Commit 57ec89d

Browse files
authored
Merge pull request #388 from Copper280z/timer_prescaler
Set STM32 timer prescaler based on timer clock frequency
2 parents f3492df + f2b7b22 commit 57ec89d

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/drivers/hardware_specific/stm32/stm32_mcu.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ PinMap* timerPinsUsed[SIMPLEFOC_STM32_MAX_PINTIMERSUSED];
2626

2727

2828

29+
bool _getPwmState(void* params) {
30+
// assume timers are synchronized and that there's at least one timer
31+
HardwareTimer* pHT = ((STM32DriverParams*)params)->timers[0];
32+
TIM_HandleTypeDef* htim = pHT->getHandle();
33+
34+
bool dir = __HAL_TIM_IS_TIM_COUNTING_DOWN(htim);
2935

36+
return dir;
37+
}
3038

3139

3240
// setting pwm to hardware pin - instead analogWrite()
@@ -230,7 +238,7 @@ int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) { //
230238
#endif
231239
return -1;
232240
}
233-
#elif defined(STM32F4xx) || defined(STM32F1xx) || defined(STM32L4xx)
241+
#elif defined(STM32F4xx) || defined(STM32F1xx) || defined(STM32L4xx) || defined(STM32F7xx)
234242

235243
// function finds the appropriate timer source trigger for the master/slave timer combination
236244
// returns -1 if no trigger source is found
@@ -303,6 +311,30 @@ int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) {
303311
}
304312
#endif
305313

314+
void syncTimerFrequency(long pwm_frequency, HardwareTimer *timers[], uint8_t num_timers) {
315+
uint32_t max_frequency = 0;
316+
uint32_t min_frequency = UINT32_MAX;
317+
for (size_t i=0; i<num_timers; i++) {
318+
uint32_t freq = timers[i]->getTimerClkFreq();
319+
if (freq > max_frequency) {
320+
max_frequency = freq;
321+
} else if (freq < min_frequency) {
322+
min_frequency = freq;
323+
}
324+
}
325+
if (max_frequency==min_frequency) return;
326+
uint32_t overflow_value = min_frequency/pwm_frequency;
327+
for (size_t i=0; i<num_timers; i++) {
328+
uint32_t prescale_factor = timers[i]->getTimerClkFreq()/min_frequency;
329+
#ifdef SIMPLEFOC_DEBUG
330+
SIMPLEFOC_DEBUG("STM32-DRV: Setting prescale to ", (float)prescale_factor);
331+
SIMPLEFOC_DEBUG("STM32-DRV: Setting Overflow to ", (float)overflow_value);
332+
#endif
333+
timers[i]->setPrescaleFactor(prescale_factor);
334+
timers[i]->setOverflow(overflow_value,TICK_FORMAT);
335+
timers[i]->refresh();
336+
}
337+
}
306338

307339
void _alignTimersNew() {
308340
int numTimers = 0;
@@ -382,7 +414,7 @@ void _alignTimersNew() {
382414
// enable timer clock
383415
for (int i=0; i<numTimers; i++) {
384416
timers[i]->pause();
385-
//timers[i]->refresh();
417+
// timers[i]->refresh();
386418
#ifdef SIMPLEFOC_STM32_DEBUG
387419
SIMPLEFOC_DEBUG("STM32-DRV: Restarting timer ", getTimerNumber(get_timer_index(timers[i]->getHandle()->Instance)));
388420
#endif
@@ -735,6 +767,8 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
735767

736768
HardwareTimer* HT1 = _initPinPWM(pwm_frequency, pinTimers[0]);
737769
HardwareTimer* HT2 = _initPinPWM(pwm_frequency, pinTimers[1]);
770+
HardwareTimer *timers[2] = {HT1, HT2};
771+
syncTimerFrequency(pwm_frequency, timers, 2);
738772
// allign the timers
739773
_alignPWMTimers(HT1, HT2, HT2);
740774

@@ -779,6 +813,9 @@ void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const in
779813
HardwareTimer* HT2 = _initPinPWM(pwm_frequency, pinTimers[1]);
780814
HardwareTimer* HT3 = _initPinPWM(pwm_frequency, pinTimers[2]);
781815

816+
HardwareTimer *timers[3] = {HT1, HT2, HT3};
817+
syncTimerFrequency(pwm_frequency, timers, 3);
818+
782819
uint32_t channel1 = STM_PIN_CHANNEL(pinTimers[0]->function);
783820
uint32_t channel2 = STM_PIN_CHANNEL(pinTimers[1]->function);
784821
uint32_t channel3 = STM_PIN_CHANNEL(pinTimers[2]->function);
@@ -821,6 +858,8 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in
821858
HardwareTimer* HT2 = _initPinPWM(pwm_frequency, pinTimers[1]);
822859
HardwareTimer* HT3 = _initPinPWM(pwm_frequency, pinTimers[2]);
823860
HardwareTimer* HT4 = _initPinPWM(pwm_frequency, pinTimers[3]);
861+
HardwareTimer *timers[4] = {HT1, HT2, HT3, HT4};
862+
syncTimerFrequency(pwm_frequency, timers, 4);
824863
// allign the timers
825864
_alignPWMTimers(HT1, HT2, HT3, HT4);
826865

@@ -918,6 +957,8 @@ void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, cons
918957
HardwareTimer* HT4 = _initPinPWMLow(pwm_frequency, pinTimers[3]);
919958
HardwareTimer* HT5 = _initPinPWMHigh(pwm_frequency, pinTimers[4]);
920959
HardwareTimer* HT6 = _initPinPWMLow(pwm_frequency, pinTimers[5]);
960+
HardwareTimer *timers[6] = {HT1, HT2, HT3, HT4, HT5, HT6};
961+
syncTimerFrequency(pwm_frequency, timers, 6);
921962
uint32_t channel1 = STM_PIN_CHANNEL(pinTimers[0]->function);
922963
uint32_t channel2 = STM_PIN_CHANNEL(pinTimers[1]->function);
923964
uint32_t channel3 = STM_PIN_CHANNEL(pinTimers[2]->function);

src/drivers/hardware_specific/stm32/stm32_mcu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ typedef struct STM32DriverParams {
2828
void _stopTimers(HardwareTimer **timers_to_stop, int timer_num=6);
2929
void _startTimers(HardwareTimer **timers_to_start, int timer_num=6);
3030

31+
// timer query functions
32+
bool _getPwmState(void* params);
33+
3134
#endif
3235
#endif

0 commit comments

Comments
 (0)