blob: e3ee2f296f592e67b534f2d4edba7c02a06e426b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
//! # 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<UartInner>,
}
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 {}
|