diff --git a/ci.sh b/ci.sh index 91c7cd3b..b3429a0a 100755 --- a/ci.sh +++ b/ci.sh @@ -46,10 +46,13 @@ cargo batch \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits \ + --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits \ --- build --release --manifest-path docs/modules/ROOT/examples/basic/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-pac/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-hal/Cargo.toml --target thumbv7em-none-eabi \ diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 2b642db8..1257e015 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -49,7 +49,7 @@ fn main() { // We *shouldn't* have singletons for these, but the HAL currently requires // singletons, for using with RccPeripheral to enable/disable clocks to them. "rcc" => { - if r.version == "h7" { + if r.version.starts_with("h7") { singletons.push("MCO1".to_string()); singletons.push("MCO2".to_string()); } @@ -436,7 +436,7 @@ fn main() { // MCO is special if pin.signal.starts_with("MCO_") { // Supported in H7 only for now - if regs.version == "h7" { + if regs.version.starts_with("h7") { peri = format_ident!("{}", pin.signal.replace("_", "")); } else { continue; diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs index 6f36daa2..387b6247 100644 --- a/embassy-stm32/src/adc/v3.rs +++ b/embassy-stm32/src/adc/v3.rs @@ -9,11 +9,11 @@ pub const VDDA_CALIB_MV: u32 = 3000; /// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock /// configuration. unsafe fn enable() { - #[cfg(rcc_h7)] + #[cfg(stm32h7)] crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true)); - #[cfg(rcc_g0)] + #[cfg(stm32g0)] crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true)); - #[cfg(rcc_l4)] + #[cfg(stm32l4)] crate::pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); } @@ -54,9 +54,9 @@ pub struct Vref; impl AdcPin for Vref {} impl super::sealed::AdcPin for Vref { fn channel(&self) -> u8 { - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] let val = 0; - #[cfg(rcc_g0)] + #[cfg(stm32g0)] let val = 13; val } @@ -66,9 +66,9 @@ pub struct Temperature; impl AdcPin for Temperature {} impl super::sealed::AdcPin for Temperature { fn channel(&self) -> u8 { - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] let val = 17; - #[cfg(rcc_g0)] + #[cfg(stm32g0)] let val = 12; val } @@ -78,9 +78,9 @@ pub struct Vbat; impl AdcPin for Vbat {} impl super::sealed::AdcPin for Vbat { fn channel(&self) -> u8 { - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] let val = 18; - #[cfg(rcc_g0)] + #[cfg(stm32g0)] let val = 14; val } @@ -281,7 +281,7 @@ impl<'d, T: Instance> Adc<'d, T> { /// Calculates the system VDDA by sampling the internal VREF channel and comparing /// the result with the value stored at the factory. If the chip's VDDA is not stable, run /// this before each ADC conversion. - #[cfg(not(rcc_g0))] // TODO is this supposed to be public? + #[cfg(not(stm32g0))] // TODO is this supposed to be public? #[allow(unused)] // TODO is this supposed to be public? fn calibrate(&mut self, vref: &mut Vref) { let vref_cal = unsafe { crate::pac::VREFINTCAL.data().read().value() }; @@ -363,11 +363,11 @@ impl<'d, T: Instance> Adc<'d, T> { } // Configure ADC - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] T::regs() .cfgr() .modify(|reg| reg.set_res(self.resolution.res())); - #[cfg(rcc_g0)] + #[cfg(stm32g0)] T::regs() .cfgr1() .modify(|reg| reg.set_res(self.resolution.res())); @@ -376,9 +376,9 @@ impl<'d, T: Instance> Adc<'d, T> { Self::set_channel_sample_time(pin.channel(), self.sample_time); // Select channel - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel())); - #[cfg(rcc_g0)] + #[cfg(stm32g0)] T::regs() .chselr() .write(|reg| reg.set_chsel(pin.channel() as u32)); @@ -400,14 +400,14 @@ impl<'d, T: Instance> Adc<'d, T> { } } - #[cfg(rcc_g0)] + #[cfg(stm32g0)] unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) { T::regs() .smpr() .modify(|reg| reg.set_smp1(sample_time.sample_time())); } - #[cfg(not(rcc_g0))] + #[cfg(not(stm32g0))] unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) { if ch <= 9 { T::regs() diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac/v2.rs index 751eebf7..9fb01fa9 100644 --- a/embassy-stm32/src/dac/v2.rs +++ b/embassy-stm32/src/dac/v2.rs @@ -115,9 +115,11 @@ impl<'d, T: Instance> Dac<'d, T> { // configuration. #[cfg(rcc_h7)] crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); - #[cfg(rcc_g0)] + #[cfg(rcc_h7ab)] + crate::pac::RCC.apb1lenr().modify(|w| w.set_dac1en(true)); + #[cfg(stm32g0)] crate::pac::RCC.apbenr1().modify(|w| w.set_dac1en(true)); - #[cfg(rcc_l4)] + #[cfg(stm32l4)] crate::pac::RCC.apb1enr1().modify(|w| w.set_dac1en(true)); if channels >= 1 { diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index a37de2d6..2f0715cf 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -49,6 +49,12 @@ macro_rules! dma_num { (BDMA) => { 0 }; + (BDMA1) => { + 0 + }; + (BDMA2) => { + 1 + }; } pub(crate) unsafe fn on_irq() { @@ -80,6 +86,9 @@ pub(crate) unsafe fn init() { } pac::dma_channels! { + ($channel_peri:ident, BDMA1, bdma, $channel_num:expr, $dmamux:tt) => { + // BDMA1 in H7 doesn't use DMAMUX, which breaks + }; ($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => { impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri { diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs index fd076581..971695a0 100644 --- a/embassy-stm32/src/dma/dmamux.rs +++ b/embassy-stm32/src/dma/dmamux.rs @@ -28,7 +28,7 @@ pub(crate) mod sealed { } pub struct DMAMUX1; -#[cfg(rcc_h7)] +#[cfg(stm32h7)] pub struct DMAMUX2; pub trait MuxChannel: sealed::MuxChannel + super::Channel { diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 07d08684..909d0ee8 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs @@ -388,6 +388,6 @@ pub(crate) unsafe fn init() { #[cfg(not(any(rcc_wb, rcc_wl5, rcc_f1)))] ::enable(); - #[cfg(rcc_f1)] + #[cfg(stm32f1)] ::enable(); } diff --git a/embassy-stm32/src/rcc/l0.rs b/embassy-stm32/src/rcc/l0.rs index e482dcc2..69279117 100644 --- a/embassy-stm32/src/rcc/l0.rs +++ b/embassy-stm32/src/rcc/l0.rs @@ -1,5 +1,7 @@ use crate::pac::rcc::vals::{Hpre, Msirange, Plldiv, Pllmul, Pllsrc, Ppre, Sw}; -use crate::pac::{CRS, RCC, SYSCFG}; +use crate::pac::RCC; +#[cfg(crs)] +use crate::pac::{CRS, SYSCFG}; use crate::rcc::{set_freqs, Clocks}; use crate::time::Hertz; use crate::time::U32Ext; @@ -180,6 +182,7 @@ pub struct Config { pub ahb_pre: AHBPrescaler, pub apb1_pre: APBPrescaler, pub apb2_pre: APBPrescaler, + #[cfg(crs)] pub enable_hsi48: bool, } @@ -191,6 +194,7 @@ impl Default for Config { ahb_pre: AHBPrescaler::NotDivided, apb1_pre: APBPrescaler::NotDivided, apb2_pre: APBPrescaler::NotDivided, + #[cfg(crs)] enable_hsi48: false, } } @@ -312,6 +316,7 @@ pub(crate) unsafe fn init(config: Config) { } }; + #[cfg(crs)] if config.enable_hsi48 { // Reset SYSCFG peripheral RCC.apb2rstr().modify(|w| w.set_syscfgrst(true)); diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 5c223bc4..01c66f76 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs @@ -33,18 +33,20 @@ pub struct Clocks { pub apb2_tim: Hertz, #[cfg(any(rcc_wl5, rcc_u5))] pub apb3: Hertz, - #[cfg(any(rcc_h7))] + #[cfg(any(rcc_h7, rcc_h7ab))] pub apb4: Hertz, // AHB pub ahb1: Hertz, #[cfg(any( - rcc_l4, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_g4, rcc_u5, rcc_wb, rcc_wl5 + rcc_l4, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7ab, rcc_g4, rcc_u5, rcc_wb, rcc_wl5 ))] pub ahb2: Hertz, - #[cfg(any(rcc_l4, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_u5, rcc_wb, rcc_wl5))] + #[cfg(any( + rcc_l4, rcc_f4, rcc_f410, rcc_f7, rcc_h7, rcc_h7ab, rcc_u5, rcc_wb, rcc_wl5 + ))] pub ahb3: Hertz, - #[cfg(any(rcc_h7))] + #[cfg(any(rcc_h7, rcc_h7ab))] pub ahb4: Hertz, #[cfg(any(rcc_f4, rcc_f410, rcc_f7))] diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 7efe0d3a..98054e05 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -11,12 +11,12 @@ use embassy::time::TICKS_PER_SECOND; use stm32_metapac::timer::regs; use crate::interrupt; -use crate::interrupt::{CriticalSection, Interrupt}; -use crate::pac::timer::{vals, TimGp16}; +use crate::interrupt::CriticalSection; +use crate::pac::timer::vals; use crate::peripherals; use crate::rcc::sealed::RccPeripheral; - -use self::sealed::Instance as _; +use crate::timer::sealed::Basic16bitInstance as BasicInstance; +use crate::timer::sealed::GeneralPurpose16bitInstance as Instance; const ALARM_COUNT: usize = 3; @@ -29,25 +29,35 @@ type T = peripherals::TIM4; #[cfg(time_driver_tim5)] type T = peripherals::TIM5; -#[cfg(time_driver_tim2)] -#[interrupt] -fn TIM2() { - DRIVER.on_interrupt() -} -#[cfg(time_driver_tim3)] -#[interrupt] -fn TIM3() { - DRIVER.on_interrupt() -} -#[cfg(time_driver_tim4)] -#[interrupt] -fn TIM4() { - DRIVER.on_interrupt() -} -#[cfg(time_driver_tim5)] -#[interrupt] -fn TIM5() { - DRIVER.on_interrupt() +crate::pac::interrupts! { + (TIM2, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim2)] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; + (TIM3, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim3)] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; + (TIM4, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim4)] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; + (TIM5, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim5)] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; } // Clock timekeeping works with something we call "periods", which are time intervals @@ -93,6 +103,7 @@ impl AlarmState { } struct RtcDriver { + timer: T, /// Number of 2^15 periods elapsed since boot. period: AtomicU32, alarm_count: AtomicU8, @@ -103,6 +114,7 @@ struct RtcDriver { const ALARM_STATE_NEW: AlarmState = AlarmState::new(); embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { + timer: unsafe { core::mem::transmute(()) }, // steal is not const period: AtomicU32::new(0), alarm_count: AtomicU8::new(0), alarms: Mutex::const_new(CriticalSectionRawMutex::new(), [ALARM_STATE_NEW; ALARM_COUNT]), @@ -110,10 +122,10 @@ embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { impl RtcDriver { fn init(&'static self) { - let r = T::regs(); + let r = self.timer.regs_gp16(); - T::enable(); - T::reset(); + ::enable(); + ::reset(); let timer_freq = T::frequency(); @@ -142,7 +154,7 @@ impl RtcDriver { // Enable CC0, disable others r.dier().write(|w| w.set_ccie(0, true)); - let irq: ::Interrupt = core::mem::transmute(()); + let irq: ::Interrupt = core::mem::transmute(()); irq.unpend(); irq.enable(); @@ -151,7 +163,7 @@ impl RtcDriver { } fn on_interrupt(&self) { - let r = T::regs(); + let r = self.timer.regs_gp16(); // NOTE(unsafe) Use critical section to access the methods // XXX: reduce the size of this critical section ? @@ -182,7 +194,7 @@ impl RtcDriver { } fn next_period(&self) { - let r = T::regs(); + let r = self.timer.regs_gp16(); let period = self.period.fetch_add(1, Ordering::Relaxed) + 1; let t = (period as u64) << 15; @@ -224,7 +236,7 @@ impl RtcDriver { impl Driver for RtcDriver { fn now(&self) -> u64 { - let r = T::regs(); + let r = self.timer.regs_gp16(); let period = self.period.load(Ordering::Relaxed); compiler_fence(Ordering::Acquire); @@ -261,7 +273,7 @@ impl Driver for RtcDriver { fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) { critical_section::with(|cs| { - let r = T::regs(); + let r = self.timer.regs_gp16(); let n = alarm.id() as _; let alarm = self.get_alarm(cs, alarm); @@ -291,37 +303,3 @@ impl Driver for RtcDriver { pub(crate) fn init() { DRIVER.init() } - -// ------------------------------------------------------ - -pub(crate) mod sealed { - use super::*; - pub trait Instance { - type Interrupt: Interrupt; - - fn regs() -> TimGp16; - } -} - -pub trait Instance: sealed::Instance + Sized + RccPeripheral + 'static {} - -macro_rules! impl_timer { - ($inst:ident) => { - impl sealed::Instance for peripherals::$inst { - type Interrupt = crate::interrupt::$inst; - - fn regs() -> TimGp16 { - crate::pac::timer::TimGp16(crate::pac::$inst.0) - } - } - - impl Instance for peripherals::$inst {} - }; -} - -crate::pac::peripherals!( - (timer, TIM2) => { impl_timer!(TIM2); }; - (timer, TIM3) => { impl_timer!(TIM3); }; - (timer, TIM4) => { impl_timer!(TIM4); }; - (timer, TIM5) => { impl_timer!(TIM5); }; -); diff --git a/stm32-data b/stm32-data index 608581a8..cb78ac90 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit 608581a8960b95c4d472f59d0b028b47053d5873 +Subproject commit cb78ac90ba8607d6bb38296607c02e28c60391f8