Merge pull request #449 from papyDoctor/main

Added set_fifos/set_rx_watermark/set_tx_watermark
This commit is contained in:
Jan Niehusmann 2022-09-17 10:25:52 +02:00 committed by GitHub
commit cbed25944a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 11 deletions

View file

@ -62,7 +62,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
device.uartlcr_h.write(|w| {
// FIFOs are enabled
w.fen().set_bit();
w.fen().set_bit(); // Leaved here for backward compatibility
set_format(w, &config.data_bits, &config.stop_bits, &config.parity);
w
});
@ -108,6 +108,29 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Enabled, D, P> {
self.transition(Disabled)
}
/// Enable/disable the rx/tx FIFO
///
/// Unfortunately, it's not possible to enable/disable rx/tx
/// independently on this chip
/// Default is false
pub fn set_fifos(&mut self, enable: bool) {
super::reader::set_fifos(&self.device, enable)
}
/// Set rx FIFO watermark
///
/// See DS: Table 423
pub fn set_rx_watermark(&mut self, watermark: FifoWatermark) {
super::reader::set_rx_watermark(&self.device, watermark)
}
/// Set tx FIFO watermark
///
/// See DS: Table 423
pub fn set_tx_watermark(&mut self, watermark: FifoWatermark) {
super::writer::set_tx_watermark(&self.device, watermark)
}
/// Enables the Receive Interrupt.
///
/// The relevant UARTx IRQ will fire when there is data in the receive register.

View file

@ -2,7 +2,7 @@
//!
//! This module is for receiving data with a UART.
use super::{UartDevice, ValidUartPinout};
use super::{FifoWatermark, UartDevice, ValidUartPinout};
use rp2040_pac::uart0::RegisterBlock;
use embedded_hal::serial::Read;
@ -52,16 +52,37 @@ pub(crate) fn is_readable<D: UartDevice>(device: &D) -> bool {
device.uartfr.read().rxfe().bit_is_clear()
}
/// Enable/disable the rx/tx FIFO
///
/// Unfortunately, it's not possible to enable/disable rx/tx
/// independently on this chip
/// Default is false
pub fn set_fifos(rb: &RegisterBlock, enable: bool) {
if enable {
rb.uartlcr_h.modify(|_r, w| w.fen().set_bit())
} else {
rb.uartlcr_h.modify(|_r, w| w.fen().clear_bit())
}
}
/// Set rx FIFO watermark
///
/// See DS: Table 423
pub fn set_rx_watermark(rb: &RegisterBlock, watermark: FifoWatermark) {
let wm = match watermark {
FifoWatermark::Bytes4 => 0,
FifoWatermark::Bytes8 => 1,
FifoWatermark::Bytes16 => 2,
FifoWatermark::Bytes24 => 3,
FifoWatermark::Bytes28 => 4,
};
rb.uartifls.modify(|_r, w| unsafe { w.rxiflsel().bits(wm) });
}
/// Enables the Receive Interrupt.
///
/// The relevant UARTx IRQ will fire when there is data in the receive register.
pub(crate) fn enable_rx_interrupt(rb: &RegisterBlock) {
// Access the UART FIFO Level Select. We set the RX FIFO trip level
// to be half-full.
// 2 means '>= 1/2 full'.
rb.uartifls.modify(|_r, w| unsafe { w.rxiflsel().bits(2) });
// Access the UART Interrupt Mask Set/Clear register. Setting a bit
// high enables the interrupt.

View file

@ -44,7 +44,6 @@ pub enum DataBits {
pub enum StopBits {
/// 1 bit
One,
/// 2 bits
Two,
}
@ -54,7 +53,6 @@ pub enum StopBits {
pub enum Parity {
/// Odd parity
Odd,
/// Even parity
Even,
}
@ -86,6 +84,28 @@ pub struct UartConfig {
pub parity: Option<Parity>,
}
/// Rx/Tx FIFO Watermark
///
/// Determine the FIFO level that trigger DMA/Interrupt
/// Default is Bytes16, see DS Table 423 and UARTIFLS Register
/// Example of use:
/// uart0.set_fifos(true); // Default is false
/// uart0.set_rx_watermark(hal::uart::FifoWatermark::Bytes8);
/// uart0.enable_rx_interrupt();
///
pub enum FifoWatermark {
/// Trigger when 4 bytes are (Rx: filled / Tx: available)
Bytes4,
/// Trigger when 8 bytes are (Rx: filled / Tx: available)
Bytes8,
/// Trigger when 16 bytes are (Rx: filled / Tx: available)
Bytes16,
/// Trigger when 24 bytes are (Rx: filled / Tx: available)
Bytes24,
/// Trigger when 28 bytes are (Rx: filled / Tx: available)
Bytes28,
}
impl Default for UartConfig {
fn default() -> Self {
Self {

View file

@ -2,7 +2,7 @@
//!
//! This module is for transmitting data with a UART.
use super::{UartDevice, ValidUartPinout};
use super::{FifoWatermark, UartDevice, ValidUartPinout};
use core::fmt;
use core::{convert::Infallible, marker::PhantomData};
use embedded_hal::serial::Write;
@ -12,6 +12,20 @@ use rp2040_pac::uart0::RegisterBlock;
#[cfg(feature = "eh1_0_alpha")]
use eh1_0_alpha::serial as eh1;
/// Set tx FIFO watermark
///
/// See DS: Table 423
pub fn set_tx_watermark(rb: &RegisterBlock, watermark: FifoWatermark) {
let wm = match watermark {
FifoWatermark::Bytes4 => 4,
FifoWatermark::Bytes8 => 3,
FifoWatermark::Bytes16 => 2,
FifoWatermark::Bytes24 => 1,
FifoWatermark::Bytes28 => 0,
};
rb.uartifls.modify(|_r, w| unsafe { w.txiflsel().bits(wm) });
}
/// Returns `Err(WouldBlock)` if the UART TX FIFO still has data in it or
/// `Ok(())` if the FIFO is empty.
pub(crate) fn transmit_flushed(rb: &RegisterBlock) -> nb::Result<(), Infallible> {