kiibohd_log/lib.rs
1// Copyright 2021 Jacob Alexander
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8#![no_std]
9
10pub use log;
11
12#[cfg(feature = "semihosting")]
13pub use cortex_m_semihosting;
14
15#[cfg(feature = "rtt")]
16pub use rtt_target;
17
18/// Logger Structure
19///
20/// Example RTT Usage
21/// ```
22/// use kiibohd_log::{log, Logger};
23///
24/// static LOGGER: Logger = Logger::new(log::LevelFilter::Info);
25///
26/// fn main() {
27/// // Setup RTT logging
28/// let mut channels = rtt_target::rtt_init_default!();
29///
30/// // cortex-m or riscv
31/// //rtt_target::set_print_channel(channels.up.0);
32/// // otherwise use set_print_channel_cs
33/// log::set_logger(&LOGGER).unwrap();
34///
35/// // Example usage
36/// log::trace!("Trace message");
37/// log::debug!("Debug message");
38/// log::info!("Info message");
39/// log::warn!("Warn message");
40/// log::error!("Error message");
41///
42/// // Read downchannel
43/// let mut buf = [0u8; 16];
44/// channels.down.0.read(&mut buf[..]);
45/// log::trace!("{:?}", buf);
46/// }
47/// ```
48///
49/// Example Semihosting Usage
50/// ```
51/// use kiibohd_log::{log, Logger};
52///
53/// static LOGGER: Logger = Logger::new(log::LevelFilter::Info);
54///
55/// fn main() {
56/// log::set_logger(&LOGGER).unwrap();
57///
58/// // Example usage
59/// log::trace!("Trace message");
60/// log::debug!("Debug message");
61/// log::info!("Info message");
62/// log::warn!("Warn message");
63/// log::error!("Error message");
64/// }
65/// ```
66pub struct Logger {
67 level_filter: log::LevelFilter,
68}
69
70impl Logger {
71 pub const fn new(level_filter: log::LevelFilter) -> Self {
72 Self { level_filter }
73 }
74}
75
76impl log::Log for Logger {
77 fn enabled(&self, metadata: &log::Metadata) -> bool {
78 self.level_filter.ge(&metadata.level())
79 }
80
81 // Handle entry prefixes
82 fn log(&self, record: &log::Record) {
83 if self.enabled(record.metadata()) {
84 #[cfg(any(feature = "rtt", feature = "semihosting"))]
85 let color = match record.level() {
86 log::Level::Error => "1;5;31",
87 log::Level::Warn => "1;33",
88 log::Level::Info => "1;32",
89 log::Level::Debug => "1;35",
90 log::Level::Trace => "1;90",
91 };
92 #[cfg(any(feature = "rtt", feature = "semihosting"))]
93 let dwt = unsafe { &*cortex_m::peripheral::DWT::ptr() };
94 #[cfg(feature = "rtt")]
95 rtt_target::rprintln!(
96 "{:10}:\x1b[{}m{:5}\x1b[0m:{}",
97 dwt.get_cycle_count(),
98 color,
99 record.level(),
100 record.args()
101 );
102 #[cfg(feature = "semihosting")]
103 cortex_m_semihosting::hprintln!(
104 "{:10}:\x1b[{}m{:5}\x1b[0m:{}",
105 dwt.get_cycle_count(),
106 color,
107 record.level(),
108 record.args()
109 )
110 .ok();
111 /* TODO (HaaTa) Add itm support
112 #[cfg(feature = "itm")]
113 {
114 let itm = unsafe { &mut *cortex_m::peripheral::ITM::ptr() };
115 let stim = &mut itm.stim[0];
116 cortex_m::iprintln!(stim,
117 "{}:\x1b[{}m{}\x1b[0m - {}",
118 dwt.cyccnt.read(),
119 color,
120 record.level(),
121 record.args()
122 );
123 }
124 */
125 }
126 }
127
128 fn flush(&self) {}
129}