From 1d075f89e7a9f9eeec6db1b25d2a367b9a93310a Mon Sep 17 00:00:00 2001 From: Piroro-hs Date: Thu, 22 Oct 2020 15:05:15 +0900 Subject: [PATCH 1/3] Fix rcc docs --- src/rcc.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/rcc.rs b/src/rcc.rs index d6215fe84..3ca2a7159 100644 --- a/src/rcc.rs +++ b/src/rcc.rs @@ -87,7 +87,7 @@ impl AHB { /// ``` /// let dp = pac::Peripherals::take().unwrap(); /// let rcc = dp.RCC.constrain(); -/// use_ahb(&mut rcc.apb1) +/// use_apb1(&mut rcc.apb1) /// ``` pub struct APB1 { _0: (), @@ -112,7 +112,7 @@ impl APB1 { /// ``` /// let dp = pac::Peripherals::take().unwrap(); /// let rcc = dp.RCC.constrain(); -/// use_ahb(&mut rcc.apb2) +/// use_apb2(&mut rcc.apb2) /// ``` pub struct APB2 { _0: (), @@ -212,7 +212,7 @@ impl BDCR { /// ``` /// let dp = pac::Peripherals::take().unwrap(); /// let rcc = dp.RCC.constrain(); -/// use_ahb(&mut rcc.cfgr) +/// use_cfgr(&mut rcc.cfgr) /// ``` pub struct CFGR { hse: Option, @@ -376,10 +376,11 @@ impl CFGR { } // PLL_MUL maximal value is 16 - assert!(divisor <= 16); - // PRE_DIV maximal value is 16 assert!(multiplier <= 16); + // PRE_DIV maximal value is 16 + assert!(divisor <= 16); + (multiplier, Some(divisor)) } // HSI division is always divided by 2 and has no adjustable division From 47f1816d68253ea9191f3921681e9059b6416b50 Mon Sep 17 00:00:00 2001 From: Piroro-hs Date: Thu, 22 Oct 2020 15:21:04 +0900 Subject: [PATCH 2/3] Support HSE bypass and CSS --- src/rcc.rs | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/rcc.rs b/src/rcc.rs index 3ca2a7159..21964d94d 100644 --- a/src/rcc.rs +++ b/src/rcc.rs @@ -21,13 +21,7 @@ impl RccExt for RCC { apb1: APB1 { _0: () }, apb2: APB2 { _0: () }, bdcr: BDCR { _0: () }, - cfgr: CFGR { - hse: None, - hclk: None, - pclk1: None, - pclk2: None, - sysclk: None, - }, + cfgr: CFGR::default(), } } } @@ -214,8 +208,11 @@ impl BDCR { /// let rcc = dp.RCC.constrain(); /// use_cfgr(&mut rcc.cfgr) /// ``` +#[derive(Default)] pub struct CFGR { hse: Option, + hse_bypass: bool, + css: bool, hclk: Option, pclk1: Option, pclk2: Option, @@ -286,13 +283,34 @@ fn into_pre_div(div: u8) -> cfgr2::PREDIV_A { } impl CFGR { - /// Uses HSE (external oscillator) instead of HSI (internal RC oscillator) as the clock source. + /// Enable HSE (external clock) in crystal mode. + /// Uses external oscillator instead of HSI (internal RC oscillator) as the clock source. /// Will result in a hang if an external oscillator is not connected or it fails to start. pub fn use_hse(mut self, freq: F) -> Self where F: Into, { self.hse = Some(freq.into().0); + self.hse_bypass = false; + self + } + + /// Enable HSE (external clock) in bypass mode. + /// Uses user provided clock instead of HSI (internal RC oscillator) as the clock source. + /// Will result in a hang if an external clock source is not connected. + pub fn use_hse_bypass(mut self, freq: F) -> Self + where + F: Into, + { + self.hse = Some(freq.into().0); + self.hse_bypass = true; + self + } + + /// Enable CSS (Clock Security System). + /// No effect if HSE is not enabled. + pub fn enable_css(mut self) -> Self { + self.css = true; self } @@ -584,9 +602,17 @@ impl CFGR { let rcc = unsafe { &*RCC::ptr() }; + // enable HSE and wait for it to be ready if self.hse.is_some() { - // enable HSE and wait for it to be ready - rcc.cr.modify(|_, w| w.hseon().on()); + rcc.cr.modify(|_, w| { + if self.css { + w.csson().on(); + } + if self.hse_bypass { + w.hsebyp().bypassed(); + } + w.hseon().on() + }); while rcc.cr.read().hserdy().is_not_ready() {} } From bd9f8585789f3f93fabf9ba81b616e00d7c7555a Mon Sep 17 00:00:00 2001 From: Piroro-hs Date: Thu, 29 Oct 2020 14:24:32 +0900 Subject: [PATCH 3/3] Update HSE bypass function to h7xx-hal compatible --- CHANGELOG.md | 1 + src/rcc.rs | 27 ++++++++++----------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 427404c76..6f8edb0f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - SPI4 peripheral for supported devices. ([#99](https://github.com/stm32-rs/stm32f3xx-hal/pull/99)) - Support for I2C transfer of more than 255 bytes, and 0 byte write ([#154](https://github.com/stm32-rs/stm32f3xx-hal/pull/154)) +- Support for HSE bypass and CSS ([#156](https://github.com/stm32-rs/stm32f3xx-hal/pull/156)) ### Changed diff --git a/src/rcc.rs b/src/rcc.rs index 21964d94d..6d543fcfd 100644 --- a/src/rcc.rs +++ b/src/rcc.rs @@ -283,31 +283,28 @@ fn into_pre_div(div: u8) -> cfgr2::PREDIV_A { } impl CFGR { - /// Enable HSE (external clock) in crystal mode. - /// Uses external oscillator instead of HSI (internal RC oscillator) as the clock source. + /// Uses HSE (external oscillator) instead of HSI (internal RC oscillator) as the clock source. /// Will result in a hang if an external oscillator is not connected or it fails to start. pub fn use_hse(mut self, freq: F) -> Self where F: Into, { self.hse = Some(freq.into().0); - self.hse_bypass = false; self } - /// Enable HSE (external clock) in bypass mode. - /// Uses user provided clock instead of HSI (internal RC oscillator) as the clock source. - /// Will result in a hang if an external clock source is not connected. - pub fn use_hse_bypass(mut self, freq: F) -> Self - where - F: Into, - { - self.hse = Some(freq.into().0); + /// Enable HSE bypass. + /// Uses user provided clock signal instead of an external oscillator. + /// OSC_OUT pin is free and can be used as GPIO. + /// No effect if HSE is not enabled. + pub fn bypass_hse(mut self) -> Self { self.hse_bypass = true; self } /// Enable CSS (Clock Security System). + /// System clock is automatically switched to HSI and an interrupt (CSSI) is generated + /// when HSE clock failure is detected. /// No effect if HSE is not enabled. pub fn enable_css(mut self) -> Self { self.css = true; @@ -605,12 +602,8 @@ impl CFGR { // enable HSE and wait for it to be ready if self.hse.is_some() { rcc.cr.modify(|_, w| { - if self.css { - w.csson().on(); - } - if self.hse_bypass { - w.hsebyp().bypassed(); - } + w.hsebyp().bit(self.hse_bypass); + w.csson().bit(self.css); w.hseon().on() });