Skip to content

Commit d382bf0

Browse files
authored
Merge pull request #4729 from embassy-rs/mco2
stm32: add config to MCO to control the drive strength.
2 parents 5ad7105 + 02b08a5 commit d382bf0

File tree

8 files changed

+98
-14
lines changed

8 files changed

+98
-14
lines changed

embassy-stm32/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
- fix: RTC register definition for STM32L4P5 and L4Q5 as they use v3 register map.
2727
- fix: Cut down the capabilities of the STM32L412 and L422 RTC as those are missing binary timer mode and underflow interrupt.
2828
- fix: Allow configuration of the internal pull up/down resistors on the pins for the Qei peripheral, as well as the Qei decoder mode.
29+
- feat: stm32/rcc/mco: Added support for IO driver strength when using Master Clock Out IO. This changes signature on Mco::new taking a McoConfig struct ([#4679](https://github.com/embassy-rs/embassy/pull/4679))
2930

3031
## 0.4.0 - 2025-08-26
3132

embassy-stm32/src/rcc/mco.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,29 @@ pub struct Mco<'d, T: McoInstance> {
9191

9292
impl<'d, T: McoInstance> Mco<'d, T> {
9393
/// Create a new MCO instance.
94-
pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, prescaler: McoPrescaler) -> Self {
94+
pub fn new(_peri: Peri<'d, T>, pin: Peri<'d, impl McoPin<T>>, source: T::Source, config: McoConfig) -> Self {
9595
critical_section::with(|_| unsafe {
96-
T::_apply_clock_settings(source, prescaler);
97-
set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh));
96+
T::_apply_clock_settings(source, config.prescaler);
97+
set_as_af!(pin, AfType::output(OutputType::PushPull, config.speed));
9898
});
9999

100100
Self { phantom: PhantomData }
101101
}
102102
}
103+
104+
#[non_exhaustive]
105+
pub struct McoConfig {
106+
/// Master Clock Out prescaler
107+
pub prescaler: McoPrescaler,
108+
/// IO Drive Strength
109+
pub speed: Speed,
110+
}
111+
112+
impl Default for McoConfig {
113+
fn default() -> Self {
114+
Self {
115+
prescaler: McoPrescaler::DIV1,
116+
speed: Speed::VeryHigh,
117+
}
118+
}
119+
}

examples/stm32f4/src/bin/mco.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use defmt::*;
55
use embassy_executor::Spawner;
66
use embassy_stm32::gpio::{Level, Output, Speed};
7-
use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoPrescaler};
7+
use embassy_stm32::rcc::{Mco, Mco1Source, Mco2Source, McoConfig, McoPrescaler};
88
use embassy_time::Timer;
99
use {defmt_rtt as _, panic_probe as _};
1010

@@ -13,8 +13,20 @@ async fn main(_spawner: Spawner) {
1313
let p = embassy_stm32::init(Default::default());
1414
info!("Hello World!");
1515

16-
let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV1);
17-
let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::PLL, McoPrescaler::DIV4);
16+
let config_mco1 = {
17+
let mut config = McoConfig::default();
18+
config.prescaler = McoPrescaler::DIV1;
19+
config
20+
};
21+
22+
let config_mco2 = {
23+
let mut config = McoConfig::default();
24+
config.prescaler = McoPrescaler::DIV4;
25+
config
26+
};
27+
28+
let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, config_mco1);
29+
let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::PLL, config_mco2);
1830
let mut led = Output::new(p.PB7, Level::High, Speed::Low);
1931

2032
loop {

examples/stm32h5/src/bin/mco.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![no_std]
2+
#![no_main]
3+
4+
use defmt::*;
5+
use embassy_executor::Spawner;
6+
use embassy_stm32::gpio::Speed;
7+
use embassy_stm32::rcc::{Mco, Mco2Source, McoConfig};
8+
use {defmt_rtt as _, panic_probe as _};
9+
10+
#[embassy_executor::main]
11+
async fn main(_spawner: Spawner) {
12+
let p = embassy_stm32::init(Default::default());
13+
14+
/* Default "VeryHigh" drive strength and prescaler DIV1 */
15+
// let _mco = Mco::new(p.MCO2, p.PC9, Mco2Source::SYS, McoConfig::default());
16+
17+
/* Choose Speed::Low drive strength */
18+
let config = {
19+
let mut config = McoConfig::default();
20+
config.speed = Speed::Low;
21+
config
22+
};
23+
24+
let _mco = Mco::new(p.MCO2, p.PC9, Mco2Source::SYS, config);
25+
26+
info!("Clock out with low drive strength set on Master Clock Out 2 pin as AF on PC9");
27+
28+
loop {}
29+
}

examples/stm32h7/src/bin/camera.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use embassy_executor::Spawner;
55
use embassy_stm32::dcmi::{self, *};
66
use embassy_stm32::gpio::{Level, Output, Speed};
77
use embassy_stm32::i2c::I2c;
8-
use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler};
8+
use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler};
99
use embassy_stm32::{bind_interrupts, i2c, peripherals, Config};
1010
use embassy_time::Timer;
1111
use ov7725::*;
@@ -48,7 +48,14 @@ async fn main(_spawner: Spawner) {
4848
let p = embassy_stm32::init(config);
4949

5050
defmt::info!("Hello World!");
51-
let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV3);
51+
52+
let mco_config = {
53+
let mut config = McoConfig::default();
54+
config.prescaler = McoPrescaler::DIV3;
55+
config
56+
};
57+
58+
let mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, mco_config);
5259

5360
let mut led = Output::new(p.PE3, Level::High, Speed::Low);
5461
let cam_i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, p.DMA1_CH1, p.DMA1_CH2, Default::default());

examples/stm32h7/src/bin/mco.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use defmt::*;
55
use embassy_executor::Spawner;
66
use embassy_stm32::gpio::{Level, Output, Speed};
7-
use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler};
7+
use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler};
88
use embassy_time::Timer;
99
use {defmt_rtt as _, panic_probe as _};
1010

@@ -15,7 +15,13 @@ async fn main(_spawner: Spawner) {
1515

1616
let mut led = Output::new(p.PB14, Level::High, Speed::Low);
1717

18-
let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8);
18+
let config = {
19+
let mut config = McoConfig::default();
20+
config.prescaler = McoPrescaler::DIV8;
21+
config
22+
};
23+
24+
let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, config);
1925

2026
loop {
2127
info!("high");

examples/stm32h7rs/src/bin/mco.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use defmt::*;
55
use embassy_executor::Spawner;
66
use embassy_stm32::gpio::{Level, Output, Speed};
7-
use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler};
7+
use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler};
88
use embassy_time::Timer;
99
use {defmt_rtt as _, panic_probe as _};
1010

@@ -15,7 +15,13 @@ async fn main(_spawner: Spawner) {
1515

1616
let mut led = Output::new(p.PB14, Level::High, Speed::Low);
1717

18-
let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV8);
18+
let config = {
19+
let mut config = McoConfig::default();
20+
config.prescaler = McoPrescaler::DIV8;
21+
config
22+
};
23+
24+
let _mco = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, config);
1925

2026
loop {
2127
info!("high");

examples/stm32l4/src/bin/mco.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use defmt::*;
55
use embassy_executor::Spawner;
66
use embassy_stm32::gpio::{Level, Output, Speed};
7-
use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource};
7+
use embassy_stm32::rcc::{Mco, McoConfig, McoPrescaler, McoSource};
88
use embassy_time::Timer;
99
use {defmt_rtt as _, panic_probe as _};
1010

@@ -13,7 +13,13 @@ async fn main(_spawner: Spawner) {
1313
let p = embassy_stm32::init(Default::default());
1414
info!("Hello World!");
1515

16-
let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI, McoPrescaler::DIV1);
16+
let config = {
17+
let mut config = McoConfig::default();
18+
config.prescaler = McoPrescaler::DIV1;
19+
config
20+
};
21+
22+
let _mco = Mco::new(p.MCO, p.PA8, McoSource::HSI, config);
1723

1824
let mut led = Output::new(p.PB14, Level::High, Speed::Low);
1925

0 commit comments

Comments
 (0)