diff options
| -rw-r--r-- | embassy-nrf-examples/src/bin/uart.rs | 5 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 101 | ||||
| -rw-r--r-- | embassy/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy/src/uart.rs | 15 |
4 files changed, 73 insertions, 49 deletions
diff --git a/embassy-nrf-examples/src/bin/uart.rs b/embassy-nrf-examples/src/bin/uart.rs index e8230c81a..cb38e8fcb 100644 --- a/embassy-nrf-examples/src/bin/uart.rs +++ b/embassy-nrf-examples/src/bin/uart.rs | |||
| @@ -10,6 +10,7 @@ use cortex_m_rt::entry; | |||
| 10 | use defmt::panic; | 10 | use defmt::panic; |
| 11 | use embassy::executor::{task, Executor}; | 11 | use embassy::executor::{task, Executor}; |
| 12 | use embassy::time::{Duration, Timer}; | 12 | use embassy::time::{Duration, Timer}; |
| 13 | use embassy::uart::Uart; | ||
| 13 | use embassy::util::Forever; | 14 | use embassy::util::Forever; |
| 14 | use embassy_nrf::{interrupt, pac, rtc, uarte}; | 15 | use embassy_nrf::{interrupt, pac, rtc, uarte}; |
| 15 | use futures::future::{select, Either}; | 16 | use futures::future::{select, Either}; |
| @@ -24,7 +25,7 @@ async fn run(mut uart: uarte::Uarte<pac::UARTE0>) { | |||
| 24 | let mut buf = [0; 8]; | 25 | let mut buf = [0; 8]; |
| 25 | buf.copy_from_slice(b"Hello!\r\n"); | 26 | buf.copy_from_slice(b"Hello!\r\n"); |
| 26 | 27 | ||
| 27 | uart.send(&buf).await; | 28 | unwrap!(uart.send(&buf).await); |
| 28 | info!("wrote hello in uart!"); | 29 | info!("wrote hello in uart!"); |
| 29 | 30 | ||
| 30 | loop { | 31 | loop { |
| @@ -54,7 +55,7 @@ async fn run(mut uart: uarte::Uarte<pac::UARTE0>) { | |||
| 54 | info!("read done, got {:[u8]}", received); | 55 | info!("read done, got {:[u8]}", received); |
| 55 | 56 | ||
| 56 | // Echo back received data | 57 | // Echo back received data |
| 57 | uart.send(received).await; | 58 | unwrap!(uart.send(received).await); |
| 58 | } | 59 | } |
| 59 | } | 60 | } |
| 60 | } | 61 | } |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 3983c96b4..648298b84 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -139,51 +139,10 @@ where | |||
| 139 | self.instance.enable.write(|w| w.enable().enabled()); | 139 | self.instance.enable.write(|w| w.enable().enabled()); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | /// Sends serial data. | ||
| 143 | /// | ||
| 144 | /// `tx_buffer` is marked as static as per `embedded-dma` requirements. | ||
| 145 | /// It it safe to use a buffer with a non static lifetime if memory is not | ||
| 146 | /// reused until the future has finished. | ||
| 147 | pub fn send<'a>(&'a mut self, tx_buffer: &'a [u8]) -> SendFuture<'a, T> { | ||
| 148 | // Panic if TX is running which can happen if the user has called | ||
| 149 | // `mem::forget()` on a previous future after polling it once. | ||
| 150 | assert!(!self.tx_started()); | ||
| 151 | |||
| 152 | self.enable(); | ||
| 153 | |||
| 154 | SendFuture { | ||
| 155 | uarte: self, | ||
| 156 | buf: tx_buffer, | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | fn tx_started(&self) -> bool { | 142 | fn tx_started(&self) -> bool { |
| 161 | self.instance.events_txstarted.read().bits() != 0 | 143 | self.instance.events_txstarted.read().bits() != 0 |
| 162 | } | 144 | } |
| 163 | 145 | ||
| 164 | /// Receives serial data. | ||
| 165 | /// | ||
| 166 | /// The future is pending until the buffer is completely filled. | ||
| 167 | /// A common pattern is to use [`stop()`](ReceiveFuture::stop) to cancel | ||
| 168 | /// unfinished transfers after a timeout to prevent lockup when no more data | ||
| 169 | /// is incoming. | ||
| 170 | /// | ||
| 171 | /// `rx_buffer` is marked as static as per `embedded-dma` requirements. | ||
| 172 | /// It it safe to use a buffer with a non static lifetime if memory is not | ||
| 173 | /// reused until the future has finished. | ||
| 174 | pub fn receive<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> ReceiveFuture<'a, T> { | ||
| 175 | // Panic if RX is running which can happen if the user has called | ||
| 176 | // `mem::forget()` on a previous future after polling it once. | ||
| 177 | assert!(!self.rx_started()); | ||
| 178 | |||
| 179 | self.enable(); | ||
| 180 | |||
| 181 | ReceiveFuture { | ||
| 182 | uarte: self, | ||
| 183 | buf: rx_buffer, | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | fn rx_started(&self) -> bool { | 146 | fn rx_started(&self) -> bool { |
| 188 | self.instance.events_rxstarted.read().bits() != 0 | 147 | self.instance.events_rxstarted.read().bits() != 0 |
| 189 | } | 148 | } |
| @@ -231,6 +190,52 @@ where | |||
| 231 | } | 190 | } |
| 232 | } | 191 | } |
| 233 | 192 | ||
| 193 | impl<T: Instance> embassy::uart::Uart for Uarte<T> { | ||
| 194 | type ReceiveFuture<'a> = ReceiveFuture<'a, T>; | ||
| 195 | type SendFuture<'a> = SendFuture<'a, T>; | ||
| 196 | |||
| 197 | /// Sends serial data. | ||
| 198 | /// | ||
| 199 | /// `tx_buffer` is marked as static as per `embedded-dma` requirements. | ||
| 200 | /// It it safe to use a buffer with a non static lifetime if memory is not | ||
| 201 | /// reused until the future has finished. | ||
| 202 | fn send<'a>(&'a mut self, tx_buffer: &'a [u8]) -> SendFuture<'a, T> { | ||
| 203 | // Panic if TX is running which can happen if the user has called | ||
| 204 | // `mem::forget()` on a previous future after polling it once. | ||
| 205 | assert!(!self.tx_started()); | ||
| 206 | |||
| 207 | self.enable(); | ||
| 208 | |||
| 209 | SendFuture { | ||
| 210 | uarte: self, | ||
| 211 | buf: tx_buffer, | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | /// Receives serial data. | ||
| 216 | /// | ||
| 217 | /// The future is pending until the buffer is completely filled. | ||
| 218 | /// A common pattern is to use [`stop()`](ReceiveFuture::stop) to cancel | ||
| 219 | /// unfinished transfers after a timeout to prevent lockup when no more data | ||
| 220 | /// is incoming. | ||
| 221 | /// | ||
| 222 | /// `rx_buffer` is marked as static as per `embedded-dma` requirements. | ||
| 223 | /// It it safe to use a buffer with a non static lifetime if memory is not | ||
| 224 | /// reused until the future has finished. | ||
| 225 | fn receive<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> ReceiveFuture<'a, T> { | ||
| 226 | // Panic if RX is running which can happen if the user has called | ||
| 227 | // `mem::forget()` on a previous future after polling it once. | ||
| 228 | assert!(!self.rx_started()); | ||
| 229 | |||
| 230 | self.enable(); | ||
| 231 | |||
| 232 | ReceiveFuture { | ||
| 233 | uarte: self, | ||
| 234 | buf: rx_buffer, | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 234 | /// Future for the [`Uarte::send()`] method. | 239 | /// Future for the [`Uarte::send()`] method. |
| 235 | pub struct SendFuture<'a, T> | 240 | pub struct SendFuture<'a, T> |
| 236 | where | 241 | where |
| @@ -263,9 +268,9 @@ impl<'a, T> Future for SendFuture<'a, T> | |||
| 263 | where | 268 | where |
| 264 | T: Instance, | 269 | T: Instance, |
| 265 | { | 270 | { |
| 266 | type Output = (); | 271 | type Output = Result<(), embassy::uart::Error>; |
| 267 | 272 | ||
| 268 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { | 273 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 269 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; | 274 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; |
| 270 | 275 | ||
| 271 | if !uarte.tx_started() { | 276 | if !uarte.tx_started() { |
| @@ -289,7 +294,7 @@ where | |||
| 289 | uarte.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 294 | uarte.tasks_starttx.write(|w| unsafe { w.bits(1) }); |
| 290 | } | 295 | } |
| 291 | 296 | ||
| 292 | T::state().tx_done.poll_wait(cx) | 297 | T::state().tx_done.poll_wait(cx).map(|()| Ok(())) |
| 293 | } | 298 | } |
| 294 | } | 299 | } |
| 295 | 300 | ||
| @@ -324,7 +329,7 @@ impl<'a, T> Future for ReceiveFuture<'a, T> | |||
| 324 | where | 329 | where |
| 325 | T: Instance, | 330 | T: Instance, |
| 326 | { | 331 | { |
| 327 | type Output = (); | 332 | type Output = Result<(), embassy::uart::Error>; |
| 328 | 333 | ||
| 329 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | 334 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 330 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; | 335 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; |
| @@ -349,7 +354,7 @@ where | |||
| 349 | uarte.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 354 | uarte.tasks_startrx.write(|w| unsafe { w.bits(1) }); |
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | T::state().rx_done.poll_wait(cx).map(|_| ()) | 357 | T::state().rx_done.poll_wait(cx).map(|_| Ok(())) |
| 353 | } | 358 | } |
| 354 | } | 359 | } |
| 355 | 360 | ||
| @@ -370,7 +375,9 @@ mod private { | |||
| 370 | pub trait Sealed {} | 375 | pub trait Sealed {} |
| 371 | } | 376 | } |
| 372 | 377 | ||
| 373 | pub trait Instance: Deref<Target = pac::uarte0::RegisterBlock> + Sized + private::Sealed { | 378 | pub trait Instance: |
| 379 | Deref<Target = pac::uarte0::RegisterBlock> + Sized + private::Sealed + 'static | ||
| 380 | { | ||
| 374 | type Interrupt: OwnedInterrupt; | 381 | type Interrupt: OwnedInterrupt; |
| 375 | 382 | ||
| 376 | #[doc(hidden)] | 383 | #[doc(hidden)] |
diff --git a/embassy/src/lib.rs b/embassy/src/lib.rs index 8f93535e3..02d72a84f 100644 --- a/embassy/src/lib.rs +++ b/embassy/src/lib.rs | |||
| @@ -12,4 +12,5 @@ pub mod interrupt; | |||
| 12 | pub mod io; | 12 | pub mod io; |
| 13 | pub mod rand; | 13 | pub mod rand; |
| 14 | pub mod time; | 14 | pub mod time; |
| 15 | pub mod uart; | ||
| 15 | pub mod util; | 16 | pub mod util; |
diff --git a/embassy/src/uart.rs b/embassy/src/uart.rs new file mode 100644 index 000000000..b40b9e9bd --- /dev/null +++ b/embassy/src/uart.rs | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | |||
| 3 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
| 4 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 5 | #[non_exhaustive] | ||
| 6 | pub enum Error { | ||
| 7 | Other, | ||
| 8 | } | ||
| 9 | |||
| 10 | pub trait Uart { | ||
| 11 | type ReceiveFuture<'a>: Future<Output = Result<(), Error>>; | ||
| 12 | type SendFuture<'a>: Future<Output = Result<(), Error>>; | ||
| 13 | fn receive<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReceiveFuture<'a>; | ||
| 14 | fn send<'a>(&'a mut self, buf: &'a [u8]) -> Self::SendFuture<'a>; | ||
| 15 | } | ||
