aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-17 02:34:45 +0000
committerGitHub <[email protected]>2024-02-17 02:34:45 +0000
commita3f508e6d1492fb7b6bf4bb973b5e54c84905e92 (patch)
tree689f8e4ef600031a7d2d9b8fb402d11e4aaccb1c
parentb7c98b9ec984d035188681d1b2445c6f3a42efcf (diff)
parentbbe1eebc534f57c74f1735e5d99ed3c4136636bd (diff)
Merge pull request #2570 from eZioPan/time-driver-singleton
Add missing TIM for time-driver; reorder time-driver selection when use "time-drvier-any"
-rw-r--r--embassy-stm32/build.rs41
-rw-r--r--embassy-stm32/src/time_driver.rs66
2 files changed, 73 insertions, 34 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index ee88d4541..068a74733 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -182,40 +182,33 @@ fn main() {
182 182
183 let time_driver_singleton = match time_driver.as_ref().map(|x| x.as_ref()) { 183 let time_driver_singleton = match time_driver.as_ref().map(|x| x.as_ref()) {
184 None => "", 184 None => "",
185 Some("tim1") => "TIM1",
185 Some("tim2") => "TIM2", 186 Some("tim2") => "TIM2",
186 Some("tim3") => "TIM3", 187 Some("tim3") => "TIM3",
187 Some("tim4") => "TIM4", 188 Some("tim4") => "TIM4",
188 Some("tim5") => "TIM5", 189 Some("tim5") => "TIM5",
190 Some("tim8") => "TIM8",
189 Some("tim9") => "TIM9", 191 Some("tim9") => "TIM9",
190 Some("tim11") => "TIM11",
191 Some("tim12") => "TIM12", 192 Some("tim12") => "TIM12",
192 Some("tim15") => "TIM15", 193 Some("tim15") => "TIM15",
194 Some("tim20") => "TIM20",
193 Some("tim21") => "TIM21", 195 Some("tim21") => "TIM21",
194 Some("tim22") => "TIM22", 196 Some("tim22") => "TIM22",
197 Some("tim23") => "TIM23",
198 Some("tim24") => "TIM24",
195 Some("any") => { 199 Some("any") => {
196 if singletons.contains(&"TIM2".to_string()) { 200 // Order of TIM candidators:
197 "TIM2" 201 // 1. 2CH -> 2CH_CMP -> GP16 -> GP32 -> ADV
198 } else if singletons.contains(&"TIM3".to_string()) { 202 // 2. In same catagory: larger TIM number first
199 "TIM3" 203 [
200 } else if singletons.contains(&"TIM4".to_string()) { 204 "TIM22", "TIM21", "TIM12", "TIM9", // 2CH
201 "TIM4" 205 "TIM15", // 2CH_CMP
202 } else if singletons.contains(&"TIM5".to_string()) { 206 "TIM19", "TIM4", "TIM3", // GP16
203 "TIM5" 207 "TIM24", "TIM23", "TIM5", "TIM2", // GP32
204 } else if singletons.contains(&"TIM9".to_string()) { 208 "TIM20", "TIM8", "TIM1", //ADV
205 "TIM9" 209 ]
206 } else if singletons.contains(&"TIM11".to_string()) { 210 .iter()
207 "TIM11" 211 .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.")
208 } else if singletons.contains(&"TIM12".to_string()) {
209 "TIM12"
210 } else if singletons.contains(&"TIM15".to_string()) {
211 "TIM15"
212 } else if singletons.contains(&"TIM21".to_string()) {
213 "TIM21"
214 } else if singletons.contains(&"TIM22".to_string()) {
215 "TIM22"
216 } else {
217 panic!("time-driver-any requested, but the chip doesn't have TIM2, TIM3, TIM4, TIM5, TIM9, TIM11, TIM12 or TIM15.")
218 }
219 } 212 }
220 _ => panic!("unknown time_driver {:?}", time_driver), 213 _ => panic!("unknown time_driver {:?}", time_driver),
221 }; 214 };
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
1use core::cell::Cell; 3use core::cell::Cell;
2use core::convert::TryInto; 4use core::convert::TryInto;
3use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering}; 5use 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)))] 33cfg_if::cfg_if! {
32const 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 {
35const ALARM_COUNT: usize = 1; 37 const ALARM_COUNT: usize = 3;
38 }
39}
36 40
41#[cfg(time_drvier_tim1)]
42type T = peripherals::TIM1;
37#[cfg(time_driver_tim2)] 43#[cfg(time_driver_tim2)]
38type T = peripherals::TIM2; 44type T = peripherals::TIM2;
39#[cfg(time_driver_tim3)] 45#[cfg(time_driver_tim3)]
@@ -42,6 +48,8 @@ type T = peripherals::TIM3;
42type T = peripherals::TIM4; 48type T = peripherals::TIM4;
43#[cfg(time_driver_tim5)] 49#[cfg(time_driver_tim5)]
44type T = peripherals::TIM5; 50type T = peripherals::TIM5;
51#[cfg(time_driver_tim8)]
52type T = peripherals::TIM8;
45#[cfg(time_driver_tim9)] 53#[cfg(time_driver_tim9)]
46type T = peripherals::TIM9; 54type T = peripherals::TIM9;
47#[cfg(time_driver_tim11)] 55#[cfg(time_driver_tim11)]
@@ -50,12 +58,26 @@ type T = peripherals::TIM11;
50type T = peripherals::TIM12; 58type T = peripherals::TIM12;
51#[cfg(time_driver_tim15)] 59#[cfg(time_driver_tim15)]
52type T = peripherals::TIM15; 60type T = peripherals::TIM15;
61#[cfg(time_driver_tim20)]
62type T = peripherals::TIM20;
53#[cfg(time_driver_tim21)] 63#[cfg(time_driver_tim21)]
54type T = peripherals::TIM21; 64type T = peripherals::TIM21;
55#[cfg(time_driver_tim22)] 65#[cfg(time_driver_tim22)]
56type T = peripherals::TIM22; 66type T = peripherals::TIM22;
67#[cfg(time_driver_tim23)]
68type T = peripherals::TIM23;
69#[cfg(time_driver_tim24)]
70type T = peripherals::TIM24;
57 71
58foreach_interrupt! { 72foreach_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