From caac7009f6a707446d4dfb556d27d949eba568a8 Mon Sep 17 00:00:00 2001 From: Christian Egerer Date: Fri, 12 Apr 2024 14:31:54 +0300 Subject: [PATCH 1/2] add option to set HSE bypass bit --- src/rcc.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/rcc.rs b/src/rcc.rs index 508270b7..57e0b9ab 100644 --- a/src/rcc.rs +++ b/src/rcc.rs @@ -22,6 +22,7 @@ impl RccExt for RCC { Rcc { cfgr: CFGR { hse: None, + hse_bypass: false, hclk: None, pclk1: None, pclk2: None, @@ -110,6 +111,7 @@ const HSI: u32 = 8_000_000; // Hz #[derive(Debug, Default, PartialEq, Eq)] pub struct CFGR { hse: Option, + hse_bypass: bool, hclk: Option, pclk1: Option, pclk2: Option, @@ -127,6 +129,20 @@ impl CFGR { self } + /// Bypasses the high-speed external oscillator and uses an external clock input on the OSC_IN + /// pin. + /// + /// For this configuration, the OSC_IN pin should be connected to a clock source with a + /// frequency specified in the call to use_hse(), and the OSC_OUT pin should not be connected. + /// + /// This function has no effect unless use_hse() is also called. + pub fn bypass_hse_oscillator(self) -> Self { + Self { + hse_bypass: true, + ..self + } + } + /// Sets the desired frequency for the HCLK clock #[inline(always)] pub fn hclk(mut self, freq: Hertz) -> Self { @@ -208,7 +224,12 @@ impl CFGR { if cfg.hse.is_some() { // enable HSE and wait for it to be ready - rcc.cr.modify(|_, w| w.hseon().set_bit()); + rcc.cr.modify(|_, w| { + if cfg.hse_bypass { + w.hsebyp().bypassed(); + } + w.hseon().set_bit() + }); while rcc.cr.read().hserdy().bit_is_clear() {} } @@ -478,6 +499,7 @@ pub trait Reset: RccBus { #[derive(Clone, Copy, Debug, PartialEq)] pub struct Config { pub hse: Option, + pub hse_bypass: bool, pub pllmul: Option, pub hpre: HPre, pub ppre1: PPre, @@ -491,6 +513,7 @@ impl Default for Config { fn default() -> Self { Self { hse: None, + hse_bypass: false, pllmul: None, hpre: HPre::Div1, ppre1: PPre::Div1, @@ -549,6 +572,7 @@ pub type AdcPre = rcc::cfgr::ADCPRE_A; impl Config { pub const fn from_cfgr(cfgr: CFGR) -> Self { let hse = cfgr.hse; + let hse_bypass = cfgr.hse_bypass; let pllsrcclk = if let Some(hse) = hse { hse } else { HSI / 2 }; let pllmul = if let Some(sysclk) = cfgr.sysclk { @@ -649,6 +673,7 @@ impl Config { Self { hse, + hse_bypass, pllmul: pllmul_bits, hpre: hpre_bits, ppre1: ppre1_bits, @@ -730,6 +755,7 @@ fn rcc_config_usb() { let config = Config::from_cfgr(cfgr); let config_expected = Config { hse: Some(8_000_000), + hse_bypass: false, pllmul: Some(4), hpre: HPre::Div1, ppre1: PPre::Div2, From c2dc3be5c735315291851e3357c4a4ce6343fa43 Mon Sep 17 00:00:00 2001 From: Christian Egerer Date: Mon, 15 Apr 2024 10:22:30 +0300 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed11be36..8b1d43b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add dac - Fix flash error flag clearing +### Added + +- Allow to set HSE bypass bit in `RCC` clock configuration register to use an external clock input on the `OSC_IN` pin + ## [v0.10.0] - 2022-12-12 - `Timer`: adds `get_interrupt` to `Timer`