Set STM32 timer prescaler based on timer clock frequency #388
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit adds a function which calculates the correct timer prescaler value based on the actual timer clock frequency and sets it. This is necessary because some stm32duino clock configs, specifically the nucleo-f746zg, set things up such that the timers have an input frequency that differs by 2x. Families other than F7 also allow for this, but don't seem to have the same problem with the default configs.
HardwareTimer->setOverflow(num, HERTZ_FORMAT) attempts to deal with this, but it does so by setting TIMx->ARR to a value that differs by 2x, instead of setting the prescaler. For some PWM frequencies this leads to an off-by-one error in ARR between the different timers(with the 2x factor taken into account). The values I observed with the aforementioned f746 were
This new function finds the lowest timer frequency for all timers, then calculates the prescaler value for each timer that's required to make the counter frequency match. It also calculates the correct overflow value for this frequency and sets it with HT->setOverflow(num, TICK_FORMAT), which does not reset the prescaler value. This method does require that no further calls to setOverflow are made with HERTZ_FORMAT, otherwise the prescaler value will be overwritten.
Additionally this change also adds the _getPwmState function, in anticipation of merging HFI support, as well as adding the STM32F7 family to the list of defines in _getInternalSourceTrigger. The F7 family timer interconnections appear to mirror the F4 family.
pg713 of RM0385 rev8 (STM32F74xx and F75xx reference manual)
pg794
So far I've tested this on the F746 nucleo + SFOC shield and it works as expected. I haven't tested further on other targets.