From bbe1eebc534f57c74f1735e5d99ed3c4136636bd Mon Sep 17 00:00:00 2001 From: eZio Pan Date: Wed, 14 Feb 2024 17:17:27 +0800 Subject: [PATCH] Add missing TIM for time-driver; reorder time-driver selection when use "time-drvier-any". --- embassy-stm32/build.rs | 41 ++++++++------------ embassy-stm32/src/time_driver.rs | 66 +++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 34 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 35023bf1f..5241dbb27 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -183,40 +183,33 @@ fn main() { let time_driver_singleton = match time_driver.as_ref().map(|x| x.as_ref()) { None => "", + Some("tim1") => "TIM1", Some("tim2") => "TIM2", Some("tim3") => "TIM3", Some("tim4") => "TIM4", Some("tim5") => "TIM5", + Some("tim8") => "TIM8", Some("tim9") => "TIM9", - Some("tim11") => "TIM11", Some("tim12") => "TIM12", Some("tim15") => "TIM15", + Some("tim20") => "TIM20", Some("tim21") => "TIM21", Some("tim22") => "TIM22", + Some("tim23") => "TIM23", + Some("tim24") => "TIM24", Some("any") => { - if singletons.contains(&"TIM2".to_string()) { - "TIM2" - } else if singletons.contains(&"TIM3".to_string()) { - "TIM3" - } else if singletons.contains(&"TIM4".to_string()) { - "TIM4" - } else if singletons.contains(&"TIM5".to_string()) { - "TIM5" - } else if singletons.contains(&"TIM9".to_string()) { - "TIM9" - } else if singletons.contains(&"TIM11".to_string()) { - "TIM11" - } else if singletons.contains(&"TIM12".to_string()) { - "TIM12" - } else if singletons.contains(&"TIM15".to_string()) { - "TIM15" - } else if singletons.contains(&"TIM21".to_string()) { - "TIM21" - } else if singletons.contains(&"TIM22".to_string()) { - "TIM22" - } else { - panic!("time-driver-any requested, but the chip doesn't have TIM2, TIM3, TIM4, TIM5, TIM9, TIM11, TIM12 or TIM15.") - } + // Order of TIM candidators: + // 1. 2CH -> 2CH_CMP -> GP16 -> GP32 -> ADV + // 2. In same catagory: larger TIM number first + [ + "TIM22", "TIM21", "TIM12", "TIM9", // 2CH + "TIM15", // 2CH_CMP + "TIM19", "TIM4", "TIM3", // GP16 + "TIM24", "TIM23", "TIM5", "TIM2", // GP32 + "TIM20", "TIM8", "TIM1", //ADV + ] + .iter() + .find(|tim| singletons.contains(&tim.to_string())).expect("time-driver-any requested, but the chip doesn't have TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM12, TIM15, TIM20, TIM21, TIM22, TIM23 or TIM24.") } _ => panic!("unknown time_driver {:?}", time_driver), }; diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs index 29ff4a736..a1f54307d 100644 --- a/embassy-stm32/src/time_driver.rs +++ b/embassy-stm32/src/time_driver.rs @@ -1,3 +1,5 @@ +#![allow(non_snake_case)] + use core::cell::Cell; use core::convert::TryInto; use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; @@ -22,18 +24,22 @@ use crate::{interrupt, peripherals}; // As of 2023-12-04, this driver is implemented using CC1 as the halfway rollover interrupt, and any // additional CC capabilities to provide timer alarms to embassy-time. embassy-time requires AT LEAST // one alarm to be allocatable, which means timers that only have CC1, such as TIM16/TIM17, are not -// candidates for use as an embassy-time driver provider. +// candidates for use as an embassy-time driver provider. (a.k.a 1CH and 1CH_CMP are not, others are good.) // // The values of ALARM_COUNT below are not the TOTAL CC registers available, but rather the number // available after reserving CC1 for regular time keeping. For example, TIM2 has four CC registers: // CC1, CC2, CC3, and CC4, so it can provide ALARM_COUNT = 3. -#[cfg(not(any(time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22)))] -const ALARM_COUNT: usize = 3; - -#[cfg(any(time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22))] -const ALARM_COUNT: usize = 1; +cfg_if::cfg_if! { + if #[cfg(any(time_driver_tim9, time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22))] { + const ALARM_COUNT: usize = 1; + } else { + const ALARM_COUNT: usize = 3; + } +} +#[cfg(time_drvier_tim1)] +type T = peripherals::TIM1; #[cfg(time_driver_tim2)] type T = peripherals::TIM2; #[cfg(time_driver_tim3)] @@ -42,6 +48,8 @@ type T = peripherals::TIM3; type T = peripherals::TIM4; #[cfg(time_driver_tim5)] type T = peripherals::TIM5; +#[cfg(time_driver_tim8)] +type T = peripherals::TIM8; #[cfg(time_driver_tim9)] type T = peripherals::TIM9; #[cfg(time_driver_tim11)] @@ -50,12 +58,26 @@ type T = peripherals::TIM11; type T = peripherals::TIM12; #[cfg(time_driver_tim15)] type T = peripherals::TIM15; +#[cfg(time_driver_tim20)] +type T = peripherals::TIM20; #[cfg(time_driver_tim21)] type T = peripherals::TIM21; #[cfg(time_driver_tim22)] type T = peripherals::TIM22; +#[cfg(time_driver_tim23)] +type T = peripherals::TIM23; +#[cfg(time_driver_tim24)] +type T = peripherals::TIM24; foreach_interrupt! { + (TIM1, timer, $block:ident, UP, $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")] @@ -88,16 +110,16 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; - (TIM9, timer, $block:ident, UP, $irq:ident) => { - #[cfg(time_driver_tim9)] + (TIM8, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim8)] #[cfg(feature = "rt")] #[interrupt] fn $irq() { DRIVER.on_interrupt() } }; - (TIM11, timer, $block:ident, UP, $irq:ident) => { - #[cfg(time_driver_tim11)] + (TIM9, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim9)] #[cfg(feature = "rt")] #[interrupt] fn $irq() { @@ -120,6 +142,14 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; + (TIM20, timer, $block:ident, UP, $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")] @@ -136,6 +166,22 @@ foreach_interrupt! { DRIVER.on_interrupt() } }; + (TIM23, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim23)] + #[cfg(feature = "rt")] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; + (TIM24, timer, $block:ident, UP, $irq:ident) => { + #[cfg(time_driver_tim24)] + #[cfg(feature = "rt")] + #[interrupt] + fn $irq() { + DRIVER.on_interrupt() + } + }; } // Clock timekeeping works with something we call "periods", which are time intervals