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,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,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,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 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,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,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 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/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-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 \
|
--- 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
|
// We *shouldn't* have singletons for these, but the HAL currently requires
|
||||||
// singletons, for using with RccPeripheral to enable/disable clocks to them.
|
// singletons, for using with RccPeripheral to enable/disable clocks to them.
|
||||||
"rcc" => {
|
"rcc" => {
|
||||||
if r.version == "h7" {
|
if r.version.starts_with("h7") {
|
||||||
singletons.push("MCO1".to_string());
|
singletons.push("MCO1".to_string());
|
||||||
singletons.push("MCO2".to_string());
|
singletons.push("MCO2".to_string());
|
||||||
}
|
}
|
||||||
@ -436,7 +436,7 @@ fn main() {
|
|||||||
// MCO is special
|
// MCO is special
|
||||||
if pin.signal.starts_with("MCO_") {
|
if pin.signal.starts_with("MCO_") {
|
||||||
// Supported in H7 only for now
|
// Supported in H7 only for now
|
||||||
if regs.version == "h7" {
|
if regs.version.starts_with("h7") {
|
||||||
peri = format_ident!("{}", pin.signal.replace("_", ""));
|
peri = format_ident!("{}", pin.signal.replace("_", ""));
|
||||||
} else {
|
} else {
|
||||||
continue;
|
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
|
/// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock
|
||||||
/// configuration.
|
/// configuration.
|
||||||
unsafe fn enable() {
|
unsafe fn enable() {
|
||||||
#[cfg(rcc_h7)]
|
#[cfg(stm32h7)]
|
||||||
crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true));
|
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));
|
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));
|
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> AdcPin<T> for Vref {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
impl<T: Instance> super::sealed::AdcPin<T> for Vref {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
#[cfg(not(rcc_g0))]
|
#[cfg(not(stm32g0))]
|
||||||
let val = 0;
|
let val = 0;
|
||||||
#[cfg(rcc_g0)]
|
#[cfg(stm32g0)]
|
||||||
let val = 13;
|
let val = 13;
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
@ -66,9 +66,9 @@ pub struct Temperature;
|
|||||||
impl<T: Instance> AdcPin<T> for Temperature {}
|
impl<T: Instance> AdcPin<T> for Temperature {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
impl<T: Instance> super::sealed::AdcPin<T> for Temperature {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
#[cfg(not(rcc_g0))]
|
#[cfg(not(stm32g0))]
|
||||||
let val = 17;
|
let val = 17;
|
||||||
#[cfg(rcc_g0)]
|
#[cfg(stm32g0)]
|
||||||
let val = 12;
|
let val = 12;
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
@ -78,9 +78,9 @@ pub struct Vbat;
|
|||||||
impl<T: Instance> AdcPin<T> for Vbat {}
|
impl<T: Instance> AdcPin<T> for Vbat {}
|
||||||
impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
|
impl<T: Instance> super::sealed::AdcPin<T> for Vbat {
|
||||||
fn channel(&self) -> u8 {
|
fn channel(&self) -> u8 {
|
||||||
#[cfg(not(rcc_g0))]
|
#[cfg(not(stm32g0))]
|
||||||
let val = 18;
|
let val = 18;
|
||||||
#[cfg(rcc_g0)]
|
#[cfg(stm32g0)]
|
||||||
let val = 14;
|
let val = 14;
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
/// Calculates the system VDDA by sampling the internal VREF channel and comparing
|
/// 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
|
/// the result with the value stored at the factory. If the chip's VDDA is not stable, run
|
||||||
/// this before each ADC conversion.
|
/// 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?
|
#[allow(unused)] // TODO is this supposed to be public?
|
||||||
fn calibrate(&mut self, vref: &mut Vref) {
|
fn calibrate(&mut self, vref: &mut Vref) {
|
||||||
let vref_cal = unsafe { crate::pac::VREFINTCAL.data().read().value() };
|
let vref_cal = unsafe { crate::pac::VREFINTCAL.data().read().value() };
|
||||||
@ -363,11 +363,11 @@ impl<'d, T: Instance> Adc<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configure ADC
|
// Configure ADC
|
||||||
#[cfg(not(rcc_g0))]
|
#[cfg(not(stm32g0))]
|
||||||
T::regs()
|
T::regs()
|
||||||
.cfgr()
|
.cfgr()
|
||||||
.modify(|reg| reg.set_res(self.resolution.res()));
|
.modify(|reg| reg.set_res(self.resolution.res()));
|
||||||
#[cfg(rcc_g0)]
|
#[cfg(stm32g0)]
|
||||||
T::regs()
|
T::regs()
|
||||||
.cfgr1()
|
.cfgr1()
|
||||||
.modify(|reg| reg.set_res(self.resolution.res()));
|
.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);
|
Self::set_channel_sample_time(pin.channel(), self.sample_time);
|
||||||
|
|
||||||
// Select channel
|
// Select channel
|
||||||
#[cfg(not(rcc_g0))]
|
#[cfg(not(stm32g0))]
|
||||||
T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
|
T::regs().sqr1().write(|reg| reg.set_sq(0, pin.channel()));
|
||||||
#[cfg(rcc_g0)]
|
#[cfg(stm32g0)]
|
||||||
T::regs()
|
T::regs()
|
||||||
.chselr()
|
.chselr()
|
||||||
.write(|reg| reg.set_chsel(pin.channel() as u32));
|
.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) {
|
unsafe fn set_channel_sample_time(_ch: u8, sample_time: SampleTime) {
|
||||||
T::regs()
|
T::regs()
|
||||||
.smpr()
|
.smpr()
|
||||||
.modify(|reg| reg.set_smp1(sample_time.sample_time()));
|
.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) {
|
unsafe fn set_channel_sample_time(ch: u8, sample_time: SampleTime) {
|
||||||
if ch <= 9 {
|
if ch <= 9 {
|
||||||
T::regs()
|
T::regs()
|
||||||
|
@ -115,9 +115,11 @@ impl<'d, T: Instance> Dac<'d, T> {
|
|||||||
// configuration.
|
// configuration.
|
||||||
#[cfg(rcc_h7)]
|
#[cfg(rcc_h7)]
|
||||||
crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true));
|
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));
|
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));
|
crate::pac::RCC.apb1enr1().modify(|w| w.set_dac1en(true));
|
||||||
|
|
||||||
if channels >= 1 {
|
if channels >= 1 {
|
||||||
|
@ -49,6 +49,12 @@ macro_rules! dma_num {
|
|||||||
(BDMA) => {
|
(BDMA) => {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
(BDMA1) => {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
(BDMA2) => {
|
||||||
|
1
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn on_irq() {
|
pub(crate) unsafe fn on_irq() {
|
||||||
@ -80,6 +86,9 @@ pub(crate) unsafe fn init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pac::dma_channels! {
|
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) => {
|
($channel_peri:ident, $dma_peri:ident, bdma, $channel_num:expr, $dmamux:tt) => {
|
||||||
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
impl crate::dma::sealed::Channel for crate::peripherals::$channel_peri {
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DMAMUX1;
|
pub struct DMAMUX1;
|
||||||
#[cfg(rcc_h7)]
|
#[cfg(stm32h7)]
|
||||||
pub struct DMAMUX2;
|
pub struct DMAMUX2;
|
||||||
|
|
||||||
pub trait MuxChannel: sealed::MuxChannel + super::Channel {
|
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)))]
|
#[cfg(not(any(rcc_wb, rcc_wl5, rcc_f1)))]
|
||||||
<crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
|
<crate::peripherals::SYSCFG as crate::rcc::sealed::RccPeripheral>::enable();
|
||||||
#[cfg(rcc_f1)]
|
#[cfg(stm32f1)]
|
||||||
<crate::peripherals::AFIO as crate::rcc::sealed::RccPeripheral>::enable();
|
<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::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::rcc::{set_freqs, Clocks};
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::time::U32Ext;
|
use crate::time::U32Ext;
|
||||||
@ -180,6 +182,7 @@ pub struct Config {
|
|||||||
pub ahb_pre: AHBPrescaler,
|
pub ahb_pre: AHBPrescaler,
|
||||||
pub apb1_pre: APBPrescaler,
|
pub apb1_pre: APBPrescaler,
|
||||||
pub apb2_pre: APBPrescaler,
|
pub apb2_pre: APBPrescaler,
|
||||||
|
#[cfg(crs)]
|
||||||
pub enable_hsi48: bool,
|
pub enable_hsi48: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +194,7 @@ impl Default for Config {
|
|||||||
ahb_pre: AHBPrescaler::NotDivided,
|
ahb_pre: AHBPrescaler::NotDivided,
|
||||||
apb1_pre: APBPrescaler::NotDivided,
|
apb1_pre: APBPrescaler::NotDivided,
|
||||||
apb2_pre: APBPrescaler::NotDivided,
|
apb2_pre: APBPrescaler::NotDivided,
|
||||||
|
#[cfg(crs)]
|
||||||
enable_hsi48: false,
|
enable_hsi48: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,6 +316,7 @@ pub(crate) unsafe fn init(config: Config) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(crs)]
|
||||||
if config.enable_hsi48 {
|
if config.enable_hsi48 {
|
||||||
// Reset SYSCFG peripheral
|
// Reset SYSCFG peripheral
|
||||||
RCC.apb2rstr().modify(|w| w.set_syscfgrst(true));
|
RCC.apb2rstr().modify(|w| w.set_syscfgrst(true));
|
||||||
|
@ -33,18 +33,20 @@ pub struct Clocks {
|
|||||||
pub apb2_tim: Hertz,
|
pub apb2_tim: Hertz,
|
||||||
#[cfg(any(rcc_wl5, rcc_u5))]
|
#[cfg(any(rcc_wl5, rcc_u5))]
|
||||||
pub apb3: Hertz,
|
pub apb3: Hertz,
|
||||||
#[cfg(any(rcc_h7))]
|
#[cfg(any(rcc_h7, rcc_h7ab))]
|
||||||
pub apb4: Hertz,
|
pub apb4: Hertz,
|
||||||
|
|
||||||
// AHB
|
// AHB
|
||||||
pub ahb1: Hertz,
|
pub ahb1: Hertz,
|
||||||
#[cfg(any(
|
#[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,
|
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,
|
pub ahb3: Hertz,
|
||||||
#[cfg(any(rcc_h7))]
|
#[cfg(any(rcc_h7, rcc_h7ab))]
|
||||||
pub ahb4: Hertz,
|
pub ahb4: Hertz,
|
||||||
|
|
||||||
#[cfg(any(rcc_f4, rcc_f410, rcc_f7))]
|
#[cfg(any(rcc_f4, rcc_f410, rcc_f7))]
|
||||||
|
@ -11,12 +11,12 @@ use embassy::time::TICKS_PER_SECOND;
|
|||||||
use stm32_metapac::timer::regs;
|
use stm32_metapac::timer::regs;
|
||||||
|
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::{CriticalSection, Interrupt};
|
use crate::interrupt::CriticalSection;
|
||||||
use crate::pac::timer::{vals, TimGp16};
|
use crate::pac::timer::vals;
|
||||||
use crate::peripherals;
|
use crate::peripherals;
|
||||||
use crate::rcc::sealed::RccPeripheral;
|
use crate::rcc::sealed::RccPeripheral;
|
||||||
|
use crate::timer::sealed::Basic16bitInstance as BasicInstance;
|
||||||
use self::sealed::Instance as _;
|
use crate::timer::sealed::GeneralPurpose16bitInstance as Instance;
|
||||||
|
|
||||||
const ALARM_COUNT: usize = 3;
|
const ALARM_COUNT: usize = 3;
|
||||||
|
|
||||||
@ -29,25 +29,35 @@ type T = peripherals::TIM4;
|
|||||||
#[cfg(time_driver_tim5)]
|
#[cfg(time_driver_tim5)]
|
||||||
type T = peripherals::TIM5;
|
type T = peripherals::TIM5;
|
||||||
|
|
||||||
#[cfg(time_driver_tim2)]
|
crate::pac::interrupts! {
|
||||||
#[interrupt]
|
(TIM2, timer, $block:ident, UP, $irq:ident) => {
|
||||||
fn TIM2() {
|
#[cfg(time_driver_tim2)]
|
||||||
DRIVER.on_interrupt()
|
#[interrupt]
|
||||||
}
|
fn $irq() {
|
||||||
#[cfg(time_driver_tim3)]
|
DRIVER.on_interrupt()
|
||||||
#[interrupt]
|
}
|
||||||
fn TIM3() {
|
};
|
||||||
DRIVER.on_interrupt()
|
(TIM3, timer, $block:ident, UP, $irq:ident) => {
|
||||||
}
|
#[cfg(time_driver_tim3)]
|
||||||
#[cfg(time_driver_tim4)]
|
#[interrupt]
|
||||||
#[interrupt]
|
fn $irq() {
|
||||||
fn TIM4() {
|
DRIVER.on_interrupt()
|
||||||
DRIVER.on_interrupt()
|
}
|
||||||
}
|
};
|
||||||
#[cfg(time_driver_tim5)]
|
(TIM4, timer, $block:ident, UP, $irq:ident) => {
|
||||||
#[interrupt]
|
#[cfg(time_driver_tim4)]
|
||||||
fn TIM5() {
|
#[interrupt]
|
||||||
DRIVER.on_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
|
// Clock timekeeping works with something we call "periods", which are time intervals
|
||||||
@ -93,6 +103,7 @@ impl AlarmState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RtcDriver {
|
struct RtcDriver {
|
||||||
|
timer: T,
|
||||||
/// Number of 2^15 periods elapsed since boot.
|
/// Number of 2^15 periods elapsed since boot.
|
||||||
period: AtomicU32,
|
period: AtomicU32,
|
||||||
alarm_count: AtomicU8,
|
alarm_count: AtomicU8,
|
||||||
@ -103,6 +114,7 @@ struct RtcDriver {
|
|||||||
const ALARM_STATE_NEW: AlarmState = AlarmState::new();
|
const ALARM_STATE_NEW: AlarmState = AlarmState::new();
|
||||||
|
|
||||||
embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
|
embassy::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
|
||||||
|
timer: unsafe { core::mem::transmute(()) }, // steal is not const
|
||||||
period: AtomicU32::new(0),
|
period: AtomicU32::new(0),
|
||||||
alarm_count: AtomicU8::new(0),
|
alarm_count: AtomicU8::new(0),
|
||||||
alarms: Mutex::const_new(CriticalSectionRawMutex::new(), [ALARM_STATE_NEW; ALARM_COUNT]),
|
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 {
|
impl RtcDriver {
|
||||||
fn init(&'static self) {
|
fn init(&'static self) {
|
||||||
let r = T::regs();
|
let r = self.timer.regs_gp16();
|
||||||
|
|
||||||
T::enable();
|
<T as RccPeripheral>::enable();
|
||||||
T::reset();
|
<T as RccPeripheral>::reset();
|
||||||
|
|
||||||
let timer_freq = T::frequency();
|
let timer_freq = T::frequency();
|
||||||
|
|
||||||
@ -142,7 +154,7 @@ impl RtcDriver {
|
|||||||
// Enable CC0, disable others
|
// Enable CC0, disable others
|
||||||
r.dier().write(|w| w.set_ccie(0, true));
|
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.unpend();
|
||||||
irq.enable();
|
irq.enable();
|
||||||
|
|
||||||
@ -151,7 +163,7 @@ impl RtcDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_interrupt(&self) {
|
fn on_interrupt(&self) {
|
||||||
let r = T::regs();
|
let r = self.timer.regs_gp16();
|
||||||
|
|
||||||
// NOTE(unsafe) Use critical section to access the methods
|
// NOTE(unsafe) Use critical section to access the methods
|
||||||
// XXX: reduce the size of this critical section ?
|
// XXX: reduce the size of this critical section ?
|
||||||
@ -182,7 +194,7 @@ impl RtcDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn next_period(&self) {
|
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 period = self.period.fetch_add(1, Ordering::Relaxed) + 1;
|
||||||
let t = (period as u64) << 15;
|
let t = (period as u64) << 15;
|
||||||
@ -224,7 +236,7 @@ impl RtcDriver {
|
|||||||
|
|
||||||
impl Driver for RtcDriver {
|
impl Driver for RtcDriver {
|
||||||
fn now(&self) -> u64 {
|
fn now(&self) -> u64 {
|
||||||
let r = T::regs();
|
let r = self.timer.regs_gp16();
|
||||||
|
|
||||||
let period = self.period.load(Ordering::Relaxed);
|
let period = self.period.load(Ordering::Relaxed);
|
||||||
compiler_fence(Ordering::Acquire);
|
compiler_fence(Ordering::Acquire);
|
||||||
@ -261,7 +273,7 @@ impl Driver for RtcDriver {
|
|||||||
|
|
||||||
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) {
|
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) {
|
||||||
critical_section::with(|cs| {
|
critical_section::with(|cs| {
|
||||||
let r = T::regs();
|
let r = self.timer.regs_gp16();
|
||||||
|
|
||||||
let n = alarm.id() as _;
|
let n = alarm.id() as _;
|
||||||
let alarm = self.get_alarm(cs, alarm);
|
let alarm = self.get_alarm(cs, alarm);
|
||||||
@ -291,37 +303,3 @@ impl Driver for RtcDriver {
|
|||||||
pub(crate) fn init() {
|
pub(crate) fn init() {
|
||||||
DRIVER.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