aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf <[email protected]>2022-05-11 20:56:57 +0200
committerRalf <[email protected]>2022-05-12 09:09:39 +0200
commitc90968bb70e626c5d2c375befbbf19423f48ba5e (patch)
tree791582fe12d36516d837363946bfaf948d092084
parent1a216958ac121befa7da6912db307516d1ddcb07 (diff)
stm32/rcc: Modify only relevant CFGR bits and keep the settings previously done.
PLL settings remained intact because these bits are not writable when PLL is enabled, but prescaler settings were overwritten by selecting PLL as sysclk (CFGR.SW[1:0]).
-rw-r--r--embassy-stm32/src/rcc/f3.rs17
1 files changed, 11 insertions, 6 deletions
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs
index 5a7351444..c2aec04c4 100644
--- a/embassy-stm32/src/rcc/f3.rs
+++ b/embassy-stm32/src/rcc/f3.rs
@@ -111,8 +111,9 @@ pub(crate) unsafe fn init(config: Config) {
111 }); 111 });
112 112
113 // Enable HSE 113 // Enable HSE
114 // RM0316: "Bits 31:26 Reserved, must be kept at reset value."
114 if config.hse.is_some() { 115 if config.hse.is_some() {
115 RCC.cr().write(|w| { 116 RCC.cr().modify(|w| {
116 w.set_hsebyp(config.bypass_hse); 117 w.set_hsebyp(config.bypass_hse);
117 // We turn on clock security to switch to HSI when HSE fails 118 // We turn on clock security to switch to HSI when HSE fails
118 w.set_csson(true); 119 w.set_csson(true);
@@ -122,27 +123,30 @@ pub(crate) unsafe fn init(config: Config) {
122 } 123 }
123 124
124 // Enable PLL 125 // Enable PLL
126 // RM0316: "Reserved, must be kept at reset value."
125 if let Some(ref pll_config) = pll_config { 127 if let Some(ref pll_config) = pll_config {
126 RCC.cfgr().write(|w| { 128 RCC.cfgr().modify(|w| {
127 w.set_pllmul(pll_config.pll_mul); 129 w.set_pllmul(pll_config.pll_mul);
128 w.set_pllsrc(pll_config.pll_src); 130 w.set_pllsrc(pll_config.pll_src);
129 }); 131 });
130 if let Some(pll_div) = pll_config.pll_div { 132 if let Some(pll_div) = pll_config.pll_div {
131 RCC.cfgr2().write(|w| w.set_prediv(pll_div)); 133 RCC.cfgr2().modify(|w| w.set_prediv(pll_div));
132 } 134 }
133 RCC.cr().modify(|w| w.set_pllon(true)); 135 RCC.cr().modify(|w| w.set_pllon(true));
134 while !RCC.cr().read().pllrdy() {} 136 while !RCC.cr().read().pllrdy() {}
135 } 137 }
136 138
139 // CFGR has been written before (PLL) don't overwrite these settings
137 if config.pll48 { 140 if config.pll48 {
138 let usb_pre = get_usb_pre(&config, sysclk, pclk1, &pll_config); 141 let usb_pre = get_usb_pre(&config, sysclk, pclk1, &pll_config);
139 RCC.cfgr().write(|w| { 142 RCC.cfgr().modify(|w| {
140 w.set_usbpre(usb_pre); 143 w.set_usbpre(usb_pre);
141 }); 144 });
142 } 145 }
143 146
144 // Set prescalers 147 // Set prescalers
145 RCC.cfgr().write(|w| { 148 // CFGR has been written before (PLL, PLL48) don't overwrite these settings
149 RCC.cfgr().modify(|w| {
146 w.set_ppre2(ppre2_bits); 150 w.set_ppre2(ppre2_bits);
147 w.set_ppre1(ppre1_bits); 151 w.set_ppre1(ppre1_bits);
148 w.set_hpre(hpre_bits); 152 w.set_hpre(hpre_bits);
@@ -153,7 +157,8 @@ pub(crate) unsafe fn init(config: Config) {
153 // 1 to 16 AHB cycles after write" 157 // 1 to 16 AHB cycles after write"
154 cortex_m::asm::delay(16); 158 cortex_m::asm::delay(16);
155 159
156 RCC.cfgr().write(|w| { 160 // CFGR has been written before (PLL, PLL48, clock divider) don't overwrite these settings
161 RCC.cfgr().modify(|w| {
157 w.set_sw(match (pll_config, config.hse) { 162 w.set_sw(match (pll_config, config.hse) {
158 (Some(_), _) => Sw::PLL, 163 (Some(_), _) => Sw::PLL,
159 (None, Some(_)) => Sw::HSE, 164 (None, Some(_)) => Sw::HSE,