Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

mattmart3
Copy link
Contributor

@mattmart3 mattmart3 commented May 28, 2024

Pull Request Overview

This PR is a continuation of PR #3888. It is mostly a refactoring to allow peripheral clocks to access the clocks module features. The main motivation is to allow peripherals to get their clock frequency also when the HSE clock is used as PLL source or SYSCLK source, that was not possible before this PR because the HSE clock is controlled by the clocks module but peripheral clocks were only able to access the rcc module. Also, this would also help to extend the peripherals implementation in future: other peripherals might need to access some other clock info from the clocks module (e.g. PLLI2S or PLL48CK). To let peripheral access the clocks module, a ClocksCtrl trait object is passed to the peripherals. Even if a new trait seems unnecessary here, it avoids the peripherals to become chip specific: they would had required the ChipSpecific trait bound generic instead. At first, I tried to just pass a Clocks struct reference to peripherals but they became far more verbose and most of the implementation became bound to the ChipSpecific trait. There were also lifetime conflicts between the ChipSpecific generic and gpio pins. Here a non working example. Thus I think that using the ClocksCtrl trait is the less intrusive approach for now and might be reconsidered in future.
This PR also comes with some other minor refactoring and cleanup for rcc and clocks modules.

Testing Strategy

The tests listed in #3888 have been re-run on a nucleo_f39zi board with the following additional configurations:

Clock Config 5

pub fn test_config5<ChipSpecs: ChipSpecsTrait>(clocks: &Clocks<ChipSpecs>) {
    clocks
        .pll
        .set_frequency_mhz(PllSource::HSI, HSI_FREQUENCY_MHZ, 112)
        .unwrap();
    clocks.pll.enable().unwrap();
    clocks.set_apb1_prescaler(APBPrescaler::DivideBy2).unwrap();
    clocks.set_apb2_prescaler(APBPrescaler::DivideBy2).unwrap();
    clocks.set_ahb_prescaler(AHBPrescaler::DivideBy4).unwrap();
    clocks.set_sys_clock_source(SysClockSource::PLL).unwrap();
}

Clock Config 6

  pub fn test_config6<ChipSpecs: ChipSpecsTrait>(clocks: &Clocks<ChipSpecs>) {
      clocks.hse.set_frequency_mhz(8);
      clocks.hse.enable(crate::rcc::HseMode::BYPASS).unwrap();
      clocks.set_sys_clock_source(SysClockSource::HSE).unwrap();
  }

Clock Config 7

    pub fn test_config7<ChipSpecs: ChipSpecsTrait>(clocks: &Clocks<ChipSpecs>) {
     clocks.hse.set_frequency_mhz(8);
     clocks.hse.enable(crate::rcc::HseMode::BYPASS).unwrap();
     clocks
         .pll
         .set_frequency_mhz(PllSource::HSE, clocks.hse.get_frequency_mhz().unwrap(), 80)
         .unwrap();
     clocks.pll.enable().unwrap();
     clocks.set_apb1_prescaler(APBPrescaler::DivideBy2).unwrap();
     clocks.set_apb2_prescaler(APBPrescaler::DivideBy1).unwrap();
     clocks.set_ahb_prescaler(AHBPrescaler::DivideBy2).unwrap();
     clocks.set_sys_clock_source(SysClockSource::PLL).unwrap();
 }

I also had to increase the enable wait cycles for PLL and HSE clocks due to #4004 :

diff --git a/chips/stm32f4xx/src/clocks/hse.rs b/chips/stm32f4xx/src/clocks/hse.rs
index 22bdd4069..edc0245c9 100644
--- a/chips/stm32f4xx/src/clocks/hse.rs
+++ b/chips/stm32f4xx/src/clocks/hse.rs
@@ -89,7 +89,7 @@ impl<'a> Hse<'a> {

         self.rcc.enable_hse_clock();

-        for _ in 0..100 {
+        for _ in 0..500 {
             if self.rcc.is_ready_hse_clock() {
                 return Ok(());
             }
diff --git a/chips/stm32f4xx/src/clocks/pll.rs b/chips/stm32f4xx/src/clocks/pll.rs
index 741401459..18ae80366 100644
--- a/chips/stm32f4xx/src/clocks/pll.rs
+++ b/chips/stm32f4xx/src/clocks/pll.rs
@@ -228,7 +228,7 @@ impl<'a, PllConstants: clock_constants::PllConstants> Pll<'a, PllConstants> {

         // Wait until the PLL clock is locked.
         // 200 was obtained by running tests in release mode
-        for _ in 0..200 {
+        for _ in 0..500 {
             if self.rcc.is_locked_pll_clock() {
                 return Ok(());
             }

With all configurations (1 to 7) I repeated the usart tests (process console at different baud rates 9600, 115200, 921600) and the timer test (simple application toggling a gpio every second).

All tests succeeded without issues except for config 6 with usart at baudrate 921600, but this is likely due to the baud error being too high at that configuration, no issue with baudrate 460800.

TODO or Help Wanted

This PR affects all the stm32f4 boards, but I could only test the nucleo_f439zi board.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

@github-actions github-actions bot added chips/stm32 Change pertains to the stm32 family of MCUSs WG-Network In the purview of the Network working group. labels May 28, 2024
Copy link
Contributor

@bradjc bradjc left a comment

Choose a reason for hiding this comment

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

Blocked on removing the as in the imports.

mattmart3 added 5 commits May 28, 2024 18:56
Introduce a Stm32f4Clocks trait to let peripheral clocks access clocks
features without the need of the ChipSpecific bind.

Note: this moves the clocks struct initialization into the board crates
since it has to be already instantiated when passing its reference to
the peripherals. This commit also removes the rcc reference passing to
peripherals since it is now accessed from the Stm32f4Clocks trait object.
…odule

Peripheral clock logic moved from rcc.rs to a new clocks/periph.rs module.
All peripheral modules adapted to access the peripheral clock though the
new module path.
…thods

The clocks module uses frequencies in MHz base unit. Also, peripherals
needs the system clock frequency in Hz base unit. Thus, for clarity,
make it explicit when MHz base unit is used and consider Hz as base unit
when not specified. This seems to be the general policy around the code
base, for instance the kernel::hil::time::Frequency trait.
These getters were added in commit
f0d2308
stm32f4xx: rcc: implement get_frequency method for peripheral clocks

Renamed just to comply with the names of their respective setters.
Peripheral clocks used to rely on the rcc module to retrieve the HCLK
frequency (mistakenly called SYSCLK as SYSCLK should not consider the
AHB prescaler). Such implementation had the limitation that the rcc
module was not aware of the HSE clock settings, meaning that dynamic
frequency operations were not supported when the HSE clock was used as
SYSCLK source. See commit f0d2308:
stm32f4xx: rcc: implement get_frequency method for peripheral clocks

This commit instead exposes the HCLK frequency calculated by the clocks
module to peripheral clocks, thus extending the support for the HSE
source clock.

This commit also moves the methods to retrieve the PLL frequency and
SYSCLK frequency (without AHB prescaler division) from the rcc module to
the pll and clocks modules respectively. They are not necessary anymore
since PLL and SYSCLK frequencies are being retrieved from cached
variables, but are kept for future use.
@mattmart3 mattmart3 force-pushed the stm32f4-clocks-rework branch from 28f3515 to d32ebff Compare May 28, 2024 17:04
@mattmart3
Copy link
Contributor Author

@bradjc I applied the changes based on your suggestions. I also rebased on top of the current master and rerun the tests mentioned in the PR description.

@mattmart3 mattmart3 requested a review from bradjc May 29, 2024 14:45
@alevy
Copy link
Member

alevy commented May 29, 2024

FYI @wjakobczyk and @alexandruradovici

@alevy alevy added this pull request to the merge queue May 31, 2024
Merged via the queue into tock:master with commit fe92699 May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chips/stm32 Change pertains to the stm32 family of MCUSs WG-Network In the purview of the Network working group.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants