[embassy-stm32]: started stm32g4 RCC refactor
* Copied API from f.rs where applicable * HSE and HSI independantly configurable * Boost mode set by user rather * Added HSE, pll1_q and pll1_p frequencies to set_clocks call * Stubbed max module based on f.rs, needs cleanup
This commit is contained in:
		
							parent
							
								
									e8c998aad8
								
							
						
					
					
						commit
						5b7eff6541
					
				| @ -1,10 +1,10 @@ | |||||||
| use stm32_metapac::flash::vals::Latency; | use stm32_metapac::flash::vals::Latency; | ||||||
| use stm32_metapac::rcc::vals::{Adcsel, Pllsrc, Sw}; | use stm32_metapac::rcc::vals::{Adcsel, Sw}; | ||||||
| use stm32_metapac::FLASH; | use stm32_metapac::FLASH; | ||||||
| 
 | 
 | ||||||
| pub use crate::pac::rcc::vals::{ | pub use crate::pac::rcc::vals::{ | ||||||
|     Adcsel as AdcClockSource, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler, Pllm as PllM, Plln as PllN, |     Adcsel as AdcClockSource, Clk48sel, Fdcansel as FdCanClockSource, Hpre as AHBPrescaler, Pllm as PllPreDiv, | ||||||
|     Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, |     Plln as PllMul, Pllp as PllPDiv, Pllq as PllQDiv, Pllr as PllRDiv, Pllsrc, Ppre as APBPrescaler, Sw as Sysclk, | ||||||
| }; | }; | ||||||
| use crate::pac::{PWR, RCC}; | use crate::pac::{PWR, RCC}; | ||||||
| use crate::time::Hertz; | use crate::time::Hertz; | ||||||
| @ -12,28 +12,20 @@ use crate::time::Hertz; | |||||||
| /// HSI speed
 | /// HSI speed
 | ||||||
| pub const HSI_FREQ: Hertz = Hertz(16_000_000); | pub const HSI_FREQ: Hertz = Hertz(16_000_000); | ||||||
| 
 | 
 | ||||||
| /// System clock mux source
 | #[derive(Clone, Copy, Eq, PartialEq)] | ||||||
| #[derive(Clone, Copy)] | pub enum HseMode { | ||||||
| pub enum ClockSrc { |     /// crystal/ceramic oscillator (HSEBYP=0)
 | ||||||
|     HSE(Hertz), |     Oscillator, | ||||||
|     HSI, |     /// external analog clock (low swing) (HSEBYP=1)
 | ||||||
|     PLL, |     Bypass, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// PLL clock input source
 | #[derive(Clone, Copy, Eq, PartialEq)] | ||||||
| #[derive(Clone, Copy, Debug)] | pub struct Hse { | ||||||
| pub enum PllSource { |     /// HSE frequency.
 | ||||||
|     HSI, |     pub freq: Hertz, | ||||||
|     HSE(Hertz), |     /// HSE mode.
 | ||||||
| } |     pub mode: HseMode, | ||||||
| 
 |  | ||||||
| impl Into<Pllsrc> for PllSource { |  | ||||||
|     fn into(self) -> Pllsrc { |  | ||||||
|         match self { |  | ||||||
|             PllSource::HSE(..) => Pllsrc::HSE, |  | ||||||
|             PllSource::HSI => Pllsrc::HSI, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// PLL Configuration
 | /// PLL Configuration
 | ||||||
| @ -43,22 +35,22 @@ impl Into<Pllsrc> for PllSource { | |||||||
| /// frequency ranges for each of these settings.
 | /// frequency ranges for each of these settings.
 | ||||||
| pub struct Pll { | pub struct Pll { | ||||||
|     /// PLL Source clock selection.
 |     /// PLL Source clock selection.
 | ||||||
|     pub source: PllSource, |     pub source: Pllsrc, | ||||||
| 
 | 
 | ||||||
|     /// PLL pre-divider
 |     /// PLL pre-divider
 | ||||||
|     pub prediv_m: PllM, |     pub prediv: PllPreDiv, | ||||||
| 
 | 
 | ||||||
|     /// PLL multiplication factor for VCO
 |     /// PLL multiplication factor for VCO
 | ||||||
|     pub mul_n: PllN, |     pub mul: PllMul, | ||||||
| 
 | 
 | ||||||
|     /// PLL division factor for P clock (ADC Clock)
 |     /// PLL division factor for P clock (ADC Clock)
 | ||||||
|     pub div_p: Option<PllP>, |     pub divp: Option<PllPDiv>, | ||||||
| 
 | 
 | ||||||
|     /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI)
 |     /// PLL division factor for Q clock (USB, I2S23, SAI1, FDCAN, QSPI)
 | ||||||
|     pub div_q: Option<PllQ>, |     pub divq: Option<PllQDiv>, | ||||||
| 
 | 
 | ||||||
|     /// PLL division factor for R clock (SYSCLK)
 |     /// PLL division factor for R clock (SYSCLK)
 | ||||||
|     pub div_r: Option<PllR>, |     pub divr: Option<PllRDiv>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Sets the source for the 48MHz clock to the USB and RNG peripherals.
 | /// Sets the source for the 48MHz clock to the USB and RNG peripherals.
 | ||||||
| @ -73,39 +65,53 @@ pub enum Clock48MhzSrc { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Clocks configutation
 | /// Clocks configutation
 | ||||||
|  | #[non_exhaustive] | ||||||
| pub struct Config { | pub struct Config { | ||||||
|     pub mux: ClockSrc, |     pub hsi: bool, | ||||||
|  |     pub hse: Option<Hse>, | ||||||
|  |     pub sys: Sysclk, | ||||||
|  |     pub hsi48: Option<super::Hsi48Config>, | ||||||
|  | 
 | ||||||
|  |     pub pll: Option<Pll>, | ||||||
|  | 
 | ||||||
|  |     /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration
 | ||||||
|  |     /// MUST turn on the PLLR output.
 | ||||||
|     pub ahb_pre: AHBPrescaler, |     pub ahb_pre: AHBPrescaler, | ||||||
|     pub apb1_pre: APBPrescaler, |     pub apb1_pre: APBPrescaler, | ||||||
|     pub apb2_pre: APBPrescaler, |     pub apb2_pre: APBPrescaler, | ||||||
|     pub low_power_run: bool, |     pub low_power_run: bool, | ||||||
|     /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration
 | 
 | ||||||
|     /// MUST turn on the PLLR output.
 |  | ||||||
|     pub pll: Option<Pll>, |  | ||||||
|     /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
 |     /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
 | ||||||
|     pub clock_48mhz_src: Option<Clock48MhzSrc>, |     pub clk48_src: Option<Clock48MhzSrc>, | ||||||
|  | 
 | ||||||
|  |     pub ls: super::LsConfig, | ||||||
|  | 
 | ||||||
|     pub adc12_clock_source: AdcClockSource, |     pub adc12_clock_source: AdcClockSource, | ||||||
|     pub adc345_clock_source: AdcClockSource, |     pub adc345_clock_source: AdcClockSource, | ||||||
|     pub fdcan_clock_source: FdCanClockSource, |     pub fdcan_clock_source: FdCanClockSource, | ||||||
| 
 | 
 | ||||||
|     pub ls: super::LsConfig, |     pub boost: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Default for Config { | impl Default for Config { | ||||||
|     #[inline] |     #[inline] | ||||||
|     fn default() -> Config { |     fn default() -> Config { | ||||||
|         Config { |         Config { | ||||||
|             mux: ClockSrc::HSI, |             hsi: true, | ||||||
|  |             hse: None, | ||||||
|  |             sys: Sysclk::HSI, | ||||||
|  |             hsi48: Some(Default::default()), | ||||||
|  |             pll: None, | ||||||
|             ahb_pre: AHBPrescaler::DIV1, |             ahb_pre: AHBPrescaler::DIV1, | ||||||
|             apb1_pre: APBPrescaler::DIV1, |             apb1_pre: APBPrescaler::DIV1, | ||||||
|             apb2_pre: APBPrescaler::DIV1, |             apb2_pre: APBPrescaler::DIV1, | ||||||
|             low_power_run: false, |             low_power_run: false, | ||||||
|             pll: None, |             clk48_src: Some(Clock48MhzSrc::Hsi48(Default::default())), | ||||||
|             clock_48mhz_src: Some(Clock48MhzSrc::Hsi48(Default::default())), |             ls: Default::default(), | ||||||
|             adc12_clock_source: Adcsel::DISABLE, |             adc12_clock_source: Adcsel::DISABLE, | ||||||
|             adc345_clock_source: Adcsel::DISABLE, |             adc345_clock_source: Adcsel::DISABLE, | ||||||
|             fdcan_clock_source: FdCanClockSource::PCLK1, |             fdcan_clock_source: FdCanClockSource::PCLK1, | ||||||
|             ls: Default::default(), |             boost: false, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -117,34 +123,60 @@ pub struct PllFreq { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(crate) unsafe fn init(config: Config) { | pub(crate) unsafe fn init(config: Config) { | ||||||
|  |     // Configure HSI
 | ||||||
|  |     let hsi = match config.hsi { | ||||||
|  |         false => { | ||||||
|  |             RCC.cr().modify(|w| w.set_hsion(false)); | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |         true => { | ||||||
|  |             RCC.cr().modify(|w| w.set_hsion(true)); | ||||||
|  |             while !RCC.cr().read().hsirdy() {} | ||||||
|  |             Some(HSI_FREQ) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // Configure HSE
 | ||||||
|  |     let hse = match config.hse { | ||||||
|  |         None => { | ||||||
|  |             RCC.cr().modify(|w| w.set_hseon(false)); | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |         Some(hse) => { | ||||||
|  |             match hse.mode { | ||||||
|  |                 HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), | ||||||
|  |                 HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); | ||||||
|  |             RCC.cr().modify(|w| w.set_hseon(true)); | ||||||
|  |             while !RCC.cr().read().hserdy() {} | ||||||
|  |             Some(hse.freq) | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     let pll_freq = config.pll.map(|pll_config| { |     let pll_freq = config.pll.map(|pll_config| { | ||||||
|         let src_freq = match pll_config.source { |         let src_freq = match pll_config.source { | ||||||
|             PllSource::HSI => { |             Pllsrc::HSI => unwrap!(hsi), | ||||||
|                 RCC.cr().write(|w| w.set_hsion(true)); |             Pllsrc::HSE => unwrap!(hse), | ||||||
|                 while !RCC.cr().read().hsirdy() {} |             _ => unreachable!(), | ||||||
| 
 |  | ||||||
|                 HSI_FREQ |  | ||||||
|             } |  | ||||||
|             PllSource::HSE(freq) => { |  | ||||||
|                 RCC.cr().write(|w| w.set_hseon(true)); |  | ||||||
|                 while !RCC.cr().read().hserdy() {} |  | ||||||
|                 freq |  | ||||||
|             } |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         // TODO: check PLL input, internal and output frequencies for validity
 | ||||||
|  | 
 | ||||||
|         // Disable PLL before configuration
 |         // Disable PLL before configuration
 | ||||||
|         RCC.cr().modify(|w| w.set_pllon(false)); |         RCC.cr().modify(|w| w.set_pllon(false)); | ||||||
|         while RCC.cr().read().pllrdy() {} |         while RCC.cr().read().pllrdy() {} | ||||||
| 
 | 
 | ||||||
|         let internal_freq = src_freq / pll_config.prediv_m * pll_config.mul_n; |         let internal_freq = src_freq / pll_config.prediv * pll_config.mul; | ||||||
| 
 | 
 | ||||||
|         RCC.pllcfgr().write(|w| { |         RCC.pllcfgr().write(|w| { | ||||||
|             w.set_plln(pll_config.mul_n); |             w.set_plln(pll_config.mul); | ||||||
|             w.set_pllm(pll_config.prediv_m); |             w.set_pllm(pll_config.prediv); | ||||||
|             w.set_pllsrc(pll_config.source.into()); |             w.set_pllsrc(pll_config.source.into()); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         let pll_p_freq = pll_config.div_p.map(|div_p| { |         let pll_p_freq = pll_config.divp.map(|div_p| { | ||||||
|             RCC.pllcfgr().modify(|w| { |             RCC.pllcfgr().modify(|w| { | ||||||
|                 w.set_pllp(div_p); |                 w.set_pllp(div_p); | ||||||
|                 w.set_pllpen(true); |                 w.set_pllpen(true); | ||||||
| @ -152,7 +184,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|             internal_freq / div_p |             internal_freq / div_p | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         let pll_q_freq = pll_config.div_q.map(|div_q| { |         let pll_q_freq = pll_config.divq.map(|div_q| { | ||||||
|             RCC.pllcfgr().modify(|w| { |             RCC.pllcfgr().modify(|w| { | ||||||
|                 w.set_pllq(div_q); |                 w.set_pllq(div_q); | ||||||
|                 w.set_pllqen(true); |                 w.set_pllqen(true); | ||||||
| @ -160,7 +192,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|             internal_freq / div_q |             internal_freq / div_q | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         let pll_r_freq = pll_config.div_r.map(|div_r| { |         let pll_r_freq = pll_config.divr.map(|div_r| { | ||||||
|             RCC.pllcfgr().modify(|w| { |             RCC.pllcfgr().modify(|w| { | ||||||
|                 w.set_pllr(div_r); |                 w.set_pllr(div_r); | ||||||
|                 w.set_pllren(true); |                 w.set_pllren(true); | ||||||
| @ -179,22 +211,10 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     let (sys_clk, sw) = match config.mux { |     let (sys_clk, sw) = match config.sys { | ||||||
|         ClockSrc::HSI => { |         Sysclk::HSI => (HSI_FREQ, Sw::HSI), | ||||||
|             // Enable HSI
 |         Sysclk::HSE => (unwrap!(hse), Sw::HSE), | ||||||
|             RCC.cr().write(|w| w.set_hsion(true)); |         Sysclk::PLL1_R => { | ||||||
|             while !RCC.cr().read().hsirdy() {} |  | ||||||
| 
 |  | ||||||
|             (HSI_FREQ, Sw::HSI) |  | ||||||
|         } |  | ||||||
|         ClockSrc::HSE(freq) => { |  | ||||||
|             // Enable HSE
 |  | ||||||
|             RCC.cr().write(|w| w.set_hseon(true)); |  | ||||||
|             while !RCC.cr().read().hserdy() {} |  | ||||||
| 
 |  | ||||||
|             (freq, Sw::HSE) |  | ||||||
|         } |  | ||||||
|         ClockSrc::PLL => { |  | ||||||
|             assert!(pll_freq.is_some()); |             assert!(pll_freq.is_some()); | ||||||
|             assert!(pll_freq.as_ref().unwrap().pll_r.is_some()); |             assert!(pll_freq.as_ref().unwrap().pll_r.is_some()); | ||||||
| 
 | 
 | ||||||
| @ -202,10 +222,9 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
| 
 | 
 | ||||||
|             assert!(freq <= 170_000_000); |             assert!(freq <= 170_000_000); | ||||||
| 
 | 
 | ||||||
|             if freq >= 150_000_000 { |             if config.boost { | ||||||
|                 // Enable Core Boost mode on freq >= 150Mhz ([RM0440] p234)
 |                 // Enable Core Boost mode ([RM0440] p234)
 | ||||||
|                 PWR.cr5().modify(|w| w.set_r1mode(false)); |                 PWR.cr5().modify(|w| w.set_r1mode(false)); | ||||||
|                 // Set flash wait state in boost mode based on frequency ([RM0440] p191)
 |  | ||||||
|                 if freq <= 36_000_000 { |                 if freq <= 36_000_000 { | ||||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); |                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); | ||||||
|                 } else if freq <= 68_000_000 { |                 } else if freq <= 68_000_000 { | ||||||
| @ -218,8 +237,8 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS4)); |                     FLASH.acr().modify(|w| w.set_latency(Latency::WS4)); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|  |                 // Enable Core Boost mode ([RM0440] p234)
 | ||||||
|                 PWR.cr5().modify(|w| w.set_r1mode(true)); |                 PWR.cr5().modify(|w| w.set_r1mode(true)); | ||||||
|                 // Set flash wait state in normal mode based on frequency ([RM0440] p191)
 |  | ||||||
|                 if freq <= 30_000_000 { |                 if freq <= 30_000_000 { | ||||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); |                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); | ||||||
|                 } else if freq <= 60_000_000 { |                 } else if freq <= 60_000_000 { | ||||||
| @ -235,6 +254,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
| 
 | 
 | ||||||
|             (Hertz(freq), Sw::PLL1_R) |             (Hertz(freq), Sw::PLL1_R) | ||||||
|         } |         } | ||||||
|  |         _ => unreachable!(), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     RCC.cfgr().modify(|w| { |     RCC.cfgr().modify(|w| { | ||||||
| @ -263,7 +283,7 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Setup the 48 MHz clock if needed
 |     // Setup the 48 MHz clock if needed
 | ||||||
|     if let Some(clock_48mhz_src) = config.clock_48mhz_src { |     if let Some(clock_48mhz_src) = config.clk48_src { | ||||||
|         let source = match clock_48mhz_src { |         let source = match clock_48mhz_src { | ||||||
|             Clock48MhzSrc::PllQ => { |             Clock48MhzSrc::PllQ => { | ||||||
|                 // Make sure the PLLQ is enabled and running at 48Mhz
 |                 // Make sure the PLLQ is enabled and running at 48Mhz
 | ||||||
| @ -317,9 +337,33 @@ pub(crate) unsafe fn init(config: Config) { | |||||||
|         pclk2_tim: Some(apb2_tim_freq), |         pclk2_tim: Some(apb2_tim_freq), | ||||||
|         adc: adc12_ck, |         adc: adc12_ck, | ||||||
|         adc34: adc345_ck, |         adc34: adc345_ck, | ||||||
|         pll1_p: None, |         pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p), | ||||||
|         pll1_q: None, // TODO
 |         pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_p), | ||||||
|         hse: None,    // TODO
 |         hse: hse, | ||||||
|         rtc: rtc, |         rtc: rtc, | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // TODO: if necessary, make more of these gated behind cfg attrs
 | ||||||
|  | mod max { | ||||||
|  |     use core::ops::RangeInclusive; | ||||||
|  | 
 | ||||||
|  |     use crate::time::Hertz; | ||||||
|  | 
 | ||||||
|  |     /// HSE 4-48MHz (RM0440 p280)
 | ||||||
|  |     pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000); | ||||||
|  | 
 | ||||||
|  |     /// External Clock ?-48MHz (RM0440 p280)
 | ||||||
|  |     pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000); | ||||||
|  | 
 | ||||||
|  |     /// SYSCLK ?-170MHz (RM0440 p282)
 | ||||||
|  |     pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); | ||||||
|  | 
 | ||||||
|  |     /// PLL Output frequency ?-170MHz (RM0440 p281)
 | ||||||
|  |     pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); | ||||||
|  | 
 | ||||||
|  |     // Left over from f.rs, remove if not necessary
 | ||||||
|  |     pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(12_500_000)..=Hertz(216_000_000); | ||||||
|  |     pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000); | ||||||
|  |     pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000); | ||||||
|  | } | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| use defmt::*; | use defmt::*; | ||||||
| use embassy_executor::Spawner; | use embassy_executor::Spawner; | ||||||
| use embassy_stm32::adc::{Adc, SampleTime}; | use embassy_stm32::adc::{Adc, SampleTime}; | ||||||
| use embassy_stm32::rcc::{AdcClockSource, ClockSrc, Pll, PllM, PllN, PllR, PllSource}; | use embassy_stm32::rcc::{AdcClockSource, Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk}; | ||||||
| use embassy_stm32::Config; | use embassy_stm32::Config; | ||||||
| use embassy_time::{Delay, Timer}; | use embassy_time::{Delay, Timer}; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
| @ -14,17 +14,17 @@ async fn main(_spawner: Spawner) { | |||||||
|     let mut config = Config::default(); |     let mut config = Config::default(); | ||||||
| 
 | 
 | ||||||
|     config.rcc.pll = Some(Pll { |     config.rcc.pll = Some(Pll { | ||||||
|         source: PllSource::HSI, |         source: Pllsrc::HSI, | ||||||
|         prediv_m: PllM::DIV4, |         prediv: PllPreDiv::DIV4, | ||||||
|         mul_n: PllN::MUL85, |         mul: PllMul::MUL85, | ||||||
|         div_p: None, |         divp: None, | ||||||
|         div_q: None, |         divq: None, | ||||||
|         // Main system clock at 170 MHz
 |         // Main system clock at 170 MHz
 | ||||||
|         div_r: Some(PllR::DIV2), |         divr: Some(PllRDiv::DIV2), | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     config.rcc.adc12_clock_source = AdcClockSource::SYS; |     config.rcc.adc12_clock_source = AdcClockSource::SYS; | ||||||
|     config.rcc.mux = ClockSrc::PLL; |     config.rcc.sys = Sysclk::PLL1_R; | ||||||
| 
 | 
 | ||||||
|     let mut p = embassy_stm32::init(config); |     let mut p = embassy_stm32::init(config); | ||||||
|     info!("Hello World!"); |     info!("Hello World!"); | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| use defmt::*; | use defmt::*; | ||||||
| use embassy_executor::Spawner; | use embassy_executor::Spawner; | ||||||
| use embassy_stm32::rcc::{ClockSrc, Pll, PllM, PllN, PllR, PllSource}; | use embassy_stm32::rcc::{Pll, PllMul, PllPreDiv, PllRDiv, Pllsrc, Sysclk}; | ||||||
| use embassy_stm32::Config; | use embassy_stm32::Config; | ||||||
| use embassy_time::Timer; | use embassy_time::Timer; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
| @ -13,16 +13,16 @@ async fn main(_spawner: Spawner) { | |||||||
|     let mut config = Config::default(); |     let mut config = Config::default(); | ||||||
| 
 | 
 | ||||||
|     config.rcc.pll = Some(Pll { |     config.rcc.pll = Some(Pll { | ||||||
|         source: PllSource::HSI, |         source: Pllsrc::HSI, | ||||||
|         prediv_m: PllM::DIV4, |         prediv: PllPreDiv::DIV4, | ||||||
|         mul_n: PllN::MUL85, |         mul: PllMul::MUL85, | ||||||
|         div_p: None, |         divp: None, | ||||||
|         div_q: None, |         divq: None, | ||||||
|         // Main system clock at 170 MHz
 |         // Main system clock at 170 MHz
 | ||||||
|         div_r: Some(PllR::DIV2), |         divr: Some(PllRDiv::DIV2), | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     config.rcc.mux = ClockSrc::PLL; |     config.rcc.sys = Sysclk::PLL1_R; | ||||||
| 
 | 
 | ||||||
|     let _p = embassy_stm32::init(config); |     let _p = embassy_stm32::init(config); | ||||||
|     info!("Hello World!"); |     info!("Hello World!"); | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ | |||||||
| 
 | 
 | ||||||
| use defmt::{panic, *}; | use defmt::{panic, *}; | ||||||
| use embassy_executor::Spawner; | use embassy_executor::Spawner; | ||||||
| use embassy_stm32::rcc::{Clock48MhzSrc, ClockSrc, Hsi48Config, Pll, PllM, PllN, PllQ, PllR, PllSource}; | use embassy_stm32::rcc::{ | ||||||
|  |     Clock48MhzSrc, Hse, HseMode, Hsi48Config, Pll, PllMul, PllPreDiv, PllQDiv, PllRDiv, Pllsrc, Sysclk, | ||||||
|  | }; | ||||||
| use embassy_stm32::time::Hertz; | use embassy_stm32::time::Hertz; | ||||||
| use embassy_stm32::usb::{self, Driver, Instance}; | use embassy_stm32::usb::{self, Driver, Instance}; | ||||||
| use embassy_stm32::{bind_interrupts, peripherals, Config}; | use embassy_stm32::{bind_interrupts, peripherals, Config}; | ||||||
| @ -24,25 +26,30 @@ async fn main(_spawner: Spawner) { | |||||||
|     // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE.
 |     // Change this to `false` to use the HSE clock source for the USB. This example assumes an 8MHz HSE.
 | ||||||
|     const USE_HSI48: bool = true; |     const USE_HSI48: bool = true; | ||||||
| 
 | 
 | ||||||
|     let plldivq = if USE_HSI48 { None } else { Some(PllQ::DIV6) }; |     let plldivq = if USE_HSI48 { None } else { Some(PllQDiv::DIV6) }; | ||||||
| 
 | 
 | ||||||
|     config.rcc.pll = Some(Pll { |     config.rcc.hse = Some(Hse { | ||||||
|         source: PllSource::HSE(Hertz(8_000_000)), |         freq: Hertz(8_000_000), | ||||||
|         prediv_m: PllM::DIV2, |         mode: HseMode::Oscillator, | ||||||
|         mul_n: PllN::MUL72, |  | ||||||
|         div_p: None, |  | ||||||
|         div_q: plldivq, |  | ||||||
|         // Main system clock at 144 MHz
 |  | ||||||
|         div_r: Some(PllR::DIV2), |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     config.rcc.mux = ClockSrc::PLL; |     config.rcc.pll = Some(Pll { | ||||||
|  |         source: Pllsrc::HSE, | ||||||
|  |         prediv: PllPreDiv::DIV2, | ||||||
|  |         mul: PllMul::MUL72, | ||||||
|  |         divp: None, | ||||||
|  |         divq: plldivq, | ||||||
|  |         // Main system clock at 144 MHz
 | ||||||
|  |         divr: Some(PllRDiv::DIV2), | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     config.rcc.sys = Sysclk::PLL1_R; | ||||||
| 
 | 
 | ||||||
|     if USE_HSI48 { |     if USE_HSI48 { | ||||||
|         // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
 |         // Sets up the Clock Recovery System (CRS) to use the USB SOF to trim the HSI48 oscillator.
 | ||||||
|         config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); |         config.rcc.clk48_src = Some(Clock48MhzSrc::Hsi48(Hsi48Config { sync_from_usb: true })); | ||||||
|     } else { |     } else { | ||||||
|         config.rcc.clock_48mhz_src = Some(Clock48MhzSrc::PllQ); |         config.rcc.clk48_src = Some(Clock48MhzSrc::PllQ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let p = embassy_stm32::init(config); |     let p = embassy_stm32::init(config); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user