use core::ops::{Deref, DerefMut}; use libcortex_a9::mutex::{Mutex, MutexGuard}; use crate::uart::Uart; const UART_RATE: u32 = 115_200; static mut UART: Mutex = Mutex::new(LazyUart::Uninitialized); #[doc(hidden)] pub fn get_uart<'a>() -> MutexGuard<'a, LazyUart> { unsafe { UART.lock() } } /// Initializes the UART on first use through `.deref_mut()` for debug /// output through the `print!` and `println!` macros. pub enum LazyUart { Uninitialized, Initialized(Uart), } impl Deref for LazyUart { type Target = Uart; fn deref(&self) -> &Uart { match self { LazyUart::Uninitialized => panic!("stdio not initialized!"), LazyUart::Initialized(uart) => uart, } } } impl DerefMut for LazyUart { fn deref_mut(&mut self) -> &mut Uart { match self { LazyUart::Uninitialized => { let uart = Uart::serial(UART_RATE); *self = LazyUart::Initialized(uart); self } LazyUart::Initialized(uart) => uart, } } } #[macro_export] macro_rules! print { ($($arg:tt)*) => ({ use core::fmt::Write; let mut uart = $crate::stdio::get_uart(); let _ = write!(uart, $($arg)*); }) } #[macro_export] macro_rules! println { ($($arg:tt)*) => ({ use core::fmt::Write; let mut uart = $crate::stdio::get_uart(); let _ = write!(uart, $($arg)*); let _ = write!(uart, "\r\n"); while !uart.tx_fifo_empty() {} }) }