1#[cfg(not(feature = "std"))]
21pub mod ffi {
22 use core::ffi::{c_char, c_int};
23
24 unsafe extern "C" {
25 pub fn printf_on_uart(format: *const c_char, ...) -> c_int;
26
27 }
28}
29
30use core::ffi::c_char;
31
32use alloc::{ffi::CString, format};
33
34use crate::log::ffi::printf_on_uart;
35use crate::os::{System, SystemFn};
36
37
38const COLOR_RED: &str = "\x1b[31m";
39const COLOR_GREEN: &str = "\x1b[32m";
40const COLOR_YELLOW: &str = "\x1b[33m";
41const COLOR_BLUE: &str = "\x1b[34m";
42const COLOR_MAGENTA: &str = "\x1b[35m";
43const COLOR_CYAN: &str = "\x1b[36m";
44const COLOR_RESET: &str = "\x1b[0m";
45pub const RETURN: &str = "\r\n";
46
47pub mod log_levels {
48 pub const FLAG_DEBUG: u8 = 1 << 0;
49 pub const FLAG_INFO: u8 = 1 << 1;
50 pub const FLAG_WARNING: u8 = 1 << 2;
51 pub const FLAG_ERROR: u8 = 1 << 3;
52 pub const FLAG_FATAL: u8 = 1 << 4;
53 pub const FLAG_COLOR_ON: u8 = 1 << 6;
54 pub const FLAG_STATE_ON: u8 = 1 << 7;
55
56 pub const LEVEL_DEBUG: u8 = FLAG_DEBUG | FLAG_INFO | FLAG_WARNING | FLAG_ERROR | FLAG_FATAL;
57 pub const LEVEL_INFO: u8 = FLAG_INFO | FLAG_WARNING | FLAG_ERROR | FLAG_FATAL;
58 pub const LEVEL_WARNING: u8 = FLAG_WARNING | FLAG_ERROR | FLAG_FATAL;
59 pub const LEVEL_ERROR: u8 = FLAG_ERROR | FLAG_FATAL;
60
61 pub const LEVEL_FATAL: u8 = FLAG_FATAL;
62}
63
64static mut MASK: u8 = log_levels::LEVEL_DEBUG | log_levels::FLAG_COLOR_ON | log_levels::FLAG_STATE_ON;
65static mut BUSY: u8 = 0;
66
67#[cfg(not(feature = "std"))]
68#[macro_export]
69macro_rules! print {
70 ($($arg:tt)*) => {{
71 unsafe {
72 use alloc::string::ToString;
73 let formatted = alloc::format!($($arg)*);
74 if let Ok(c_str) = alloc::ffi::CString::new(formatted) {
75 $crate::log::ffi::printf_on_uart(b"%s\0".as_ptr() as *const core::ffi::c_char, c_str.as_ptr());
76 }
77 }
78 }};
79}
80
81#[cfg(not(feature = "std"))]
82#[macro_export]
83macro_rules! println {
84 () => {
85 $crate::print!("\r\n")
86 };
87 ($fmt:expr) => {{
88 unsafe {
89 use alloc::string::ToString;
90 let formatted = alloc::format!(concat!($fmt, "\r\n"));
91 if let Ok(c_str) = alloc::ffi::CString::new(formatted) {
92 $crate::log::ffi::printf_on_uart(b"%s\0".as_ptr() as *const core::ffi::c_char, c_str.as_ptr());
93 }
94 }
95 }};
96 ($fmt:expr, $($arg:tt)*) => {{
97 unsafe {
98 use alloc::string::ToString;
99 let formatted = alloc::format!(concat!($fmt, "\r\n"), $($arg)*);
100 if let Ok(c_str) = alloc::ffi::CString::new(formatted) {
101 $crate::log::ffi::printf_on_uart(b"%s\0".as_ptr() as *const core::ffi::c_char, c_str.as_ptr());
102 }
103 }
104 }};
105}
106
107pub fn set_level_log(level: u8) {
108 unsafe {
109 MASK =
110 (MASK & log_levels::FLAG_STATE_ON) | (level & !log_levels::FLAG_STATE_ON);
111 }
112}
113
114pub fn set_enable_log(enabled: bool) {
115 unsafe {
116 if enabled {
117 MASK |= log_levels::FLAG_STATE_ON;
118 } else {
119 MASK &= !log_levels::FLAG_STATE_ON;
120 }
121 }
122}
123
124pub fn get_enable_log() -> bool {
125 unsafe { (MASK & log_levels::FLAG_STATE_ON) != 0 }
126}
127
128pub fn is_enabled_log(log_type: u8) -> bool {
129 unsafe { (MASK & log_levels::FLAG_STATE_ON) != 0 && (MASK & log_type) != 0 }
130}
131
132pub fn get_level_log() -> u8 {
133 unsafe { MASK & !log_levels::FLAG_STATE_ON & !log_levels::FLAG_COLOR_ON }
134}
135
136pub fn set_enable_color(enabled: bool) {
137 unsafe {
138 if enabled {
139 MASK |= log_levels::FLAG_COLOR_ON;
140 } else {
141 MASK &= !log_levels::FLAG_COLOR_ON;
142 }
143 }
144}
145
146
147
148pub fn sys_log(tag: &str, log_type: u8, to_print: &str) {
149 unsafe {
150 while BUSY != 0 {}
151 BUSY = 1;
152
153 let mut color_reset = COLOR_RESET;
154 let color = if MASK & log_levels::FLAG_COLOR_ON == log_levels::FLAG_COLOR_ON {
155
156 match log_type {
157 log_levels::FLAG_DEBUG => COLOR_CYAN,
158 log_levels::FLAG_INFO => COLOR_GREEN,
159 log_levels::FLAG_WARNING => COLOR_YELLOW,
160 log_levels::FLAG_ERROR => COLOR_RED,
161 log_levels::FLAG_FATAL => COLOR_MAGENTA,
162 _ => COLOR_RESET,
163 }
164 } else {
165 color_reset = "";
166 ""
167 };
168
169
170 let now = System::get_current_time_us();
171
172
173 #[cfg(not(feature = "std"))]
174 {
175 let formatted = format!("{color}({millis}ms)[{tag}] {to_print}{color_reset}{RETURN}", millis=now.as_millis());
176 if let Ok(c_str) = CString::new(formatted) {
177 printf_on_uart(b"%s\0".as_ptr() as *const c_char, c_str.as_ptr());
178 }
179 }
180
181 #[cfg(feature = "std")]
182 {
183 print!("{}[{}] ", color, tag);
184 core::fmt::write(&mut core::fmt::Formatter::new(), args).unwrap();
185 print!("{}", COLOR_RESET);
186 print!("\r\n");
187 }
188
189 BUSY = 0;
190 }
191}
192
193#[macro_export]
194macro_rules! log_debug {
195 ($app_tag:expr, $fmt:expr $(, $($arg:tt)*)?) => {{
196 if $crate::log::is_enabled_log($crate::log::log_levels::FLAG_DEBUG) {
197 let msg = alloc::format!($fmt $(, $($arg)*)?);
198 $crate::log::sys_log($app_tag, $crate::log::log_levels::FLAG_DEBUG, &msg);
199 }
200 }};
201}
202
203#[macro_export]
204macro_rules! log_info {
205 ($app_tag:expr, $fmt:expr $(, $($arg:tt)*)?) => {{
206 if $crate::log::is_enabled_log($crate::log::log_levels::FLAG_INFO) {
207 let msg = alloc::format!($fmt $(, $($arg)*)?);
208 $crate::log::sys_log($app_tag, $crate::log::log_levels::FLAG_INFO, &msg);
209 }
210 }};
211}
212
213#[macro_export]
214macro_rules! log_warning {
215 ($app_tag:expr, $fmt:expr $(, $($arg:tt)*)?) => {{
216 if $crate::log::is_enabled_log($crate::log::log_levels::FLAG_WARNING) {
217 let msg = alloc::format!($fmt $(, $($arg)*)?);
218 $crate::log::sys_log($app_tag, $crate::log::log_levels::FLAG_WARNING, &msg);
219 }
220 }};
221}
222
223#[macro_export]
224macro_rules! log_error {
225 ($app_tag:expr, $fmt:expr $(, $($arg:tt)*)?) => {{
226 if $crate::log::is_enabled_log($crate::log::log_levels::FLAG_ERROR) {
227 let msg = alloc::format!($fmt $(, $($arg)*)?);
228 $crate::log::sys_log($app_tag, $crate::log::log_levels::FLAG_ERROR, &msg);
229 }
230 }};
231}
232
233#[macro_export]
234macro_rules! log_fatal {
235 ($app_tag:expr, $fmt:expr $(, $($arg:tt)*)?) => {{
236 if $crate::log::is_enabled_log($crate::log::log_levels::FLAG_FATAL) {
237 let msg = alloc::format!($fmt $(, $($arg)*)?);
238 $crate::log::sys_log($app_tag, $crate::log::log_levels::FLAG_FATAL, &msg);
239 }
240 }};
241}