mpfs_hal/
print.rs

1use crate::{uart::*, Mutex, Peripheral};
2use core::panic::PanicInfo;
3
4use embedded_io::Write;
5
6static mut UART: Option<Uart<UART0>> = None;
7static MUTEX: Mutex = Mutex::new();
8
9pub(crate) fn init_print() {
10    unsafe { UART = Some(Uart::new(UART0::take().unwrap(), UartConfig::default())) }
11}
12
13pub struct Printer;
14
15impl Printer {
16    // We need to hold onto a lock _longer_ than just what `write_str` needs
17    // because `writeln` will call `write_str` multiple times.
18    pub fn with_lock<F>(f: F)
19    where
20        F: FnOnce(),
21    {
22        let lock_token = MUTEX.lock();
23        f();
24        MUTEX.release(lock_token);
25    }
26}
27
28impl core::fmt::Write for Printer {
29    fn write_str(&mut self, s: &str) -> core::fmt::Result {
30        #[allow(static_mut_refs)]
31        let uart = unsafe { UART.as_mut().unwrap() };
32        uart.write(s.as_bytes()).unwrap();
33        Ok(())
34    }
35}
36
37#[macro_export]
38macro_rules! println {
39    ($($arg:tt)*) => {{
40        {
41            use core::fmt::Write;
42            $crate::Printer::with_lock(|| {
43                writeln!($crate::Printer, $($arg)*).ok();
44            });
45        }
46    }};
47}
48
49#[macro_export]
50macro_rules! print {
51    ($($arg:tt)*) => {{
52        {
53            use core::fmt::Write;
54            $crate::Printer::with_lock(|| {
55                write!($crate::Printer, $($arg)*).ok();
56            });
57        }
58    }};
59}
60
61pub fn print_panic(panic: &PanicInfo<'_>) {
62    if let Some(location) = panic.location() {
63        println!(
64            "PANIC at {}:{}: {}",
65            location.file(),
66            location.line(),
67            panic.message()
68        );
69    }
70}
71
72pub struct UnguardedPrinter;
73
74impl core::fmt::Write for UnguardedPrinter {
75    fn write_str(&mut self, s: &str) -> core::fmt::Result {
76        unsafe {
77            // If the UART is not initialized, do nothing
78            #[allow(static_mut_refs)]
79            if UART.is_none() {
80                return Ok(());
81            }
82            super::pac::MSS_UART_polled_tx(UART0::steal().address(), s.as_ptr(), s.len() as u32);
83        }
84        Ok(())
85    }
86}
87
88#[macro_export]
89macro_rules! println_unguarded {
90    ($($arg:tt)*) => {{
91        {
92            use core::fmt::Write;
93            writeln!($crate::UnguardedPrinter, $($arg)*).ok();
94        }
95    }};
96}
97
98#[macro_export]
99macro_rules! print_unguarded {
100    ($($arg:tt)*) => {{
101        {
102            use core::fmt::Write;
103            write!($crate::UnguardedPrinter, $($arg)*).ok();
104        }
105    }};
106}