1use crate::{Mutex, Peripheral, uart::*};
2use core::panic::PanicInfo;
3
4use embedded_io::Write;
5
6static mut UART: Option<UartTx<UartTx0>> = None;
7static MUTEX: Mutex = Mutex::new();
8
9pub(crate) fn init_print() {
10 let baud_rate = match option_env!("DEBUG_UART_BAUD_RATE") {
11 Some(size) => u32::from_str_radix(size, 10)
12 .expect("DEBUG_UART_BAUD_RATE must be a valid decimal number"),
13 None => 115_200,
14 };
15 unsafe {
16 UART = Some(UartTx::new(
17 UartTx0::take().unwrap(),
18 UartConfig {
19 baud_rate: BaudRate::Custom(baud_rate),
20 ..Default::default()
21 },
22 ))
23 }
24}
25
26pub struct Printer;
27
28impl Printer {
29 pub fn with_lock<F>(f: F)
32 where
33 F: FnOnce(),
34 {
35 let lock_token = MUTEX.lock();
36 f();
37 MUTEX.release(lock_token);
38 }
39}
40
41impl core::fmt::Write for Printer {
42 fn write_str(&mut self, s: &str) -> core::fmt::Result {
43 #[allow(static_mut_refs)]
44 let uart = unsafe { UART.as_mut().unwrap() };
45 uart.write(s.as_bytes()).unwrap();
46 Ok(())
47 }
48}
49
50#[macro_export]
51macro_rules! println {
52 ($($arg:tt)*) => {{
53 {
54 use core::fmt::Write;
55 $crate::Printer::with_lock(|| {
56 writeln!($crate::Printer, $($arg)*).ok();
57 });
58 }
59 }};
60}
61
62#[macro_export]
63macro_rules! print {
64 ($($arg:tt)*) => {{
65 {
66 use core::fmt::Write;
67 $crate::Printer::with_lock(|| {
68 write!($crate::Printer, $($arg)*).ok();
69 });
70 }
71 }};
72}
73
74pub fn print_panic(panic: &PanicInfo<'_>) {
75 if let Some(location) = panic.location() {
76 println!(
77 "PANIC at {}:{}: {}",
78 location.file(),
79 location.line(),
80 panic.message()
81 );
82 }
83}
84
85pub struct UnguardedPrinter;
86
87impl core::fmt::Write for UnguardedPrinter {
88 fn write_str(&mut self, s: &str) -> core::fmt::Result {
89 unsafe {
90 #[allow(static_mut_refs)]
92 if UART.is_none() {
93 return Ok(());
94 }
95 super::pac::MSS_UART_polled_tx(UartTx0::steal().address(), s.as_ptr(), s.len() as u32);
96 }
97 Ok(())
98 }
99}
100
101#[macro_export]
102macro_rules! println_unguarded {
103 ($($arg:tt)*) => {{
104 {
105 use core::fmt::Write;
106 writeln!($crate::UnguardedPrinter, $($arg)*).ok();
107 }
108 }};
109}
110
111#[macro_export]
112macro_rules! print_unguarded {
113 ($($arg:tt)*) => {{
114 {
115 use core::fmt::Write;
116 write!($crate::UnguardedPrinter, $($arg)*).ok();
117 }
118 }};
119}