From a7429a7f468faef9c7a213f800604086af349fe3 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 19 Dec 2023 11:26:08 +0100 Subject: [PATCH] docs: document spi, rtc and rest of uart for embassy-rp --- embassy-rp/src/pwm.rs | 5 ++++ embassy-rp/src/rtc/mod.rs | 1 + embassy-rp/src/spi.rs | 31 ++++++++++++++++++++++++ embassy-rp/src/uart/mod.rs | 48 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 2 deletions(-) diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 516b8254..5b96557a 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs @@ -61,9 +61,13 @@ impl Default for Config { } } +/// PWM input mode. pub enum InputMode { + /// Level mode. Level, + /// Rising edge mode. RisingEdge, + /// Falling edge mode. FallingEdge, } @@ -77,6 +81,7 @@ impl From for Divmode { } } +/// PWM driver. pub struct Pwm<'d, T: Channel> { inner: PeripheralRef<'d, T>, pin_a: Option>, diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs index 60ca8627..c3df3ee5 100644 --- a/embassy-rp/src/rtc/mod.rs +++ b/embassy-rp/src/rtc/mod.rs @@ -194,6 +194,7 @@ mod sealed { } } +/// RTC peripheral instance. pub trait Instance: sealed::Instance {} impl sealed::Instance for crate::peripherals::RTC { diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 6ba985a6..a2a22ffe 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -11,6 +11,7 @@ use crate::gpio::sealed::Pin as _; use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::{pac, peripherals, Peripheral}; +/// SPI errors. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[non_exhaustive] @@ -18,11 +19,15 @@ pub enum Error { // No errors for now } +/// SPI configuration. #[non_exhaustive] #[derive(Clone)] pub struct Config { + /// Frequency. pub frequency: u32, + /// Phase. pub phase: Phase, + /// Polarity. pub polarity: Polarity, } @@ -36,6 +41,7 @@ impl Default for Config { } } +/// SPI driver. pub struct Spi<'d, T: Instance, M: Mode> { inner: PeripheralRef<'d, T>, tx_dma: Option>, @@ -119,6 +125,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { } } + /// Write data to SPI blocking execution until done. pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { let p = self.inner.regs(); for &b in data { @@ -131,6 +138,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { Ok(()) } + /// Transfer data in place to SPI blocking execution until done. pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> { let p = self.inner.regs(); for b in data { @@ -143,6 +151,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { Ok(()) } + /// Read data from SPI blocking execution until done. pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> { let p = self.inner.regs(); for b in data { @@ -155,6 +164,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { Ok(()) } + /// Transfer data to SPI blocking execution until done. pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { let p = self.inner.regs(); let len = read.len().max(write.len()); @@ -172,12 +182,14 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { Ok(()) } + /// Block execution until SPI is done. pub fn flush(&mut self) -> Result<(), Error> { let p = self.inner.regs(); while p.sr().read().bsy() {} Ok(()) } + /// Set SPI frequency. pub fn set_frequency(&mut self, freq: u32) { let (presc, postdiv) = calc_prescs(freq); let p = self.inner.regs(); @@ -196,6 +208,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { } impl<'d, T: Instance> Spi<'d, T, Blocking> { + /// Create an SPI driver in blocking mode. pub fn new_blocking( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -216,6 +229,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { ) } + /// Create an SPI driver in blocking mode supporting writes only. pub fn new_blocking_txonly( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -235,6 +249,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { ) } + /// Create an SPI driver in blocking mode supporting reads only. pub fn new_blocking_rxonly( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -256,6 +271,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { } impl<'d, T: Instance> Spi<'d, T, Async> { + /// Create an SPI driver in async mode supporting DMA operations. pub fn new( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -278,6 +294,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { ) } + /// Create an SPI driver in async mode supporting DMA write operations only. pub fn new_txonly( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -298,6 +315,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { ) } + /// Create an SPI driver in async mode supporting DMA read operations only. pub fn new_rxonly( inner: impl Peripheral

+ 'd, clk: impl Peripheral

+ 'd> + 'd, @@ -318,6 +336,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { ) } + /// Write data to SPI using DMA. pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { let tx_ch = self.tx_dma.as_mut().unwrap(); let tx_transfer = unsafe { @@ -340,6 +359,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { Ok(()) } + /// Read data from SPI using DMA. pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { // Start RX first. Transfer starts when TX starts, if RX // is not started yet we might lose bytes. @@ -365,10 +385,12 @@ impl<'d, T: Instance> Spi<'d, T, Async> { Ok(()) } + /// Transfer data to SPI using DMA. pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> { self.transfer_inner(rx_buffer, tx_buffer).await } + /// Transfer data in place to SPI using DMA. pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { self.transfer_inner(words, words).await } @@ -434,7 +456,10 @@ mod sealed { } } +/// Mode. pub trait Mode: sealed::Mode {} + +/// SPI instance trait. pub trait Instance: sealed::Instance {} macro_rules! impl_instance { @@ -454,9 +479,13 @@ macro_rules! impl_instance { impl_instance!(SPI0, Spi0, 16, 17); impl_instance!(SPI1, Spi1, 18, 19); +/// CLK pin. pub trait ClkPin: GpioPin {} +/// CS pin. pub trait CsPin: GpioPin {} +/// MOSI pin. pub trait MosiPin: GpioPin {} +/// MISO pin. pub trait MisoPin: GpioPin {} macro_rules! impl_pin { @@ -503,7 +532,9 @@ macro_rules! impl_mode { }; } +/// Blocking mode. pub struct Blocking; +/// Async mode. pub struct Async; impl_mode!(Blocking); diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 26f21193..32be7661 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -20,11 +20,16 @@ use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; mod buffered; pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; +/// Word length. #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum DataBits { + /// 5 bits. DataBits5, + /// 6 bits. DataBits6, + /// 7 bits. DataBits7, + /// 8 bits. DataBits8, } @@ -39,13 +44,18 @@ impl DataBits { } } +/// Parity bit. #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum Parity { + /// No parity. ParityNone, + /// Even parity. ParityEven, + /// Odd parity. ParityOdd, } +/// Stop bits. #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum StopBits { #[doc = "1 stop bit"] @@ -54,20 +64,25 @@ pub enum StopBits { STOP2, } +/// UART config. #[non_exhaustive] #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct Config { + /// Baud rate. pub baudrate: u32, + /// Word length. pub data_bits: DataBits, + /// Stop bits. pub stop_bits: StopBits, + /// Parity bit. pub parity: Parity, /// Invert the tx pin output pub invert_tx: bool, /// Invert the rx pin input pub invert_rx: bool, - // Invert the rts pin + /// Invert the rts pin pub invert_rts: bool, - // Invert the cts pin + /// Invert the cts pin pub invert_cts: bool, } @@ -102,21 +117,25 @@ pub enum Error { Framing, } +/// Internal DMA state of UART RX. pub struct DmaState { rx_err_waker: AtomicWaker, rx_errs: AtomicU16, } +/// UART driver. pub struct Uart<'d, T: Instance, M: Mode> { tx: UartTx<'d, T, M>, rx: UartRx<'d, T, M>, } +/// UART TX driver. pub struct UartTx<'d, T: Instance, M: Mode> { tx_dma: Option>, phantom: PhantomData<(&'d mut T, M)>, } +/// UART RX driver. pub struct UartRx<'d, T: Instance, M: Mode> { rx_dma: Option>, phantom: PhantomData<(&'d mut T, M)>, @@ -142,6 +161,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { } } + /// Transmit the provided buffer blocking execution until done. pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { let r = T::regs(); for &b in buffer { @@ -151,12 +171,14 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { Ok(()) } + /// Flush UART TX blocking execution until done. pub fn blocking_flush(&mut self) -> Result<(), Error> { let r = T::regs(); while !r.uartfr().read().txfe() {} Ok(()) } + /// Check if UART is busy transmitting. pub fn busy(&self) -> bool { T::regs().uartfr().read().busy() } @@ -191,6 +213,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { } impl<'d, T: Instance> UartTx<'d, T, Blocking> { + /// Convert this uart TX instance into a buffered uart using the provided + /// irq and transmit buffer. pub fn into_buffered( self, irq: impl Binding>, @@ -203,6 +227,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> { } impl<'d, T: Instance> UartTx<'d, T, Async> { + /// Write to UART TX from the provided buffer using DMA. pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { let ch = self.tx_dma.as_mut().unwrap(); let transfer = unsafe { @@ -246,6 +271,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { } } + /// Read from UART RX blocking execution until done. pub fn blocking_read(&mut self, mut buffer: &mut [u8]) -> Result<(), Error> { while buffer.len() > 0 { let received = self.drain_fifo(buffer)?; @@ -294,6 +320,7 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> { } impl<'d, T: Instance> UartRx<'d, T, Blocking> { + /// Create a new UART RX instance for blocking mode operations. pub fn new_blocking( _uart: impl Peripheral

+ 'd, rx: impl Peripheral

> + 'd, @@ -304,6 +331,8 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> { Self::new_inner(false, None) } + /// Convert this uart RX instance into a buffered uart using the provided + /// irq and receive buffer. pub fn into_buffered( self, irq: impl Binding>, @@ -315,6 +344,7 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> { } } +/// Interrupt handler. pub struct InterruptHandler { _uart: PhantomData, } @@ -338,6 +368,7 @@ impl interrupt::typelevel::Handler for InterruptHandl } impl<'d, T: Instance> UartRx<'d, T, Async> { + /// Read from UART RX into the provided buffer. pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { // clear error flags before we drain the fifo. errors that have accumulated // in the flags will also be present in the fifo. @@ -458,6 +489,8 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { ) } + /// Convert this uart instance into a buffered uart using the provided + /// irq, transmit and receive buffers. pub fn into_buffered( self, irq: impl Binding>, @@ -667,22 +700,27 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { } impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { + /// Transmit the provided buffer blocking execution until done. pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { self.tx.blocking_write(buffer) } + /// Flush UART TX blocking execution until done. pub fn blocking_flush(&mut self) -> Result<(), Error> { self.tx.blocking_flush() } + /// Read from UART RX blocking execution until done. pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { self.rx.blocking_read(buffer) } + /// Check if UART is busy transmitting. pub fn busy(&self) -> bool { self.tx.busy() } + /// Wait until TX is empty and send break condition. pub async fn send_break(&mut self, bits: u32) { self.tx.send_break(bits).await } @@ -695,10 +733,12 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { } impl<'d, T: Instance> Uart<'d, T, Async> { + /// Write to UART TX from the provided buffer. pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { self.tx.write(buffer).await } + /// Read from UART RX into the provided buffer. pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { self.rx.read(buffer).await } @@ -889,6 +929,7 @@ mod sealed { pub trait RtsPin {} } +/// UART mode. pub trait Mode: sealed::Mode {} macro_rules! impl_mode { @@ -898,12 +939,15 @@ macro_rules! impl_mode { }; } +/// Blocking mode. pub struct Blocking; +/// Async mode. pub struct Async; impl_mode!(Blocking); impl_mode!(Async); +/// UART instance trait. pub trait Instance: sealed::Instance {} macro_rules! impl_instance {