aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 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
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