1use core::cell::Cell;
86use core::marker::PhantomData;
87use core::ops::Index;
88use core::sync::atomic::{fence, Ordering};
89use kernel::hil;
90use kernel::hil::time::ConvertTicks;
91use kernel::hil::uart;
92use kernel::utilities::cells::{OptionalCell, TakeCell, VolatileCell};
93use kernel::ErrorCode;
94
95pub const DEFAULT_UP_BUFFER_LENGTH: usize = 1024;
97
98pub const DEFAULT_DOWN_BUFFER_LENGTH: usize = 32;
100
101const TX_MS_DELAY: u32 = 1;
103
104const RX_MS_DELAY: u32 = 100;
106
107#[repr(C)]
113pub struct SeggerRttMemory<'a> {
114 id: [u8; 16],
115 number_up_buffers: u32,
116 number_down_buffers: u32,
117 up_buffer: SeggerRttBuffer<'a>,
118 down_buffer: SeggerRttBuffer<'a>,
119}
120
121#[repr(C)]
122pub struct SeggerRttBuffer<'a> {
123 name: *const u8, pub buffer: *const VolatileCell<u8>, pub length: u32,
127 pub write_position: VolatileCell<u32>,
128 read_position: VolatileCell<u32>,
129 flags: u32,
130 _lifetime: PhantomData<&'a ()>,
131}
132
133impl Index<usize> for SeggerRttBuffer<'_> {
134 type Output = VolatileCell<u8>;
135
136 fn index(&self, index: usize) -> &Self::Output {
137 let index = index as isize;
138 if index >= self.length as isize {
139 panic!("Index out of bounds {}/{}", index, self.length)
140 } else {
141 unsafe { &*self.buffer.offset(index) }
142 }
143 }
144}
145
146impl<'a> SeggerRttMemory<'a> {
147 pub fn new_raw(
148 up_buffer_name: &'a [u8],
149 up_buffer: &'a [VolatileCell<u8>],
150 down_buffer_name: &'a [u8],
151 down_buffer: &'a [VolatileCell<u8>],
152 ) -> SeggerRttMemory<'a> {
153 SeggerRttMemory {
154 id: *b"SEGGER RTT\0\0\0\0\0\0",
162 number_up_buffers: 1,
163 number_down_buffers: 1,
164 up_buffer: SeggerRttBuffer {
165 name: up_buffer_name.as_ptr(),
166 buffer: up_buffer.as_ptr(),
167 length: up_buffer.len() as u32,
168 write_position: VolatileCell::new(0),
169 read_position: VolatileCell::new(0),
170 flags: 0,
171 _lifetime: PhantomData,
172 },
173 down_buffer: SeggerRttBuffer {
174 name: down_buffer_name.as_ptr(),
175 buffer: down_buffer.as_ptr(),
176 length: down_buffer.len() as u32,
177 write_position: VolatileCell::new(0),
178 read_position: VolatileCell::new(0),
179 flags: 0,
180 _lifetime: PhantomData,
181 },
182 }
183 }
184
185 pub fn get_up_buffer_ptr(&self) -> *const SeggerRttBuffer<'a> {
189 &self.up_buffer
190 }
191
192 pub fn write_sync(&self, buf: &[u8]) {
193 let mut index = self.up_buffer.write_position.get() as usize;
194 fence(Ordering::SeqCst);
195
196 let buffer_len = self.up_buffer.length as usize;
197 for c in buf.iter() {
198 index = (index + 1) % buffer_len;
199 while self.up_buffer.read_position.get() as usize == index {
200 core::hint::spin_loop();
201 }
202 self.up_buffer[index].set(*c);
203 fence(Ordering::SeqCst);
204 self.up_buffer.write_position.set(index as u32);
205 fence(Ordering::SeqCst);
206 }
207 }
208}
209
210pub struct SeggerRtt<'a, A: hil::time::Alarm<'a>> {
211 alarm: &'a A, config: TakeCell<'a, SeggerRttMemory<'a>>,
213 tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
214 tx_client_buffer: TakeCell<'static, [u8]>,
215 tx_len: Cell<usize>,
216 rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
217 rx_client_buffer: TakeCell<'static, [u8]>,
218 rx_cursor: Cell<usize>,
219 rx_len: Cell<usize>,
220}
221
222impl<'a, A: hil::time::Alarm<'a>> SeggerRtt<'a, A> {
223 pub fn new(alarm: &'a A, config: &'a mut SeggerRttMemory<'a>) -> SeggerRtt<'a, A> {
224 SeggerRtt {
225 alarm,
226 config: TakeCell::new(config),
227 tx_client: OptionalCell::empty(),
228 tx_client_buffer: TakeCell::empty(),
229 tx_len: Cell::new(0),
230 rx_client: OptionalCell::empty(),
231 rx_client_buffer: TakeCell::empty(),
232 rx_cursor: Cell::new(0),
233 rx_len: Cell::new(0),
234 }
235 }
236}
237
238impl<'a, A: hil::time::Alarm<'a>> uart::Transmit<'a> for SeggerRtt<'a, A> {
239 fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
240 self.tx_client.set(client);
241 }
242
243 fn transmit_buffer(
244 &self,
245 tx_data: &'static mut [u8],
246 tx_len: usize,
247 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
248 if self.config.is_some() {
249 self.config.map(|config| {
250 let mut index = config.up_buffer.write_position.get() as usize;
254 fence(Ordering::SeqCst);
255
256 let buffer_len = config.up_buffer.length as usize;
257 for i in 0..tx_len {
258 config.up_buffer[(i + index) % buffer_len].set(tx_data[i]);
259 }
260 fence(Ordering::SeqCst);
261
262 index = (index + tx_len) % buffer_len;
263 config.up_buffer.write_position.set(index as u32);
264 fence(Ordering::SeqCst);
265
266 self.tx_len.set(tx_len);
267 self.tx_client_buffer.replace(tx_data);
269
270 let delay = self.alarm.ticks_from_ms(TX_MS_DELAY);
278 self.alarm.set_alarm(self.alarm.now(), delay);
279 });
280 Ok(())
281 } else {
282 Err((ErrorCode::BUSY, tx_data))
283 }
284 }
285
286 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
287 Err(ErrorCode::FAIL)
288 }
289
290 fn transmit_abort(&self) -> Result<(), ErrorCode> {
291 Ok(())
292 }
293}
294
295impl<'a, A: hil::time::Alarm<'a>> hil::time::AlarmClient for SeggerRtt<'a, A> {
296 fn alarm(&self) {
297 self.tx_client.map(|client| {
298 self.tx_client_buffer.take().map(|buffer| {
299 client.transmitted_buffer(buffer, self.tx_len.get(), Ok(()));
300 });
301 });
302 self.rx_client.map(|client| {
303 self.rx_client_buffer.take().map(|buffer| {
304 self.config.map(|config| {
305 let write_position = &config.down_buffer.write_position;
306 let read_position = &config.down_buffer.read_position;
307
308 fence(Ordering::SeqCst);
310 while self.rx_cursor.get() < self.rx_len.get()
311 && write_position.get() != read_position.get()
312 {
313 buffer[self.rx_cursor.get()] =
314 config.down_buffer[read_position.get() as usize].get();
315 fence(Ordering::SeqCst);
317 read_position.set((read_position.get() + 1) % config.down_buffer.length);
318 self.rx_cursor.set(self.rx_cursor.get() + 1);
319 }
320 fence(Ordering::SeqCst);
322 });
323 if self.rx_cursor.get() == self.rx_len.get() {
324 client.received_buffer(buffer, self.rx_len.get(), Ok(()), uart::Error::None);
325 } else {
326 let delay = self.alarm.ticks_from_ms(RX_MS_DELAY);
327 self.alarm.set_alarm(self.alarm.now(), delay);
328 self.rx_client_buffer.put(Some(buffer))
329 }
330 });
331 });
332 }
333}
334
335impl<'a, A: hil::time::Alarm<'a>> uart::Configure for SeggerRtt<'a, A> {
338 fn configure(&self, _parameters: uart::Parameters) -> Result<(), ErrorCode> {
339 Err(ErrorCode::FAIL)
340 }
341}
342
343impl<'a, A: hil::time::Alarm<'a>> uart::Receive<'a> for SeggerRtt<'a, A> {
344 fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
345 self.rx_client.set(client)
346 }
347
348 fn receive_buffer(
349 &self,
350 buffer: &'static mut [u8],
351 len: usize,
352 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
353 self.rx_client_buffer.put(Some(buffer));
354 self.rx_len.set(len);
355 self.rx_cursor.set(0);
356 if !self.alarm.is_armed() {
357 let delay = self.alarm.ticks_from_ms(RX_MS_DELAY);
358 self.alarm.set_alarm(self.alarm.now(), delay);
359 }
360 Ok(())
361 }
362
363 fn receive_word(&self) -> Result<(), ErrorCode> {
364 Err(ErrorCode::FAIL)
365 }
366
367 fn receive_abort(&self) -> Result<(), ErrorCode> {
368 Ok(())
369 }
370}