Merge pull request #2324 from barnabywalters/stm32-usart-docs
stm32: Documented usart public API
This commit is contained in:
commit
7ec1ed4de3
@ -82,6 +82,7 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Buffered UART State
|
||||||
pub struct State {
|
pub struct State {
|
||||||
rx_waker: AtomicWaker,
|
rx_waker: AtomicWaker,
|
||||||
rx_buf: RingBuffer,
|
rx_buf: RingBuffer,
|
||||||
@ -91,6 +92,7 @@ pub struct State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
/// Create new state
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
rx_buf: RingBuffer::new(),
|
rx_buf: RingBuffer::new(),
|
||||||
@ -101,15 +103,18 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Bidirectional buffered UART
|
||||||
pub struct BufferedUart<'d, T: BasicInstance> {
|
pub struct BufferedUart<'d, T: BasicInstance> {
|
||||||
rx: BufferedUartRx<'d, T>,
|
rx: BufferedUartRx<'d, T>,
|
||||||
tx: BufferedUartTx<'d, T>,
|
tx: BufferedUartTx<'d, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tx-only buffered UART
|
||||||
pub struct BufferedUartTx<'d, T: BasicInstance> {
|
pub struct BufferedUartTx<'d, T: BasicInstance> {
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rx-only buffered UART
|
||||||
pub struct BufferedUartRx<'d, T: BasicInstance> {
|
pub struct BufferedUartRx<'d, T: BasicInstance> {
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
}
|
}
|
||||||
@ -142,6 +147,7 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: BasicInstance> BufferedUart<'d, T> {
|
impl<'d, T: BasicInstance> BufferedUart<'d, T> {
|
||||||
|
/// Create a new bidirectional buffered UART driver
|
||||||
pub fn new(
|
pub fn new(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
@ -158,6 +164,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
|
|||||||
Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
|
Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
|
||||||
pub fn new_with_rtscts(
|
pub fn new_with_rtscts(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
@ -185,6 +192,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
|
|||||||
Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
|
Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new bidirectional buffered UART driver with a driver-enable pin
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
pub fn new_with_de(
|
pub fn new_with_de(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
@ -246,10 +254,12 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split the driver into a Tx and Rx part (useful for sending to separate tasks)
|
||||||
pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) {
|
pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) {
|
||||||
(self.tx, self.rx)
|
(self.tx, self.rx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
reconfigure::<T>(config)?;
|
reconfigure::<T>(config)?;
|
||||||
|
|
||||||
@ -337,6 +347,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
reconfigure::<T>(config)?;
|
reconfigure::<T>(config)?;
|
||||||
|
|
||||||
@ -418,6 +429,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
reconfigure::<T>(config)?;
|
reconfigure::<T>(config)?;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Universal Synchronous/Asynchronous Receiver Transmitter (USART, UART, LPUART)
|
//! Universal Synchronous/Asynchronous Receiver Transmitter (USART, UART, LPUART)
|
||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
@ -77,21 +78,29 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt
|
|||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
/// Number of data bits
|
||||||
pub enum DataBits {
|
pub enum DataBits {
|
||||||
|
/// 8 Data Bits
|
||||||
DataBits8,
|
DataBits8,
|
||||||
|
/// 9 Data Bits
|
||||||
DataBits9,
|
DataBits9,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
/// Parity
|
||||||
pub enum Parity {
|
pub enum Parity {
|
||||||
|
/// No parity
|
||||||
ParityNone,
|
ParityNone,
|
||||||
|
/// Even Parity
|
||||||
ParityEven,
|
ParityEven,
|
||||||
|
/// Odd Parity
|
||||||
ParityOdd,
|
ParityOdd,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
/// Number of stop bits
|
||||||
pub enum StopBits {
|
pub enum StopBits {
|
||||||
#[doc = "1 stop bit"]
|
#[doc = "1 stop bit"]
|
||||||
STOP1,
|
STOP1,
|
||||||
@ -106,26 +115,37 @@ pub enum StopBits {
|
|||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
/// Config Error
|
||||||
pub enum ConfigError {
|
pub enum ConfigError {
|
||||||
|
/// Baudrate too low
|
||||||
BaudrateTooLow,
|
BaudrateTooLow,
|
||||||
|
/// Baudrate too high
|
||||||
BaudrateTooHigh,
|
BaudrateTooHigh,
|
||||||
|
/// Rx or Tx not enabled
|
||||||
RxOrTxNotEnabled,
|
RxOrTxNotEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
/// Config
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
/// Baud rate
|
||||||
pub baudrate: u32,
|
pub baudrate: u32,
|
||||||
|
/// Number of data bits
|
||||||
pub data_bits: DataBits,
|
pub data_bits: DataBits,
|
||||||
|
/// Number of stop bits
|
||||||
pub stop_bits: StopBits,
|
pub stop_bits: StopBits,
|
||||||
|
/// Parity type
|
||||||
pub parity: Parity,
|
pub parity: Parity,
|
||||||
/// if true, on read-like method, if there is a latent error pending,
|
|
||||||
/// read will abort, the error reported and cleared
|
/// If true: on a read-like method, if there is a latent error pending,
|
||||||
/// if false, the error is ignored and cleared
|
/// the read will abort and the error will be reported and cleared
|
||||||
|
///
|
||||||
|
/// If false: the error is ignored and cleared
|
||||||
pub detect_previous_overrun: bool,
|
pub detect_previous_overrun: bool,
|
||||||
|
|
||||||
/// Set this to true if the line is considered noise free.
|
/// Set this to true if the line is considered noise free.
|
||||||
/// This will increase the receivers tolerance to clock deviations,
|
/// This will increase the receiver’s tolerance to clock deviations,
|
||||||
/// but will effectively disable noise detection.
|
/// but will effectively disable noise detection.
|
||||||
#[cfg(not(usart_v1))]
|
#[cfg(not(usart_v1))]
|
||||||
pub assume_noise_free: bool,
|
pub assume_noise_free: bool,
|
||||||
@ -188,6 +208,7 @@ enum ReadCompletionEvent {
|
|||||||
Idle(usize),
|
Idle(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Bidirectional UART Driver
|
||||||
pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> {
|
pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> {
|
||||||
tx: UartTx<'d, T, TxDma>,
|
tx: UartTx<'d, T, TxDma>,
|
||||||
rx: UartRx<'d, T, RxDma>,
|
rx: UartRx<'d, T, RxDma>,
|
||||||
@ -203,6 +224,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tx-only UART Driver
|
||||||
pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> {
|
pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> {
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
tx_dma: PeripheralRef<'d, TxDma>,
|
tx_dma: PeripheralRef<'d, TxDma>,
|
||||||
@ -217,6 +239,7 @@ impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rx-only UART Driver
|
||||||
pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> {
|
pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> {
|
||||||
_peri: PeripheralRef<'d, T>,
|
_peri: PeripheralRef<'d, T>,
|
||||||
rx_dma: PeripheralRef<'d, RxDma>,
|
rx_dma: PeripheralRef<'d, RxDma>,
|
||||||
@ -247,6 +270,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> {
|
|||||||
Self::new_inner(peri, tx, tx_dma, config)
|
Self::new_inner(peri, tx, tx_dma, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new tx-only UART with a clear-to-send pin
|
||||||
pub fn new_with_cts(
|
pub fn new_with_cts(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||||
@ -288,10 +312,12 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
reconfigure::<T>(config)
|
reconfigure::<T>(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an asynchronous UART write
|
||||||
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error>
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
TxDma: crate::usart::TxDma<T>,
|
TxDma: crate::usart::TxDma<T>,
|
||||||
@ -308,6 +334,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a blocking UART write
|
||||||
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 {
|
||||||
@ -317,6 +344,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Block until transmission complete
|
||||||
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 !sr(r).read().tc() {}
|
while !sr(r).read().tc() {}
|
||||||
@ -338,6 +366,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
Self::new_inner(peri, rx, rx_dma, config)
|
Self::new_inner(peri, rx, rx_dma, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new rx-only UART with a request-to-send pin
|
||||||
pub fn new_with_rts(
|
pub fn new_with_rts(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
@ -387,6 +416,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
reconfigure::<T>(config)
|
reconfigure::<T>(config)
|
||||||
}
|
}
|
||||||
@ -444,6 +474,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
Ok(sr.rxne())
|
Ok(sr.rxne())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an asynchronous UART read
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error>
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
RxDma: crate::usart::RxDma<T>,
|
RxDma: crate::usart::RxDma<T>,
|
||||||
@ -453,6 +484,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read a single u8 if there is one available, otherwise return WouldBlock
|
||||||
pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
|
pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
if self.check_rx_flags()? {
|
if self.check_rx_flags()? {
|
||||||
@ -462,6 +494,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a blocking read into `buffer`
|
||||||
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
for b in buffer {
|
for b in buffer {
|
||||||
@ -471,6 +504,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an asynchronous read with idle line detection enabled
|
||||||
pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error>
|
pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
RxDma: crate::usart::RxDma<T>,
|
RxDma: crate::usart::RxDma<T>,
|
||||||
@ -695,6 +729,7 @@ impl<'d, T: BasicInstance, TxDma> Drop for UartRx<'d, T, TxDma> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
||||||
|
/// Create a new bidirectional UART
|
||||||
pub fn new(
|
pub fn new(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
@ -711,6 +746,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config)
|
Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new bidirectional UART with request-to-send and clear-to-send pins
|
||||||
pub fn new_with_rtscts(
|
pub fn new_with_rtscts(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
@ -738,6 +774,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(usart_v1, usart_v2)))]
|
#[cfg(not(any(usart_v1, usart_v2)))]
|
||||||
|
/// Create a new bidirectional UART with a driver-enable pin
|
||||||
pub fn new_with_de(
|
pub fn new_with_de(
|
||||||
peri: impl Peripheral<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
@ -813,6 +850,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an asynchronous write
|
||||||
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error>
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
TxDma: crate::usart::TxDma<T>,
|
TxDma: crate::usart::TxDma<T>,
|
||||||
@ -820,14 +858,17 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
self.tx.write(buffer).await
|
self.tx.write(buffer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a blocking write
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Block until transmission complete
|
||||||
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
pub fn blocking_flush(&mut self) -> Result<(), Error> {
|
||||||
self.tx.blocking_flush()
|
self.tx.blocking_flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an asynchronous read into `buffer`
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error>
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
RxDma: crate::usart::RxDma<T>,
|
RxDma: crate::usart::RxDma<T>,
|
||||||
@ -835,14 +876,17 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
self.rx.read(buffer).await
|
self.rx.read(buffer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read a single `u8` or return `WouldBlock`
|
||||||
pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
|
pub fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
|
||||||
self.rx.nb_read()
|
self.rx.nb_read()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a blocking read into `buffer`
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initiate an an asynchronous read with idle line detection enabled
|
||||||
pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error>
|
pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error>
|
||||||
where
|
where
|
||||||
RxDma: crate::usart::RxDma<T>,
|
RxDma: crate::usart::RxDma<T>,
|
||||||
@ -1292,8 +1336,10 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Basic UART driver instance
|
||||||
pub trait BasicInstance: Peripheral<P = Self> + sealed::BasicInstance + 'static + Send {}
|
pub trait BasicInstance: Peripheral<P = Self> + sealed::BasicInstance + 'static + Send {}
|
||||||
|
|
||||||
|
/// Full UART driver instance
|
||||||
pub trait FullInstance: sealed::FullInstance {}
|
pub trait FullInstance: sealed::FullInstance {}
|
||||||
|
|
||||||
pin_trait!(RxPin, BasicInstance);
|
pin_trait!(RxPin, BasicInstance);
|
||||||
|
@ -11,6 +11,7 @@ use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config,
|
|||||||
use crate::dma::ReadableRingBuffer;
|
use crate::dma::ReadableRingBuffer;
|
||||||
use crate::usart::{Regs, Sr};
|
use crate::usart::{Regs, Sr};
|
||||||
|
|
||||||
|
/// Rx-only Ring-buffered UART Driver
|
||||||
pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma<T>> {
|
pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma<T>> {
|
||||||
_peri: PeripheralRef<'d, T>,
|
_peri: PeripheralRef<'d, T>,
|
||||||
ring_buf: ReadableRingBuffer<'d, RxDma, u8>,
|
ring_buf: ReadableRingBuffer<'d, RxDma, u8>,
|
||||||
@ -27,8 +28,8 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> SetConfig for RingBufferedUar
|
|||||||
|
|
||||||
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> {
|
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> {
|
||||||
/// Turn the `UartRx` into a buffered uart which can continously receive in the background
|
/// Turn the `UartRx` into a buffered uart which can continously receive in the background
|
||||||
/// without the possibility of loosing bytes. The `dma_buf` is a buffer registered to the
|
/// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the
|
||||||
/// DMA controller, and must be sufficiently large, such that it will not overflow.
|
/// DMA controller, and must be large enough to prevent overflows.
|
||||||
pub fn into_ring_buffered(self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T, RxDma> {
|
pub fn into_ring_buffered(self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T, RxDma> {
|
||||||
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
|
assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxDma> {
|
impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxDma> {
|
||||||
|
/// Clear the ring buffer and start receiving in the background
|
||||||
pub fn start(&mut self) -> Result<(), Error> {
|
pub fn start(&mut self) -> Result<(), Error> {
|
||||||
// Clear the ring buffer so that it is ready to receive data
|
// Clear the ring buffer so that it is ready to receive data
|
||||||
self.ring_buf.clear();
|
self.ring_buf.clear();
|
||||||
@ -64,6 +66,7 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxD
|
|||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cleanly stop and reconfigure the driver
|
||||||
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
|
||||||
self.teardown_uart();
|
self.teardown_uart();
|
||||||
reconfigure::<T>(config)
|
reconfigure::<T>(config)
|
||||||
|
Loading…
Reference in New Issue
Block a user