aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/uarte.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src/uarte.rs')
-rw-r--r--embassy-nrf/src/uarte.rs86
1 files changed, 41 insertions, 45 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 957fa4c71..9e485907c 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -2,12 +2,11 @@
2 2
3use core::future::Future; 3use core::future::Future;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::pin::Pin; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
7use core::task::Poll; 6use core::task::Poll;
7use embassy::interrupt::InterruptExt;
8use embassy::traits::uart::{Error, Read, Write}; 8use embassy::traits::uart::{Error, Read, Write};
9use embassy::util::{AtomicWaker, OnDrop, PeripheralBorrow}; 9use embassy::util::{AtomicWaker, OnDrop, PeripheralBorrow};
10use embassy_extras::peripheral_shared::{Peripheral, PeripheralState};
11use embassy_extras::unborrow; 10use embassy_extras::unborrow;
12use futures::future::poll_fn; 11use futures::future::poll_fn;
13 12
@@ -38,16 +37,9 @@ impl Default for Config {
38 } 37 }
39} 38}
40 39
41struct State<T: Instance> {
42 peri: T,
43
44 endrx_waker: AtomicWaker,
45 endtx_waker: AtomicWaker,
46}
47
48/// Interface to the UARTE peripheral 40/// Interface to the UARTE peripheral
49pub struct Uarte<'d, T: Instance> { 41pub struct Uarte<'d, T: Instance> {
50 inner: Peripheral<State<T>>, 42 peri: T,
51 phantom: PhantomData<&'d mut T>, 43 phantom: PhantomData<&'d mut T>,
52} 44}
53 45
@@ -72,7 +64,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
72 ) -> Self { 64 ) -> Self {
73 unborrow!(uarte, irq, rxd, txd, cts, rts); 65 unborrow!(uarte, irq, rxd, txd, cts, rts);
74 66
75 let r = uarte.regs(); 67 let r = T::regs();
76 68
77 assert!(r.enable.read().enable().is_disabled()); 69 assert!(r.enable.read().enable().is_disabled());
78 70
@@ -115,38 +107,29 @@ impl<'d, T: Instance> Uarte<'d, T> {
115 r.events_rxstarted.reset(); 107 r.events_rxstarted.reset();
116 r.events_txstarted.reset(); 108 r.events_txstarted.reset();
117 109
110 irq.set_handler(Self::on_interrupt);
111 irq.unpend();
112 irq.enable();
113
118 // Enable 114 // Enable
119 r.enable.write(|w| w.enable().enabled()); 115 r.enable.write(|w| w.enable().enabled());
120 116
121 Self { 117 Self {
122 inner: Peripheral::new( 118 peri: uarte,
123 irq,
124 State {
125 peri: uarte,
126 endrx_waker: AtomicWaker::new(),
127 endtx_waker: AtomicWaker::new(),
128 },
129 ),
130 phantom: PhantomData, 119 phantom: PhantomData,
131 } 120 }
132 } 121 }
133 122
134 fn inner(self: Pin<&mut Self>) -> Pin<&mut Peripheral<State<T>>> { 123 fn on_interrupt(_: *mut ()) {
135 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } 124 let r = T::regs();
136 } 125 let s = T::state();
137}
138
139impl<T: Instance> PeripheralState for State<T> {
140 type Interrupt = T::Interrupt;
141 126
142 fn on_interrupt(&self) {
143 let r = self.peri.regs();
144 if r.events_endrx.read().bits() != 0 { 127 if r.events_endrx.read().bits() != 0 {
145 self.endrx_waker.wake(); 128 s.endrx_waker.wake();
146 r.intenclr.write(|w| w.endrx().clear()); 129 r.intenclr.write(|w| w.endrx().clear());
147 } 130 }
148 if r.events_endtx.read().bits() != 0 { 131 if r.events_endtx.read().bits() != 0 {
149 self.endtx_waker.wake(); 132 s.endtx_waker.wake();
150 r.intenclr.write(|w| w.endtx().clear()); 133 r.intenclr.write(|w| w.endtx().clear());
151 } 134 }
152 135
@@ -163,8 +146,7 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> {
163 fn drop(&mut self) { 146 fn drop(&mut self) {
164 info!("uarte drop"); 147 info!("uarte drop");
165 148
166 let s = unsafe { Pin::new_unchecked(&mut self.inner) }.state(); 149 let r = T::regs();
167 let r = s.peri.regs();
168 150
169 let did_stoprx = r.events_rxstarted.read().bits() != 0; 151 let did_stoprx = r.events_rxstarted.read().bits() != 0;
170 let did_stoptx = r.events_txstarted.read().bits() != 0; 152 let did_stoptx = r.events_txstarted.read().bits() != 0;
@@ -194,16 +176,14 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
194 #[rustfmt::skip] 176 #[rustfmt::skip]
195 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 177 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
196 178
197 fn read<'a>(mut self: Pin<&'a mut Self>, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 179 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
198 self.as_mut().inner().register_interrupt();
199
200 async move { 180 async move {
201 let ptr = rx_buffer.as_ptr(); 181 let ptr = rx_buffer.as_ptr();
202 let len = rx_buffer.len(); 182 let len = rx_buffer.len();
203 assert!(len <= EASY_DMA_SIZE); 183 assert!(len <= EASY_DMA_SIZE);
204 184
205 let s = self.inner().state(); 185 let r = T::regs();
206 let r = s.peri.regs(); 186 let s = T::state();
207 187
208 let drop = OnDrop::new(move || { 188 let drop = OnDrop::new(move || {
209 info!("read drop: stopping"); 189 info!("read drop: stopping");
@@ -250,17 +230,15 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
250 #[rustfmt::skip] 230 #[rustfmt::skip]
251 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 231 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
252 232
253 fn write<'a>(mut self: Pin<&'a mut Self>, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { 233 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
254 self.as_mut().inner().register_interrupt();
255
256 async move { 234 async move {
257 let ptr = tx_buffer.as_ptr(); 235 let ptr = tx_buffer.as_ptr();
258 let len = tx_buffer.len(); 236 let len = tx_buffer.len();
259 assert!(len <= EASY_DMA_SIZE); 237 assert!(len <= EASY_DMA_SIZE);
260 // TODO: panic if buffer is not in SRAM 238 // TODO: panic if buffer is not in SRAM
261 239
262 let s = self.inner().state(); 240 let r = T::regs();
263 let r = s.peri.regs(); 241 let s = T::state();
264 242
265 let drop = OnDrop::new(move || { 243 let drop = OnDrop::new(move || {
266 info!("write drop: stopping"); 244 info!("write drop: stopping");
@@ -306,8 +284,22 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
306mod sealed { 284mod sealed {
307 use super::*; 285 use super::*;
308 286
287 pub struct State {
288 pub endrx_waker: AtomicWaker,
289 pub endtx_waker: AtomicWaker,
290 }
291 impl State {
292 pub const fn new() -> Self {
293 Self {
294 endrx_waker: AtomicWaker::new(),
295 endtx_waker: AtomicWaker::new(),
296 }
297 }
298 }
299
309 pub trait Instance { 300 pub trait Instance {
310 fn regs(&self) -> &pac::uarte0::RegisterBlock; 301 fn regs() -> &'static pac::uarte0::RegisterBlock;
302 fn state() -> &'static State;
311 } 303 }
312} 304}
313 305
@@ -318,9 +310,13 @@ pub trait Instance: sealed::Instance + 'static {
318macro_rules! impl_instance { 310macro_rules! impl_instance {
319 ($type:ident, $irq:ident) => { 311 ($type:ident, $irq:ident) => {
320 impl sealed::Instance for peripherals::$type { 312 impl sealed::Instance for peripherals::$type {
321 fn regs(&self) -> &pac::uarte0::RegisterBlock { 313 fn regs() -> &'static pac::uarte0::RegisterBlock {
322 unsafe { &*pac::$type::ptr() } 314 unsafe { &*pac::$type::ptr() }
323 } 315 }
316 fn state() -> &'static sealed::State {
317 static STATE: sealed::State = sealed::State::new();
318 &STATE
319 }
324 } 320 }
325 impl Instance for peripherals::$type { 321 impl Instance for peripherals::$type {
326 type Interrupt = interrupt::$irq; 322 type Interrupt = interrupt::$irq;