1#![no_std]
2
3use cortex_m::iprint;
4use stm32f1xx_hal::pac::{ITM, DCB};
5
6#[macro_export]
7macro_rules! log_debug {
8 ($logger:expr, $fmt:expr) => {
9 unsafe {
10 $logger.borrow_mut().log_debug($fmt);
11 }
12 };
13 ($logger:expr, $fmt:expr, $($arg:tt)*) => {
14 unsafe {
15 extern crate alloc;
16 $logger.borrow_mut().log_debug(&alloc::format!($fmt, $($arg)*));
17 }
18 };
19}
20
21#[macro_export]
22macro_rules! log_info {
23 ($logger:expr, $fmt:expr) => {
24 unsafe {
25 $logger.borrow_mut().log_info($fmt);
26 }
27 };
28 ($logger:expr, $fmt:expr, $($arg:tt)*) => {
29 unsafe {
30 extern crate alloc;
31 $logger.borrow_mut().log_info(&alloc::format!($fmt, $($arg)*));
32 }
33 };
34}
35
36#[macro_export]
37macro_rules! log_warning {
38 ($logger:expr, $fmt:expr) => {
39 unsafe {
40 $logger.borrow_mut().log_warning($fmt);
41 }
42 };
43 ($logger:expr, $fmt:expr, $($arg:tt)*) => {
44 unsafe {
45 extern crate alloc;
46 $logger.borrow_mut().log_warning(&alloc::format!($fmt, $($arg)*));
47 }
48 };
49}
50
51#[macro_export]
52macro_rules! log_error {
53 ($logger:expr, $fmt:expr) => {
54 unsafe {
55 $logger.borrow_mut().log_error($fmt);
56 }
57 };
58 ($logger:expr, $fmt:expr, $($arg:tt)*) => {
59 unsafe {
60 extern crate alloc;
61 $logger.borrow_mut().log_error(&alloc::format!($fmt, $($arg)*));
62 }
63 };
64}
65
66pub enum LogLevel {
67 Debug,
68 Info,
69 Warning,
70 Error,
71}
72
73pub struct Logger {
74 log_level: LogLevel,
75 itm: ITM,
76}
77
78impl Logger {
79 pub fn new(log_level: LogLevel, itm: ITM) -> Self {
80 Logger { log_level, itm }
81 }
82
83 pub fn change_log_level(&mut self, log_level: LogLevel) {
84 self.log_level = log_level;
85 }
86
87 pub fn log_debug(&mut self, message: &str) {
88 if matches!(self.log_level, LogLevel::Debug) {
89 self.log("[DEBUG] ");
90 self.log(message);
91 self.log("\r\n");
92 }
93 }
94
95 pub fn log_info(&mut self, message: &str) {
96 if matches!(self.log_level, LogLevel::Debug) || matches!(self.log_level, LogLevel::Info) {
97 self.log("[INFO] ");
98 self.log(message);
99 self.log("\r\n");
100 }
101 }
102
103 pub fn log_warning(&mut self, message: &str) {
104 if matches!(self.log_level, LogLevel::Debug)
105 || matches!(self.log_level, LogLevel::Info)
106 || matches!(self.log_level, LogLevel::Warning)
107 {
108 self.log("[WARNING] ");
109 self.log(message);
110 self.log("\r\n");
111 }
112 }
113
114 pub fn log_error(&mut self, message: &str) {
115 self.log("[ERROR] ");
116 self.log(message);
117 self.log("\r\n");
118 }
119
120 fn log(&mut self, message: &str) {
121 if !DCB::is_debugger_attached() {
123 return;
124 }
125
126 iprint!(&mut self.itm.stim[0], message);
127 }
128}