aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/uarte.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-02-01 00:48:33 +0100
committerDario Nieuwenhuis <[email protected]>2023-02-01 01:17:41 +0100
commitb5cf332cc076a0de11ce6a0563a2235c9e57eb5c (patch)
treece14e014dfbe8c3764040d7f9f1ffee84ab5747b /embassy-nrf/src/uarte.rs
parentca10fe7135d10084e38038f3cd433da39e505bea (diff)
nrf: docs.
Diffstat (limited to 'embassy-nrf/src/uarte.rs')
-rw-r--r--embassy-nrf/src/uarte.rs76
1 files changed, 52 insertions, 24 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 031cf82fd..48457744b 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -1,8 +1,6 @@
1#![macro_use] 1//! Universal Asynchronous Receiver Transmitter (UART) driver.
2
3//! Async UART
4//! 2//!
5//! Async UART is provided in two flavors - this one and also [crate::buffered_uarte::BufferedUarte]. 3//! The UART driver is provided in two flavors - this one and also [crate::buffered_uarte::BufferedUarte].
6//! The [Uarte] here is useful for those use-cases where reading the UARTE peripheral is 4//! The [Uarte] here is useful for those use-cases where reading the UARTE peripheral is
7//! exclusively awaited on. If the [Uarte] is required to be awaited on with some other future, 5//! exclusively awaited on. If the [Uarte] is required to be awaited on with some other future,
8//! for example when using `futures_util::future::select`, then you should consider 6//! for example when using `futures_util::future::select`, then you should consider
@@ -13,6 +11,8 @@
13//! memory may be used given that buffers are passed in directly to its read and write 11//! memory may be used given that buffers are passed in directly to its read and write
14//! methods. 12//! methods.
15 13
14#![macro_use]
15
16use core::future::poll_fn; 16use core::future::poll_fn;
17use core::sync::atomic::{compiler_fence, Ordering}; 17use core::sync::atomic::{compiler_fence, Ordering};
18use core::task::Poll; 18use core::task::Poll;
@@ -32,10 +32,13 @@ use crate::timer::{Frequency, Instance as TimerInstance, Timer};
32use crate::util::slice_in_ram_or; 32use crate::util::slice_in_ram_or;
33use crate::{pac, Peripheral}; 33use crate::{pac, Peripheral};
34 34
35/// UARTE config.
35#[derive(Clone)] 36#[derive(Clone)]
36#[non_exhaustive] 37#[non_exhaustive]
37pub struct Config { 38pub struct Config {
39 /// Parity bit.
38 pub parity: Parity, 40 pub parity: Parity,
41 /// Baud rate.
39 pub baudrate: Baudrate, 42 pub baudrate: Baudrate,
40} 43}
41 44
@@ -48,31 +51,33 @@ impl Default for Config {
48 } 51 }
49} 52}
50 53
54/// UART error.
51#[derive(Debug, Clone, Copy, PartialEq, Eq)] 55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52#[cfg_attr(feature = "defmt", derive(defmt::Format))] 56#[cfg_attr(feature = "defmt", derive(defmt::Format))]
53#[non_exhaustive] 57#[non_exhaustive]
54pub enum Error { 58pub enum Error {
59 /// Buffer was too long.
55 BufferTooLong, 60 BufferTooLong,
56 DMABufferNotInDataMemory, 61 /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash.
57 // TODO: add other error variants. 62 BufferNotInRAM,
58} 63}
59 64
60/// Interface to the UARTE peripheral using EasyDMA to offload the transmission and reception workload. 65/// UARTE driver.
61///
62/// For more details about EasyDMA, consult the module documentation.
63pub struct Uarte<'d, T: Instance> { 66pub struct Uarte<'d, T: Instance> {
64 tx: UarteTx<'d, T>, 67 tx: UarteTx<'d, T>,
65 rx: UarteRx<'d, T>, 68 rx: UarteRx<'d, T>,
66} 69}
67 70
68/// Transmitter interface to the UARTE peripheral obtained 71/// Transmitter part of the UARTE driver.
69/// via [Uarte]::split. 72///
73/// This can be obtained via [`Uarte::split`], or created directly.
70pub struct UarteTx<'d, T: Instance> { 74pub struct UarteTx<'d, T: Instance> {
71 _p: PeripheralRef<'d, T>, 75 _p: PeripheralRef<'d, T>,
72} 76}
73 77
74/// Receiver interface to the UARTE peripheral obtained 78/// Receiver part of the UARTE driver.
75/// via [Uarte]::split. 79///
80/// This can be obtained via [`Uarte::split`], or created directly.
76pub struct UarteRx<'d, T: Instance> { 81pub struct UarteRx<'d, T: Instance> {
77 _p: PeripheralRef<'d, T>, 82 _p: PeripheralRef<'d, T>,
78} 83}
@@ -165,16 +170,16 @@ impl<'d, T: Instance> Uarte<'d, T> {
165 } 170 }
166 } 171 }
167 172
168 /// Split the Uarte into a transmitter and receiver, which is 173 /// Split the Uarte into the transmitter and receiver parts.
169 /// particularly useful when having two tasks correlating to 174 ///
170 /// transmitting and receiving. 175 /// This is useful to concurrently transmit and receive from independent tasks.
171 pub fn split(self) -> (UarteTx<'d, T>, UarteRx<'d, T>) { 176 pub fn split(self) -> (UarteTx<'d, T>, UarteRx<'d, T>) {
172 (self.tx, self.rx) 177 (self.tx, self.rx)
173 } 178 }
174 179
175 /// Split the Uarte into a transmitter and receiver that will 180 /// Split the Uarte into the transmitter and receiver with idle support parts.
176 /// return on idle, which is determined as the time it takes 181 ///
177 /// for two bytes to be received. 182 /// This is useful to concurrently transmit and receive from independent tasks.
178 pub fn split_with_idle<U: TimerInstance>( 183 pub fn split_with_idle<U: TimerInstance>(
179 self, 184 self,
180 timer: impl Peripheral<P = U> + 'd, 185 timer: impl Peripheral<P = U> + 'd,
@@ -247,10 +252,12 @@ impl<'d, T: Instance> Uarte<'d, T> {
247 } 252 }
248 } 253 }
249 254
255 /// Read bytes until the buffer is filled.
250 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 256 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
251 self.rx.read(buffer).await 257 self.rx.read(buffer).await
252 } 258 }
253 259
260 /// Write all bytes in the buffer.
254 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 261 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
255 self.tx.write(buffer).await 262 self.tx.write(buffer).await
256 } 263 }
@@ -260,10 +267,12 @@ impl<'d, T: Instance> Uarte<'d, T> {
260 self.tx.write_from_ram(buffer).await 267 self.tx.write_from_ram(buffer).await
261 } 268 }
262 269
270 /// Read bytes until the buffer is filled.
263 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 271 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
264 self.rx.blocking_read(buffer) 272 self.rx.blocking_read(buffer)
265 } 273 }
266 274
275 /// Write all bytes in the buffer.
267 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { 276 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
268 self.tx.blocking_write(buffer) 277 self.tx.blocking_write(buffer)
269 } 278 }
@@ -355,10 +364,11 @@ impl<'d, T: Instance> UarteTx<'d, T> {
355 Self { _p: uarte } 364 Self { _p: uarte }
356 } 365 }
357 366
367 /// Write all bytes in the buffer.
358 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 368 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
359 match self.write_from_ram(buffer).await { 369 match self.write_from_ram(buffer).await {
360 Ok(_) => Ok(()), 370 Ok(_) => Ok(()),
361 Err(Error::DMABufferNotInDataMemory) => { 371 Err(Error::BufferNotInRAM) => {
362 trace!("Copying UARTE tx buffer into RAM for DMA"); 372 trace!("Copying UARTE tx buffer into RAM for DMA");
363 let ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..buffer.len()]; 373 let ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..buffer.len()];
364 ram_buf.copy_from_slice(buffer); 374 ram_buf.copy_from_slice(buffer);
@@ -368,12 +378,13 @@ impl<'d, T: Instance> UarteTx<'d, T> {
368 } 378 }
369 } 379 }
370 380
381 /// Same as [`write`](Self::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
371 pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { 382 pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> {
372 if buffer.len() == 0 { 383 if buffer.len() == 0 {
373 return Ok(()); 384 return Ok(());
374 } 385 }
375 386
376 slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?; 387 slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
377 if buffer.len() > EASY_DMA_SIZE { 388 if buffer.len() > EASY_DMA_SIZE {
378 return Err(Error::BufferTooLong); 389 return Err(Error::BufferTooLong);
379 } 390 }
@@ -423,10 +434,11 @@ impl<'d, T: Instance> UarteTx<'d, T> {
423 Ok(()) 434 Ok(())
424 } 435 }
425 436
437 /// Write all bytes in the buffer.
426 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { 438 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
427 match self.blocking_write_from_ram(buffer) { 439 match self.blocking_write_from_ram(buffer) {
428 Ok(_) => Ok(()), 440 Ok(_) => Ok(()),
429 Err(Error::DMABufferNotInDataMemory) => { 441 Err(Error::BufferNotInRAM) => {
430 trace!("Copying UARTE tx buffer into RAM for DMA"); 442 trace!("Copying UARTE tx buffer into RAM for DMA");
431 let ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..buffer.len()]; 443 let ram_buf = &mut [0; FORCE_COPY_BUFFER_SIZE][..buffer.len()];
432 ram_buf.copy_from_slice(buffer); 444 ram_buf.copy_from_slice(buffer);
@@ -436,12 +448,13 @@ impl<'d, T: Instance> UarteTx<'d, T> {
436 } 448 }
437 } 449 }
438 450
451 /// Same as [`write_from_ram`](Self::write_from_ram) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
439 pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { 452 pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> {
440 if buffer.len() == 0 { 453 if buffer.len() == 0 {
441 return Ok(()); 454 return Ok(());
442 } 455 }
443 456
444 slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?; 457 slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
445 if buffer.len() > EASY_DMA_SIZE { 458 if buffer.len() > EASY_DMA_SIZE {
446 return Err(Error::BufferTooLong); 459 return Err(Error::BufferTooLong);
447 } 460 }
@@ -549,6 +562,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
549 Self { _p: uarte } 562 Self { _p: uarte }
550 } 563 }
551 564
565 /// Read bytes until the buffer is filled.
552 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 566 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
553 if buffer.len() == 0 { 567 if buffer.len() == 0 {
554 return Ok(()); 568 return Ok(());
@@ -602,6 +616,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
602 Ok(()) 616 Ok(())
603 } 617 }
604 618
619 /// Read bytes until the buffer is filled.
605 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 620 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
606 if buffer.len() == 0 { 621 if buffer.len() == 0 {
607 return Ok(()); 622 return Ok(());
@@ -653,6 +668,9 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> {
653 } 668 }
654} 669}
655 670
671/// Receiver part of the UARTE driver, with `read_until_idle` support.
672///
673/// This can be obtained via [`Uarte::split_with_idle`].
656pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> { 674pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> {
657 rx: UarteRx<'d, T>, 675 rx: UarteRx<'d, T>,
658 timer: Timer<'d, U>, 676 timer: Timer<'d, U>,
@@ -661,16 +679,21 @@ pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> {
661} 679}
662 680
663impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { 681impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
682 /// Read bytes until the buffer is filled.
664 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 683 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
665 self.ppi_ch1.disable(); 684 self.ppi_ch1.disable();
666 self.rx.read(buffer).await 685 self.rx.read(buffer).await
667 } 686 }
668 687
688 /// Read bytes until the buffer is filled.
669 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 689 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
670 self.ppi_ch1.disable(); 690 self.ppi_ch1.disable();
671 self.rx.blocking_read(buffer) 691 self.rx.blocking_read(buffer)
672 } 692 }
673 693
694 /// Read bytes until the buffer is filled, or the line becomes idle.
695 ///
696 /// Returns the amount of bytes read.
674 pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { 697 pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
675 if buffer.len() == 0 { 698 if buffer.len() == 0 {
676 return Ok(0); 699 return Ok(0);
@@ -727,6 +750,9 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
727 Ok(n) 750 Ok(n)
728 } 751 }
729 752
753 /// Read bytes until the buffer is filled, or the line becomes idle.
754 ///
755 /// Returns the amount of bytes read.
730 pub fn blocking_read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { 756 pub fn blocking_read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
731 if buffer.len() == 0 { 757 if buffer.len() == 0 {
732 return Ok(0); 758 return Ok(0);
@@ -860,7 +886,9 @@ pub(crate) mod sealed {
860 } 886 }
861} 887}
862 888
889/// UARTE peripheral instance.
863pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { 890pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
891 /// Interrupt for this peripheral.
864 type Interrupt: Interrupt; 892 type Interrupt: Interrupt;
865} 893}
866 894
@@ -919,7 +947,7 @@ mod eh1 {
919 fn kind(&self) -> embedded_hal_1::serial::ErrorKind { 947 fn kind(&self) -> embedded_hal_1::serial::ErrorKind {
920 match *self { 948 match *self {
921 Self::BufferTooLong => embedded_hal_1::serial::ErrorKind::Other, 949 Self::BufferTooLong => embedded_hal_1::serial::ErrorKind::Other,
922 Self::DMABufferNotInDataMemory => embedded_hal_1::serial::ErrorKind::Other, 950 Self::BufferNotInRAM => embedded_hal_1::serial::ErrorKind::Other,
923 } 951 }
924 } 952 }
925 } 953 }