aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src/time_driver.rs
diff options
context:
space:
mode:
authorCaleb Jamison <[email protected]>2024-08-07 23:20:26 -0400
committerCaleb Jamison <[email protected]>2024-08-08 21:35:21 -0400
commitb185e02a42ad751ec6c31ffa6a1b87503f15489d (patch)
tree0f0c66747267d24d95b5957b22db7e5c525cb00e /embassy-rp/src/time_driver.rs
parent891c5ee10584cd990dad529e3506fe1328e4e69d (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.rs73
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};
10use crate::interrupt::InterruptExt; 10use crate::interrupt::InterruptExt;
11use crate::{interrupt, pac}; 11use crate::{interrupt, pac};
12 12
13#[cfg(feature = "rp2040")]
14use pac::TIMER;
15#[cfg(feature = "rp235x")]
16use pac::TIMER0 as TIMER;
17
13struct AlarmState { 18struct 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{
35impl Driver for TimerDriver { 40impl 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]
155fn TIMER_IRQ_0() { 170fn 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]
161fn TIMER_IRQ_1() { 176fn 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]
167fn TIMER_IRQ_2() { 182fn 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]
173fn TIMER_IRQ_3() { 188fn 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]
194fn TIMER0_IRQ_0() {
195 DRIVER.check_alarm(0)
196}
197
198#[cfg(all(feature = "rt", feature = "rp235x"))]
199#[interrupt]
200fn TIMER0_IRQ_1() {
201 DRIVER.check_alarm(1)
202}
203
204#[cfg(all(feature = "rt", feature = "rp235x"))]
205#[interrupt]
206fn TIMER0_IRQ_2() {
207 DRIVER.check_alarm(2)
208}
209
210#[cfg(all(feature = "rt", feature = "rp235x"))]
211#[interrupt]
212fn TIMER0_IRQ_3() {
213 DRIVER.check_alarm(3)
214}