//! Quick and dirty LiteX uart drier


const REG_RXTX: u32 = 0;
const REG_TXFULL: u32 = 0x4;
//const REG_RXEMPTY: u32 = 0x8;

use crate::{write_reg, read_reg};
use core::fmt::Write;

pub enum Error {
    TxFull,
    RxEmpty,
}

pub struct LiteXUart {
    base_addr: u32,
}

impl LiteXUart {
    pub fn new(base_addr: u32) -> Self{ Self {base_addr} }

    pub fn try_put_char(&mut self, c: u8) -> Result<(), Error> {
        unsafe {
            if read_reg::<u32>(self.base_addr + REG_TXFULL) != 0 {
                return Err(Error::TxFull);
            }

            write_reg::<u32>(self.base_addr + REG_RXTX, c as u32);
            Ok(())
        }
    }
}

impl Write for LiteXUart {
    fn write_str(&mut self, s: &str) -> core::fmt::Result {
        for b in s.as_bytes() {
            // It's okay to loop on this because we'll always clear the buffer
            while let Err(Error::TxFull) = self.try_put_char(*b) {}
            //self.try_put_char(*b);
        }

        Ok(())
    }
}
