diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-12 21:54:53 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-02-13 01:21:51 +0100 |
| commit | b7c147445a98ced9557ca6c0950f6083d0cf09af (patch) | |
| tree | 3a19f86014e5f80f5b16c7c8d1f5541f500aecf3 | |
| parent | 739c69bd637baf471585648db4d253089301d6c8 (diff) | |
stm32/rcc: port F1 to new API.
| -rw-r--r-- | embassy-stm32/src/rcc/f1.rs | 372 | ||||
| -rw-r--r-- | examples/stm32f1/src/bin/hello.rs | 4 | ||||
| -rw-r--r-- | examples/stm32f1/src/bin/usb_serial.rs | 20 | ||||
| -rw-r--r-- | tests/stm32/.cargo/config.toml | 4 | ||||
| -rw-r--r-- | tests/stm32/src/common.rs | 18 |
5 files changed, 257 insertions, 161 deletions
diff --git a/embassy-stm32/src/rcc/f1.rs b/embassy-stm32/src/rcc/f1.rs index 7f0adab27..9fdd4c11c 100644 --- a/embassy-stm32/src/rcc/f1.rs +++ b/embassy-stm32/src/rcc/f1.rs | |||
| @@ -1,191 +1,257 @@ | |||
| 1 | use core::convert::TryFrom; | ||
| 2 | |||
| 3 | use crate::pac::flash::vals::Latency; | 1 | use crate::pac::flash::vals::Latency; |
| 4 | use crate::pac::rcc::vals::*; | 2 | use crate::pac::rcc::vals::Pllsrc; |
| 3 | #[cfg(any(rcc_f1, rcc_f1cl))] | ||
| 4 | use crate::pac::rcc::vals::Usbpre; | ||
| 5 | pub use crate::pac::rcc::vals::{ | ||
| 6 | Adcpre as ADCPrescaler, Hpre as AHBPrescaler, Pllmul as PllMul, Pllxtpre as PllPreDiv, Ppre as APBPrescaler, | ||
| 7 | Sw as Sysclk, | ||
| 8 | }; | ||
| 5 | use crate::pac::{FLASH, RCC}; | 9 | use crate::pac::{FLASH, RCC}; |
| 6 | use crate::time::Hertz; | 10 | use crate::time::Hertz; |
| 7 | 11 | ||
| 8 | /// HSI speed | 12 | /// HSI speed |
| 9 | pub const HSI_FREQ: Hertz = Hertz(8_000_000); | 13 | pub const HSI_FREQ: Hertz = Hertz(8_000_000); |
| 10 | 14 | ||
| 11 | /// Configuration of the clocks | 15 | #[derive(Clone, Copy, Eq, PartialEq)] |
| 12 | /// | 16 | pub enum HseMode { |
| 17 | /// crystal/ceramic oscillator (HSEBYP=0) | ||
| 18 | Oscillator, | ||
| 19 | /// external analog clock (low swing) (HSEBYP=1) | ||
| 20 | Bypass, | ||
| 21 | } | ||
| 22 | |||
| 23 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
| 24 | pub struct Hse { | ||
| 25 | /// HSE frequency. | ||
| 26 | pub freq: Hertz, | ||
| 27 | /// HSE mode. | ||
| 28 | pub mode: HseMode, | ||
| 29 | } | ||
| 30 | |||
| 31 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
| 32 | pub enum PllSource { | ||
| 33 | HSE, | ||
| 34 | HSI, | ||
| 35 | } | ||
| 36 | |||
| 37 | #[derive(Clone, Copy)] | ||
| 38 | pub struct Pll { | ||
| 39 | pub src: PllSource, | ||
| 40 | |||
| 41 | /// PLL pre-divider. | ||
| 42 | /// | ||
| 43 | /// On some F3 chips, this must be 2 if `src == HSI`. Init will panic if this is not the case. | ||
| 44 | pub prediv: PllPreDiv, | ||
| 45 | |||
| 46 | /// PLL multiplication factor. | ||
| 47 | pub mul: PllMul, | ||
| 48 | } | ||
| 49 | |||
| 50 | /// Clocks configutation | ||
| 13 | #[non_exhaustive] | 51 | #[non_exhaustive] |
| 14 | #[derive(Default)] | ||
| 15 | pub struct Config { | 52 | pub struct Config { |
| 16 | pub hse: Option<Hertz>, | 53 | pub hsi: bool, |
| 54 | pub hse: Option<Hse>, | ||
| 55 | pub sys: Sysclk, | ||
| 17 | 56 | ||
| 18 | pub sys_ck: Option<Hertz>, | 57 | pub pll: Option<Pll>, |
| 19 | pub hclk: Option<Hertz>, | 58 | |
| 20 | pub pclk1: Option<Hertz>, | 59 | pub ahb_pre: AHBPrescaler, |
| 21 | pub pclk2: Option<Hertz>, | 60 | pub apb1_pre: APBPrescaler, |
| 22 | pub adcclk: Option<Hertz>, | 61 | pub apb2_pre: APBPrescaler, |
| 23 | pub pllxtpre: bool, | 62 | |
| 63 | pub adc_pre: ADCPrescaler, | ||
| 24 | 64 | ||
| 25 | pub ls: super::LsConfig, | 65 | pub ls: super::LsConfig, |
| 26 | } | 66 | } |
| 27 | 67 | ||
| 28 | pub(crate) unsafe fn init(config: Config) { | 68 | impl Default for Config { |
| 29 | let pllxtpre_div = if config.pllxtpre { 2 } else { 1 }; | 69 | fn default() -> Self { |
| 30 | let pllsrcclk = config.hse.map(|hse| hse.0 / pllxtpre_div).unwrap_or(HSI_FREQ.0 / 2); | 70 | Self { |
| 71 | hsi: true, | ||
| 72 | hse: None, | ||
| 73 | sys: Sysclk::HSI, | ||
| 74 | pll: None, | ||
| 75 | ahb_pre: AHBPrescaler::DIV1, | ||
| 76 | apb1_pre: APBPrescaler::DIV1, | ||
| 77 | apb2_pre: APBPrescaler::DIV1, | ||
| 78 | ls: Default::default(), | ||
| 31 | 79 | ||
| 32 | let sysclk = config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk); | 80 | // ensure ADC is not out of range by default even if APB2 is maxxed out (36mhz) |
| 33 | let pllmul = sysclk / pllsrcclk; | 81 | adc_pre: ADCPrescaler::DIV6, |
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 34 | 85 | ||
| 35 | let (pllmul_bits, real_sysclk) = if pllmul == 1 { | 86 | /// Initialize and Set the clock frequencies |
| 36 | (None, config.hse.map(|hse| hse.0).unwrap_or(HSI_FREQ.0)) | 87 | pub(crate) unsafe fn init(config: Config) { |
| 37 | } else { | 88 | // Configure HSI |
| 38 | let pllmul = core::cmp::min(core::cmp::max(pllmul, 1), 16); | 89 | let hsi = match config.hsi { |
| 39 | (Some(pllmul as u8 - 2), pllsrcclk * pllmul) | 90 | false => { |
| 91 | RCC.cr().modify(|w| w.set_hsion(false)); | ||
| 92 | None | ||
| 93 | } | ||
| 94 | true => { | ||
| 95 | RCC.cr().modify(|w| w.set_hsion(true)); | ||
| 96 | while !RCC.cr().read().hsirdy() {} | ||
| 97 | Some(HSI_FREQ) | ||
| 98 | } | ||
| 40 | }; | 99 | }; |
| 41 | 100 | ||
| 42 | assert!(real_sysclk <= 72_000_000); | 101 | // Configure HSE |
| 43 | 102 | let hse = match config.hse { | |
| 44 | let hpre_bits = config | 103 | None => { |
| 45 | .hclk | 104 | RCC.cr().modify(|w| w.set_hseon(false)); |
| 46 | .map(|hclk| match real_sysclk / hclk.0 { | 105 | None |
| 47 | 0 => unreachable!(), | 106 | } |
| 48 | 1 => 0b0111, | 107 | Some(hse) => { |
| 49 | 2 => 0b1000, | 108 | match hse.mode { |
| 50 | 3..=5 => 0b1001, | 109 | HseMode::Bypass => assert!(max::HSE_BYP.contains(&hse.freq)), |
| 51 | 6..=11 => 0b1010, | 110 | HseMode::Oscillator => assert!(max::HSE_OSC.contains(&hse.freq)), |
| 52 | 12..=39 => 0b1011, | 111 | } |
| 53 | 40..=95 => 0b1100, | 112 | |
| 54 | 96..=191 => 0b1101, | 113 | RCC.cr().modify(|w| w.set_hsebyp(hse.mode != HseMode::Oscillator)); |
| 55 | 192..=383 => 0b1110, | 114 | RCC.cr().modify(|w| w.set_hseon(true)); |
| 56 | _ => 0b1111, | 115 | while !RCC.cr().read().hserdy() {} |
| 57 | }) | 116 | Some(hse.freq) |
| 58 | .unwrap_or(0b0111); | 117 | } |
| 59 | |||
| 60 | let hclk = if hpre_bits >= 0b1100 { | ||
| 61 | real_sysclk / (1 << (hpre_bits - 0b0110)) | ||
| 62 | } else { | ||
| 63 | real_sysclk / (1 << (hpre_bits - 0b0111)) | ||
| 64 | }; | 118 | }; |
| 65 | 119 | ||
| 66 | assert!(hclk <= 72_000_000); | 120 | // Enable PLL |
| 67 | 121 | let pll = config.pll.map(|pll| { | |
| 68 | let ppre1_bits = config | 122 | let (src_val, src_freq) = match pll.src { |
| 69 | .pclk1 | 123 | PllSource::HSI => { |
| 70 | .map(|pclk1| match hclk / pclk1.0 { | 124 | if pll.prediv != PllPreDiv::DIV2 { |
| 71 | 0 => unreachable!(), | 125 | panic!("if PLL source is HSI, PLL prediv must be 2."); |
| 72 | 1 => 0b011, | 126 | } |
| 73 | 2 => 0b100, | 127 | (Pllsrc::HSI_DIV2, unwrap!(hsi)) |
| 74 | 3..=5 => 0b101, | 128 | } |
| 75 | 6..=11 => 0b110, | 129 | PllSource::HSE => (Pllsrc::HSE_DIV_PREDIV, unwrap!(hse)), |
| 76 | _ => 0b111, | 130 | }; |
| 77 | }) | 131 | let in_freq = src_freq / pll.prediv; |
| 78 | .unwrap_or(0b011); | 132 | assert!(max::PLL_IN.contains(&in_freq)); |
| 79 | 133 | let out_freq = in_freq * pll.mul; | |
| 80 | let ppre1 = 1 << (ppre1_bits - 0b011); | 134 | assert!(max::PLL_OUT.contains(&out_freq)); |
| 81 | let pclk1 = hclk / u32::try_from(ppre1).unwrap(); | 135 | |
| 82 | let timer_mul1 = if ppre1 == 1 { 1 } else { 2 }; | 136 | RCC.cfgr().modify(|w| { |
| 83 | 137 | w.set_pllmul(pll.mul); | |
| 84 | assert!(pclk1 <= 36_000_000); | 138 | w.set_pllsrc(src_val); |
| 85 | 139 | w.set_pllxtpre(pll.prediv); | |
| 86 | let ppre2_bits = config | ||
| 87 | .pclk2 | ||
| 88 | .map(|pclk2| match hclk / pclk2.0 { | ||
| 89 | 0 => unreachable!(), | ||
| 90 | 1 => 0b011, | ||
| 91 | 2 => 0b100, | ||
| 92 | 3..=5 => 0b101, | ||
| 93 | 6..=11 => 0b110, | ||
| 94 | _ => 0b111, | ||
| 95 | }) | ||
| 96 | .unwrap_or(0b011); | ||
| 97 | |||
| 98 | let ppre2 = 1 << (ppre2_bits - 0b011); | ||
| 99 | let pclk2 = hclk / u32::try_from(ppre2).unwrap(); | ||
| 100 | let timer_mul2 = if ppre2 == 1 { 1 } else { 2 }; | ||
| 101 | |||
| 102 | assert!(pclk2 <= 72_000_000); | ||
| 103 | |||
| 104 | FLASH.acr().write(|w| { | ||
| 105 | w.set_latency(if real_sysclk <= 24_000_000 { | ||
| 106 | Latency::WS0 | ||
| 107 | } else if real_sysclk <= 48_000_000 { | ||
| 108 | Latency::WS1 | ||
| 109 | } else { | ||
| 110 | Latency::WS2 | ||
| 111 | }); | 140 | }); |
| 112 | // the prefetch buffer is enabled by default, let's keep it enabled | 141 | RCC.cr().modify(|w| w.set_pllon(true)); |
| 113 | w.set_prftbe(true); | 142 | while !RCC.cr().read().pllrdy() {} |
| 143 | |||
| 144 | out_freq | ||
| 114 | }); | 145 | }); |
| 115 | 146 | ||
| 116 | // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the | 147 | #[cfg(any(rcc_f1, rcc_f1cl))] |
| 117 | // PLL output frequency is a supported one. | 148 | let usb = match pll { |
| 118 | // usbpre == false: divide clock by 1.5, otherwise no division | 149 | Some(Hertz(72_000_000)) => { |
| 119 | #[cfg(not(rcc_f100))] | 150 | RCC.cfgr().modify(|w| w.set_usbpre(Usbpre::DIV1_5)); |
| 120 | let (usbpre, _usbclk_valid) = match (config.hse, pllmul_bits, real_sysclk) { | 151 | Some(Hertz(48_000_000)) |
| 121 | (Some(_), Some(_), 72_000_000) => (false, true), | 152 | } |
| 122 | (Some(_), Some(_), 48_000_000) => (true, true), | 153 | Some(Hertz(48_000_000)) => { |
| 123 | _ => (true, false), | 154 | RCC.cfgr().modify(|w| w.set_usbpre(Usbpre::DIV1)); |
| 155 | Some(Hertz(48_000_000)) | ||
| 156 | } | ||
| 157 | _ => None, | ||
| 124 | }; | 158 | }; |
| 125 | 159 | ||
| 126 | let apre_bits: u8 = config | 160 | // Configure sysclk |
| 127 | .adcclk | 161 | let sys = match config.sys { |
| 128 | .map(|adcclk| match pclk2 / adcclk.0 { | 162 | Sysclk::HSI => unwrap!(hsi), |
| 129 | 0..=2 => 0b00, | 163 | Sysclk::HSE => unwrap!(hse), |
| 130 | 3..=4 => 0b01, | 164 | Sysclk::PLL1_P => unwrap!(pll), |
| 131 | 5..=7 => 0b10, | 165 | _ => unreachable!(), |
| 132 | _ => 0b11, | 166 | }; |
| 133 | }) | ||
| 134 | .unwrap_or(0b11); | ||
| 135 | |||
| 136 | let apre = (apre_bits + 1) << 1; | ||
| 137 | let adcclk = pclk2 / unwrap!(u32::try_from(apre)); | ||
| 138 | |||
| 139 | assert!(adcclk <= 14_000_000); | ||
| 140 | |||
| 141 | if config.hse.is_some() { | ||
| 142 | // enable HSE and wait for it to be ready | ||
| 143 | RCC.cr().modify(|w| w.set_hseon(true)); | ||
| 144 | while !RCC.cr().read().hserdy() {} | ||
| 145 | } | ||
| 146 | 167 | ||
| 147 | if let Some(pllmul_bits) = pllmul_bits { | 168 | let hclk = sys / config.ahb_pre; |
| 148 | let pllctpre_flag: u8 = if config.pllxtpre { 1 } else { 0 }; | 169 | let (pclk1, pclk1_tim) = super::util::calc_pclk(hclk, config.apb1_pre); |
| 149 | RCC.cfgr() | 170 | let (pclk2, pclk2_tim) = super::util::calc_pclk(hclk, config.apb2_pre); |
| 150 | .modify(|w| w.set_pllxtpre(Pllxtpre::from_bits(pllctpre_flag))); | ||
| 151 | 171 | ||
| 152 | // enable PLL and wait for it to be ready | 172 | assert!(max::HCLK.contains(&hclk)); |
| 153 | RCC.cfgr().modify(|w| { | 173 | assert!(max::PCLK1.contains(&pclk1)); |
| 154 | w.set_pllmul(Pllmul::from_bits(pllmul_bits)); | 174 | assert!(max::PCLK2.contains(&pclk2)); |
| 155 | w.set_pllsrc(Pllsrc::from_bits(config.hse.is_some() as u8)); | ||
| 156 | }); | ||
| 157 | 175 | ||
| 158 | RCC.cr().modify(|w| w.set_pllon(true)); | 176 | let adc = pclk2 / config.adc_pre; |
| 159 | while !RCC.cr().read().pllrdy() {} | 177 | assert!(max::ADC.contains(&adc)); |
| 160 | } | 178 | |
| 179 | // Set latency based on HCLK frquency | ||
| 180 | let latency = match hclk.0 { | ||
| 181 | ..=24_000_000 => Latency::WS0, | ||
| 182 | ..=48_000_000 => Latency::WS1, | ||
| 183 | _ => Latency::WS2, | ||
| 184 | }; | ||
| 185 | FLASH.acr().modify(|w| { | ||
| 186 | w.set_latency(latency); | ||
| 187 | // RM0316: "The prefetch buffer must be kept on when using a prescaler | ||
| 188 | // different from 1 on the AHB clock.", "Half-cycle access cannot be | ||
| 189 | // used when there is a prescaler different from 1 on the AHB clock" | ||
| 190 | if config.ahb_pre != AHBPrescaler::DIV1 { | ||
| 191 | w.set_hlfcya(false); | ||
| 192 | w.set_prftbe(true); | ||
| 193 | } | ||
| 194 | }); | ||
| 161 | 195 | ||
| 162 | // Only needed for stm32f103? | 196 | // Set prescalers |
| 197 | // CFGR has been written before (PLL, PLL48) don't overwrite these settings | ||
| 163 | RCC.cfgr().modify(|w| { | 198 | RCC.cfgr().modify(|w| { |
| 164 | w.set_adcpre(Adcpre::from_bits(apre_bits)); | 199 | w.set_ppre1(config.apb1_pre); |
| 165 | w.set_ppre2(Ppre::from_bits(ppre2_bits)); | 200 | w.set_ppre2(config.apb2_pre); |
| 166 | w.set_ppre1(Ppre::from_bits(ppre1_bits)); | 201 | w.set_hpre(config.ahb_pre); |
| 167 | w.set_hpre(Hpre::from_bits(hpre_bits)); | 202 | w.set_adcpre(config.adc_pre); |
| 168 | #[cfg(not(rcc_f100))] | ||
| 169 | w.set_usbpre(Usbpre::from_bits(usbpre as u8)); | ||
| 170 | w.set_sw(if pllmul_bits.is_some() { | ||
| 171 | Sw::PLL1_P | ||
| 172 | } else if config.hse.is_some() { | ||
| 173 | Sw::HSE | ||
| 174 | } else { | ||
| 175 | Sw::HSI | ||
| 176 | }); | ||
| 177 | }); | 203 | }); |
| 178 | 204 | ||
| 205 | // Wait for the new prescalers to kick in | ||
| 206 | // "The clocks are divided with the new prescaler factor from | ||
| 207 | // 1 to 16 AHB cycles after write" | ||
| 208 | cortex_m::asm::delay(16); | ||
| 209 | |||
| 210 | // CFGR has been written before (PLL, PLL48, clock divider) don't overwrite these settings | ||
| 211 | RCC.cfgr().modify(|w| w.set_sw(config.sys)); | ||
| 212 | while RCC.cfgr().read().sws() != config.sys {} | ||
| 213 | |||
| 179 | let rtc = config.ls.init(); | 214 | let rtc = config.ls.init(); |
| 180 | 215 | ||
| 181 | set_clocks!( | 216 | set_clocks!( |
| 182 | sys: Some(Hertz(real_sysclk)), | 217 | hsi: hsi, |
| 183 | pclk1: Some(Hertz(pclk1)), | 218 | hse: hse, |
| 184 | pclk2: Some(Hertz(pclk2)), | 219 | pll1_p: pll, |
| 185 | pclk1_tim: Some(Hertz(pclk1 * timer_mul1)), | 220 | sys: Some(sys), |
| 186 | pclk2_tim: Some(Hertz(pclk2 * timer_mul2)), | 221 | pclk1: Some(pclk1), |
| 187 | hclk1: Some(Hertz(hclk)), | 222 | pclk2: Some(pclk2), |
| 188 | adc: Some(Hertz(adcclk)), | 223 | pclk1_tim: Some(pclk1_tim), |
| 224 | pclk2_tim: Some(pclk2_tim), | ||
| 225 | hclk1: Some(hclk), | ||
| 226 | adc: Some(adc), | ||
| 189 | rtc: rtc, | 227 | rtc: rtc, |
| 228 | #[cfg(any(rcc_f1, rcc_f1cl))] | ||
| 229 | usb: usb, | ||
| 230 | lse: None, | ||
| 190 | ); | 231 | ); |
| 191 | } | 232 | } |
| 233 | |||
| 234 | mod max { | ||
| 235 | use core::ops::RangeInclusive; | ||
| 236 | |||
| 237 | use crate::time::Hertz; | ||
| 238 | |||
| 239 | #[cfg(not(rcc_f1cl))] | ||
| 240 | pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(16_000_000); | ||
| 241 | #[cfg(not(rcc_f1cl))] | ||
| 242 | pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(25_000_000); | ||
| 243 | |||
| 244 | #[cfg(rcc_f1cl)] | ||
| 245 | pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(3_000_000)..=Hertz(25_000_000); | ||
| 246 | #[cfg(rcc_f1cl)] | ||
| 247 | pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(50_000_000); | ||
| 248 | |||
| 249 | pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(72_000_000); | ||
| 250 | pub(crate) const PCLK1: RangeInclusive<Hertz> = Hertz(0)..=Hertz(36_000_000); | ||
| 251 | pub(crate) const PCLK2: RangeInclusive<Hertz> = Hertz(0)..=Hertz(72_000_000); | ||
| 252 | |||
| 253 | pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(25_000_000); | ||
| 254 | pub(crate) const PLL_OUT: RangeInclusive<Hertz> = Hertz(16_000_000)..=Hertz(72_000_000); | ||
| 255 | |||
| 256 | pub(crate) const ADC: RangeInclusive<Hertz> = Hertz(0)..=Hertz(14_000_000); | ||
| 257 | } | ||
diff --git a/examples/stm32f1/src/bin/hello.rs b/examples/stm32f1/src/bin/hello.rs index 7b761ecc1..3c295612c 100644 --- a/examples/stm32f1/src/bin/hello.rs +++ b/examples/stm32f1/src/bin/hello.rs | |||
| @@ -3,15 +3,13 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::time::Hertz; | ||
| 7 | use embassy_stm32::Config; | 6 | use embassy_stm32::Config; |
| 8 | use embassy_time::Timer; | 7 | use embassy_time::Timer; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 9 | ||
| 11 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) -> ! { | 11 | async fn main(_spawner: Spawner) -> ! { |
| 13 | let mut config = Config::default(); | 12 | let config = Config::default(); |
| 14 | config.rcc.sys_ck = Some(Hertz(36_000_000)); | ||
| 15 | let _p = embassy_stm32::init(config); | 13 | let _p = embassy_stm32::init(config); |
| 16 | 14 | ||
| 17 | loop { | 15 | loop { |
diff --git a/examples/stm32f1/src/bin/usb_serial.rs b/examples/stm32f1/src/bin/usb_serial.rs index e28381893..1ae6c1dee 100644 --- a/examples/stm32f1/src/bin/usb_serial.rs +++ b/examples/stm32f1/src/bin/usb_serial.rs | |||
| @@ -21,9 +21,23 @@ bind_interrupts!(struct Irqs { | |||
| 21 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 22 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 23 | let mut config = Config::default(); | 23 | let mut config = Config::default(); |
| 24 | config.rcc.hse = Some(Hertz(8_000_000)); | 24 | { |
| 25 | config.rcc.sys_ck = Some(Hertz(48_000_000)); | 25 | use embassy_stm32::rcc::*; |
| 26 | config.rcc.pclk1 = Some(Hertz(24_000_000)); | 26 | config.rcc.hse = Some(Hse { |
| 27 | freq: Hertz(8_000_000), | ||
| 28 | // Oscillator for bluepill, Bypass for nucleos. | ||
| 29 | mode: HseMode::Oscillator, | ||
| 30 | }); | ||
| 31 | config.rcc.pll = Some(Pll { | ||
| 32 | src: PllSource::HSE, | ||
| 33 | prediv: PllPreDiv::DIV1, | ||
| 34 | mul: PllMul::MUL9, | ||
| 35 | }); | ||
| 36 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 37 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 38 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 39 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 40 | } | ||
| 27 | let mut p = embassy_stm32::init(config); | 41 | let mut p = embassy_stm32::init(config); |
| 28 | 42 | ||
| 29 | info!("Hello World!"); | 43 | info!("Hello World!"); |
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml index 8e32b4cee..528bd3451 100644 --- a/tests/stm32/.cargo/config.toml +++ b/tests/stm32/.cargo/config.toml | |||
| @@ -14,9 +14,9 @@ rustflags = [ | |||
| 14 | ] | 14 | ] |
| 15 | 15 | ||
| 16 | [build] | 16 | [build] |
| 17 | target = "thumbv6m-none-eabi" | 17 | #target = "thumbv6m-none-eabi" |
| 18 | #target = "thumbv7m-none-eabi" | 18 | #target = "thumbv7m-none-eabi" |
| 19 | #target = "thumbv7em-none-eabi" | 19 | target = "thumbv7em-none-eabi" |
| 20 | #target = "thumbv8m.main-none-eabihf" | 20 | #target = "thumbv8m.main-none-eabihf" |
| 21 | 21 | ||
| 22 | [env] | 22 | [env] |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 36fe8a235..182ad6298 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -247,6 +247,24 @@ pub fn config() -> Config { | |||
| 247 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; | 247 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | #[cfg(feature = "stm32f103c8")] | ||
| 251 | { | ||
| 252 | use embassy_stm32::rcc::*; | ||
| 253 | config.rcc.hse = Some(Hse { | ||
| 254 | freq: Hertz(8_000_000), | ||
| 255 | mode: HseMode::Oscillator, | ||
| 256 | }); | ||
| 257 | config.rcc.pll = Some(Pll { | ||
| 258 | src: PllSource::HSE, | ||
| 259 | prediv: PllPreDiv::DIV1, | ||
| 260 | mul: PllMul::MUL9, | ||
| 261 | }); | ||
| 262 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 263 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 264 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 265 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 266 | } | ||
| 267 | |||
| 250 | #[cfg(feature = "stm32f207zg")] | 268 | #[cfg(feature = "stm32f207zg")] |
| 251 | { | 269 | { |
| 252 | use embassy_stm32::rcc::*; | 270 | use embassy_stm32::rcc::*; |
