diff options
| -rw-r--r-- | embassy-stm32/src/pwr/u5.rs | 31 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/u5/mod.rs | 507 | ||||
| -rw-r--r-- | examples/stm32u5/.cargo/config.toml | 3 | ||||
| -rw-r--r-- | examples/stm32u5/Cargo.toml | 8 | ||||
| m--------- | stm32-data | 0 |
5 files changed, 543 insertions, 6 deletions
diff --git a/embassy-stm32/src/pwr/u5.rs b/embassy-stm32/src/pwr/u5.rs index 8b1378917..a90659d9c 100644 --- a/embassy-stm32/src/pwr/u5.rs +++ b/embassy-stm32/src/pwr/u5.rs | |||
| @@ -1 +1,32 @@ | |||
| 1 | use crate::peripherals; | ||
| 1 | 2 | ||
| 3 | /// Voltage Scale | ||
| 4 | /// | ||
| 5 | /// Represents the voltage range feeding the CPU core. The maximum core | ||
| 6 | /// clock frequency depends on this value. | ||
| 7 | #[derive(Copy, Clone, PartialEq)] | ||
| 8 | pub enum VoltageScale { | ||
| 9 | // Highest frequency | ||
| 10 | Range1, | ||
| 11 | Range2, | ||
| 12 | Range3, | ||
| 13 | // Lowest power | ||
| 14 | Range4, | ||
| 15 | } | ||
| 16 | |||
| 17 | /// Power Configuration | ||
| 18 | /// | ||
| 19 | /// Generated when the PWR peripheral is frozen. The existence of this | ||
| 20 | /// value indicates that the voltage scaling configuration can no | ||
| 21 | /// longer be changed. | ||
| 22 | pub struct Power { | ||
| 23 | pub(crate) vos: VoltageScale, | ||
| 24 | } | ||
| 25 | |||
| 26 | impl Power { | ||
| 27 | pub fn new(_peri: peripherals::PWR) -> Self { | ||
| 28 | Self { | ||
| 29 | vos: VoltageScale::Range4, | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
diff --git a/embassy-stm32/src/rcc/u5/mod.rs b/embassy-stm32/src/rcc/u5/mod.rs index dbf5e8dfb..6e68b2205 100644 --- a/embassy-stm32/src/rcc/u5/mod.rs +++ b/embassy-stm32/src/rcc/u5/mod.rs | |||
| @@ -1,8 +1,295 @@ | |||
| 1 | pub struct Config {} | 1 | use crate::pac; |
| 2 | use crate::peripherals::{self, RCC}; | ||
| 3 | use crate::pwr::{Power, VoltageScale}; | ||
| 4 | use crate::rcc::{set_freqs, Clocks}; | ||
| 5 | use crate::time::{Hertz, U32Ext}; | ||
| 6 | use stm32_metapac::rcc::vals::{Hpre, Msirange, Msirgsel, Pllm, Pllsrc, Ppre, Sw}; | ||
| 7 | |||
| 8 | /// HSI16 speed | ||
| 9 | pub const HSI16_FREQ: u32 = 16_000_000; | ||
| 10 | |||
| 11 | #[derive(Copy, Clone)] | ||
| 12 | pub enum ClockSrc { | ||
| 13 | MSI(MSIRange), | ||
| 14 | HSE(Hertz), | ||
| 15 | HSI16, | ||
| 16 | PLL1R(PllSrc, PllM, PllN, PllClkDiv), | ||
| 17 | } | ||
| 18 | |||
| 19 | #[derive(Clone, Copy, Debug)] | ||
| 20 | pub enum PllSrc { | ||
| 21 | MSI(MSIRange), | ||
| 22 | HSE(Hertz), | ||
| 23 | HSI16, | ||
| 24 | } | ||
| 25 | |||
| 26 | impl Into<Pllsrc> for PllSrc { | ||
| 27 | fn into(self) -> Pllsrc { | ||
| 28 | match self { | ||
| 29 | PllSrc::MSI(..) => Pllsrc::MSIS, | ||
| 30 | PllSrc::HSE(..) => Pllsrc::HSE, | ||
| 31 | PllSrc::HSI16 => Pllsrc::HSI16, | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | seq_macro::seq!(N in 2..=128 { | ||
| 37 | #[derive(Copy, Clone, Debug)] | ||
| 38 | pub enum PllClkDiv { | ||
| 39 | NotDivided, | ||
| 40 | #( | ||
| 41 | Div#N = (N-1), | ||
| 42 | )* | ||
| 43 | } | ||
| 44 | |||
| 45 | impl PllClkDiv { | ||
| 46 | fn to_div(&self) -> u8 { | ||
| 47 | match self { | ||
| 48 | PllClkDiv::NotDivided => 1, | ||
| 49 | #( | ||
| 50 | PllClkDiv::Div#N => (N + 1), | ||
| 51 | )* | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | }); | ||
| 56 | |||
| 57 | impl Into<u8> for PllClkDiv { | ||
| 58 | fn into(self) -> u8 { | ||
| 59 | (self as u8) + 1 | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | seq_macro::seq!(N in 4..=512 { | ||
| 64 | #[derive(Copy, Clone, Debug)] | ||
| 65 | pub enum PllN { | ||
| 66 | NotMultiplied, | ||
| 67 | #( | ||
| 68 | Mul#N = (N-1), | ||
| 69 | )* | ||
| 70 | } | ||
| 71 | |||
| 72 | impl PllN { | ||
| 73 | fn to_mul(&self) -> u16 { | ||
| 74 | match self { | ||
| 75 | PllN::NotMultiplied => 1, | ||
| 76 | #( | ||
| 77 | PllN::Mul#N => (N + 1), | ||
| 78 | )* | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | }); | ||
| 83 | |||
| 84 | impl Into<u16> for PllN { | ||
| 85 | fn into(self) -> u16 { | ||
| 86 | (self as u16) + 1 | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | // Pre-division | ||
| 91 | #[derive(Copy, Clone, Debug)] | ||
| 92 | pub enum PllM { | ||
| 93 | NotDivided = 0b0000, | ||
| 94 | Div2 = 0b0001, | ||
| 95 | Div3 = 0b0010, | ||
| 96 | Div4 = 0b0011, | ||
| 97 | Div5 = 0b0100, | ||
| 98 | Div6 = 0b0101, | ||
| 99 | Div7 = 0b0110, | ||
| 100 | Div8 = 0b0111, | ||
| 101 | Div9 = 0b1000, | ||
| 102 | Div10 = 0b1001, | ||
| 103 | Div11 = 0b1010, | ||
| 104 | Div12 = 0b1011, | ||
| 105 | Div13 = 0b1100, | ||
| 106 | Div14 = 0b1101, | ||
| 107 | Div15 = 0b1110, | ||
| 108 | Div16 = 0b1111, | ||
| 109 | } | ||
| 110 | |||
| 111 | impl Into<Pllm> for PllM { | ||
| 112 | fn into(self) -> Pllm { | ||
| 113 | Pllm(self as u8) | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | /// AHB prescaler | ||
| 118 | #[derive(Clone, Copy, PartialEq)] | ||
| 119 | pub enum AHBPrescaler { | ||
| 120 | NotDivided, | ||
| 121 | Div2, | ||
| 122 | Div4, | ||
| 123 | Div8, | ||
| 124 | Div16, | ||
| 125 | Div64, | ||
| 126 | Div128, | ||
| 127 | Div256, | ||
| 128 | Div512, | ||
| 129 | } | ||
| 130 | |||
| 131 | impl Into<Hpre> for AHBPrescaler { | ||
| 132 | fn into(self) -> Hpre { | ||
| 133 | match self { | ||
| 134 | AHBPrescaler::NotDivided => Hpre::NONE, | ||
| 135 | AHBPrescaler::Div2 => Hpre::DIV2, | ||
| 136 | AHBPrescaler::Div4 => Hpre::DIV4, | ||
| 137 | AHBPrescaler::Div8 => Hpre::DIV8, | ||
| 138 | AHBPrescaler::Div16 => Hpre::DIV16, | ||
| 139 | AHBPrescaler::Div64 => Hpre::DIV64, | ||
| 140 | AHBPrescaler::Div128 => Hpre::DIV128, | ||
| 141 | AHBPrescaler::Div256 => Hpre::DIV256, | ||
| 142 | AHBPrescaler::Div512 => Hpre::DIV512, | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | impl Into<u8> for AHBPrescaler { | ||
| 148 | fn into(self) -> u8 { | ||
| 149 | match self { | ||
| 150 | AHBPrescaler::NotDivided => 1, | ||
| 151 | AHBPrescaler::Div2 => 0x08, | ||
| 152 | AHBPrescaler::Div4 => 0x09, | ||
| 153 | AHBPrescaler::Div8 => 0x0a, | ||
| 154 | AHBPrescaler::Div16 => 0x0b, | ||
| 155 | AHBPrescaler::Div64 => 0x0c, | ||
| 156 | AHBPrescaler::Div128 => 0x0d, | ||
| 157 | AHBPrescaler::Div256 => 0x0e, | ||
| 158 | AHBPrescaler::Div512 => 0x0f, | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | impl Default for AHBPrescaler { | ||
| 164 | fn default() -> Self { | ||
| 165 | AHBPrescaler::NotDivided | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | /// APB prescaler | ||
| 170 | #[derive(Clone, Copy)] | ||
| 171 | pub enum APBPrescaler { | ||
| 172 | NotDivided, | ||
| 173 | Div2, | ||
| 174 | Div4, | ||
| 175 | Div8, | ||
| 176 | Div16, | ||
| 177 | } | ||
| 178 | |||
| 179 | impl Into<Ppre> for APBPrescaler { | ||
| 180 | fn into(self) -> Ppre { | ||
| 181 | match self { | ||
| 182 | APBPrescaler::NotDivided => Ppre::NONE, | ||
| 183 | APBPrescaler::Div2 => Ppre::DIV2, | ||
| 184 | APBPrescaler::Div4 => Ppre::DIV4, | ||
| 185 | APBPrescaler::Div8 => Ppre::DIV8, | ||
| 186 | APBPrescaler::Div16 => Ppre::DIV16, | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | impl Default for APBPrescaler { | ||
| 192 | fn default() -> Self { | ||
| 193 | APBPrescaler::NotDivided | ||
| 194 | } | ||
| 195 | } | ||
| 196 | |||
| 197 | impl Into<u8> for APBPrescaler { | ||
| 198 | fn into(self) -> u8 { | ||
| 199 | match self { | ||
| 200 | APBPrescaler::NotDivided => 1, | ||
| 201 | APBPrescaler::Div2 => 0x04, | ||
| 202 | APBPrescaler::Div4 => 0x05, | ||
| 203 | APBPrescaler::Div8 => 0x06, | ||
| 204 | APBPrescaler::Div16 => 0x07, | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | impl Into<Sw> for ClockSrc { | ||
| 210 | fn into(self) -> Sw { | ||
| 211 | match self { | ||
| 212 | ClockSrc::MSI(..) => Sw::MSIS, | ||
| 213 | ClockSrc::HSE(..) => Sw::HSE, | ||
| 214 | ClockSrc::HSI16 => Sw::HSI16, | ||
| 215 | ClockSrc::PLL1R(..) => Sw::PLL1R, | ||
| 216 | } | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | #[derive(Debug, Copy, Clone)] | ||
| 221 | pub enum MSIRange { | ||
| 222 | Range48mhz = 48_000_000, | ||
| 223 | Range24mhz = 24_000_000, | ||
| 224 | Range16mhz = 16_000_000, | ||
| 225 | Range12mhz = 12_000_000, | ||
| 226 | Range4mhz = 4_000_000, | ||
| 227 | Range2mhz = 2_000_000, | ||
| 228 | Range1_33mhz = 1_330_000, | ||
| 229 | Range1mhz = 1_000_000, | ||
| 230 | Range3_072mhz = 3_072_000, | ||
| 231 | Range1_536mhz = 1_536_000, | ||
| 232 | Range1_024mhz = 1_024_000, | ||
| 233 | Range768khz = 768_000, | ||
| 234 | Range400khz = 400_000, | ||
| 235 | Range200khz = 200_000, | ||
| 236 | Range133khz = 133_000, | ||
| 237 | Range100khz = 100_000, | ||
| 238 | } | ||
| 239 | |||
| 240 | impl Into<u32> for MSIRange { | ||
| 241 | fn into(self) -> u32 { | ||
| 242 | self as u32 | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | impl Into<Msirange> for MSIRange { | ||
| 247 | fn into(self) -> Msirange { | ||
| 248 | match self { | ||
| 249 | MSIRange::Range48mhz => Msirange::RANGE_48MHZ, | ||
| 250 | MSIRange::Range24mhz => Msirange::RANGE_24MHZ, | ||
| 251 | MSIRange::Range16mhz => Msirange::RANGE_16MHZ, | ||
| 252 | MSIRange::Range12mhz => Msirange::RANGE_12MHZ, | ||
| 253 | MSIRange::Range4mhz => Msirange::RANGE_4MHZ, | ||
| 254 | MSIRange::Range2mhz => Msirange::RANGE_2MHZ, | ||
| 255 | MSIRange::Range1_33mhz => Msirange::RANGE_1_33MHZ, | ||
| 256 | MSIRange::Range1mhz => Msirange::RANGE_1MHZ, | ||
| 257 | MSIRange::Range3_072mhz => Msirange::RANGE_3_072MHZ, | ||
| 258 | MSIRange::Range1_536mhz => Msirange::RANGE_1_536MHZ, | ||
| 259 | MSIRange::Range1_024mhz => Msirange::RANGE_1_024MHZ, | ||
| 260 | MSIRange::Range768khz => Msirange::RANGE_768KHZ, | ||
| 261 | MSIRange::Range400khz => Msirange::RANGE_400KHZ, | ||
| 262 | MSIRange::Range200khz => Msirange::RANGE_200KHZ, | ||
| 263 | MSIRange::Range133khz => Msirange::RANGE_133KHZ, | ||
| 264 | MSIRange::Range100khz => Msirange::RANGE_100KHZ, | ||
| 265 | } | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 269 | impl Default for MSIRange { | ||
| 270 | fn default() -> Self { | ||
| 271 | MSIRange::Range4mhz | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | #[derive(Copy, Clone)] | ||
| 276 | pub struct Config { | ||
| 277 | mux: ClockSrc, | ||
| 278 | ahb_pre: AHBPrescaler, | ||
| 279 | apb1_pre: APBPrescaler, | ||
| 280 | apb2_pre: APBPrescaler, | ||
| 281 | apb3_pre: APBPrescaler, | ||
| 282 | } | ||
| 2 | 283 | ||
| 3 | impl Config { | 284 | impl Config { |
| 4 | pub fn new() -> Self { | 285 | pub fn new() -> Self { |
| 5 | Config {} | 286 | Config { |
| 287 | mux: ClockSrc::MSI(MSIRange::default()), | ||
| 288 | ahb_pre: Default::default(), | ||
| 289 | apb1_pre: Default::default(), | ||
| 290 | apb2_pre: Default::default(), | ||
| 291 | apb3_pre: Default::default(), | ||
| 292 | } | ||
| 6 | } | 293 | } |
| 7 | } | 294 | } |
| 8 | 295 | ||
| @@ -12,4 +299,218 @@ impl Default for Config { | |||
| 12 | } | 299 | } |
| 13 | } | 300 | } |
| 14 | 301 | ||
| 15 | pub unsafe fn init(_config: Config) {} | 302 | /// Extension trait that freezes the `RCC` peripheral with provided clocks configuration |
| 303 | pub trait RccExt { | ||
| 304 | fn freeze(self, config: Config, power: &Power) -> Clocks; | ||
| 305 | } | ||
| 306 | |||
| 307 | impl RccExt for RCC { | ||
| 308 | #[inline] | ||
| 309 | fn freeze(self, cfgr: Config, power: &Power) -> Clocks { | ||
| 310 | let rcc = pac::RCC; | ||
| 311 | |||
| 312 | let sys_clk = match cfgr.mux { | ||
| 313 | ClockSrc::MSI(range) => { | ||
| 314 | unsafe { | ||
| 315 | rcc.icscr1().modify(|w| { | ||
| 316 | let bits: Msirange = range.into(); | ||
| 317 | w.set_msisrange(bits); | ||
| 318 | w.set_msirgsel(Msirgsel::RCC_ICSCR1); | ||
| 319 | }); | ||
| 320 | rcc.cr().write(|w| { | ||
| 321 | w.set_msipllen(false); | ||
| 322 | w.set_msison(true); | ||
| 323 | w.set_msison(true); | ||
| 324 | }); | ||
| 325 | while !rcc.cr().read().msisrdy() {} | ||
| 326 | } | ||
| 327 | |||
| 328 | range.into() | ||
| 329 | } | ||
| 330 | ClockSrc::HSE(freq) => { | ||
| 331 | unsafe { | ||
| 332 | rcc.cr().write(|w| w.set_hseon(true)); | ||
| 333 | while !rcc.cr().read().hserdy() {} | ||
| 334 | } | ||
| 335 | |||
| 336 | freq.0 | ||
| 337 | } | ||
| 338 | ClockSrc::HSI16 => { | ||
| 339 | unsafe { | ||
| 340 | rcc.cr().write(|w| w.set_hsion(true)); | ||
| 341 | while !rcc.cr().read().hsirdy() {} | ||
| 342 | } | ||
| 343 | |||
| 344 | HSI16_FREQ | ||
| 345 | } | ||
| 346 | ClockSrc::PLL1R(src, m, n, div) => { | ||
| 347 | let freq = match src { | ||
| 348 | PllSrc::MSI(_) => MSIRange::default().into(), | ||
| 349 | PllSrc::HSE(hertz) => hertz.0, | ||
| 350 | PllSrc::HSI16 => HSI16_FREQ, | ||
| 351 | }; | ||
| 352 | |||
| 353 | // disable | ||
| 354 | unsafe { | ||
| 355 | rcc.cr().modify(|w| w.set_pllon(0, false)); | ||
| 356 | while rcc.cr().read().pllrdy(0) {} | ||
| 357 | } | ||
| 358 | |||
| 359 | let vco = freq * n as u8 as u32; | ||
| 360 | let pll_ck = vco / (div as u8 as u32 + 1); | ||
| 361 | |||
| 362 | unsafe { | ||
| 363 | rcc.pll1cfgr().write(|w| { | ||
| 364 | w.set_pllm(m.into()); | ||
| 365 | w.set_pllsrc(src.into()); | ||
| 366 | }); | ||
| 367 | |||
| 368 | rcc.pll1divr().modify(|w| { | ||
| 369 | w.set_pllr(div.to_div()); | ||
| 370 | w.set_plln(n.to_mul()); | ||
| 371 | }); | ||
| 372 | |||
| 373 | // Enable PLL | ||
| 374 | rcc.cr().modify(|w| w.set_pllon(0, true)); | ||
| 375 | while !rcc.cr().read().pllrdy(0) {} | ||
| 376 | rcc.pll1cfgr().modify(|w| w.set_pllren(true)); | ||
| 377 | } | ||
| 378 | |||
| 379 | unsafe { | ||
| 380 | rcc.cr().write(|w| w.set_pllon(0, true)); | ||
| 381 | while !rcc.cr().read().pllrdy(0) {} | ||
| 382 | } | ||
| 383 | |||
| 384 | pll_ck | ||
| 385 | } | ||
| 386 | }; | ||
| 387 | |||
| 388 | // states and programming delay | ||
| 389 | let wait_states = match power.vos { | ||
| 390 | // VOS 0 range VCORE 1.26V - 1.40V | ||
| 391 | VoltageScale::Range1 => { | ||
| 392 | if sys_clk < 32_000_000 { | ||
| 393 | 0 | ||
| 394 | } else if sys_clk < 64_000_000 { | ||
| 395 | 1 | ||
| 396 | } else if sys_clk < 96_000_000 { | ||
| 397 | 2 | ||
| 398 | } else if sys_clk < 128_000_000 { | ||
| 399 | 3 | ||
| 400 | } else { | ||
| 401 | 4 | ||
| 402 | } | ||
| 403 | } | ||
| 404 | // VOS 1 range VCORE 1.15V - 1.26V | ||
| 405 | VoltageScale::Range2 => { | ||
| 406 | if sys_clk < 30_000_000 { | ||
| 407 | 0 | ||
| 408 | } else if sys_clk < 60_000_000 { | ||
| 409 | 1 | ||
| 410 | } else if sys_clk < 90_000_000 { | ||
| 411 | 2 | ||
| 412 | } else { | ||
| 413 | 3 | ||
| 414 | } | ||
| 415 | } | ||
| 416 | // VOS 2 range VCORE 1.05V - 1.15V | ||
| 417 | VoltageScale::Range3 => { | ||
| 418 | if sys_clk < 24_000_000 { | ||
| 419 | 0 | ||
| 420 | } else if sys_clk < 48_000_000 { | ||
| 421 | 1 | ||
| 422 | } else { | ||
| 423 | 2 | ||
| 424 | } | ||
| 425 | } | ||
| 426 | // VOS 3 range VCORE 0.95V - 1.05V | ||
| 427 | VoltageScale::Range4 => { | ||
| 428 | if sys_clk < 12_000_000 { | ||
| 429 | 0 | ||
| 430 | } else { | ||
| 431 | 1 | ||
| 432 | } | ||
| 433 | } | ||
| 434 | }; | ||
| 435 | |||
| 436 | unsafe { | ||
| 437 | pac::FLASH.acr().modify(|w| { | ||
| 438 | w.set_latency(wait_states); | ||
| 439 | }) | ||
| 440 | } | ||
| 441 | |||
| 442 | unsafe { | ||
| 443 | rcc.cfgr1().modify(|w| { | ||
| 444 | w.set_sw(cfgr.mux.into()); | ||
| 445 | }); | ||
| 446 | |||
| 447 | rcc.cfgr2().modify(|w| { | ||
| 448 | w.set_hpre(cfgr.ahb_pre.into()); | ||
| 449 | w.set_ppre1(cfgr.apb1_pre.into()); | ||
| 450 | w.set_ppre2(cfgr.apb2_pre.into()); | ||
| 451 | }); | ||
| 452 | |||
| 453 | rcc.cfgr3().modify(|w| { | ||
| 454 | w.set_ppre3(cfgr.apb3_pre.into()); | ||
| 455 | }); | ||
| 456 | } | ||
| 457 | |||
| 458 | let ahb_freq: u32 = match cfgr.ahb_pre { | ||
| 459 | AHBPrescaler::NotDivided => sys_clk, | ||
| 460 | pre => { | ||
| 461 | let pre: u8 = pre.into(); | ||
| 462 | let pre = 1 << (pre as u32 - 7); | ||
| 463 | sys_clk / pre | ||
| 464 | } | ||
| 465 | }; | ||
| 466 | |||
| 467 | let (apb1_freq, apb1_tim_freq) = match cfgr.apb1_pre { | ||
| 468 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | ||
| 469 | pre => { | ||
| 470 | let pre: u8 = pre.into(); | ||
| 471 | let pre: u8 = 1 << (pre - 3); | ||
| 472 | let freq = ahb_freq / pre as u32; | ||
| 473 | (freq, freq * 2) | ||
| 474 | } | ||
| 475 | }; | ||
| 476 | |||
| 477 | let (apb2_freq, apb2_tim_freq) = match cfgr.apb2_pre { | ||
| 478 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | ||
| 479 | pre => { | ||
| 480 | let pre: u8 = pre.into(); | ||
| 481 | let pre: u8 = 1 << (pre - 3); | ||
| 482 | let freq = ahb_freq / (1 << (pre as u8 - 3)); | ||
| 483 | (freq, freq * 2) | ||
| 484 | } | ||
| 485 | }; | ||
| 486 | |||
| 487 | let (apb3_freq, _apb3_tim_freq) = match cfgr.apb3_pre { | ||
| 488 | APBPrescaler::NotDivided => (ahb_freq, ahb_freq), | ||
| 489 | pre => { | ||
| 490 | let pre: u8 = pre.into(); | ||
| 491 | let pre: u8 = 1 << (pre - 3); | ||
| 492 | let freq = ahb_freq / (1 << (pre as u8 - 3)); | ||
| 493 | (freq, freq * 2) | ||
| 494 | } | ||
| 495 | }; | ||
| 496 | |||
| 497 | Clocks { | ||
| 498 | sys: sys_clk.hz(), | ||
| 499 | ahb1: ahb_freq.hz(), | ||
| 500 | ahb2: ahb_freq.hz(), | ||
| 501 | ahb3: ahb_freq.hz(), | ||
| 502 | apb1: apb1_freq.hz(), | ||
| 503 | apb2: apb2_freq.hz(), | ||
| 504 | apb3: apb3_freq.hz(), | ||
| 505 | apb1_tim: apb1_tim_freq.hz(), | ||
| 506 | apb2_tim: apb2_tim_freq.hz(), | ||
| 507 | } | ||
| 508 | } | ||
| 509 | } | ||
| 510 | |||
| 511 | pub unsafe fn init(config: Config) { | ||
| 512 | let r = <peripherals::RCC as embassy::util::Steal>::steal(); | ||
| 513 | let power = Power::new(<peripherals::PWR as embassy::util::Steal>::steal()); | ||
| 514 | let clocks = r.freeze(config, &power); | ||
| 515 | set_freqs(clocks); | ||
| 516 | } | ||
diff --git a/examples/stm32u5/.cargo/config.toml b/examples/stm32u5/.cargo/config.toml index ba3ef1dc5..9f5e14801 100644 --- a/examples/stm32u5/.cargo/config.toml +++ b/examples/stm32u5/.cargo/config.toml | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | # replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` | 2 | # replace STM32F429ZITx with your chip as listed in `probe-run --list-chips` |
| 3 | runner = "probe-run --chip STM32U585AIIx" | 3 | #runner = "probe-run --chip STM32U585AIIx" |
| 4 | runner = "/Users/bob/outboard-repos/probe-run/target/debug/probe-run-rp --chip STM32U585AIIx" | ||
| 4 | 5 | ||
| 5 | [build] | 6 | [build] |
| 6 | target = "thumbv7em-none-eabi" | 7 | target = "thumbv7em-none-eabi" |
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index b3c3c9700..e84e1992f 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml | |||
| @@ -22,8 +22,8 @@ embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = | |||
| 22 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "unstable-pac", "stm32u585ai", "memory-x" ] } | 22 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "defmt-trace", "unstable-pac", "stm32u585ai", "memory-x" ] } |
| 23 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | 23 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } |
| 24 | 24 | ||
| 25 | defmt = "0.2.3" | 25 | defmt = "0.2" |
| 26 | defmt-rtt = "0.2.0" | 26 | defmt-rtt = "0.2" |
| 27 | 27 | ||
| 28 | cortex-m = "0.7.3" | 28 | cortex-m = "0.7.3" |
| 29 | cortex-m-rt = "0.7.0" | 29 | cortex-m-rt = "0.7.0" |
| @@ -35,3 +35,7 @@ heapless = { version = "0.7.5", default-features = false } | |||
| 35 | 35 | ||
| 36 | micromath = "2.0.0" | 36 | micromath = "2.0.0" |
| 37 | 37 | ||
| 38 | #[patch.crates-io] | ||
| 39 | #defmt = { git="https://github.com/knurling-rs/defmt.git" } | ||
| 40 | #defmt-rtt = { git="https://github.com/knurling-rs/defmt.git" } | ||
| 41 | |||
diff --git a/stm32-data b/stm32-data | |||
| Subproject e106785ebae82f43c4abd33b9a3f3ea3b31d608 | Subproject 103d86c0558b5ce90ab4765f87b5e756b55312f | ||
