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 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 #[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}