diff options
| author | eZio Pan <[email protected]> | 2024-02-14 17:17:27 +0800 |
|---|---|---|
| committer | eZio Pan <[email protected]> | 2024-02-14 17:43:46 +0800 |
| commit | bbe1eebc534f57c74f1735e5d99ed3c4136636bd (patch) | |
| tree | 9d0f9e0a372f7190d3830bda00458bc48b18138a | |
| parent | 63d592c7b0d1115b57abfd4e8ed918059749b8ff (diff) | |
Add missing TIM for time-driver; reorder time-driver selection when use "time-drvier-any".
| -rw-r--r-- | embassy-stm32/build.rs | 41 | ||||
| -rw-r--r-- | 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() { | |||
| 183 | 183 | ||
| 184 | let time_driver_singleton = match time_driver.as_ref().map(|x| x.as_ref()) { | 184 | let time_driver_singleton = match time_driver.as_ref().map(|x| x.as_ref()) { |
| 185 | None => "", | 185 | None => "", |
| 186 | Some("tim1") => "TIM1", | ||
| 186 | Some("tim2") => "TIM2", | 187 | Some("tim2") => "TIM2", |
| 187 | Some("tim3") => "TIM3", | 188 | Some("tim3") => "TIM3", |
| 188 | Some("tim4") => "TIM4", | 189 | Some("tim4") => "TIM4", |
| 189 | Some("tim5") => "TIM5", | 190 | Some("tim5") => "TIM5", |
| 191 | Some("tim8") => "TIM8", | ||
| 190 | Some("tim9") => "TIM9", | 192 | Some("tim9") => "TIM9", |
| 191 | Some("tim11") => "TIM11", | ||
| 192 | Some("tim12") => "TIM12", | 193 | Some("tim12") => "TIM12", |
| 193 | Some("tim15") => "TIM15", | 194 | Some("tim15") => "TIM15", |
| 195 | Some("tim20") => "TIM20", | ||
| 194 | Some("tim21") => "TIM21", | 196 | Some("tim21") => "TIM21", |
| 195 | Some("tim22") => "TIM22", | 197 | Some("tim22") => "TIM22", |
| 198 | Some("tim23") => "TIM23", | ||
| 199 | Some("tim24") => "TIM24", | ||
| 196 | Some("any") => { | 200 | Some("any") => { |
| 197 | if singletons.contains(&"TIM2".to_string()) { | 201 | // Order of TIM candidators: |
| 198 | "TIM2" | 202 | // 1. 2CH -> 2CH_CMP -> GP16 -> GP32 -> ADV |
| 199 | } else if singletons.contains(&"TIM3".to_string()) { | 203 | // 2. In same catagory: larger TIM number first |
| 200 | "TIM3" | 204 | [ |
| 201 | } else if singletons.contains(&"TIM4".to_string()) { | 205 | "TIM22", "TIM21", "TIM12", "TIM9", // 2CH |
| 202 | "TIM4" | 206 | "TIM15", // 2CH_CMP |
| 203 | } else if singletons.contains(&"TIM5".to_string()) { | 207 | "TIM19", "TIM4", "TIM3", // GP16 |
| 204 | "TIM5" | 208 | "TIM24", "TIM23", "TIM5", "TIM2", // GP32 |
| 205 | } else if singletons.contains(&"TIM9".to_string()) { | 209 | "TIM20", "TIM8", "TIM1", //ADV |
| 206 | "TIM9" | 210 | ] |
| 207 | } else if singletons.contains(&"TIM11".to_string()) { | 211 | .iter() |
| 208 | "TIM11" | 212 | .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.") |
| 209 | } else if singletons.contains(&"TIM12".to_string()) { | ||
| 210 | "TIM12" | ||
| 211 | } else if singletons.contains(&"TIM15".to_string()) { | ||
| 212 | "TIM15" | ||
| 213 | } else if singletons.contains(&"TIM21".to_string()) { | ||
| 214 | "TIM21" | ||
| 215 | } else if singletons.contains(&"TIM22".to_string()) { | ||
| 216 | "TIM22" | ||
| 217 | } else { | ||
| 218 | panic!("time-driver-any requested, but the chip doesn't have TIM2, TIM3, TIM4, TIM5, TIM9, TIM11, TIM12 or TIM15.") | ||
| 219 | } | ||
| 220 | } | 213 | } |
| 221 | _ => panic!("unknown time_driver {:?}", time_driver), | 214 | _ => panic!("unknown time_driver {:?}", time_driver), |
| 222 | }; | 215 | }; |
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 @@ | |||
| 1 | #![allow(non_snake_case)] | ||
| 2 | |||
| 1 | use core::cell::Cell; | 3 | use core::cell::Cell; |
| 2 | use core::convert::TryInto; | 4 | use core::convert::TryInto; |
| 3 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; |
| @@ -22,18 +24,22 @@ use crate::{interrupt, peripherals}; | |||
| 22 | // As of 2023-12-04, this driver is implemented using CC1 as the halfway rollover interrupt, and any | 24 | // As of 2023-12-04, this driver is implemented using CC1 as the halfway rollover interrupt, and any |
| 23 | // additional CC capabilities to provide timer alarms to embassy-time. embassy-time requires AT LEAST | 25 | // additional CC capabilities to provide timer alarms to embassy-time. embassy-time requires AT LEAST |
| 24 | // one alarm to be allocatable, which means timers that only have CC1, such as TIM16/TIM17, are not | 26 | // one alarm to be allocatable, which means timers that only have CC1, such as TIM16/TIM17, are not |
| 25 | // candidates for use as an embassy-time driver provider. | 27 | // candidates for use as an embassy-time driver provider. (a.k.a 1CH and 1CH_CMP are not, others are good.) |
| 26 | // | 28 | // |
| 27 | // The values of ALARM_COUNT below are not the TOTAL CC registers available, but rather the number | 29 | // The values of ALARM_COUNT below are not the TOTAL CC registers available, but rather the number |
| 28 | // available after reserving CC1 for regular time keeping. For example, TIM2 has four CC registers: | 30 | // available after reserving CC1 for regular time keeping. For example, TIM2 has four CC registers: |
| 29 | // CC1, CC2, CC3, and CC4, so it can provide ALARM_COUNT = 3. | 31 | // CC1, CC2, CC3, and CC4, so it can provide ALARM_COUNT = 3. |
| 30 | 32 | ||
| 31 | #[cfg(not(any(time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22)))] | 33 | cfg_if::cfg_if! { |
| 32 | const ALARM_COUNT: usize = 3; | 34 | if #[cfg(any(time_driver_tim9, time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22))] { |
| 33 | 35 | const ALARM_COUNT: usize = 1; | |
| 34 | #[cfg(any(time_driver_tim12, time_driver_tim15, time_driver_tim21, time_driver_tim22))] | 36 | } else { |
| 35 | const ALARM_COUNT: usize = 1; | 37 | const ALARM_COUNT: usize = 3; |
| 38 | } | ||
| 39 | } | ||
| 36 | 40 | ||
| 41 | #[cfg(time_drvier_tim1)] | ||
| 42 | type T = peripherals::TIM1; | ||
| 37 | #[cfg(time_driver_tim2)] | 43 | #[cfg(time_driver_tim2)] |
| 38 | type T = peripherals::TIM2; | 44 | type T = peripherals::TIM2; |
| 39 | #[cfg(time_driver_tim3)] | 45 | #[cfg(time_driver_tim3)] |
| @@ -42,6 +48,8 @@ type T = peripherals::TIM3; | |||
| 42 | type T = peripherals::TIM4; | 48 | type T = peripherals::TIM4; |
| 43 | #[cfg(time_driver_tim5)] | 49 | #[cfg(time_driver_tim5)] |
| 44 | type T = peripherals::TIM5; | 50 | type T = peripherals::TIM5; |
| 51 | #[cfg(time_driver_tim8)] | ||
| 52 | type T = peripherals::TIM8; | ||
| 45 | #[cfg(time_driver_tim9)] | 53 | #[cfg(time_driver_tim9)] |
| 46 | type T = peripherals::TIM9; | 54 | type T = peripherals::TIM9; |
| 47 | #[cfg(time_driver_tim11)] | 55 | #[cfg(time_driver_tim11)] |
| @@ -50,12 +58,26 @@ type T = peripherals::TIM11; | |||
| 50 | type T = peripherals::TIM12; | 58 | type T = peripherals::TIM12; |
| 51 | #[cfg(time_driver_tim15)] | 59 | #[cfg(time_driver_tim15)] |
| 52 | type T = peripherals::TIM15; | 60 | type T = peripherals::TIM15; |
| 61 | #[cfg(time_driver_tim20)] | ||
| 62 | type T = peripherals::TIM20; | ||
| 53 | #[cfg(time_driver_tim21)] | 63 | #[cfg(time_driver_tim21)] |
| 54 | type T = peripherals::TIM21; | 64 | type T = peripherals::TIM21; |
| 55 | #[cfg(time_driver_tim22)] | 65 | #[cfg(time_driver_tim22)] |
| 56 | type T = peripherals::TIM22; | 66 | type T = peripherals::TIM22; |
| 67 | #[cfg(time_driver_tim23)] | ||
| 68 | type T = peripherals::TIM23; | ||
| 69 | #[cfg(time_driver_tim24)] | ||
| 70 | type T = peripherals::TIM24; | ||
| 57 | 71 | ||
| 58 | foreach_interrupt! { | 72 | foreach_interrupt! { |
| 73 | (TIM1, timer, $block:ident, UP, $irq:ident) => { | ||
| 74 | #[cfg(time_driver_tim1)] | ||
| 75 | #[cfg(feature = "rt")] | ||
| 76 | #[interrupt] | ||
| 77 | fn $irq() { | ||
| 78 | DRIVER.on_interrupt() | ||
| 79 | } | ||
| 80 | }; | ||
| 59 | (TIM2, timer, $block:ident, UP, $irq:ident) => { | 81 | (TIM2, timer, $block:ident, UP, $irq:ident) => { |
| 60 | #[cfg(time_driver_tim2)] | 82 | #[cfg(time_driver_tim2)] |
| 61 | #[cfg(feature = "rt")] | 83 | #[cfg(feature = "rt")] |
| @@ -88,16 +110,16 @@ foreach_interrupt! { | |||
| 88 | DRIVER.on_interrupt() | 110 | DRIVER.on_interrupt() |
| 89 | } | 111 | } |
| 90 | }; | 112 | }; |
| 91 | (TIM9, timer, $block:ident, UP, $irq:ident) => { | 113 | (TIM8, timer, $block:ident, UP, $irq:ident) => { |
| 92 | #[cfg(time_driver_tim9)] | 114 | #[cfg(time_driver_tim8)] |
| 93 | #[cfg(feature = "rt")] | 115 | #[cfg(feature = "rt")] |
| 94 | #[interrupt] | 116 | #[interrupt] |
| 95 | fn $irq() { | 117 | fn $irq() { |
| 96 | DRIVER.on_interrupt() | 118 | DRIVER.on_interrupt() |
| 97 | } | 119 | } |
| 98 | }; | 120 | }; |
| 99 | (TIM11, timer, $block:ident, UP, $irq:ident) => { | 121 | (TIM9, timer, $block:ident, UP, $irq:ident) => { |
| 100 | #[cfg(time_driver_tim11)] | 122 | #[cfg(time_driver_tim9)] |
| 101 | #[cfg(feature = "rt")] | 123 | #[cfg(feature = "rt")] |
| 102 | #[interrupt] | 124 | #[interrupt] |
| 103 | fn $irq() { | 125 | fn $irq() { |
| @@ -120,6 +142,14 @@ foreach_interrupt! { | |||
| 120 | DRIVER.on_interrupt() | 142 | DRIVER.on_interrupt() |
| 121 | } | 143 | } |
| 122 | }; | 144 | }; |
| 145 | (TIM20, timer, $block:ident, UP, $irq:ident) => { | ||
| 146 | #[cfg(time_driver_tim20)] | ||
| 147 | #[cfg(feature = "rt")] | ||
| 148 | #[interrupt] | ||
| 149 | fn $irq() { | ||
| 150 | DRIVER.on_interrupt() | ||
| 151 | } | ||
| 152 | }; | ||
| 123 | (TIM21, timer, $block:ident, UP, $irq:ident) => { | 153 | (TIM21, timer, $block:ident, UP, $irq:ident) => { |
| 124 | #[cfg(time_driver_tim21)] | 154 | #[cfg(time_driver_tim21)] |
| 125 | #[cfg(feature = "rt")] | 155 | #[cfg(feature = "rt")] |
| @@ -136,6 +166,22 @@ foreach_interrupt! { | |||
| 136 | DRIVER.on_interrupt() | 166 | DRIVER.on_interrupt() |
| 137 | } | 167 | } |
| 138 | }; | 168 | }; |
| 169 | (TIM23, timer, $block:ident, UP, $irq:ident) => { | ||
| 170 | #[cfg(time_driver_tim23)] | ||
| 171 | #[cfg(feature = "rt")] | ||
| 172 | #[interrupt] | ||
| 173 | fn $irq() { | ||
| 174 | DRIVER.on_interrupt() | ||
| 175 | } | ||
| 176 | }; | ||
| 177 | (TIM24, timer, $block:ident, UP, $irq:ident) => { | ||
| 178 | #[cfg(time_driver_tim24)] | ||
| 179 | #[cfg(feature = "rt")] | ||
| 180 | #[interrupt] | ||
| 181 | fn $irq() { | ||
| 182 | DRIVER.on_interrupt() | ||
| 183 | } | ||
| 184 | }; | ||
| 139 | } | 185 | } |
| 140 | 186 | ||
| 141 | // Clock timekeeping works with something we call "periods", which are time intervals | 187 | // Clock timekeeping works with something we call "periods", which are time intervals |
