From 5c45723777dbd7d9d23188f5b5a2adc417e29292 Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun <tcbennun@maxiluxsystems.com> Date: Fri, 23 Feb 2024 14:33:25 +0000 Subject: [PATCH] stm32: timers: use TIMx_CC interrupt source for advanced timers fixes (hopefully) time driver when using TIM1/8/20 --- embassy-stm32/src/time_driver.rs | 34 ++++++++++++++++++++++++++++++++ embassy-stm32/src/timer/mod.rs | 19 ++++++++++++++---- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 8e4e606a4..37b2e7526 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -16,6 +16,8 @@ use crate::pac::timer::vals; use crate::rcc::sealed::RccPeripheral; #[cfg(feature = "low-power")] use crate::rtc::Rtc; +#[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] +use crate::timer::sealed::AdvancedControlInstance; use crate::timer::sealed::{CoreInstance, GeneralPurpose16bitInstance as Instance}; use crate::{interrupt, peripherals}; @@ -76,6 +78,14 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; + (TIM1, timer, $block:ident, CC, $irq:ident) => { + #[cfg(time_driver_tim1)] + #[cfg(feature = "rt")] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; (TIM2, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim2)] #[cfg(feature = "rt")] @@ -116,6 +126,14 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; + (TIM8, timer, $block:ident, CC, $irq:ident) => { + #[cfg(time_driver_tim8)] + #[cfg(feature = "rt")] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; (TIM9, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim9)] #[cfg(feature = "rt")] @@ -148,6 +166,14 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; + (TIM20, timer, $block:ident, CC, $irq:ident) => { + #[cfg(time_driver_tim20)] + #[cfg(feature = "rt")] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; (TIM21, timer, $block:ident, UP, $irq:ident) => { #[cfg(time_driver_tim21)] #[cfg(feature = "rt")] @@ -281,6 +307,14 @@ impl RtcDriver { <T as CoreInstance>::Interrupt::unpend(); unsafe { <T as CoreInstance>::Interrupt::enable() }; + #[cfg(any(time_driver_tim1, time_driver_tim8, time_driver_tim20))] + { + <T as AdvancedControlInstance>::CaptureCompareInterrupt::unpend(); + unsafe { + <T as AdvancedControlInstance>::CaptureCompareInterrupt::enable(); + } + } + r.cr1().modify(|w| w.set_cen(true)); } diff --git a/embassy-stm32/src/timer/mod.rs b/embassy-stm32/src/timer/mod.rs index 9397da2a1..c8f580101 100644 --- a/embassy-stm32/src/timer/mod.rs +++ b/embassy-stm32/src/timer/mod.rs @@ -464,6 +464,9 @@ pub(crate) mod sealed { pub trait AdvancedControlInstance: GeneralPurpose2ChannelComplementaryInstance + GeneralPurpose16bitInstance { + /// Capture compare interrupt for this timer. + type CaptureCompareInterrupt: interrupt::typelevel::Interrupt; + /// Get access to the advanced timer registers. fn regs_advanced() -> crate::pac::timer::TimAdv; @@ -831,8 +834,10 @@ macro_rules! impl_2ch_cmp_timer { #[allow(unused)] macro_rules! impl_adv_timer { - ($inst:ident) => { + ($inst:ident, $irq:ident) => { impl sealed::AdvancedControlInstance for crate::peripherals::$inst { + type CaptureCompareInterrupt = crate::interrupt::typelevel::$irq; + fn regs_advanced() -> crate::pac::timer::TimAdv { unsafe { crate::pac::timer::TimAdv::from_ptr(crate::pac::$inst.as_ptr()) } } @@ -905,11 +910,13 @@ foreach_interrupt! { impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); - impl_adv_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; + ($inst:ident, timer, TIM_1CH_CMP, CC, $irq:ident) => { + impl_adv_timer!($inst, $irq); + }; ($inst:ident, timer, TIM_2CH_CMP, UP, $irq:ident) => { @@ -921,11 +928,13 @@ foreach_interrupt! { impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); - impl_adv_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; + ($inst:ident, timer, TIM_2CH_CMP, CC, $irq:ident) => { + impl_adv_timer!($inst, $irq); + }; ($inst:ident, timer, TIM_ADV, UP, $irq:ident) => { @@ -937,11 +946,13 @@ foreach_interrupt! { impl_gp16_timer!($inst); impl_1ch_cmp_timer!($inst); impl_2ch_cmp_timer!($inst); - impl_adv_timer!($inst); impl BasicInstance for crate::peripherals::$inst {} impl CaptureCompare16bitInstance for crate::peripherals::$inst {} impl ComplementaryCaptureCompare16bitInstance for crate::peripherals::$inst {} }; + ($inst:ident, timer, TIM_ADV, CC, $irq:ident) => { + impl_adv_timer!($inst, $irq); + }; } // Update Event trigger DMA for every timer