docs: document spi, rtc and rest of uart for embassy-rp
This commit is contained in:
parent
e45e3e76b5
commit
486b67e895
4 changed files with 83 additions and 2 deletions
|
@ -61,9 +61,13 @@ impl Default for Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// PWM input mode.
|
||||||
pub enum InputMode {
|
pub enum InputMode {
|
||||||
|
/// Level mode.
|
||||||
Level,
|
Level,
|
||||||
|
/// Rising edge mode.
|
||||||
RisingEdge,
|
RisingEdge,
|
||||||
|
/// Falling edge mode.
|
||||||
FallingEdge,
|
FallingEdge,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +81,7 @@ impl From<InputMode> for Divmode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// PWM driver.
|
||||||
pub struct Pwm<'d, T: Channel> {
|
pub struct Pwm<'d, T: Channel> {
|
||||||
inner: PeripheralRef<'d, T>,
|
inner: PeripheralRef<'d, T>,
|
||||||
pin_a: Option<PeripheralRef<'d, AnyPin>>,
|
pin_a: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
|
|
|
@ -194,6 +194,7 @@ mod sealed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// RTC peripheral instance.
|
||||||
pub trait Instance: sealed::Instance {}
|
pub trait Instance: sealed::Instance {}
|
||||||
|
|
||||||
impl sealed::Instance for crate::peripherals::RTC {
|
impl sealed::Instance for crate::peripherals::RTC {
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::gpio::sealed::Pin as _;
|
||||||
use crate::gpio::{AnyPin, Pin as GpioPin};
|
use crate::gpio::{AnyPin, Pin as GpioPin};
|
||||||
use crate::{pac, peripherals, Peripheral};
|
use crate::{pac, peripherals, Peripheral};
|
||||||
|
|
||||||
|
/// SPI errors.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
@ -18,11 +19,15 @@ pub enum Error {
|
||||||
// No errors for now
|
// No errors for now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SPI configuration.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
/// Frequency.
|
||||||
pub frequency: u32,
|
pub frequency: u32,
|
||||||
|
/// Phase.
|
||||||
pub phase: Phase,
|
pub phase: Phase,
|
||||||
|
/// Polarity.
|
||||||
pub polarity: Polarity,
|
pub polarity: Polarity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +41,7 @@ impl Default for Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SPI driver.
|
||||||
pub struct Spi<'d, T: Instance, M: Mode> {
|
pub struct Spi<'d, T: Instance, M: Mode> {
|
||||||
inner: PeripheralRef<'d, T>,
|
inner: PeripheralRef<'d, T>,
|
||||||
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||||
|
@ -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> {
|
pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
for &b in data {
|
for &b in data {
|
||||||
|
@ -131,6 +138,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfer data in place to SPI blocking execution until done.
|
||||||
pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
for b in data {
|
for b in data {
|
||||||
|
@ -143,6 +151,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read data from SPI blocking execution until done.
|
||||||
pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
for b in data {
|
for b in data {
|
||||||
|
@ -155,6 +164,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfer data to SPI blocking execution until done.
|
||||||
pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
|
pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
let len = read.len().max(write.len());
|
let len = read.len().max(write.len());
|
||||||
|
@ -172,12 +182,14 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Block execution until SPI is done.
|
||||||
pub fn flush(&mut self) -> Result<(), Error> {
|
pub fn flush(&mut self) -> Result<(), Error> {
|
||||||
let p = self.inner.regs();
|
let p = self.inner.regs();
|
||||||
while p.sr().read().bsy() {}
|
while p.sr().read().bsy() {}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set SPI frequency.
|
||||||
pub fn set_frequency(&mut self, freq: u32) {
|
pub fn set_frequency(&mut self, freq: u32) {
|
||||||
let (presc, postdiv) = calc_prescs(freq);
|
let (presc, postdiv) = calc_prescs(freq);
|
||||||
let p = self.inner.regs();
|
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> {
|
impl<'d, T: Instance> Spi<'d, T, Blocking> {
|
||||||
|
/// Create an SPI driver in blocking mode.
|
||||||
pub fn new_blocking(
|
pub fn new_blocking(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + '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(
|
pub fn new_blocking_txonly(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + '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(
|
pub fn new_blocking_rxonly(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
||||||
|
@ -256,6 +271,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Spi<'d, T, Async> {
|
impl<'d, T: Instance> Spi<'d, T, Async> {
|
||||||
|
/// Create an SPI driver in async mode supporting DMA operations.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + '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(
|
pub fn new_txonly(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + '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(
|
pub fn new_rxonly(
|
||||||
inner: impl Peripheral<P = T> + 'd,
|
inner: impl Peripheral<P = T> + 'd,
|
||||||
clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd,
|
clk: impl Peripheral<P = impl ClkPin<T> + '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> {
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let tx_ch = self.tx_dma.as_mut().unwrap();
|
let tx_ch = self.tx_dma.as_mut().unwrap();
|
||||||
let tx_transfer = unsafe {
|
let tx_transfer = unsafe {
|
||||||
|
@ -340,6 +359,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read data from SPI using DMA.
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
// Start RX first. Transfer starts when TX starts, if RX
|
// Start RX first. Transfer starts when TX starts, if RX
|
||||||
// is not started yet we might lose bytes.
|
// is not started yet we might lose bytes.
|
||||||
|
@ -365,10 +385,12 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Transfer data to SPI using DMA.
|
||||||
pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> {
|
pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> {
|
||||||
self.transfer_inner(rx_buffer, tx_buffer).await
|
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> {
|
pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
|
||||||
self.transfer_inner(words, words).await
|
self.transfer_inner(words, words).await
|
||||||
}
|
}
|
||||||
|
@ -434,7 +456,10 @@ mod sealed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mode.
|
||||||
pub trait Mode: sealed::Mode {}
|
pub trait Mode: sealed::Mode {}
|
||||||
|
|
||||||
|
/// SPI instance trait.
|
||||||
pub trait Instance: sealed::Instance {}
|
pub trait Instance: sealed::Instance {}
|
||||||
|
|
||||||
macro_rules! impl_instance {
|
macro_rules! impl_instance {
|
||||||
|
@ -454,9 +479,13 @@ macro_rules! impl_instance {
|
||||||
impl_instance!(SPI0, Spi0, 16, 17);
|
impl_instance!(SPI0, Spi0, 16, 17);
|
||||||
impl_instance!(SPI1, Spi1, 18, 19);
|
impl_instance!(SPI1, Spi1, 18, 19);
|
||||||
|
|
||||||
|
/// CLK pin.
|
||||||
pub trait ClkPin<T: Instance>: GpioPin {}
|
pub trait ClkPin<T: Instance>: GpioPin {}
|
||||||
|
/// CS pin.
|
||||||
pub trait CsPin<T: Instance>: GpioPin {}
|
pub trait CsPin<T: Instance>: GpioPin {}
|
||||||
|
/// MOSI pin.
|
||||||
pub trait MosiPin<T: Instance>: GpioPin {}
|
pub trait MosiPin<T: Instance>: GpioPin {}
|
||||||
|
/// MISO pin.
|
||||||
pub trait MisoPin<T: Instance>: GpioPin {}
|
pub trait MisoPin<T: Instance>: GpioPin {}
|
||||||
|
|
||||||
macro_rules! impl_pin {
|
macro_rules! impl_pin {
|
||||||
|
@ -503,7 +532,9 @@ macro_rules! impl_mode {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blocking mode.
|
||||||
pub struct Blocking;
|
pub struct Blocking;
|
||||||
|
/// Async mode.
|
||||||
pub struct Async;
|
pub struct Async;
|
||||||
|
|
||||||
impl_mode!(Blocking);
|
impl_mode!(Blocking);
|
||||||
|
|
|
@ -20,11 +20,16 @@ use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
|
||||||
mod buffered;
|
mod buffered;
|
||||||
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
|
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
|
||||||
|
|
||||||
|
/// Word length.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub enum DataBits {
|
pub enum DataBits {
|
||||||
|
/// 5 bits.
|
||||||
DataBits5,
|
DataBits5,
|
||||||
|
/// 6 bits.
|
||||||
DataBits6,
|
DataBits6,
|
||||||
|
/// 7 bits.
|
||||||
DataBits7,
|
DataBits7,
|
||||||
|
/// 8 bits.
|
||||||
DataBits8,
|
DataBits8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +44,18 @@ impl DataBits {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parity bit.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub enum Parity {
|
pub enum Parity {
|
||||||
|
/// No parity.
|
||||||
ParityNone,
|
ParityNone,
|
||||||
|
/// Even parity.
|
||||||
ParityEven,
|
ParityEven,
|
||||||
|
/// Odd parity.
|
||||||
ParityOdd,
|
ParityOdd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stop bits.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub enum StopBits {
|
pub enum StopBits {
|
||||||
#[doc = "1 stop bit"]
|
#[doc = "1 stop bit"]
|
||||||
|
@ -54,20 +64,25 @@ pub enum StopBits {
|
||||||
STOP2,
|
STOP2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UART config.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
/// Baud rate.
|
||||||
pub baudrate: u32,
|
pub baudrate: u32,
|
||||||
|
/// Word length.
|
||||||
pub data_bits: DataBits,
|
pub data_bits: DataBits,
|
||||||
|
/// Stop bits.
|
||||||
pub stop_bits: StopBits,
|
pub stop_bits: StopBits,
|
||||||
|
/// Parity bit.
|
||||||
pub parity: Parity,
|
pub parity: Parity,
|
||||||
/// Invert the tx pin output
|
/// Invert the tx pin output
|
||||||
pub invert_tx: bool,
|
pub invert_tx: bool,
|
||||||
/// Invert the rx pin input
|
/// Invert the rx pin input
|
||||||
pub invert_rx: bool,
|
pub invert_rx: bool,
|
||||||
// Invert the rts pin
|
/// Invert the rts pin
|
||||||
pub invert_rts: bool,
|
pub invert_rts: bool,
|
||||||
// Invert the cts pin
|
/// Invert the cts pin
|
||||||
pub invert_cts: bool,
|
pub invert_cts: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,21 +117,25 @@ pub enum Error {
|
||||||
Framing,
|
Framing,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internal DMA state of UART RX.
|
||||||
pub struct DmaState {
|
pub struct DmaState {
|
||||||
rx_err_waker: AtomicWaker,
|
rx_err_waker: AtomicWaker,
|
||||||
rx_errs: AtomicU16,
|
rx_errs: AtomicU16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UART driver.
|
||||||
pub struct Uart<'d, T: Instance, M: Mode> {
|
pub struct Uart<'d, T: Instance, M: Mode> {
|
||||||
tx: UartTx<'d, T, M>,
|
tx: UartTx<'d, T, M>,
|
||||||
rx: UartRx<'d, T, M>,
|
rx: UartRx<'d, T, M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UART TX driver.
|
||||||
pub struct UartTx<'d, T: Instance, M: Mode> {
|
pub struct UartTx<'d, T: Instance, M: Mode> {
|
||||||
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||||
phantom: PhantomData<(&'d mut T, M)>,
|
phantom: PhantomData<(&'d mut T, M)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UART RX driver.
|
||||||
pub struct UartRx<'d, T: Instance, M: Mode> {
|
pub struct UartRx<'d, T: Instance, M: Mode> {
|
||||||
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||||
phantom: PhantomData<(&'d mut T, M)>,
|
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> {
|
pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
for &b in buffer {
|
for &b in buffer {
|
||||||
|
@ -151,12 +171,14 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flush UART TX blocking execution until done.
|
||||||
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
while !r.uartfr().read().txfe() {}
|
while !r.uartfr().read().txfe() {}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if UART is busy transmitting.
|
||||||
pub fn busy(&self) -> bool {
|
pub fn busy(&self) -> bool {
|
||||||
T::regs().uartfr().read().busy()
|
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> {
|
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(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
|
@ -203,6 +227,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> UartTx<'d, T, Async> {
|
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> {
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let ch = self.tx_dma.as_mut().unwrap();
|
let ch = self.tx_dma.as_mut().unwrap();
|
||||||
let transfer = unsafe {
|
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> {
|
pub fn blocking_read(&mut self, mut buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
while buffer.len() > 0 {
|
while buffer.len() > 0 {
|
||||||
let received = self.drain_fifo(buffer)?;
|
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> {
|
impl<'d, T: Instance> UartRx<'d, T, Blocking> {
|
||||||
|
/// Create a new UART RX instance for blocking mode operations.
|
||||||
pub fn new_blocking(
|
pub fn new_blocking(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
|
@ -304,6 +331,8 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> {
|
||||||
Self::new_inner(false, None)
|
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(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
|
@ -315,6 +344,7 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interrupt handler.
|
||||||
pub struct InterruptHandler<T: Instance> {
|
pub struct InterruptHandler<T: Instance> {
|
||||||
_uart: PhantomData<T>,
|
_uart: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
@ -338,6 +368,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> UartRx<'d, T, Async> {
|
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> {
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
// clear error flags before we drain the fifo. errors that have accumulated
|
// clear error flags before we drain the fifo. errors that have accumulated
|
||||||
// in the flags will also be present in the fifo.
|
// 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(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
|
@ -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> {
|
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> {
|
pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
self.tx.blocking_write(buffer)
|
self.tx.blocking_write(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flush UART TX blocking execution until done.
|
||||||
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
||||||
self.tx.blocking_flush()
|
self.tx.blocking_flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read from UART RX blocking execution until done.
|
||||||
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
self.rx.blocking_read(buffer)
|
self.rx.blocking_read(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if UART is busy transmitting.
|
||||||
pub fn busy(&self) -> bool {
|
pub fn busy(&self) -> bool {
|
||||||
self.tx.busy()
|
self.tx.busy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wait until TX is empty and send break condition.
|
||||||
pub async fn send_break(&mut self, bits: u32) {
|
pub async fn send_break(&mut self, bits: u32) {
|
||||||
self.tx.send_break(bits).await
|
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> {
|
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> {
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
self.tx.write(buffer).await
|
self.tx.write(buffer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read from UART RX into the provided buffer.
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
self.rx.read(buffer).await
|
self.rx.read(buffer).await
|
||||||
}
|
}
|
||||||
|
@ -889,6 +929,7 @@ mod sealed {
|
||||||
pub trait RtsPin<T: Instance> {}
|
pub trait RtsPin<T: Instance> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UART mode.
|
||||||
pub trait Mode: sealed::Mode {}
|
pub trait Mode: sealed::Mode {}
|
||||||
|
|
||||||
macro_rules! impl_mode {
|
macro_rules! impl_mode {
|
||||||
|
@ -898,12 +939,15 @@ macro_rules! impl_mode {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blocking mode.
|
||||||
pub struct Blocking;
|
pub struct Blocking;
|
||||||
|
/// Async mode.
|
||||||
pub struct Async;
|
pub struct Async;
|
||||||
|
|
||||||
impl_mode!(Blocking);
|
impl_mode!(Blocking);
|
||||||
impl_mode!(Async);
|
impl_mode!(Async);
|
||||||
|
|
||||||
|
/// UART instance trait.
|
||||||
pub trait Instance: sealed::Instance {}
|
pub trait Instance: sealed::Instance {}
|
||||||
|
|
||||||
macro_rules! impl_instance {
|
macro_rules! impl_instance {
|
||||||
|
|
Loading…
Reference in a new issue