1use core::{fmt, ptr, slice};
6
7use crate::peripheral::itm::Stim;
8
9unsafe fn write_words(stim: &mut Stim, bytes: &[u32]) {
11 unsafe {
12 let mut p = bytes.as_ptr();
13 for _ in 0..bytes.len() {
14 while !stim.is_fifo_ready() {}
15 stim.write_u32(ptr::read(p));
16 p = p.offset(1);
17 }
18 }
19}
20
21unsafe fn write_aligned_impl(port: &mut Stim, buffer: &[u8]) {
25 unsafe {
26 let len = buffer.len();
27
28 if len == 0 {
29 return;
30 }
31
32 let split = len & !0b11;
33 #[allow(clippy::cast_ptr_alignment)]
34 write_words(
35 port,
36 slice::from_raw_parts(buffer.as_ptr() as *const u32, split >> 2),
37 );
38
39 let mut left = len & 0b11;
41 let mut ptr = buffer.as_ptr().add(split);
42
43 if left > 1 {
45 while !port.is_fifo_ready() {}
46
47 #[allow(clippy::cast_ptr_alignment)]
48 port.write_u16(ptr::read(ptr as *const u16));
49
50 ptr = ptr.offset(2);
51 left -= 2;
52 }
53
54 if left == 1 {
56 while !port.is_fifo_ready() {}
57 port.write_u8(*ptr);
58 }
59 }
60}
61
62struct Port<'p>(&'p mut Stim);
63
64impl fmt::Write for Port<'_> {
65 #[inline]
66 fn write_str(&mut self, s: &str) -> fmt::Result {
67 write_all(self.0, s.as_bytes());
68 Ok(())
69 }
70}
71
72#[repr(align(4))]
77pub struct Aligned<T: ?Sized>(pub T);
78
79#[allow(clippy::missing_inline_in_public_items)]
81pub fn write_all(port: &mut Stim, buffer: &[u8]) {
82 unsafe {
83 let mut len = buffer.len();
84 let mut ptr = buffer.as_ptr();
85
86 if len == 0 {
87 return;
88 }
89
90 if ptr as usize % 2 == 1 {
92 while !port.is_fifo_ready() {}
93 port.write_u8(*ptr);
94
95 ptr = ptr.offset(1);
97 len -= 1;
98 }
99
100 if ptr as usize % 4 == 2 {
102 if len > 1 {
103 while !port.is_fifo_ready() {}
105
106 #[allow(clippy::cast_ptr_alignment)]
108 port.write_u16(ptr::read(ptr as *const u16));
109
110 ptr = ptr.offset(2);
112 len -= 2;
113 } else {
114 if len == 1 {
115 while !port.is_fifo_ready() {}
117 port.write_u8(*ptr);
118 }
119
120 return;
121 }
122 }
123
124 write_aligned_impl(port, slice::from_raw_parts(ptr, len));
126 }
127}
128
129#[allow(clippy::missing_inline_in_public_items)]
146pub fn write_aligned(port: &mut Stim, buffer: &Aligned<[u8]>) {
147 unsafe { write_aligned_impl(port, &buffer.0) }
148}
149
150#[inline]
152pub fn write_fmt(port: &mut Stim, args: fmt::Arguments) {
153 use core::fmt::Write;
154
155 Port(port).write_fmt(args).ok();
156}
157
158#[inline]
160pub fn write_str(port: &mut Stim, string: &str) {
161 write_all(port, string.as_bytes())
162}