Skip to content

Commit

Permalink
improve UART HAL
Browse files Browse the repository at this point in the history
  • Loading branch information
kiffie committed Dec 29, 2024
1 parent 8b49765 commit 76eb5ec
Showing 1 changed file with 84 additions and 13 deletions.
97 changes: 84 additions & 13 deletions pic32-hal/src/uart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use nb::block;

/// Uart
pub struct Uart<UART, RX, TX> {
_uart: PhantomData<UART>,
uart: UART,
rx: RX,
tx: TX,
}
Expand All @@ -30,7 +30,7 @@ pub struct Tx<UART> {
}

/// UART read errors
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ReadError {
/// RX FIFO overrun
Overrun,
Expand All @@ -45,6 +45,59 @@ pub enum ReadError {
Break,
}

/// UART configuration
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Config {
/// Baudrate
pub baudrate: u32,

/// Parity
pub parity: Parity,

/// Stop bits
pub stopbits: StopBits,
}

impl Config {
/// Create a new UART configuration
pub const fn new(baudrate: u32, parity: Parity, stopbits: StopBits) -> Self {
Config {
baudrate,
parity,
stopbits,
}
}
}

pub const CONFIG_115200_8N1: Config = Config {
baudrate: 115200,
parity: Parity::None,
stopbits: StopBits::One,
};

/// UART Parity settings
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Parity {
/// No parity
None = 0,

/// Even parity
Even = 1,

/// Odd parity
Odd = 2,
}

/// Number of stop bits
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum StopBits {
/// 1 stop bit
One = 0,

/// 2 stop bits
Two = 1,
}

impl embedded_io::Error for ReadError {
fn kind(&self) -> embedded_io::ErrorKind {
embedded_io::ErrorKind::Other
Expand All @@ -57,20 +110,27 @@ macro_rules! uart_impl {
pub fn $Id(
uart: $Uart,
osc: &Osc,
baudrate: u32,
config: Config,
rx: MappedPin<RX, $Rx>,
tx: MappedPin<TX, $Tx>,
) -> Uart<$Uart, MappedPin<RX, $Rx>, MappedPin<TX, $Tx>>
where
MappedPin<RX, $Rx>: IsConnected,
MappedPin<TX, $Tx>: IsConnected,
{
let brg = osc.pb_clock().0 / (4 * baudrate) - 1;
let brg = osc.pb_clock().0 / (4 * config.baudrate) - 1;
let has_rx = rx.is_connected();
let has_tx = tx.is_connected();
unsafe {
uart.mode.write(|w| w.bits(0));
uart.mode.write(|w| w.brgh().bit(true));
uart.mode.write(|w| {
w.brgh()
.bit(true)
.pdsel()
.bits(config.parity as u8)
.stsel()
.bit(config.stopbits as u8 != 0)
});
uart.sta.write(|w| {
w.urxen()
.bit(has_rx)
Expand All @@ -82,23 +142,34 @@ macro_rules! uart_impl {
uart.brg.write(|w| w.bits(brg));
uart.modeset.write(|w| w.on().bit(true));
}
Uart {
_uart: PhantomData,
rx,
tx,
}
Uart { uart, rx, tx }
}

pub fn free(self) -> (MappedPin<RX, $Rx>, MappedPin<TX, $Tx>) {
/// Flush the transmit buffer and then send a break character.
pub fn transmit_break(&mut self) {
let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
tx.transmit_break();
}

pub fn free(self) -> ($Uart, MappedPin<RX, $Rx>, MappedPin<TX, $Tx>) {
unsafe { (*$Uart::ptr()).modeclr.write(|w| w.on().bit(true)) };
(self.rx, self.tx)
(self.uart, self.rx, self.tx)
}

pub fn split(self) -> (Tx<$Uart>, Rx<$Uart>) {
(Tx { _uart: PhantomData }, Rx { _uart: PhantomData })
}
}

impl Tx<$Uart> {
/// Flush the transmit buffer and then send a break character.
pub fn transmit_break(&mut self) {
let _ = embedded_io::Write::flush(self);
unsafe { (*$Uart::ptr()).staset.write(|w| w.utxbrk().bit(true)) };
let _ = embedded_io::Write::write_all(self, &[0]);
}
}

impl embedded_hal_0_2::serial::Write<u8> for Uart<$Uart, $Rx, $Tx> {
type Error = ();

Expand Down Expand Up @@ -197,7 +268,7 @@ macro_rules! uart_impl {
fn flush(&mut self) -> Result<(), Self::Error> {
loop {
let trmt = unsafe { (*$Uart::ptr()).sta.read().trmt().bit() };
if !trmt {
if trmt {
break;
}
}
Expand Down

0 comments on commit 76eb5ec

Please sign in to comment.