1use core::fmt::{Arguments, Result, Write};
4
5use bitflags::bitflags;
6
7bitflags! {
8 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
10 pub struct ConsoleIrqEvent: u32 {
11 const RX_READY = 1 << 0;
13 const RX_ERROR = 1 << 1;
15 const OVERRUN = 1 << 2;
17 }
18}
19
20#[def_plat_interface]
22pub trait ConsoleIf {
23 fn write_bytes(bytes: &[u8]);
25
26 fn read_bytes(bytes: &mut [u8]) -> usize;
30
31 #[cfg(feature = "irq")]
35 fn irq_num() -> Option<usize>;
36
37 #[cfg(feature = "irq")]
39 fn set_input_irq_enabled(enabled: bool);
40
41 #[cfg(feature = "irq")]
44 fn handle_irq() -> ConsoleIrqEvent;
45}
46
47struct EarlyConsole;
48
49impl Write for EarlyConsole {
50 fn write_str(&mut self, s: &str) -> Result {
51 write_text_bytes(s.as_bytes());
52 Ok(())
53 }
54}
55
56pub fn write_text_bytes(bytes: &[u8]) {
61 let mut start = 0;
62 for (i, &byte) in bytes.iter().enumerate() {
63 if byte == b'\n' {
64 if start < i {
65 write_bytes(&bytes[start..i]);
66 }
67 write_bytes(b"\r\n");
68 start = i + 1;
69 }
70 }
71 if start < bytes.len() {
72 write_bytes(&bytes[start..]);
73 }
74}
75
76pub static CONSOLE_LOCK: ax_kspin::SpinNoIrq<()> = ax_kspin::SpinNoIrq::new(());
78
79#[macro_export]
81macro_rules! console_print {
82 ($($arg:tt)*) => {
83 $crate::console::__simple_print(format_args!($($arg)*));
84 }
85}
86
87#[macro_export]
89macro_rules! console_println {
90 () => { $crate::ax_print!("\n") };
91 ($($arg:tt)*) => {
92 $crate::console::__simple_print(format_args!("{}\n", format_args!($($arg)*)));
93 }
94}
95
96#[doc(hidden)]
97pub fn __simple_print(fmt: Arguments) {
98 let _guard = CONSOLE_LOCK.lock();
99 EarlyConsole.write_fmt(fmt).unwrap();
100 drop(_guard);
101}