Module stm32h7xx_hal::rcc

source ·
Expand description

Reset and Clock Control

This module configures the RCC unit to provide set frequencies for the input to the SCGU sys_ck, the AMBA High-performance Busses and Advanced eXtensible Interface Bus hclk, the AMBA Peripheral Busses pclkN and the peripheral clock per_ck.

See Figure 49 “Core and bus clock generation” in Reference Manual RM0433 Rev 7 for more information (p 348).

HSI is 64 MHz. CSI is 4 MHz. HSI48 is 48MHz.

§Usage

This peripheral must be used alongside the PWR peripheral to freeze voltage scaling of the device.

A builder pattern is used to specify the state and frequency of possible clocks. The freeze method configures the RCC peripheral in a best-effort attempt to generate these clocks. The actual clocks configured are returned in ccdr.clocks.

No clock specification overrides another. However supplying some clock specifications may influence multiple resulting clocks, including those corresponding to other clock specifications. This is particularly the case for PLL clocks, where the frequencies of adjacent ‘P’, ’Q, and ‘R’ clock outputs must have a simple integer fraction relationship.

Some clock specifications imply other clock specifications, as follows:

  • use_hse(a) implies sys_ck(a)

  • sys_ck(b) implies pll1_p_ck(b) unless b equals HSI or use_hse(b) was specified

  • pll1_p_ck(c) implies pll1_r_ck(c/2), including when pll1_p_ck was implied by sys_ck(c) or mco2_from_pll1_p_ck(c).

Implied clock specifications can always be overridden by explicitly specifying that clock. If this results in a configuration that cannot be achieved by hardware, freeze will panic.

§Examples

Simple example:

    let dp = pac::Peripherals::take().unwrap();

    let pwr = dp.PWR.constrain();
    let pwrcfg = pwr.freeze();

    let rcc = dp.RCC.constrain();
    let ccdr = rcc
        .sys_ck(96.MHz())
        .pclk1(48.MHz())
        .freeze(pwrcfg, &dp.SYSCFG);

A more complex example, involving the PLL:

    let dp = pac::Peripherals::take().unwrap();

    let pwr = dp.PWR.constrain();
    let pwrcfg = pwr.freeze();

    let rcc = dp.RCC.constrain();
    let ccdr = rcc
        .sys_ck(200.MHz()) // Implies pll1_p_ck
        // For non-integer values, round up. `freeze` will never
        // configure a clock faster than that specified.
        .pll1_q_ck(33_333_334.hz())
        .freeze(pwrcfg, &dp.SYSCFG);

A much more complex example, indicative of real usage with a significant fraction of the STM32H7’s capabilities.

    let dp = pac::Peripherals::take().unwrap();

    let pwr = dp.PWR.constrain();
    let pwrcfg = pwr.freeze();

    let rcc = dp.RCC.constrain();
    let ccdr = rcc
        .use_hse(25.MHz()) // XTAL X1
        .sys_ck(400.MHz())
        .pll1_r_ck(100.MHz()) // for TRACECK
        .pll1_q_ck(200.MHz())
        .hclk(200.MHz())
        .pll3_strategy(PllConfigStrategy::Iterative)
        .pll3_p_ck(240.MHz()) // for LTDC
        .pll3_q_ck(48.MHz()) // for LTDC
        .pll3_r_ck(26_666_667.Hz()) // Pixel clock for LTDC
        .freeze(pwrcfg, &dp.SYSCFG);

§Peripherals

The freeze() method returns a Core Clocks Distribution and Reset (CCDR) object. This singleton tells you how the core clocks were actually configured (in CoreClocks) and allows you to configure the remaining peripherals (see PeripheralREC).

 let ccdr = ...; // Returned by `freeze()`, see examples above

 // Runtime confirmation that hclk really is 200MHz
 assert_eq!(ccdr.clocks.hclk().raw(), 200_000_000);

 // Panics if pll1_q_ck is not running
 let _ = ccdr.clocks.pll1_q_ck().unwrap();

 // Enable the clock to a peripheral and reset it
 ccdr.peripheral.FDCAN.enable().reset();

The PeripheralREC members implement move semantics, so once you have passed them to a constructor they cannot be modified again in safe Rust.

 // Constructor for custom FDCAN driver
 my_fdcan(dp.FDCAN,
          &ccdr.clocks,         // Immutable reference to core clock state
          ccdr.peripheral.FDCAN // Ownership of reset + enable control
 );

 // Compile error, value was moved ^^
 ccdr.peripheral.FDCAN.disable();

Re-exports§

Modules§

  • Backup Power Domain Reset, Enable, and Clock Control
  • Peripheral Reset and Enable Control (REC)

Structs§

  • Core Clock Distribution and Reset (CCDR)
  • Configuration of the core clocks
  • Frozen core clock frequencies
  • Configuration of a Phase Locked Loop (PLL)
  • Constrained RCC peripheral

Enums§

Traits§

  • Extension trait that constrains the RCC peripheral