diff options
| author | Caleb Jamison <[email protected]> | 2024-08-07 23:20:26 -0400 |
|---|---|---|
| committer | Caleb Jamison <[email protected]> | 2024-08-08 21:35:21 -0400 |
| commit | b185e02a42ad751ec6c31ffa6a1b87503f15489d (patch) | |
| tree | 0f0c66747267d24d95b5957b22db7e5c525cb00e /embassy-rp/src/time_driver.rs | |
| parent | 891c5ee10584cd990dad529e3506fe1328e4e69d (diff) | |
Initial rp235x support
Examples have been run, but there is not yet a test suite.
Diffstat (limited to 'embassy-rp/src/time_driver.rs')
| -rw-r--r-- | embassy-rp/src/time_driver.rs | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/embassy-rp/src/time_driver.rs b/embassy-rp/src/time_driver.rs index bab1044cb..6f532fa8e 100644 --- a/embassy-rp/src/time_driver.rs +++ b/embassy-rp/src/time_driver.rs | |||
| @@ -10,6 +10,11 @@ use embassy_time_driver::{AlarmHandle, Driver}; | |||
| 10 | use crate::interrupt::InterruptExt; | 10 | use crate::interrupt::InterruptExt; |
| 11 | use crate::{interrupt, pac}; | 11 | use crate::{interrupt, pac}; |
| 12 | 12 | ||
| 13 | #[cfg(feature = "rp2040")] | ||
| 14 | use pac::TIMER; | ||
| 15 | #[cfg(feature = "rp235x")] | ||
| 16 | use pac::TIMER0 as TIMER; | ||
| 17 | |||
| 13 | struct AlarmState { | 18 | struct AlarmState { |
| 14 | timestamp: Cell<u64>, | 19 | timestamp: Cell<u64>, |
| 15 | callback: Cell<Option<(fn(*mut ()), *mut ())>>, | 20 | callback: Cell<Option<(fn(*mut ()), *mut ())>>, |
| @@ -35,9 +40,9 @@ embassy_time_driver::time_driver_impl!(static DRIVER: TimerDriver = TimerDriver{ | |||
| 35 | impl Driver for TimerDriver { | 40 | impl Driver for TimerDriver { |
| 36 | fn now(&self) -> u64 { | 41 | fn now(&self) -> u64 { |
| 37 | loop { | 42 | loop { |
| 38 | let hi = pac::TIMER.timerawh().read(); | 43 | let hi = TIMER.timerawh().read(); |
| 39 | let lo = pac::TIMER.timerawl().read(); | 44 | let lo = TIMER.timerawl().read(); |
| 40 | let hi2 = pac::TIMER.timerawh().read(); | 45 | let hi2 = TIMER.timerawh().read(); |
| 41 | if hi == hi2 { | 46 | if hi == hi2 { |
| 42 | return (hi as u64) << 32 | (lo as u64); | 47 | return (hi as u64) << 32 | (lo as u64); |
| 43 | } | 48 | } |
| @@ -77,13 +82,13 @@ impl Driver for TimerDriver { | |||
| 77 | // Note that we're not checking the high bits at all. This means the irq may fire early | 82 | // Note that we're not checking the high bits at all. This means the irq may fire early |
| 78 | // if the alarm is more than 72 minutes (2^32 us) in the future. This is OK, since on irq fire | 83 | // if the alarm is more than 72 minutes (2^32 us) in the future. This is OK, since on irq fire |
| 79 | // it is checked if the alarm time has passed. | 84 | // it is checked if the alarm time has passed. |
| 80 | pac::TIMER.alarm(n).write_value(timestamp as u32); | 85 | TIMER.alarm(n).write_value(timestamp as u32); |
| 81 | 86 | ||
| 82 | let now = self.now(); | 87 | let now = self.now(); |
| 83 | if timestamp <= now { | 88 | if timestamp <= now { |
| 84 | // If alarm timestamp has passed the alarm will not fire. | 89 | // If alarm timestamp has passed the alarm will not fire. |
| 85 | // Disarm the alarm and return `false` to indicate that. | 90 | // Disarm the alarm and return `false` to indicate that. |
| 86 | pac::TIMER.armed().write(|w| w.set_armed(1 << n)); | 91 | TIMER.armed().write(|w| w.set_armed(1 << n)); |
| 87 | 92 | ||
| 88 | alarm.timestamp.set(u64::MAX); | 93 | alarm.timestamp.set(u64::MAX); |
| 89 | 94 | ||
| @@ -105,17 +110,17 @@ impl TimerDriver { | |||
| 105 | } else { | 110 | } else { |
| 106 | // Not elapsed, arm it again. | 111 | // Not elapsed, arm it again. |
| 107 | // This can happen if it was set more than 2^32 us in the future. | 112 | // This can happen if it was set more than 2^32 us in the future. |
| 108 | pac::TIMER.alarm(n).write_value(timestamp as u32); | 113 | TIMER.alarm(n).write_value(timestamp as u32); |
| 109 | } | 114 | } |
| 110 | }); | 115 | }); |
| 111 | 116 | ||
| 112 | // clear the irq | 117 | // clear the irq |
| 113 | pac::TIMER.intr().write(|w| w.set_alarm(n, true)); | 118 | TIMER.intr().write(|w| w.set_alarm(n, true)); |
| 114 | } | 119 | } |
| 115 | 120 | ||
| 116 | fn trigger_alarm(&self, n: usize, cs: CriticalSection) { | 121 | fn trigger_alarm(&self, n: usize, cs: CriticalSection) { |
| 117 | // disarm | 122 | // disarm |
| 118 | pac::TIMER.armed().write(|w| w.set_armed(1 << n)); | 123 | TIMER.armed().write(|w| w.set_armed(1 << n)); |
| 119 | 124 | ||
| 120 | let alarm = &self.alarms.borrow(cs)[n]; | 125 | let alarm = &self.alarms.borrow(cs)[n]; |
| 121 | alarm.timestamp.set(u64::MAX); | 126 | alarm.timestamp.set(u64::MAX); |
| @@ -138,38 +143,72 @@ pub unsafe fn init() { | |||
| 138 | }); | 143 | }); |
| 139 | 144 | ||
| 140 | // enable all irqs | 145 | // enable all irqs |
| 141 | pac::TIMER.inte().write(|w| { | 146 | TIMER.inte().write(|w| { |
| 142 | w.set_alarm(0, true); | 147 | w.set_alarm(0, true); |
| 143 | w.set_alarm(1, true); | 148 | w.set_alarm(1, true); |
| 144 | w.set_alarm(2, true); | 149 | w.set_alarm(2, true); |
| 145 | w.set_alarm(3, true); | 150 | w.set_alarm(3, true); |
| 146 | }); | 151 | }); |
| 147 | interrupt::TIMER_IRQ_0.enable(); | 152 | #[cfg(feature = "rp2040")] |
| 148 | interrupt::TIMER_IRQ_1.enable(); | 153 | { |
| 149 | interrupt::TIMER_IRQ_2.enable(); | 154 | interrupt::TIMER_IRQ_0.enable(); |
| 150 | interrupt::TIMER_IRQ_3.enable(); | 155 | interrupt::TIMER_IRQ_1.enable(); |
| 156 | interrupt::TIMER_IRQ_2.enable(); | ||
| 157 | interrupt::TIMER_IRQ_3.enable(); | ||
| 158 | } | ||
| 159 | #[cfg(feature = "rp235x")] | ||
| 160 | { | ||
| 161 | interrupt::TIMER0_IRQ_0.enable(); | ||
| 162 | interrupt::TIMER0_IRQ_1.enable(); | ||
| 163 | interrupt::TIMER0_IRQ_2.enable(); | ||
| 164 | interrupt::TIMER0_IRQ_3.enable(); | ||
| 165 | } | ||
| 151 | } | 166 | } |
| 152 | 167 | ||
| 153 | #[cfg(feature = "rt")] | 168 | #[cfg(all(feature = "rt", feature = "rp2040"))] |
| 154 | #[interrupt] | 169 | #[interrupt] |
| 155 | fn TIMER_IRQ_0() { | 170 | fn TIMER_IRQ_0() { |
| 156 | DRIVER.check_alarm(0) | 171 | DRIVER.check_alarm(0) |
| 157 | } | 172 | } |
| 158 | 173 | ||
| 159 | #[cfg(feature = "rt")] | 174 | #[cfg(all(feature = "rt", feature = "rp2040"))] |
| 160 | #[interrupt] | 175 | #[interrupt] |
| 161 | fn TIMER_IRQ_1() { | 176 | fn TIMER_IRQ_1() { |
| 162 | DRIVER.check_alarm(1) | 177 | DRIVER.check_alarm(1) |
| 163 | } | 178 | } |
| 164 | 179 | ||
| 165 | #[cfg(feature = "rt")] | 180 | #[cfg(all(feature = "rt", feature = "rp2040"))] |
| 166 | #[interrupt] | 181 | #[interrupt] |
| 167 | fn TIMER_IRQ_2() { | 182 | fn TIMER_IRQ_2() { |
| 168 | DRIVER.check_alarm(2) | 183 | DRIVER.check_alarm(2) |
| 169 | } | 184 | } |
| 170 | 185 | ||
| 171 | #[cfg(feature = "rt")] | 186 | #[cfg(all(feature = "rt", feature = "rp2040"))] |
| 172 | #[interrupt] | 187 | #[interrupt] |
| 173 | fn TIMER_IRQ_3() { | 188 | fn TIMER_IRQ_3() { |
| 174 | DRIVER.check_alarm(3) | 189 | DRIVER.check_alarm(3) |
| 175 | } | 190 | } |
| 191 | |||
| 192 | #[cfg(all(feature = "rt", feature = "rp235x"))] | ||
| 193 | #[interrupt] | ||
| 194 | fn TIMER0_IRQ_0() { | ||
| 195 | DRIVER.check_alarm(0) | ||
| 196 | } | ||
| 197 | |||
| 198 | #[cfg(all(feature = "rt", feature = "rp235x"))] | ||
| 199 | #[interrupt] | ||
| 200 | fn TIMER0_IRQ_1() { | ||
| 201 | DRIVER.check_alarm(1) | ||
| 202 | } | ||
| 203 | |||
| 204 | #[cfg(all(feature = "rt", feature = "rp235x"))] | ||
| 205 | #[interrupt] | ||
| 206 | fn TIMER0_IRQ_2() { | ||
| 207 | DRIVER.check_alarm(2) | ||
| 208 | } | ||
| 209 | |||
| 210 | #[cfg(all(feature = "rt", feature = "rp235x"))] | ||
| 211 | #[interrupt] | ||
| 212 | fn TIMER0_IRQ_3() { | ||
| 213 | DRIVER.check_alarm(3) | ||
| 214 | } | ||
