diff options
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mco.rs | 23 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/mco.rs | 18 | ||||
| -rw-r--r-- | examples/stm32h5/src/bin/mco.rs | 29 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/camera.rs | 11 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/mco.rs | 10 | ||||
| -rw-r--r-- | examples/stm32h7rs/src/bin/mco.rs | 10 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/mco.rs | 10 |
8 files changed, 98 insertions, 14 deletions
diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 80261ae41..1443472f5 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md | |||
| @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 26 | - fix: RTC register definition for STM32L4P5 and L4Q5 as they use v3 register map. | 26 | - fix: RTC register definition for STM32L4P5 and L4Q5 as they use v3 register map. |
| 27 | - fix: Cut down the capabilities of the STM32L412 and L422 RTC as those are missing binary timer mode and underflow interrupt. | 27 | - fix: Cut down the capabilities of the STM32L412 and L422 RTC as those are missing binary timer mode and underflow interrupt. |
| 28 | - fix: Allow configuration of the internal pull up/down resistors on the pins for the Qei peripheral, as well as the Qei decoder mode. | 28 | - 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)) | ||
| 29 | 30 | ||
| 30 | ## 0.4.0 - 2025-08-26 | 31 | ## 0.4.0 - 2025-08-26 |
| 31 | 32 | ||
diff --git a/embassy-stm32/src/rcc/mco.rs b/embassy-stm32/src/rcc/mco.rs index 59ccc8cb5..fa4b45a20 100644 --- a/embassy-stm32/src/rcc/mco.rs +++ b/embassy-stm32/src/rcc/mco.rs | |||
| @@ -91,12 +91,29 @@ pub struct Mco<'d, T: McoInstance> { | |||
| 91 | 91 | ||
| 92 | impl<'d, T: McoInstance> Mco<'d, T> { | 92 | impl<'d, T: McoInstance> Mco<'d, T> { |
| 93 | /// Create a new MCO instance. | 93 | /// 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 { |
| 95 | critical_section::with(|_| unsafe { | 95 | critical_section::with(|_| unsafe { |
| 96 | T::_apply_clock_settings(source, prescaler); | 96 | T::_apply_clock_settings(source, config.prescaler); |
| 97 | set_as_af!(pin, AfType::output(OutputType::PushPull, Speed::VeryHigh)); | 97 | set_as_af!(pin, AfType::output(OutputType::PushPull, config.speed)); |
| 98 | }); | 98 | }); |
| 99 | 99 | ||
| 100 | Self { phantom: PhantomData } | 100 | Self { phantom: PhantomData } |
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 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 | } | ||
diff --git a/examples/stm32f4/src/bin/mco.rs b/examples/stm32f4/src/bin/mco.rs index eb7bb6261..a2e229770 100644 --- a/examples/stm32f4/src/bin/mco.rs +++ b/examples/stm32f4/src/bin/mco.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | 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}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -13,8 +13,20 @@ async fn main(_spawner: Spawner) { | |||
| 13 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 16 | let _mco1 = Mco::new(p.MCO1, p.PA8, Mco1Source::HSI, McoPrescaler::DIV1); | 16 | let config_mco1 = { |
| 17 | let _mco2 = Mco::new(p.MCO2, p.PC9, Mco2Source::PLL, McoPrescaler::DIV4); | 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); | ||
| 18 | let mut led = Output::new(p.PB7, Level::High, Speed::Low); | 30 | let mut led = Output::new(p.PB7, Level::High, Speed::Low); |
| 19 | 31 | ||
| 20 | loop { | 32 | loop { |
diff --git a/examples/stm32h5/src/bin/mco.rs b/examples/stm32h5/src/bin/mco.rs new file mode 100644 index 000000000..1137ba25c --- /dev/null +++ b/examples/stm32h5/src/bin/mco.rs | |||
| @@ -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 | } | ||
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 8f2e265d6..039008d17 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs | |||
| @@ -5,7 +5,7 @@ use embassy_executor::Spawner; | |||
| 5 | use embassy_stm32::dcmi::{self, *}; | 5 | use embassy_stm32::dcmi::{self, *}; |
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 7 | use embassy_stm32::i2c::I2c; | 7 | use embassy_stm32::i2c::I2c; |
| 8 | use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; | 8 | use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler}; |
| 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals, Config}; | 9 | use embassy_stm32::{bind_interrupts, i2c, peripherals, Config}; |
| 10 | use embassy_time::Timer; | 10 | use embassy_time::Timer; |
| 11 | use ov7725::*; | 11 | use ov7725::*; |
| @@ -48,7 +48,14 @@ async fn main(_spawner: Spawner) { | |||
| 48 | let p = embassy_stm32::init(config); | 48 | let p = embassy_stm32::init(config); |
| 49 | 49 | ||
| 50 | defmt::info!("Hello World!"); | 50 | 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); | ||
| 52 | 59 | ||
| 53 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); | 60 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); |
| 54 | let cam_i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, p.DMA1_CH1, p.DMA1_CH2, Default::default()); | 61 | let cam_i2c = I2c::new(p.I2C1, p.PB8, p.PB9, Irqs, p.DMA1_CH1, p.DMA1_CH2, Default::default()); |
diff --git a/examples/stm32h7/src/bin/mco.rs b/examples/stm32h7/src/bin/mco.rs index a6ee27625..cafcb90f6 100644 --- a/examples/stm32h7/src/bin/mco.rs +++ b/examples/stm32h7/src/bin/mco.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 7 | use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; | 7 | use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -15,7 +15,13 @@ async fn main(_spawner: Spawner) { | |||
| 15 | 15 | ||
| 16 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); | 16 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); |
| 17 | 17 | ||
| 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); | ||
| 19 | 25 | ||
| 20 | loop { | 26 | loop { |
| 21 | info!("high"); | 27 | info!("high"); |
diff --git a/examples/stm32h7rs/src/bin/mco.rs b/examples/stm32h7rs/src/bin/mco.rs index a6ee27625..cafcb90f6 100644 --- a/examples/stm32h7rs/src/bin/mco.rs +++ b/examples/stm32h7rs/src/bin/mco.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 7 | use embassy_stm32::rcc::{Mco, Mco1Source, McoPrescaler}; | 7 | use embassy_stm32::rcc::{Mco, Mco1Source, McoConfig, McoPrescaler}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -15,7 +15,13 @@ async fn main(_spawner: Spawner) { | |||
| 15 | 15 | ||
| 16 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); | 16 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); |
| 17 | 17 | ||
| 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); | ||
| 19 | 25 | ||
| 20 | loop { | 26 | loop { |
| 21 | info!("high"); | 27 | info!("high"); |
diff --git a/examples/stm32l4/src/bin/mco.rs b/examples/stm32l4/src/bin/mco.rs index 36c002952..4cdeaa440 100644 --- a/examples/stm32l4/src/bin/mco.rs +++ b/examples/stm32l4/src/bin/mco.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::gpio::{Level, Output, Speed}; | 6 | use embassy_stm32::gpio::{Level, Output, Speed}; |
| 7 | use embassy_stm32::rcc::{Mco, McoPrescaler, McoSource}; | 7 | use embassy_stm32::rcc::{Mco, McoConfig, McoPrescaler, McoSource}; |
| 8 | use embassy_time::Timer; | 8 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| @@ -13,7 +13,13 @@ async fn main(_spawner: Spawner) { | |||
| 13 | let p = embassy_stm32::init(Default::default()); | 13 | let p = embassy_stm32::init(Default::default()); |
| 14 | info!("Hello World!"); | 14 | info!("Hello World!"); |
| 15 | 15 | ||
| 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); | ||
| 17 | 23 | ||
| 18 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); | 24 | let mut led = Output::new(p.PB14, Level::High, Speed::Low); |
| 19 | 25 | ||
