diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-22 01:15:44 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-03-29 00:58:58 +0200 |
| commit | df42c384923579c449a13511b0fdb8de3b2a4773 (patch) | |
| tree | 0c89eb75183e972e81748f9a3e601df30191c14a /embassy-nrf/src | |
| parent | 7b6086d19eca2d51c7cddf9dbbbc47eacf371472 (diff) | |
nrf/uarte: update to new api
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 427 |
1 files changed, 200 insertions, 227 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index b5e4da862..fc57f406b 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -5,43 +5,49 @@ | |||
| 5 | //! are dropped correctly (e.g. not using `mem::forget()`). | 5 | //! are dropped correctly (e.g. not using `mem::forget()`). |
| 6 | 6 | ||
| 7 | use core::future::Future; | 7 | use core::future::Future; |
| 8 | use core::ops::Deref; | 8 | use core::marker::PhantomData; |
| 9 | use core::pin::Pin; | ||
| 9 | use core::sync::atomic::{compiler_fence, Ordering}; | 10 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 10 | use core::task::{Context, Poll}; | 11 | use core::task::Poll; |
| 11 | 12 | use embassy::traits::uart::{Error, Read, Write}; | |
| 12 | use embassy::interrupt::InterruptExt; | 13 | use embassy::util::{wake_on_interrupt, OnDrop, PeripheralBorrow, Signal}; |
| 13 | use embassy::util::Signal; | 14 | use embassy_extras::unborrow; |
| 15 | use futures::future::poll_fn; | ||
| 14 | 16 | ||
| 15 | use crate::fmt::{assert, *}; | 17 | use crate::fmt::{assert, *}; |
| 18 | use crate::gpio::Pin as GpioPin; | ||
| 16 | use crate::hal::pac; | 19 | use crate::hal::pac; |
| 17 | use crate::hal::prelude::*; | ||
| 18 | use crate::hal::target_constants::EASY_DMA_SIZE; | 20 | use crate::hal::target_constants::EASY_DMA_SIZE; |
| 19 | use crate::interrupt; | 21 | use crate::interrupt; |
| 20 | use crate::interrupt::Interrupt; | 22 | use crate::interrupt::Interrupt; |
| 23 | use crate::peripherals; | ||
| 21 | 24 | ||
| 22 | pub use crate::hal::uarte::Pins; | ||
| 23 | // Re-export SVD variants to allow user to directly set values. | 25 | // Re-export SVD variants to allow user to directly set values. |
| 24 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 26 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; |
| 25 | 27 | ||
| 26 | /// Interface to the UARTE peripheral | 28 | #[non_exhaustive] |
| 27 | pub struct Uarte<T> | 29 | pub struct Config { |
| 28 | where | 30 | pub parity: Parity, |
| 29 | T: Instance, | 31 | pub baudrate: Baudrate, |
| 30 | { | ||
| 31 | instance: T, | ||
| 32 | irq: T::Interrupt, | ||
| 33 | pins: Pins, | ||
| 34 | } | 32 | } |
| 35 | 33 | ||
| 36 | pub struct State { | 34 | impl Default for Config { |
| 37 | tx_done: Signal<()>, | 35 | fn default() -> Self { |
| 38 | rx_done: Signal<u32>, | 36 | Self { |
| 37 | parity: Parity::EXCLUDED, | ||
| 38 | baudrate: Baudrate::BAUD115200, | ||
| 39 | } | ||
| 40 | } | ||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | impl<T> Uarte<T> | 43 | /// Interface to the UARTE peripheral |
| 42 | where | 44 | pub struct Uarte<'d, T: Instance> { |
| 43 | T: Instance, | 45 | peri: T, |
| 44 | { | 46 | irq: T::Interrupt, |
| 47 | phantom: PhantomData<&'d mut T>, | ||
| 48 | } | ||
| 49 | |||
| 50 | impl<'d, T: Instance> Uarte<'d, T> { | ||
| 45 | /// Creates the interface to a UARTE instance. | 51 | /// Creates the interface to a UARTE instance. |
| 46 | /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. | 52 | /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. |
| 47 | /// | 53 | /// |
| @@ -52,85 +58,48 @@ where | |||
| 52 | /// or [`receive`](Uarte::receive). | 58 | /// or [`receive`](Uarte::receive). |
| 53 | #[allow(unused_unsafe)] | 59 | #[allow(unused_unsafe)] |
| 54 | pub unsafe fn new( | 60 | pub unsafe fn new( |
| 55 | uarte: T, | 61 | uarte: impl PeripheralBorrow<Target = T> + 'd, |
| 56 | irq: T::Interrupt, | 62 | irq: impl PeripheralBorrow<Target = T::Interrupt> + 'd, |
| 57 | mut pins: Pins, | 63 | rxd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, |
| 58 | parity: Parity, | 64 | txd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, |
| 59 | baudrate: Baudrate, | 65 | cts: impl PeripheralBorrow<Target = impl GpioPin> + 'd, |
| 66 | rts: impl PeripheralBorrow<Target = impl GpioPin> + 'd, | ||
| 67 | config: Config, | ||
| 60 | ) -> Self { | 68 | ) -> Self { |
| 61 | assert!(uarte.enable.read().enable().is_disabled()); | 69 | unborrow!(uarte, irq, rxd, txd, cts, rts); |
| 62 | |||
| 63 | uarte.psel.rxd.write(|w| { | ||
| 64 | unsafe { w.bits(pins.rxd.psel_bits()) }; | ||
| 65 | w.connect().connected() | ||
| 66 | }); | ||
| 67 | |||
| 68 | pins.txd.set_high().unwrap(); | ||
| 69 | uarte.psel.txd.write(|w| { | ||
| 70 | unsafe { w.bits(pins.txd.psel_bits()) }; | ||
| 71 | w.connect().connected() | ||
| 72 | }); | ||
| 73 | |||
| 74 | // Optional pins | ||
| 75 | uarte.psel.cts.write(|w| { | ||
| 76 | if let Some(ref pin) = pins.cts { | ||
| 77 | unsafe { w.bits(pin.psel_bits()) }; | ||
| 78 | w.connect().connected() | ||
| 79 | } else { | ||
| 80 | w.connect().disconnected() | ||
| 81 | } | ||
| 82 | }); | ||
| 83 | |||
| 84 | uarte.psel.rts.write(|w| { | ||
| 85 | if let Some(ref pin) = pins.rts { | ||
| 86 | unsafe { w.bits(pin.psel_bits()) }; | ||
| 87 | w.connect().connected() | ||
| 88 | } else { | ||
| 89 | w.connect().disconnected() | ||
| 90 | } | ||
| 91 | }); | ||
| 92 | 70 | ||
| 93 | uarte.baudrate.write(|w| w.baudrate().variant(baudrate)); | 71 | let r = uarte.regs(); |
| 94 | uarte.config.write(|w| w.parity().variant(parity)); | ||
| 95 | 72 | ||
| 96 | // Enable interrupts | 73 | assert!(r.enable.read().enable().is_disabled()); |
| 97 | uarte.events_endtx.reset(); | ||
| 98 | uarte.events_endrx.reset(); | ||
| 99 | uarte | ||
| 100 | .intenset | ||
| 101 | .write(|w| w.endtx().set().txstopped().set().endrx().set().rxto().set()); | ||
| 102 | 74 | ||
| 103 | // Register ISR | 75 | // TODO OptionalPin for RTS/CTS. |
| 104 | irq.set_handler(Self::on_irq); | ||
| 105 | irq.unpend(); | ||
| 106 | irq.enable(); | ||
| 107 | 76 | ||
| 108 | Uarte { | 77 | txd.set_high(); |
| 109 | instance: uarte, | 78 | rts.set_high(); |
| 110 | irq, | 79 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); |
| 111 | pins, | 80 | txd.conf().write(|w| w.dir().output().drive().h0h1()); |
| 112 | } | 81 | //cts.conf().write(|w| w.input().connect().drive().h0h1()); |
| 113 | } | 82 | //rts.conf().write(|w| w.dir().output().drive().h0h1()); |
| 114 | 83 | ||
| 115 | pub fn free(self) -> (T, T::Interrupt, Pins) { | 84 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); |
| 116 | // Wait for the peripheral to be disabled from the ISR. | 85 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); |
| 117 | while self.instance.enable.read().enable().is_enabled() {} | 86 | //r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); |
| 118 | (self.instance, self.irq, self.pins) | 87 | //r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); |
| 119 | } | ||
| 120 | 88 | ||
| 121 | fn enable(&mut self) { | 89 | r.baudrate.write(|w| w.baudrate().variant(config.baudrate)); |
| 122 | trace!("enable"); | 90 | r.config.write(|w| w.parity().variant(config.parity)); |
| 123 | self.instance.enable.write(|w| w.enable().enabled()); | ||
| 124 | } | ||
| 125 | 91 | ||
| 126 | fn tx_started(&self) -> bool { | 92 | // Enable |
| 127 | self.instance.events_txstarted.read().bits() != 0 | 93 | r.enable.write(|w| w.enable().enabled()); |
| 128 | } | ||
| 129 | 94 | ||
| 130 | fn rx_started(&self) -> bool { | 95 | Self { |
| 131 | self.instance.events_rxstarted.read().bits() != 0 | 96 | peri: uarte, |
| 97 | irq, | ||
| 98 | phantom: PhantomData, | ||
| 99 | } | ||
| 132 | } | 100 | } |
| 133 | 101 | ||
| 102 | /* | ||
| 134 | unsafe fn on_irq(_ctx: *mut ()) { | 103 | unsafe fn on_irq(_ctx: *mut ()) { |
| 135 | let uarte = &*pac::UARTE0::ptr(); | 104 | let uarte = &*pac::UARTE0::ptr(); |
| 136 | 105 | ||
| @@ -186,54 +155,127 @@ where | |||
| 186 | uarte.enable.write(|w| w.enable().disabled()); | 155 | uarte.enable.write(|w| w.enable().disabled()); |
| 187 | } | 156 | } |
| 188 | } | 157 | } |
| 158 | */ | ||
| 189 | } | 159 | } |
| 190 | 160 | ||
| 191 | impl<T: Instance> embassy::traits::uart::Uart for Uarte<T> { | 161 | impl<'d, T: Instance> Read for Uarte<'d, T> { |
| 192 | type ReceiveFuture<'a> = ReceiveFuture<'a, T>; | 162 | #[rustfmt::skip] |
| 193 | type SendFuture<'a> = SendFuture<'a, T>; | 163 | type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; |
| 194 | 164 | ||
| 195 | /// Sends serial data. | 165 | fn read<'a>(self: Pin<&'a mut Self>, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 196 | /// | 166 | async move { |
| 197 | /// `tx_buffer` is marked as static as per `embedded-dma` requirements. | 167 | let this = unsafe { self.get_unchecked_mut() }; |
| 198 | /// It it safe to use a buffer with a non static lifetime if memory is not | 168 | |
| 199 | /// reused until the future has finished. | 169 | let ptr = rx_buffer.as_ptr(); |
| 200 | fn send<'a>(&'a mut self, tx_buffer: &'a [u8]) -> SendFuture<'a, T> { | 170 | let len = rx_buffer.len(); |
| 201 | // Panic if TX is running which can happen if the user has called | 171 | assert!(len <= EASY_DMA_SIZE); |
| 202 | // `mem::forget()` on a previous future after polling it once. | 172 | |
| 203 | assert!(!self.tx_started()); | 173 | let r = this.peri.regs(); |
| 204 | 174 | ||
| 205 | T::state().tx_done.reset(); | 175 | let drop = OnDrop::new(move || { |
| 206 | 176 | info!("read drop: stopping"); | |
| 207 | SendFuture { | 177 | |
| 208 | uarte: self, | 178 | r.intenclr.write(|w| w.endrx().clear()); |
| 209 | buf: tx_buffer, | 179 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); |
| 180 | |||
| 181 | // TX is stopped almost instantly, spinning is fine. | ||
| 182 | while r.events_endrx.read().bits() == 0 {} | ||
| 183 | info!("read drop: stopped"); | ||
| 184 | }); | ||
| 185 | |||
| 186 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | ||
| 187 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | ||
| 188 | |||
| 189 | r.events_endrx.reset(); | ||
| 190 | r.intenset.write(|w| w.endrx().set()); | ||
| 191 | |||
| 192 | compiler_fence(Ordering::SeqCst); | ||
| 193 | |||
| 194 | trace!("startrx"); | ||
| 195 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | ||
| 196 | |||
| 197 | let irq = &mut this.irq; | ||
| 198 | poll_fn(|cx| { | ||
| 199 | if r.events_endrx.read().bits() != 0 { | ||
| 200 | r.events_endrx.reset(); | ||
| 201 | return Poll::Ready(()); | ||
| 202 | } | ||
| 203 | |||
| 204 | wake_on_interrupt(irq, cx.waker()); | ||
| 205 | |||
| 206 | Poll::Pending | ||
| 207 | }) | ||
| 208 | .await; | ||
| 209 | |||
| 210 | compiler_fence(Ordering::SeqCst); | ||
| 211 | r.intenclr.write(|w| w.endrx().clear()); | ||
| 212 | drop.defuse(); | ||
| 213 | |||
| 214 | Ok(()) | ||
| 210 | } | 215 | } |
| 211 | } | 216 | } |
| 217 | } | ||
| 212 | 218 | ||
| 213 | /// Receives serial data. | 219 | impl<'d, T: Instance> Write for Uarte<'d, T> { |
| 214 | /// | 220 | #[rustfmt::skip] |
| 215 | /// The future is pending until the buffer is completely filled. | 221 | type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; |
| 216 | /// A common pattern is to use [`stop()`](ReceiveFuture::stop) to cancel | 222 | |
| 217 | /// unfinished transfers after a timeout to prevent lockup when no more data | 223 | fn write<'a>(self: Pin<&'a mut Self>, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { |
| 218 | /// is incoming. | 224 | async move { |
| 219 | /// | 225 | let this = unsafe { self.get_unchecked_mut() }; |
| 220 | /// `rx_buffer` is marked as static as per `embedded-dma` requirements. | 226 | |
| 221 | /// It it safe to use a buffer with a non static lifetime if memory is not | 227 | let ptr = tx_buffer.as_ptr(); |
| 222 | /// reused until the future has finished. | 228 | let len = tx_buffer.len(); |
| 223 | fn receive<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> ReceiveFuture<'a, T> { | 229 | assert!(len <= EASY_DMA_SIZE); |
| 224 | // Panic if RX is running which can happen if the user has called | 230 | // TODO: panic if buffer is not in SRAM |
| 225 | // `mem::forget()` on a previous future after polling it once. | 231 | |
| 226 | assert!(!self.rx_started()); | 232 | let r = this.peri.regs(); |
| 227 | 233 | ||
| 228 | T::state().rx_done.reset(); | 234 | let drop = OnDrop::new(move || { |
| 229 | 235 | info!("write drop: stopping"); | |
| 230 | ReceiveFuture { | 236 | |
| 231 | uarte: self, | 237 | r.intenclr.write(|w| w.endtx().clear()); |
| 232 | buf: rx_buffer, | 238 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); |
| 239 | |||
| 240 | // TX is stopped almost instantly, spinning is fine. | ||
| 241 | while r.events_endtx.read().bits() == 0 {} | ||
| 242 | info!("write drop: stopped"); | ||
| 243 | }); | ||
| 244 | |||
| 245 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | ||
| 246 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | ||
| 247 | |||
| 248 | r.events_endtx.reset(); | ||
| 249 | r.intenset.write(|w| w.endtx().set()); | ||
| 250 | |||
| 251 | compiler_fence(Ordering::SeqCst); | ||
| 252 | |||
| 253 | trace!("starttx"); | ||
| 254 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | ||
| 255 | |||
| 256 | let irq = &mut this.irq; | ||
| 257 | poll_fn(|cx| { | ||
| 258 | if r.events_endtx.read().bits() != 0 { | ||
| 259 | r.events_endtx.reset(); | ||
| 260 | return Poll::Ready(()); | ||
| 261 | } | ||
| 262 | |||
| 263 | wake_on_interrupt(irq, cx.waker()); | ||
| 264 | |||
| 265 | Poll::Pending | ||
| 266 | }) | ||
| 267 | .await; | ||
| 268 | |||
| 269 | compiler_fence(Ordering::SeqCst); | ||
| 270 | r.intenclr.write(|w| w.endtx().clear()); | ||
| 271 | drop.defuse(); | ||
| 272 | |||
| 273 | Ok(()) | ||
| 233 | } | 274 | } |
| 234 | } | 275 | } |
| 235 | } | 276 | } |
| 236 | 277 | ||
| 278 | /* | ||
| 237 | /// Future for the [`Uarte::send()`] method. | 279 | /// Future for the [`Uarte::send()`] method. |
| 238 | pub struct SendFuture<'a, T> | 280 | pub struct SendFuture<'a, T> |
| 239 | where | 281 | where |
| @@ -252,11 +294,8 @@ where | |||
| 252 | trace!("stoptx"); | 294 | trace!("stoptx"); |
| 253 | 295 | ||
| 254 | // Stop the transmitter to minimize the current consumption. | 296 | // Stop the transmitter to minimize the current consumption. |
| 255 | self.uarte.instance.events_txstarted.reset(); | 297 | self.uarte.peri.events_txstarted.reset(); |
| 256 | self.uarte | 298 | self.uarte.peri.tasks_stoptx.write(|w| unsafe { w.bits(1) }); |
| 257 | .instance | ||
| 258 | .tasks_stoptx | ||
| 259 | .write(|w| unsafe { w.bits(1) }); | ||
| 260 | 299 | ||
| 261 | // TX is stopped almost instantly, spinning is fine. | 300 | // TX is stopped almost instantly, spinning is fine. |
| 262 | while !T::state().tx_done.signaled() {} | 301 | while !T::state().tx_done.signaled() {} |
| @@ -264,46 +303,6 @@ where | |||
| 264 | } | 303 | } |
| 265 | } | 304 | } |
| 266 | 305 | ||
| 267 | impl<'a, T> Future for SendFuture<'a, T> | ||
| 268 | where | ||
| 269 | T: Instance, | ||
| 270 | { | ||
| 271 | type Output = Result<(), embassy::traits::uart::Error>; | ||
| 272 | |||
| 273 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
| 274 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; | ||
| 275 | |||
| 276 | if T::state().tx_done.poll_wait(cx).is_pending() { | ||
| 277 | let ptr = buf.as_ptr(); | ||
| 278 | let len = buf.len(); | ||
| 279 | assert!(len <= EASY_DMA_SIZE); | ||
| 280 | // TODO: panic if buffer is not in SRAM | ||
| 281 | |||
| 282 | uarte.enable(); | ||
| 283 | |||
| 284 | compiler_fence(Ordering::SeqCst); | ||
| 285 | uarte | ||
| 286 | .instance | ||
| 287 | .txd | ||
| 288 | .ptr | ||
| 289 | .write(|w| unsafe { w.ptr().bits(ptr as u32) }); | ||
| 290 | uarte | ||
| 291 | .instance | ||
| 292 | .txd | ||
| 293 | .maxcnt | ||
| 294 | .write(|w| unsafe { w.maxcnt().bits(len as _) }); | ||
| 295 | |||
| 296 | trace!("starttx"); | ||
| 297 | uarte.instance.tasks_starttx.write(|w| unsafe { w.bits(1) }); | ||
| 298 | while !uarte.tx_started() {} // Make sure transmission has started | ||
| 299 | |||
| 300 | Poll::Pending | ||
| 301 | } else { | ||
| 302 | Poll::Ready(Ok(())) | ||
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | /// Future for the [`Uarte::receive()`] method. | 306 | /// Future for the [`Uarte::receive()`] method. |
| 308 | pub struct ReceiveFuture<'a, T> | 307 | pub struct ReceiveFuture<'a, T> |
| 309 | where | 308 | where |
| @@ -321,11 +320,8 @@ where | |||
| 321 | if self.uarte.rx_started() { | 320 | if self.uarte.rx_started() { |
| 322 | trace!("stoprx (drop)"); | 321 | trace!("stoprx (drop)"); |
| 323 | 322 | ||
| 324 | self.uarte.instance.events_rxstarted.reset(); | 323 | self.uarte.peri.events_rxstarted.reset(); |
| 325 | self.uarte | 324 | self.uarte.peri.tasks_stoprx.write(|w| unsafe { w.bits(1) }); |
| 326 | .instance | ||
| 327 | .tasks_stoprx | ||
| 328 | .write(|w| unsafe { w.bits(1) }); | ||
| 329 | 325 | ||
| 330 | embassy_extras::low_power_wait_until(|| T::state().rx_done.signaled()) | 326 | embassy_extras::low_power_wait_until(|| T::state().rx_done.signaled()) |
| 331 | } | 327 | } |
| @@ -350,19 +346,11 @@ where | |||
| 350 | uarte.enable(); | 346 | uarte.enable(); |
| 351 | 347 | ||
| 352 | compiler_fence(Ordering::SeqCst); | 348 | compiler_fence(Ordering::SeqCst); |
| 353 | uarte | 349 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 354 | .instance | 350 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 355 | .rxd | ||
| 356 | .ptr | ||
| 357 | .write(|w| unsafe { w.ptr().bits(ptr as u32) }); | ||
| 358 | uarte | ||
| 359 | .instance | ||
| 360 | .rxd | ||
| 361 | .maxcnt | ||
| 362 | .write(|w| unsafe { w.maxcnt().bits(len as _) }); | ||
| 363 | 351 | ||
| 364 | trace!("startrx"); | 352 | trace!("startrx"); |
| 365 | uarte.instance.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 353 | uarte.peri.tasks_startrx.write(|w| unsafe { w.bits(1) }); |
| 366 | while !uarte.rx_started() {} // Make sure reception has started | 354 | while !uarte.rx_started() {} // Make sure reception has started |
| 367 | 355 | ||
| 368 | Poll::Pending | 356 | Poll::Pending |
| @@ -383,11 +371,8 @@ where | |||
| 383 | let len = if self.uarte.rx_started() { | 371 | let len = if self.uarte.rx_started() { |
| 384 | trace!("stoprx (stop)"); | 372 | trace!("stoprx (stop)"); |
| 385 | 373 | ||
| 386 | self.uarte.instance.events_rxstarted.reset(); | 374 | self.uarte.peri.events_rxstarted.reset(); |
| 387 | self.uarte | 375 | self.uarte.peri.tasks_stoprx.write(|w| unsafe { w.bits(1) }); |
| 388 | .instance | ||
| 389 | .tasks_stoprx | ||
| 390 | .write(|w| unsafe { w.bits(1) }); | ||
| 391 | T::state().rx_done.wait().await | 376 | T::state().rx_done.wait().await |
| 392 | } else { | 377 | } else { |
| 393 | // Transfer was stopped before it even started. No bytes were sent. | 378 | // Transfer was stopped before it even started. No bytes were sent. |
| @@ -396,45 +381,33 @@ where | |||
| 396 | len as _ | 381 | len as _ |
| 397 | } | 382 | } |
| 398 | } | 383 | } |
| 384 | */ | ||
| 385 | |||
| 386 | mod sealed { | ||
| 387 | use super::*; | ||
| 399 | 388 | ||
| 400 | mod private { | 389 | pub trait Instance { |
| 401 | pub trait Sealed {} | 390 | fn regs(&self) -> &pac::uarte0::RegisterBlock; |
| 391 | } | ||
| 402 | } | 392 | } |
| 403 | 393 | ||
| 404 | pub trait Instance: | 394 | pub trait Instance: sealed::Instance + 'static { |
| 405 | Deref<Target = pac::uarte0::RegisterBlock> + Sized + private::Sealed + 'static | ||
| 406 | { | ||
| 407 | type Interrupt: Interrupt; | 395 | type Interrupt: Interrupt; |
| 408 | |||
| 409 | #[doc(hidden)] | ||
| 410 | fn state() -> &'static State; | ||
| 411 | } | 396 | } |
| 412 | 397 | ||
| 413 | static UARTE0_STATE: State = State { | 398 | macro_rules! make_impl { |
| 414 | tx_done: Signal::new(), | 399 | ($type:ident, $irq:ident) => { |
| 415 | rx_done: Signal::new(), | 400 | impl sealed::Instance for peripherals::$type { |
| 416 | }; | 401 | fn regs(&self) -> &pac::uarte0::RegisterBlock { |
| 417 | impl private::Sealed for pac::UARTE0 {} | 402 | unsafe { &*pac::$type::ptr() } |
| 418 | impl Instance for pac::UARTE0 { | 403 | } |
| 419 | type Interrupt = interrupt::UARTE0_UART0; | 404 | } |
| 420 | 405 | impl Instance for peripherals::$type { | |
| 421 | fn state() -> &'static State { | 406 | type Interrupt = interrupt::$irq; |
| 422 | &UARTE0_STATE | 407 | } |
| 423 | } | 408 | }; |
| 424 | } | 409 | } |
| 425 | 410 | ||
| 411 | make_impl!(UARTE0, UARTE0_UART0); | ||
| 426 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] | 412 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] |
| 427 | static UARTE1_STATE: State = State { | 413 | make_impl!(UARTE1, UARTE1); |
| 428 | tx_done: Signal::new(), | ||
| 429 | rx_done: Signal::new(), | ||
| 430 | }; | ||
| 431 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] | ||
| 432 | impl private::Sealed for pac::UARTE1 {} | ||
| 433 | #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))] | ||
| 434 | impl Instance for pac::UARTE1 { | ||
| 435 | type Interrupt = interrupt::UARTE1; | ||
| 436 | |||
| 437 | fn state() -> &'static State { | ||
| 438 | &UARTE1_STATE | ||
| 439 | } | ||
| 440 | } | ||
