AnsweredAssumed Answered

Cannot Enable More Than 1 Output on PLL2/3

Question asked by Merle Skelton on Apr 24, 2018
Latest reply on Apr 26, 2018 by Merle Skelton

I am using the STM32H743xx Nucleo board with CubeMX V4.25.0 and CubeH7 V1.2.0.

The HAL drivers have some issues with enabling the PLLs and individual PLL outputs (P, Q, R).

1. HAL_RCC_OscConfig() always enables all PLL1 outputs (P, Q, R) even if they are not used.
2. HAL_RCCEx_PeriphCLKConfig() has the problem with PLL2/3. Only the first output enabled gets enabled. PLL2/3 also have the problem when an output is mapped to MCO1/MCO2, the PLL and output will not be enabled unless a peripheral using that output is also enabled. If a peripheral uses a PLL1 output, it only works because HAL_RCC_OscConfig() has already enabled all the PLL1 outputs.

 

At least for PLL2/3, CubeMX attempts to save power by only enabling the PLL if an output is mapped to a peripheral, and only mapped outputs are enabled. Unused outputs are not enabled. Apparently PLL1 does not have these rules. I am only using PLL1P, but outputs Q & R are also always enabled by HAL_RCC_OscConfig().

At reset, HAL_RCC_OscConfig() runs first and always enables PLL1 and all of its outputs. The good news is that because all PLL1 outputs are enabled, peripherals that use PLL1 will work. Things are not so good for PLL2/3 peripherals. For PLL2/3, which are configured by HAL_RCCEx_PeriphCLKConfig(), only the first enabled output gets enabled, and this is only because the PLL is disabled at reset. The problem in HAL_RCCEx_PeriphCLKConfig() is that after the first PLL output is enabled, the PLL is enabled. The next peripheral that attempts to use a different PLL output first sets the output enable then calls the RCCEx_PLLx_Config(). Setting an output enable for a PLL clock cannot be done when the PLL is already enabled. The PLL must be disabled first, then outputs can be enabled. As a result of RCCEx_PLLx_Config() enabling the PLL, only one PLL clock output can be enabled on PLL2/3.

 

The functions mentioned above need to be restructured to determine all the used PLLs and outputs, then enable the PLL after the required outputs are enabled. Actually Cube MX knows this and could generate another ".init" parameter specifying the OR'ed mask of PLL outputs to enable per PLL. Also, the MCO1/MCO2, outputs need to be considered as peripherals when enabling PLL outputs. I am using PLL2P mapped to MCO2 to provide an external clock. To do so, CubeMX required me to enable a peripheral like LPTIM1 also mapped to PLL2P to be able to configure PLL2. I am implementing a simple fix so I can keep working.

 

Another CubeMX improvement would be to include the fractional multiplier value in the Clock Configuration tab calculations. As I am using the fractional multiplier on PLL1, all the system related clocks in the Clock Configuration tab are wrong, but the calculated SystemCoreClock in the code is correct. Maybe the clocks are  just being rounded/truncated in the Clock Configuration tab. It would be convenient if one could hover over a clock in the Clock Configuration tab and see the actual frequency and name used in the driver code. Currently if one hovers over a clock in the Clock Configuration tab, usually only the label to the right of the clock name is displayed, which is of no help.

This posting supersedes my posting named "STM32H7 PLLFRACN Support" which I have marked as answered. This posting is more complete.

Outcomes