zynq-rs/libboard_zynq/src/stdio.rs

69 lines
1.6 KiB
Rust
Raw Normal View History

2019-11-21 00:00:57 +08:00
use core::ops::{Deref, DerefMut};
use libcortex_a9::mutex::{Mutex, MutexGuard};
use crate::uart::Uart;
2019-06-20 06:30:18 +08:00
const UART_RATE: u32 = 115_200;
2019-11-21 00:00:57 +08:00
static mut UART: Mutex<LazyUart> = Mutex::new(LazyUart::Uninitialized);
2019-06-20 06:30:18 +08:00
#[doc(hidden)]
2019-11-21 00:00:57 +08:00
pub fn get_uart<'a>() -> MutexGuard<'a, LazyUart> {
unsafe { UART.lock() }
}
pub fn drop_uart() {
unsafe { UART = Mutex::new(LazyUart::Uninitialized); }
}
2019-11-21 00:00:57 +08:00
/// 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 => {
2019-08-11 06:55:27 +08:00
let uart = Uart::serial(UART_RATE);
2019-11-21 00:00:57 +08:00
*self = LazyUart::Initialized(uart);
self
2019-06-20 06:30:18 +08:00
}
2019-11-21 00:00:57 +08:00
LazyUart::Initialized(uart) =>
uart,
2019-06-20 06:30:18 +08:00
}
}
}
2019-06-21 07:18:24 +08:00
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ({
use core::fmt::Write;
let mut uart = $crate::stdio::get_uart();
2019-08-11 06:55:27 +08:00
let _ = write!(uart, $($arg)*);
2019-06-21 07:18:24 +08:00
})
}
2019-06-20 06:30:18 +08:00
#[macro_export]
macro_rules! println {
($($arg:tt)*) => ({
use core::fmt::Write;
let mut uart = $crate::stdio::get_uart();
2019-08-11 06:55:27 +08:00
let _ = write!(uart, $($arg)*);
let _ = write!(uart, "\r\n");
2019-06-20 06:30:18 +08:00
while !uart.tx_fifo_empty() {}
})
}