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}