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:
bors[bot] 2022-02-24 05:29:33 +00:00 committed by GitHub
commit 5163de6094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 92 additions and 93 deletions

3
ci.sh
View File

@ -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 \

View File

@ -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;

View File

@ -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()

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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();
}

View File

@ -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));

View File

@ -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))]

View File

@ -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() {
crate::pac::interrupts! {
(TIM2, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim2)]
#[interrupt]
fn $irq() {
DRIVER.on_interrupt()
}
#[cfg(time_driver_tim3)]
#[interrupt]
fn TIM3() {
}
};
(TIM3, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim3)]
#[interrupt]
fn $irq() {
DRIVER.on_interrupt()
}
#[cfg(time_driver_tim4)]
#[interrupt]
fn TIM4() {
}
};
(TIM4, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim4)]
#[interrupt]
fn $irq() {
DRIVER.on_interrupt()
}
#[cfg(time_driver_tim5)]
#[interrupt]
fn TIM5() {
}
};
(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