-
Notifications
You must be signed in to change notification settings - Fork 108
Added support for HSE, LSE, different PLL sources, PLL calibration of MSI, and some more improvements #89
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
Conversation
… MSI, and some more improvements
LGTM 👍 Awesome work, and nice to see someone else dedicating their work to this HAL due to professional needs. |
Awesome! Maybe hold on merging this for a little bit though, I need to fix the documentation for this (which I will do tomorrow). |
Thanks for the PR, it's looking very nice! No complaints here :) Please do ping me when you think its ready to merge. |
I did some more testing and the generated PLL was not correct, I updated the PLL calculation and added sanity checks. Got the codesize I expected now as well. Optimized ("z") build now generates 140 bytes of code for setting up the clock with the following config: let clocks = rcc
.cfgr
.lse(CrystalBypass::Disable)
.msi(MsiFreq::RANGE4M)
.sysclk(80.mhz())
.pclk1(80.mhz())
.pclk2(80.mhz())
.freeze(&mut flash.acr); So it seems all the added checks do not impact code size after constant propagation eliminates all asserts. :) |
@MabezDev / @MathiasKoch do any of you have a card with LSE? If you have a card with LSE, here is an example code that should arrive to the #![no_main]
#![no_std]
use cortex_m_rt::entry;
use cortex_m_semihosting::hprintln;
use hal::{
prelude::*,
rcc::{CrystalBypass, MsiFreq},
};
use panic_semihosting as _;
use stm32l4xx_hal as hal;
#[entry]
fn main() -> ! {
let dp = unsafe { hal::stm32::Peripherals::steal() };
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
let clocks = rcc
.cfgr
.lse(CrystalBypass::Disable)
.msi(MsiFreq::RANGE4M)
.sysclk(80.mhz())
.pclk1(80.mhz())
.pclk2(80.mhz())
.freeze(&mut flash.acr);
hprintln!("Start with clocks: {:#?}", clocks).ok();
loop {
continue;
}
} I'll investigate more. |
Yep, i can try to give it a whack when i get the time. One thing we discovered is that it seems like the PLLConfig is a bit ambiguous.. Using this code it seems like it expects
Maybe we should consider entering it as divisors, eg 2, 4, 6, 8 instead of 0b0, 0b01 etc.? That would make |
Yeah, in a previous I used enums to represent the divisors as they are difficult to understand for a normal user. |
If you are up for it, adding Clock Security System (CSS) support would be awesome! That would give an almost finished/complete RCC implementation to the HAL. |
I gave the LSE code a try. I added |
@MathiasKoch I can add that as well! A complete setup would be great. @unizippro Thanks for testing! Then I know I have a bug with enabling the LSE, I will investigate more. Edit: I was not disabling the write protection of the backup domain, this is why LSE is failing |
Not entirely surprised.. I threw that together super quickly as I was limited on time, thanks for fixing it! One really nice thing the I'll pull out the project I was originally using this for (hopefully tonight, if not the weekend) and take these changes out for a spin. |
No problem!
Awesome, I hope it works well!
I did use the |
Good point, I still don't think this is fully fixed, AFAIK it seems to change between compiler version (or perhaps more likely, llvm version). I think the manual solution is absolutely fine as clocks aren't something that is changed all that often. |
@MathiasKoch I took a look at the PLLSAIx, the board I have (STM32L412) does not have this so I am unable to give it a try unfortunately. |
@korken89 |
I think this is close to ready. I have not tested the CSS yet, I do not have a way to break the connection to the crystal on the Nucleo board to test it. Does anyone of you have a way to test it? |
@korken89 Got around to testing in my project; unfortunately, it this PR seems to break it. In my project, I don't end up using any PLL stuff, just the internal HSI and enable the LSI. https://github.com/MWatch/kernel/blob/master/src/main.rs#L125 Seems like this PR makes the assumption of always using the PLL? |
Aah I see the issue, thanks for testing and I'll fix! |
@MabezDev This should now be fixed! @MabezDev / @MathiasKoch One question, the current implementation assumes that HSI 16 MHz is default, but from the HW the MSI 4 MHz is default. Should we change to use the MSI @ 4 MHz as the default to follow the chip defaults? |
@korken89 |
For now I added code to disable auto-started clocks, then we are not paying for having MSI and HSI running. |
Cool 👍 |
Now we should be on the safe, I also added an output in the Now it should be ready for a proper review :) |
One minor thing. Given the config:
|
@MathiasKoch The last commit should fix it! |
Yup 👍 |
Tested this again, all working! Thanks for the PR, definitely a great improvement! |
Hi, I did some refactoring of the RCC module to better support other clock and PLL configs.
We are using the STM32L412CB in our new product, so I will most likely come with a lot of PRs as I develop the codebase for the product. :)
Usage example, where the MSI is used (with PLL calibration and as source to system PLL):
All the best!
Edit: Tested on Nucleo-L412RB