//! # UART Console Definition use super::*; use crate::bsp::drivers::gpio::*; use crate::cpu::*; use crate::lib::sync::interface::Mutex; use crate::lib::sync::SpinLock; use core::fmt; /// # UART Inner Structure /// /// Keeps record of the console statistics. struct UartInner { chars_written: usize, } /// # UART Structure /// /// Wraps the UART writer in a sharable lock. pub struct Uart { inner: SpinLock, } impl UartInner { /// # Clear statistics /// /// Create the writer with cleared statistics pub const fn new() -> Self { Self { chars_written: 0 } } /// # Initialize the UART setup /// /// Set baud rate and timings pub fn init(&mut self) { UART::CR::off(); GPPUDCLK0::init(); UART::ICR::clear(); UART::IBRD::set(9); UART::FBRD::set(49); UART::LCRH::enable8(); UART::IMSC::mask(); UART::CR::all_on(); } /// # Write `char` to UART fn write_char(&mut self, ch: char) { while UART::FR::TXFF::is_set() { nop(); } UART::DR::set(ch); self.chars_written += 1; } /// # Flush UART fn flush(&self) { while UART::FR::BUSY::is_set() { nop(); } } } impl fmt::Write for UartInner { /// # Write string to UART console fn write_str(&mut self, s: &str) -> fmt::Result { for c in s.chars() { self.write_char(c); } Ok(()) } } impl Uart { /// # Create sharable UART wrapper pub const fn new() -> Self { Self { inner: SpinLock::new(UartInner::new()), } } /// # Call UART initialization pub fn init(&self) -> Result<(), &'static str> { self.inner.lock(|inner| inner.init()); Ok(()) } } impl crate::lib::console::interface::Write for Uart { /// # Write `char` to UART fn write_char(&self, c: char) { self.inner.lock(|inner| inner.write_char(c)); } /// # Write formatted string to UART fn write_fmt(&self, args: core::fmt::Arguments) -> fmt::Result { self.inner.lock(|inner| fmt::Write::write_fmt(inner, args)) } /// # Flush UART fn flush(&self) { self.inner.lock(|inner| inner.flush()); } } impl crate::lib::console::interface::Statistics for Uart { /// # Get `char` written stats fn chars_written(&self) -> usize { self.inner.lock(|inner| inner.chars_written) } } /// # UART Writer + Stats impl crate::lib::console::interface::All for Uart {}