use core::fmt::{Arguments, Result, Write};
use bitflags::bitflags;
bitflags! {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ConsoleIrqEvent: u32 {
const RX_READY = 1 << 0;
const RX_ERROR = 1 << 1;
const OVERRUN = 1 << 2;
}
}
#[def_plat_interface]
pub trait ConsoleIf {
fn write_bytes(bytes: &[u8]);
fn read_bytes(bytes: &mut [u8]) -> usize;
#[cfg(feature = "irq")]
fn irq_num() -> Option<usize>;
#[cfg(feature = "irq")]
fn set_input_irq_enabled(enabled: bool);
#[cfg(feature = "irq")]
fn handle_irq() -> ConsoleIrqEvent;
}
struct EarlyConsole;
impl Write for EarlyConsole {
fn write_str(&mut self, s: &str) -> Result {
write_text_bytes(s.as_bytes());
Ok(())
}
}
pub fn write_text_bytes(bytes: &[u8]) {
let mut start = 0;
for (i, &byte) in bytes.iter().enumerate() {
if byte == b'\n' {
if start < i {
write_bytes(&bytes[start..i]);
}
write_bytes(b"\r\n");
start = i + 1;
}
}
if start < bytes.len() {
write_bytes(&bytes[start..]);
}
}
pub static CONSOLE_LOCK: ax_kspin::SpinNoIrq<()> = ax_kspin::SpinNoIrq::new(());
#[macro_export]
macro_rules! console_print {
($($arg:tt)*) => {
$crate::console::__simple_print(format_args!($($arg)*));
}
}
#[macro_export]
macro_rules! console_println {
() => { $crate::ax_print!("\n") };
($($arg:tt)*) => {
$crate::console::__simple_print(format_args!("{}\n", format_args!($($arg)*)));
}
}
#[doc(hidden)]
pub fn __simple_print(fmt: Arguments) {
let _guard = CONSOLE_LOCK.lock();
EarlyConsole.write_fmt(fmt).unwrap();
drop(_guard);
}