use super::bcm2837::mini_uart::MiniUart; use core::fmt; use spin::Mutex; /// Struct to get a global SerialPort interface pub struct SerialPort { mu: Option, } pub trait SerialRead { fn receive(&mut self) -> u8; } impl SerialPort { /// Creates a new instance of `SerialPort`. const fn new() -> SerialPort { SerialPort { mu: None } } /// Init a newly created SerialPort, can only be called once. pub fn init(&mut self) { assert_has_not_been_called!("SerialPort::init must be called only once"); self.mu = Some(MiniUart::new()); } /// Writes the byte `byte` to the UART device. pub fn write_byte(&mut self, byte: u8) { match &mut self.mu { Some(mu) => mu.write_byte(byte), None => panic!("SerialPort is not initialized"), } } /// Reads a byte from the UART device, blocking until a byte is available. pub fn read_byte(&mut self) -> u8 { match &mut self.mu { Some(mu) => return mu.read_byte(), None => panic!("SerialPort is not initialized"), } } } impl SerialRead for SerialPort { fn receive(&mut self) -> u8 { self.read_byte() } } impl fmt::Write for SerialPort { fn write_str(&mut self, s: &str) -> fmt::Result { for byte in s.bytes() { match byte { // Backspace b'\x7f' => { self.write_byte(b'\x08'); self.write_byte(b' '); self.write_byte(b'\x08'); } // Return b'\n' => { self.write_byte(b'\r'); self.write_byte(b'\n'); } // Others _ => self.write_byte(byte), } } Ok(()) } } pub static SERIAL_PORT: Mutex = Mutex::new(SerialPort::new());