#![no_std]
#[cfg(test)]
extern crate std;
pub mod ns16550;
pub mod pl011;
use bitflags::bitflags;
pub trait PollingUart {
fn poll_status(&mut self) -> PollingEvent;
fn write_byte(&mut self, byte: u8);
fn read_byte(&mut self, status: PollingEvent) -> Option<Result<u8, TransferError>>;
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PollingEvent: u32 {
const RX_READY = 0x01;
const TX_READY = 0x02;
const RX_ERROR = 0x04;
const TX_ERROR = 0x08;
const OVERRUN = 0x10;
const MODEM_STATUS = 0x20;
}
}
impl PollingEvent {
pub const fn rx_ready(self) -> bool {
self.contains(Self::RX_READY)
}
pub const fn tx_ready(self) -> bool {
self.contains(Self::TX_READY)
}
pub const fn rx_error(self) -> bool {
self.intersects(Self::RX_ERROR.union(Self::OVERRUN))
}
}
pub type SerialEvent = PollingEvent;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SerialDirection {
Input,
Output,
}
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransferError {
#[error("data overrun by `{0:#x}`")]
Overrun(u8),
#[error("parity error")]
Parity,
#[error("framing error")]
Framing,
#[error("break condition")]
Break,
#[error("serial closed")]
Closed,
}
#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
#[error("transfer error after transferring {bytes_transferred} bytes: {kind}")]
pub struct TransBytesError {
pub bytes_transferred: usize,
#[source]
pub kind: TransferError,
}
pub use rdif_serial::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn transferred_byte_error_preserves_transfer_source() {
let error = TransBytesError {
bytes_transferred: 7,
kind: TransferError::Framing,
};
assert_eq!(
std::format!("{error}"),
"transfer error after transferring 7 bytes: framing error"
);
assert!(core::error::Error::source(&error).is_some());
}
}