use arbitrary_int::u2;
#[bitbybit::bitfield(u32)]
pub struct Fifo {
#[bits(0..=7, rw)]
data: u8,
}
#[bitbybit::bitfield(u32)]
pub struct InterruptEnable {
#[bit(3, rw)]
modem_status: bool,
#[bit(2, rw)]
line_status: bool,
#[bit(1, rw)]
thr_empty: bool,
#[bit(0, rw)]
rx_avl: bool,
}
#[bitbybit::bitenum(u3, exhaustive = false)]
#[derive(Debug, PartialEq, Eq)]
pub enum InterruptId2 {
ReceiverLineStatus = 0b011,
RxDataAvailable = 0b010,
CharTimeout = 0b110,
ThrEmpty = 0b001,
ModemStatus = 0b000,
}
#[bitbybit::bitfield(u32)]
pub struct InterruptIdentification {
#[bits(6..=7, r)]
fifo_enabled: u2,
#[bits(1..=3, r)]
int_id: Option<InterruptId2>,
#[bit(0, r)]
int_pend_n: bool,
}
#[bitbybit::bitenum(u2, exhaustive = true)]
pub enum RxFifoTrigger {
OneByte = 0b00,
FourBytes = 0b01,
EightBytes = 0b10,
FourteenBytes = 0b11,
}
impl RxFifoTrigger {
pub const fn as_num(self) -> u32 {
match self {
RxFifoTrigger::OneByte => 1,
RxFifoTrigger::FourBytes => 4,
RxFifoTrigger::EightBytes => 8,
RxFifoTrigger::FourteenBytes => 14,
}
}
}
#[bitbybit::bitfield(u32, default = 0x0)]
pub struct FifoControl {
#[bits(4..=5, rw)]
rx_fifo_trigger: RxFifoTrigger,
#[bit(3, rw)]
dma_mode_sel: bool,
#[bit(2, rw)]
reset_tx_fifo: bool,
#[bit(1, rw)]
reset_rx_fifo: bool,
#[bit(0, rw)]
fifo_enable: bool,
}
#[bitbybit::bitenum(u2, exhaustive = true)]
#[derive(Default, Debug, PartialEq, Eq)]
pub enum WordLen {
Five = 0b00,
Six = 0b01,
Seven = 0b10,
#[default]
Eight = 0b11,
}
#[bitbybit::bitenum(u1, exhaustive = true)]
#[derive(Default, Debug, PartialEq, Eq)]
pub enum StopBits {
#[default]
One = 0b0,
OnePointFiveOrTwo = 0b1,
}
#[bitbybit::bitfield(u32, default = 0x00)]
pub struct LineControl {
#[bit(7, rw)]
div_access_latch: bool,
#[bit(6, rw)]
set_break: bool,
#[bit(5, rw)]
stick_parity: bool,
#[bit(4, rw)]
even_parity: bool,
#[bit(3, rw)]
parity_enable: bool,
#[bit(2, rw)]
stop_bits: StopBits,
#[bits(0..=1, rw)]
word_len: WordLen,
}
impl LineControl {
pub fn new_for_divisor_access() -> Self {
Self::new_with_raw_value(0x80)
}
}
#[bitbybit::bitfield(u32)]
#[derive(Debug)]
pub struct LineStatus {
#[bit(7, rw)]
error_in_rx_fifo: bool,
#[bit(6, rw)]
tx_empty: bool,
#[bit(5, rw)]
thr_empty: bool,
#[bit(4, rw)]
break_interrupt: bool,
#[bit(3, rw)]
framing_error: bool,
#[bit(2, rw)]
parity_error: bool,
#[bit(1, rw)]
overrun_error: bool,
#[bit(0, rw)]
data_ready: bool,
}
#[derive(derive_mmio::Mmio)]
#[repr(C)]
pub struct Registers {
_reserved: [u32; 0x400],
fifo_or_dll: u32,
ier_or_dlm: u32,
iir_or_fcr: u32,
lcr: LineControl,
mcr: u32,
lsr: LineStatus,
msr: u32,
scr: u32,
}