Skip to content

Commit

Permalink
Merge pull request #485 from chrisegerer/hse_bypass_bit
Browse files Browse the repository at this point in the history
Allow to set HSE bypass bit in clock config
  • Loading branch information
burrbull authored Jul 16, 2024
2 parents d50ccba + c2dc3be commit 09c9770
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
28 changes: 27 additions & 1 deletion src/rcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl RccExt for RCC {
Rcc {
cfgr: CFGR {
hse: None,
hse_bypass: false,
hclk: None,
pclk1: None,
pclk2: None,
Expand Down Expand Up @@ -110,6 +111,7 @@ const HSI: u32 = 8_000_000; // Hz
#[derive(Debug, Default, PartialEq, Eq)]
pub struct CFGR {
hse: Option<u32>,
hse_bypass: bool,
hclk: Option<u32>,
pclk1: Option<u32>,
pclk2: Option<u32>,
Expand All @@ -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 {
Expand Down Expand Up @@ -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() {}
}
Expand Down Expand Up @@ -478,6 +499,7 @@ pub trait Reset: RccBus {
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Config {
pub hse: Option<u32>,
pub hse_bypass: bool,
pub pllmul: Option<u8>,
pub hpre: HPre,
pub ppre1: PPre,
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -649,6 +673,7 @@ impl Config {

Self {
hse,
hse_bypass,
pllmul: pllmul_bits,
hpre: hpre_bits,
ppre1: ppre1_bits,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 09c9770

Please sign in to comment.