Added documentation, fixed and refined boost and flash read latency config
This commit is contained in:
		
							parent
							
								
									25a95503f6
								
							
						
					
					
						commit
						e465dacf73
					
				| @ -13,6 +13,7 @@ use crate::time::Hertz; | ||||
| /// HSI speed
 | ||||
| pub const HSI_FREQ: Hertz = Hertz(16_000_000); | ||||
| 
 | ||||
| /// HSE Mode
 | ||||
| #[derive(Clone, Copy, Eq, PartialEq)] | ||||
| pub enum HseMode { | ||||
|     /// crystal/ceramic oscillator (HSEBYP=0)
 | ||||
| @ -21,6 +22,7 @@ pub enum HseMode { | ||||
|     Bypass, | ||||
| } | ||||
| 
 | ||||
| /// HSE Configuration
 | ||||
| #[derive(Clone, Copy, Eq, PartialEq)] | ||||
| pub struct Hse { | ||||
|     /// HSE frequency.
 | ||||
| @ -57,11 +59,19 @@ pub struct Pll { | ||||
| /// Clocks configutation
 | ||||
| #[non_exhaustive] | ||||
| pub struct Config { | ||||
|     /// HSI Enable
 | ||||
|     pub hsi: bool, | ||||
| 
 | ||||
|     /// HSE Configuration
 | ||||
|     pub hse: Option<Hse>, | ||||
| 
 | ||||
|     /// System Clock Configuration
 | ||||
|     pub sys: Sysclk, | ||||
| 
 | ||||
|     /// HSI48 Configuration
 | ||||
|     pub hsi48: Option<super::Hsi48Config>, | ||||
| 
 | ||||
|     /// PLL Configuration
 | ||||
|     pub pll: Option<Pll>, | ||||
| 
 | ||||
|     /// Iff PLL is requested as the main clock source in the `mux` field then the PLL configuration
 | ||||
| @ -69,17 +79,26 @@ pub struct Config { | ||||
|     pub ahb_pre: AHBPrescaler, | ||||
|     pub apb1_pre: APBPrescaler, | ||||
|     pub apb2_pre: APBPrescaler, | ||||
| 
 | ||||
|     pub low_power_run: bool, | ||||
| 
 | ||||
|     /// Sets the clock source for the 48MHz clock used by the USB and RNG peripherals.
 | ||||
|     pub clk48_src: Clk48Src, | ||||
| 
 | ||||
|     /// Low-Speed Clock Configuration
 | ||||
|     pub ls: super::LsConfig, | ||||
| 
 | ||||
|     /// Clock Source for ADCs 1 and 2
 | ||||
|     pub adc12_clock_source: AdcClockSource, | ||||
| 
 | ||||
|     /// Clock Source for ADCs 3, 4 and 5
 | ||||
|     pub adc345_clock_source: AdcClockSource, | ||||
| 
 | ||||
|     /// Clock Source for FDCAN
 | ||||
|     pub fdcan_clock_source: FdCanClockSource, | ||||
| 
 | ||||
|     /// Enable range1 boost mode
 | ||||
|     /// Recommended when the SYSCLK frequency is greater than 150MHz.
 | ||||
|     pub boost: bool, | ||||
| } | ||||
| 
 | ||||
| @ -217,36 +236,6 @@ pub(crate) unsafe fn init(config: Config) { | ||||
| 
 | ||||
|             assert!(freq <= 170_000_000); | ||||
| 
 | ||||
|             if config.boost { | ||||
|                 // Enable Core Boost mode ([RM0440] p234)
 | ||||
|                 PWR.cr5().modify(|w| w.set_r1mode(false)); | ||||
|                 if freq <= 36_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); | ||||
|                 } else if freq <= 68_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS1)); | ||||
|                 } else if freq <= 102_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS2)); | ||||
|                 } else if freq <= 136_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS3)); | ||||
|                 } else { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS4)); | ||||
|                 } | ||||
|             } else { | ||||
|                 // Enable Core Boost mode ([RM0440] p234)
 | ||||
|                 PWR.cr5().modify(|w| w.set_r1mode(true)); | ||||
|                 if freq <= 30_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS0)); | ||||
|                 } else if freq <= 60_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS1)); | ||||
|                 } else if freq <= 80_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS2)); | ||||
|                 } else if freq <= 120_000_000 { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS3)); | ||||
|                 } else { | ||||
|                     FLASH.acr().modify(|w| w.set_latency(Latency::WS4)); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             (Hertz(freq), Sw::PLL1_R) | ||||
|         } | ||||
|         _ => unreachable!(), | ||||
| @ -261,6 +250,26 @@ pub(crate) unsafe fn init(config: Config) { | ||||
| 
 | ||||
|     let ahb_freq = sys_clk / config.ahb_pre; | ||||
| 
 | ||||
|     // Configure Core Boost mode ([RM0440] p234 – inverted because setting r1mode to 0 enables boost mode!)
 | ||||
|     PWR.cr5().modify(|w| w.set_r1mode(!config.boost)); | ||||
| 
 | ||||
|     // Configure flash read access latency based on boost mode and frequency (RM0440 p98)
 | ||||
|     FLASH.acr().modify(|w| { | ||||
|         w.set_latency(match (config.boost, ahb_freq.0) { | ||||
|             (true, ..=34_000_000) => Latency::WS0, | ||||
|             (true, ..=68_000_000) => Latency::WS1, | ||||
|             (true, ..=102_000_000) => Latency::WS2, | ||||
|             (true, ..=136_000_000) => Latency::WS3, | ||||
|             (true, _) => Latency::WS4, | ||||
| 
 | ||||
|             (false, ..=36_000_000) => Latency::WS0, | ||||
|             (false, ..=60_000_000) => Latency::WS1, | ||||
|             (false, ..=90_000_000) => Latency::WS2, | ||||
|             (false, ..=120_000_000) => Latency::WS3, | ||||
|             (false, _) => Latency::WS4, | ||||
|         }) | ||||
|     }); | ||||
| 
 | ||||
|     let (apb1_freq, apb1_tim_freq) = match config.apb1_pre { | ||||
|         APBPrescaler::DIV1 => (ahb_freq, ahb_freq), | ||||
|         pre => { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user