1#![no_std]
2
3use core::convert::Infallible;
4use local_static::LocalStatic;
5use rtt_target::UpChannel;
6use rtt_target::rtt::*;
7pub use ufmt;
8
9pub struct Printer;
10
11#[cfg(all(feature = "print-enable", not(feature = "ufmt")))]
12#[macro_export]
13macro_rules! println {
14 ($($arg:tt)*) => {{
15 {
16 use core::fmt::Write;
17 writeln!($crate::Printer, $($arg)*).ok();
18 }
19 }};
20}
21
22#[cfg(all(feature = "print-enable", not(feature = "ufmt")))]
23#[macro_export]
24macro_rules! print {
25 ($($arg:tt)*) => {{
26 {
27 use core::fmt::Write;
28 write!($crate::Printer, $($arg)*).ok();
29 }
30 }};
31}
32
33#[cfg(all(feature = "print-enable", feature = "ufmt"))]
34#[macro_export]
35macro_rules! println {
36 ($($arg:tt)*) => {{
37 {
38 use $crate::ufmt::{self, uWrite, uwriteln, UnstableDoAsFormatter};
39 uwriteln!($crate::Printer, $($arg)*).ok();
40 }
41 }};
42}
43
44#[cfg(all(feature = "print-enable", feature = "ufmt"))]
45#[macro_export]
46macro_rules! print {
47 ($($arg:tt)*) => {{
48 {
49 use $crate::ufmt::{self, uWrite, uwrite, UnstableDoAsFormatter};
50 uwrite!($crate::Printer, $($arg)*).ok();
51 }
52 }};
53}
54
55#[cfg(not(feature = "print-enable"))]
56#[macro_export]
57macro_rules! println {
58 ($($arg:tt)*) => {{}};
59}
60
61#[cfg(not(feature = "print-enable"))]
62#[macro_export]
63macro_rules! print {
64 ($($arg:tt)*) => {{}};
65}
66
67#[repr(C)]
68pub struct RttControlBlock {
69 header: RttHeader,
70 up_channels: [RttChannel; 1],
71}
72
73#[used]
74#[unsafe(export_name = "_SEGGER_RTT")]
75pub static CONTROL_BLOCK: LocalStatic<RttControlBlock> = LocalStatic::new();
76pub static UP_CHANNEL: LocalStatic<UpChannel> = LocalStatic::new();
77
78pub fn rtt_print_init() {
79 unsafe {
80 let cb: &mut RttControlBlock = CONTROL_BLOCK.get_mut();
81 let name = "Output [0]\u{0}".as_bytes().as_ptr();
82 let mode = rtt_target::ChannelMode::NoBlockTrim;
83
84 cb.up_channels[0].init(name, mode, {
85 static _RTT_CHANNEL_BUFFER: LocalStatic<[u8; UP_CH_BUFF_SIZE]> = LocalStatic::new();
86 _RTT_CHANNEL_BUFFER.get_mut() as *mut [u8]
87 });
88
89 cb.header.init(cb.up_channels.len(), 0);
90 UP_CHANNEL.set(UpChannel::new(&mut (cb.up_channels)[0] as *mut _));
91 }
92}
93
94impl ufmt::uWrite for Printer {
95 type Error = Infallible;
96
97 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
98 let bytes = s.as_bytes();
99 UP_CHANNEL.get_mut().write(bytes);
100
101 Ok(())
102 }
103}
104
105impl core::fmt::Write for Printer {
106 fn write_str(&mut self, s: &str) -> core::fmt::Result {
107 let bytes = s.as_bytes();
108 UP_CHANNEL.get_mut().write(bytes);
109
110 Ok(())
111 }
112}
113
114#[cfg(feature = "up-ch-buff-size-64")]
115pub const UP_CH_BUFF_SIZE: usize = 64;
116#[cfg(feature = "up-ch-buff-size-128")]
117pub const UP_CH_BUFF_SIZE: usize = 128;
118#[cfg(feature = "up-ch-buff-size-256")]
119pub const UP_CH_BUFF_SIZE: usize = 256;
120#[cfg(feature = "up-ch-buff-size-512")]
121pub const UP_CH_BUFF_SIZE: usize = 512;
122#[cfg(feature = "up-ch-buff-size-1024")]
123pub const UP_CH_BUFF_SIZE: usize = 1024;
124#[cfg(feature = "up-ch-buff-size-2048")]
125pub const UP_CH_BUFF_SIZE: usize = 2048;
126#[cfg(feature = "up-ch-buff-size-4096")]
127pub const UP_CH_BUFF_SIZE: usize = 4096;
128
129#[cfg(not(any(
130 feature = "up-ch-buff-size-64",
131 feature = "up-ch-buff-size-128",
132 feature = "up-ch-buff-size-256",
133 feature = "up-ch-buff-size-512",
134 feature = "up-ch-buff-size-1024",
135 feature = "up-ch-buff-size-2048",
136 feature = "up-ch-buff-size-4096",
137)))]
138pub const UP_CH_BUFF_SIZE: usize = 256;