Skip to content

Conversation

astapleton
Copy link
Member

The STM32H523/STM32H533/STM32H56x/STM32H573 parts have a 3rd PLL. This configures them the same way PLL2 is configured.

Caveat: I haven't tested configuration of PLL3 on one of the above parts as I don't have any.

@usbalbin
Copy link
Member

usbalbin commented Feb 23, 2025

Modifying the rcc example to

Code
    let ccdr = rcc
        .sys_ck(250.MHz())
        .pll3_p_ck(4.MHz())
        .pll3_q_ck(8.MHz())
        .pll3_r_ck(16.MHz())
        .freeze(pwrcfg, &dp.SBS);

    info!("");
    info!("stm32h5xx-hal example - RCC");
    info!("");

    // HCLK
    info!("hclk = {} Hz", ccdr.clocks.hclk().raw());
    assert_eq!(ccdr.clocks.hclk().raw(), 250_000_000);

    // SYS_CK
    info!("sys_ck = {} Hz", ccdr.clocks.sys_ck().raw());
    assert_eq!(ccdr.clocks.sys_ck().raw(), 250_000_000);

    info!("pll3_p = {} Hz", ccdr.clocks.pll3().p_ck().unwrap().raw());
    assert_eq!(ccdr.clocks.pll3().p_ck().unwrap().raw(), 4_000_000);

    info!("pll3_q = {} Hz", ccdr.clocks.pll3().q_ck().unwrap().raw());
    assert_eq!(ccdr.clocks.pll3().q_ck().unwrap().raw(), 8_000_000);

    info!("pll3_r = {} Hz", ccdr.clocks.pll3().r_ck().unwrap().raw());
    assert_eq!(ccdr.clocks.pll3().r_ck().unwrap().raw(), 16_000_000);

and compiling for stm32h563 seems to work fine on my nucleo-h533

@usbalbin
Copy link
Member

Oh just noticed you force pushed, thanks.

Same thing with your latest changes but with stm32h533 feature works fine too!

@usbalbin
Copy link
Member

usbalbin commented Feb 23, 2025

further adding this(mostly copy pasted from g4) to let the LPTIM2 use the PLL3_R output as a test

Code
    <change pll3_r to 4MHz above>

    let prescale_bits = 0b111; // /128
    let arr = 31_250;
    // 4MHz/(128*31250)=1Hz

    let tim = dp.LPTIM2;

    ccdr.peripheral.LPTIM2.kernel_clk_mux(LPTIMSEL::Pll3R).enable().reset();

    // CFGR
    tim.cfgr().modify(|_, w| unsafe { w.presc().bits(prescale_bits) });

    // Enable
    tim.cr().modify(|_, w| w.enable().set_bit());

    // Write ARR: LPTIM must be enabled
    tim.arr().write(|w| unsafe { w.arr().bits(arr as u16) });
    while !tim.isr().read().arrok().bit_is_set() {}
    tim.icr().write(|w| w.arrokcf().set_bit());// Connected to LPTIM2_CH1
    
    tim.ccr1().write(|w| unsafe { w.ccr1().bits(arr / 2) }); // Set duty cycle
    while !tim.isr().read().cmp1ok().bit_is_set() {}
    tim.icr().write(|w| w.cmp1okcf().set_bit());

    tim.ccmr1().modify(|_, w| w.cc1e().set_bit()); // Enable ch1 output

    tim.cr().modify(|_, w| w.cntstrt().set_bit().enable().set_bit());

    let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
    let mut pa4 = gpioa.pa4.into_alternate::<3>(); // LPTIM2_CH1
    let mut pa5 = gpioa.pa5.into_push_pull_output(); // LED

    info!("presc: {}", tim.cfgr().read().presc().bits());
    info!("arr: {}", tim.arr().read().bits());
    info!("ccr1: {}", tim.ccr1().read().bits());

    let mut last_state = true;
    loop {
        let state = pa4.is_high(); // Check state of timer output
        if state {
            pa5.set_high(); // Set led on
        } else {
            pa5.set_low(); // Set led off
        }
        if state != last_state {
            info!("New state: {}", state);
        }
        last_state = state;
    }

I dont have access to an oscilloscope right now but 30 blinks seems to take about 30seconds

@astapleton
Copy link
Member Author

Great. Thanks for the thorough test!

@astapleton astapleton merged commit 38bb75b into master Feb 24, 2025
19 checks passed
@astapleton astapleton deleted the as/configure-pll3 branch February 24, 2025 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants