Merge #643
643: stm32: build fixes for troublesome chips r=Dirbaio a=Dirbaio See individual commits. Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
		
							
								
								
									
										3
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								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 \ | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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<T: Instance> AdcPin<T> for Vref {} | ||||
| impl<T: Instance> super::sealed::AdcPin<T> 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<T: Instance> AdcPin<T> for Temperature {} | ||||
| impl<T: Instance> super::sealed::AdcPin<T> 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<T: Instance> AdcPin<T> for Vbat {} | ||||
| impl<T: Instance> super::sealed::AdcPin<T> 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() | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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 { | ||||
|  | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -388,6 +388,6 @@ pub(crate) unsafe fn init() { | ||||
|  | ||||
|     #[cfg(not(any(rcc_wb, rcc_wl5, rcc_f1)))] | ||||
|     <crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable(); | ||||
|     #[cfg(rcc_f1)] | ||||
|     #[cfg(stm32f1)] | ||||
|     <crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable(); | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -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))] | ||||
|   | ||||
| @@ -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(); | ||||
|         <T as RccPeripheral>::enable(); | ||||
|         <T as RccPeripheral>::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: <T as sealed::Instance>::Interrupt = core::mem::transmute(()); | ||||
|             let irq: <T as BasicInstance>::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); }; | ||||
| ); | ||||
|   | ||||
 Submodule stm32-data updated: 608581a896...cb78ac90ba
									
								
							
		Reference in New Issue
	
	Block a user