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:
commit
5163de6094
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); };
|
||||
);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 608581a8960b95c4d472f59d0b028b47053d5873
|
||||
Subproject commit cb78ac90ba8607d6bb38296607c02e28c60391f8
|
Loading…
Reference in New Issue
Block a user