-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Improve f247 PLL output frequency calculation precision #4642
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
base: main
Are you sure you want to change the base?
Conversation
Hmm, nevermind, I forgot about the u32 problem. Although I have an alternative idea. |
b45501e
to
5c6779f
Compare
This will produce the correct result for all integer output frequencies and a truncated result for all non-integer output frequencies instead of accumulating an error. This is done by introducing a time::Scale type which is just a rational representing the numerator <-> denominator relationship of a scaling factor register.
5c6779f
to
08f590e
Compare
Okay, ended up with a different solution which uses u64 for the calculations. There's also now a new internal This is also working on my STM32 but should now work for the whole range of high speed external clock inputs (of which the HSI clock is a member). Worth noting that the division by the peripheral prescalers is still done in the "imprecise" way. But the saving grace is that if you're aiming for an integer clock post prescale, then you will need to start with an integer clock anyway, so someone targeting a very precise peripheral clock shouldn't have any issue. |
FIx looks good in essence (doing The implementation is complex however. I'd prefer if it was done without introducing a new |
Can't do Also, while working on this, I realised there's a numerator and denominator meaning that |
Yeah, just checked, a bunch of f1 and f3 chips have Usbpre which has a 1.5 divisor, and Pllmul which has a 6.5 multiplier. So implementing (Edit: Although it is extremely rare honestly...) |
oh no you're absolutely right. I forgot about those. Making a fraction struct makes sense then, hmm. |
I can split this into multiple commits if you like. One to add the rational type and one to utilise it in the timer code. Would also be happy to further discuss how to proceed with this change or something else entirely, either here or on matrix. |
It was really bugging me, okay?
The PLL frequency calculation will now produce the correct result for all integer output frequencies and a truncated result (e.g. 1234.5 -> 1234) for all non-integer output frequencies instead of accumulating an error.
I've tested this on an STM32F411CE.
I'm pretty confident that the "truncated or correct" guarantee is right, but I was a bit paranoid so I also brute forced all configurations (including many which would be unstable) of my F411CE's RCC to check: https://paste.rs/ZaZ3k.py
This addresses #3408 .