Expand description
STM32F4xx clock driver
This crate provides drivers for various clocks: HSI, PLL, system, AHB, APB1 and APB2. This documentation applies to the system clock, AHB, APB1 and APB2. For in-detail documentation for HSI and PLL, check their documentation.
§Features
- Dynamic system source
- Hardware limits verification for AHB, APB1 and APB2.
- Prescaler configuration for AHB, APB1 and APB2.
- Support for MCO1
§Limitations
- Precision of 1MHz
- No support for MCO2
§Usage 1
First, import the following enums:
// Assuming a STM32F429 chip. Change this to correspond to the chip model.
use stm32f429zi::rcc::APBPrescaler;
use stm32f429zi::rcc::AHBPrescaler;
use stm32f429zi::rcc::SysClockSource;
A reference to the crate::clocks::Clocks is needed:
// Add this in board main.rs
let clocks = &peripherals.stm32f4.clocks;
§Retrieve the AHB frequency:
let ahb_frequency = clocks.get_ahb_frequency_mhz();
debug!("Current AHB frequency is {}MHz", ahb_frequency);
§Retrieve the AHB prescaler:
let ahb_prescaler = clocks.get_ahb_prescaler();
debug!("Current AHB prescaler is {:?}", ahb_prescaler);
NOTE: If one wishes to get the usize equivalent value of crate::clocks::Clocks::get_ahb_prescaler, to use in computations for example, they must use crate::rcc::AHBPrescaler.into() method:
let ahb_prescaler_usize: usize = clocks.get_ahb_prescaler().into();
if ahb_prescaler_usize > 8 {
/* Do something */
}
§Set the AHB prescaler
clocks.set_ahb_prescaler(AHBPrescaler::DivideBy4);
§APB1 and APB2 prescalers
APB1 and APB2 prescalers are configured in a similar way as AHB prescaler, except that the corresponding enum is APBPrescaler.
§Retrieve the system clock frequency:
let sys_frequency = clocks.get_sys_clock_frequency_mhz();
debug!("Current system clock frequency is {}MHz", sys_frequency);
§Retrieve the system clock source:
let sys_source = clocks.get_sys_clock_source();
debug!("Current system clock source is {:?}", sys_source);
§Change the system clock source to PLL:
Changing the system clock source is a fastidious task because of AHB, APB1 and APB2 limits, which are chip-dependent. This example assumes a STM32F429 chip.
First, get a reference to the PLL
let pll = &peripherals.stm32f4.clocks.pll;
Then, configure its frequency and enable it
pll.set_frequency_mhz(50);
pll.enable();
STM32F429 maximum APB1 frequency is 45MHz, which is computed as following: freq_APB1 = freq_sys / AHB_prescaler / APB1_prescaler Default prescaler values are 1, which gives an frequency of 50MHz without modifying the APB1 prescaler. As such, the APB1 prescaler must be changed.
clocks.set_apb1_prescaler(APBPrescaler::DivideBy2);
Since the APB1 frequency limit is satisfied now, the system clock source can be safely changed.
clocks.set_sys_clock_source(SysClockSource::PLL);
§Another example of changing the system clock to PLL for STM32F429:
As before, Pll clock is configured and enabled.
pll.set_frequency_mhz(100);
pll.enable();
Because of the high frequency of the PLL clock, both APB1 and APB2 prescalers must be configured.
clocks.set_apb1_prescaler(APBPrescaler::DivideBy4);
clocks.set_apb2_prescaler(APBPrescaler::DivideBy2);
As an alternative, the AHB prescaler could be configured to change both APB1 and APB2 frequencies.
// Changing it to 2 wouldn't work, because it would give a frequency of 50MHz for the APB1.
clocks.set_ahb_prescaler(APBPrescaler::DivideBy4);
Now, it’s safe to change the system clock source:
clocks.set_sys_clock_source(SysClockSource::PLL);
For the purpose of brevity, any error checking has been removed. ↩
Modules§
- tests
- Tests for clocks functionalities
Structs§
- Clocks
- Main struct for configuring on-board clocks.
Traits§
- Stm32f4
Clocks - Stm32f4Clocks trait