Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rcc: Calculate PLL clocks and implement core clock configuration logic #13

Merged
merged 2 commits into from
Aug 12, 2024

Conversation

astapleton
Copy link
Contributor

This implements the PLL and clock configuration logic for the processor using the RCC peripheral.

  • The pll module is responsible for configuring the VCOs and setting up the PLL dividers for the desired frequency
  • The freeze method in the rcc module does the heavy lifting for making sure that the processor clocks are configured in the desired manner

Note: This is largely copied from the implementation in stm32h7xx-hal, although it significantly refactors and modifies the PLL configuration in the pll module. This was mostly due to the differences in the register definitions used by the calculation and the fact that the H5 family (and especially the H503 MCU) is quite a bit simpler than the H7 family. I made significant changes to the the PLL configuration due to the stm32h7xx-hal crate being a bit bugged: it calculates values for Q and R outputs that are invalid for fractional PLL configurations.

@astapleton astapleton force-pushed the as/rcc-logic branch 3 times, most recently from b4b0156 to 35c582a Compare June 7, 2024 23:43
@astapleton astapleton changed the title rcc: calculate PLL clocks and implement core clock configuration logic rcc: Calculate PLL clocks and implement core clock configuration logic Jun 7, 2024
@astapleton astapleton force-pushed the as/rcc-rec branch 4 times, most recently from 9375aa5 to 21b6790 Compare June 11, 2024 00:54
@astapleton astapleton force-pushed the as/rcc-logic branch 2 times, most recently from 9db330c to b6a314f Compare June 11, 2024 01:01
let output_q = vco_ck_achieved as f32 / pll_x_q as f32;
println!("Q Divider {}", pll_x_q);
println!("==> Output Q {} MHz", output_q / 1e6);
println!();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally there would be an assert! statements to check the values here

@richardeoin
Copy link
Member

This is by necessity quite complex and error-prone logic, and at a first review it looks good! The two options for PllConfigStrategy cover most use cases and keeps it simple. Can you explain a little more about the bug you saw with Q and R outputs for fractional dividers? The Q and R divider values are calculated from the vco output frequency, which should be valid in either integer or fractional mode

@astapleton
Copy link
Contributor Author

astapleton commented Jun 20, 2024

This is by necessity quite complex and error-prone logic, and at a first review it looks good! The two options for PllConfigStrategy cover most use cases and keeps it simple. Can you explain a little more about the bug you saw with Q and R outputs for fractional dividers? The Q and R divider values are calculated from the vco output frequency, which should be valid in either integer or fractional mode

Looking back at the patch I originally made to address the error I found, it looks like because the H7 VCO derivation chooses the maximum output frequency for the VCO (see here), it looks like if a high enough frequency is chosen for the system clock, which is then derived from PLL1, it's not possible to select frequencies in the low megahertz range on a different PLL (divider is >128).

For instance, the fractional-pll example in #15 would not work with the H7 logic: it fails calculating a divider for PLL2Q, after having chosen the max VCO output frequency of 836MHz and needing an integer divider of 135 to get to 6.144MHz. It might be that I introduced an error while adapting it for H5, so perhaps it does work fine on an actual H7.

It looks like the patch I made (last year, so my memory is a bit fuzzy) ended up becoming quite a bit more extensive than just addressing that, so the VCO setup here is quite a bit different than the H7 code.

@richardeoin
Copy link
Member

the H7 VCO derivation chooses the maximum output frequency for the VCO (see here), it looks like if a high enough frequency is chosen for the system clock, which is then derived from PLL1, it's not possible to select frequencies in the low megahertz range on a different PLL (divider is >128).

Aha, I ignored the use case of PLL outputs with frequencies of the (max VCO frequency/128) or less. Nice that you've improved that.

Thanks for adding the tests.

@astapleton astapleton force-pushed the as/rcc-logic branch 2 times, most recently from 0a405b4 to 5da38aa Compare July 31, 2024 22:31
Base automatically changed from as/rcc-rec to master August 12, 2024 17:52
@astapleton astapleton merged commit 6fa92c1 into master Aug 12, 2024
14 checks passed
@astapleton astapleton deleted the as/rcc-logic branch August 12, 2024 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants