diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-02-01 00:48:33 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-02-01 01:17:41 +0100 |
| commit | b5cf332cc076a0de11ce6a0563a2235c9e57eb5c (patch) | |
| tree | ce14e014dfbe8c3764040d7f9f1ffee84ab5747b /embassy-nrf/src/uarte.rs | |
| parent | ca10fe7135d10084e38038f3cd433da39e505bea (diff) | |
nrf: docs.
Diffstat (limited to 'embassy-nrf/src/uarte.rs')
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 76 |
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 | |||
| 16 | use core::future::poll_fn; | 16 | use core::future::poll_fn; |
| 17 | use core::sync::atomic::{compiler_fence, Ordering}; | 17 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 18 | use core::task::Poll; | 18 | use core::task::Poll; |
| @@ -32,10 +32,13 @@ use crate::timer::{Frequency, Instance as TimerInstance, Timer}; | |||
| 32 | use crate::util::slice_in_ram_or; | 32 | use crate::util::slice_in_ram_or; |
| 33 | use crate::{pac, Peripheral}; | 33 | use crate::{pac, Peripheral}; |
| 34 | 34 | ||
| 35 | /// UARTE config. | ||
| 35 | #[derive(Clone)] | 36 | #[derive(Clone)] |
| 36 | #[non_exhaustive] | 37 | #[non_exhaustive] |
| 37 | pub struct Config { | 38 | pub 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] |
| 54 | pub enum Error { | 58 | pub 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. | ||
| 63 | pub struct Uarte<'d, T: Instance> { | 66 | pub 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. | ||
| 70 | pub struct UarteTx<'d, T: Instance> { | 74 | pub 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. | ||
| 76 | pub struct UarteRx<'d, T: Instance> { | 81 | pub 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`]. | ||
| 656 | pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> { | 674 | pub 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 | ||
| 663 | impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | 681 | impl<'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. | ||
| 863 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { | 890 | pub 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 | } |
