1use std::iter::Peekable;
6use std::time::Duration;
7use std::vec::Vec;
8
9use anyhow::{Result, bail};
10use thiserror::Error;
11
12use crate::io::gpio::{
13 ClockNature, Edge, MonitoringEvent, MonitoringReadResponse, MonitoringStartResponse,
14};
15use crate::test_utils::bitbanging::uart::{UartBitbangDecoder, UartTransfer};
16
17#[derive(Error, Debug, PartialEq)]
18pub enum UartBitbangError {
19 #[error("Uart bitbanging RX monitoring needs a more reliable clock source")]
20 InaccurateMonitoringClock,
21 #[error("RX monitoring recorded double rising edge")]
22 DoubleRisingEdge,
23 #[error("RX monitoring recorded double falling edge")]
24 DoubleFallingEdge,
25 #[error("RX monitoring provided edges out-of-order")]
26 EdgesOutOfOrder,
27}
28
29pub struct UartRxMonitoringDecoder {
35 pub decoder: UartBitbangDecoder,
36 clock_resolution: u64,
37 initial_timestamp: u64,
38 last_event: Option<MonitoringEvent>,
39 last_sample_time: Option<u64>,
40}
41
42impl UartRxMonitoringDecoder {
43 pub fn new(
44 decoder: UartBitbangDecoder,
45 clock_nature: ClockNature,
46 start: MonitoringStartResponse,
47 ) -> Result<Self> {
48 let ClockNature::Wallclock { resolution, .. } = clock_nature else {
49 Err(UartBitbangError::InaccurateMonitoringClock)?
50 };
51 Ok(Self {
52 decoder,
53 clock_resolution: resolution,
54 initial_timestamp: start.timestamp,
55 last_event: None,
56 last_sample_time: None,
57 })
58 }
59
60 fn timestamp_to_nanos(&self, timestamp: u64) -> u64 {
63 let delta = (timestamp - self.initial_timestamp) as u128;
64 let nanos = delta * 1_000_000_000u128 / self.clock_resolution as u128;
65 nanos as u64
66 }
67
68 fn samples_since(&self, from: u64, until: u64, period_ns: u64) -> u64 {
71 let time_elapsed = until - from;
72 (time_elapsed + period_ns / 2) / period_ns
74 }
75
76 fn sample_until_stable_state<I: Iterator<Item = MonitoringEvent>>(
80 &mut self,
81 events: &mut Peekable<I>,
82 end_time: u64,
83 period_ns: u64,
84 ) -> Result<bool> {
85 let frame_bit_time = self.decoder.config.bit_time_per_frame() as u64;
86 let last_ts = match self.last_event {
87 Some(last_event) => last_event.timestamp,
88 None => self.initial_timestamp,
89 };
90 let mut last_time = self.timestamp_to_nanos(last_ts);
91
92 while let Some(event) = events.peek() {
93 let timestamp = self.timestamp_to_nanos(event.timestamp);
94 if timestamp < last_time {
95 Err(UartBitbangError::EdgesOutOfOrder)?
96 } else if self.samples_since(last_time, timestamp, period_ns) > frame_bit_time {
97 return Ok(true);
98 }
99 last_time = timestamp;
100 self.last_event = events.next();
101 }
102 Ok(self.samples_since(last_time, end_time, period_ns) > frame_bit_time)
103 }
104
105 fn get_last_state<I: Iterator<Item = MonitoringEvent>>(
113 &mut self,
114 events: &mut Peekable<I>,
115 end_time: u64,
116 period_ns: u64,
117 ) -> Result<Option<(u64, u8)>> {
118 if let Some(last_sample_time) = self.last_sample_time {
120 let Some(last_event) = self.last_event else {
121 bail!("Previous sampling time exists but previous event does not");
122 };
123 let value = match last_event.edge {
124 Edge::Rising => 0x01,
125 Edge::Falling => 0x00,
126 };
127 return Ok(Some((last_sample_time, value)));
128 };
129
130 if !self.sample_until_stable_state(events, end_time, period_ns)? {
132 return Ok(None);
133 }
134
135 let Some(first_event) = events.peek() else {
137 return Ok(None);
138 };
139
140 let edge_time = if first_event.edge == Edge::Falling {
141 self.timestamp_to_nanos(first_event.timestamp)
142 } else {
143 events.next();
146 let Some(second_event) = events.peek() else {
147 return Ok(None);
148 };
149 self.timestamp_to_nanos(second_event.timestamp)
150 };
151 Ok(Some((edge_time, 0x01)))
152 }
153
154 fn decode_sample(&mut self, sample: u8, decoded: &mut Vec<u8>) -> Result<()> {
156 if let Some(transfer) = self.decoder.decode_sample(sample)? {
157 match transfer {
158 UartTransfer::Byte { data } => decoded.push(data),
159 UartTransfer::Broken { error, .. } => {
160 Err(error)?;
161 }
162 UartTransfer::Break => (),
164 }
165 }
166 Ok(())
167 }
168
169 fn decode_edge(
183 &mut self,
184 event: MonitoringEvent,
185 decoded: &mut Vec<u8>,
186 period_ns: u64,
187 last_sample_time: &mut u64,
188 value: &mut u8,
189 ) -> Result<()> {
190 if event.edge == Edge::Falling && *value == 0 {
191 Err(UartBitbangError::DoubleFallingEdge)?
192 } else if event.edge == Edge::Rising && *value == 1 {
193 Err(UartBitbangError::DoubleRisingEdge)?
194 }
195 let sampling_end = self.timestamp_to_nanos(event.timestamp);
196 if sampling_end < *last_sample_time {
197 Err(UartBitbangError::EdgesOutOfOrder)?
198 }
199
200 let num_samples = self.samples_since(*last_sample_time, sampling_end, period_ns);
202 *last_sample_time += period_ns * num_samples;
203 for _ in 0..num_samples {
204 if self.decoder.is_idle() && event.edge == Edge::Falling {
205 break;
207 }
208 self.decode_sample(*value, decoded)?;
209 }
210
211 if self.decoder.is_idle() && event.edge == Edge::Falling {
212 *last_sample_time = self.timestamp_to_nanos(event.timestamp);
214 }
215 self.last_event = Some(event);
216 *value = if *value == 0x00 { 0x01 } else { 0x00 };
217 Ok(())
218 }
219
220 fn decode_waveform(
230 &mut self,
231 events: Vec<MonitoringEvent>,
232 signal_index: u8,
233 end_time: u64,
234 period: &Duration,
235 ) -> Result<Vec<u8>> {
236 let mut decoded = Vec::new();
237 let mut events_iter = events
238 .into_iter()
239 .filter(|event| event.signal_index == signal_index)
240 .peekable();
241 let period_ns = period.as_nanos() as u64;
242 let last_state = self.get_last_state(&mut events_iter, end_time, period_ns)?;
243 let Some((mut last_sample_time, mut value)) = last_state else {
244 return Ok(decoded);
246 };
247 for event in events_iter {
248 self.decode_edge(
249 event,
250 &mut decoded,
251 period_ns,
252 &mut last_sample_time,
253 &mut value,
254 )?;
255 }
256 self.last_sample_time = Some(last_sample_time);
257 if value != 0x00 {
262 while !self.decoder.is_idle() {
263 if (last_sample_time + period_ns / 2) >= end_time {
264 break;
265 }
266 last_sample_time += period_ns;
267 self.last_sample_time = Some(last_sample_time);
268 self.decode_sample(value, &mut decoded)?;
269 }
270 }
271 Ok(decoded)
272 }
273
274 pub fn decode_response(
287 &mut self,
288 response: MonitoringReadResponse,
289 signal_index: u8,
290 baud_rate: u32,
291 ) -> Result<Vec<u8>> {
292 let sampling_period = Duration::from_nanos(1_000_000_000u64 / baud_rate as u64);
293 let read_end_timestamp = self.timestamp_to_nanos(response.timestamp);
294 self.decode_waveform(
295 response.events,
296 signal_index,
297 read_end_timestamp,
298 &sampling_period,
299 )
300 }
301}
302
303#[cfg(test)]
304mod test {
305 use super::*;
306
307 use std::sync::LazyLock;
308
309 use serialport::Parity;
310
311 use crate::test_utils::bitbanging::uart::{UartBitbangConfig, UartStopBits};
312
313 static CLOCK_NATURE: ClockNature = ClockNature::Wallclock {
314 resolution: 1_000_000,
315 offset: None,
316 };
317 static BAUD_RATE: u32 = 57600;
318 static START_RESPONSE: LazyLock<MonitoringStartResponse> =
319 LazyLock::new(|| MonitoringStartResponse {
320 timestamp: 0,
321 initial_levels: vec![true],
322 });
323 static EVENT_TIMESTAMPS: [u64; 112] = [
325 5889252340, 5889252358, 5889252375, 5889252392, 5889252410, 5889252427, 5889252445,
326 5889252462, 5889252479, 5889252497, 5889252514, 5889252532, 5889252549, 5889252636,
327 5889252654, 5889252671, 5889252688, 5889252723, 5889252740, 5889252775, 5889252793,
328 5889252810, 5889252827, 5889252845, 5889252862, 5889252914, 5889252932, 5889252949,
329 5889252967, 5889252984, 5889253001, 5889253019, 5889253036, 5889253141, 5889253158,
330 5889253193, 5889253210, 5889253245, 5889253263, 5889253315, 5889253349, 5889253367,
331 5889253386, 5889253402, 5889253419, 5889253454, 5889253471, 5889253489, 5889253523,
332 5889253541, 5889253558, 5889253610, 5889253628, 5889253645, 5889253697, 5889253715,
333 5889253732, 5889253767, 5889253784, 5889253837, 5889253871, 5889253889, 5889253906,
334 5889253924, 5889253941, 5889254011, 5889254046, 5889254063, 5889254080, 5889254115,
335 5889254167, 5889254185, 5889254219, 5889254238, 5889254254, 5889254272, 5889254324,
336 5889254359, 5889254393, 5889254411, 5889254428, 5889254533, 5889254550, 5889254585,
337 5889254603, 5889254655, 5889254672, 5889254689, 5889254741, 5889254759, 5889254776,
338 5889254794, 5889254811, 5889254828, 5889254846, 5889254881, 5889254915, 5889254933,
339 5889254950, 5889254968, 5889255002, 5889255037, 5889255089, 5889255107, 5889255124,
340 5889255176, 5889255194, 5889255211, 5889255264, 5889255281, 5889255298, 5889255455,
341 ];
342 static READ_RESPONSE_TIMESTAMP: u64 = 5889262827;
343 static EXPECTED_RESPONSE: &str = "UART bitbang test\0";
344
345 fn edge(signal_index: u8, edge: Edge, timestamp: u64) -> MonitoringEvent {
347 MonitoringEvent {
348 signal_index,
349 edge,
350 timestamp,
351 }
352 }
353
354 fn sample_and_decode(
355 decoder: UartBitbangDecoder,
356 start_idle: bool,
357 start_response: MonitoringStartResponse,
358 edge_timestamps: &[u64],
359 read_timestamp: u64,
360 baud_rate: u32,
361 expected: String,
362 ) -> Result<()> {
363 let edges = if start_idle {
364 [Edge::Falling, Edge::Rising]
365 } else {
366 [Edge::Rising, Edge::Falling]
367 };
368 let events = edge_timestamps
369 .iter()
370 .enumerate()
371 .map(|(i, t)| edge(0, edges[i % 2], *t))
372 .collect::<Vec<_>>();
373 let read_response = MonitoringReadResponse {
374 events,
375 timestamp: read_timestamp,
376 };
377
378 let mut response_decoder =
379 UartRxMonitoringDecoder::new(decoder, CLOCK_NATURE, start_response)?;
380 let decoded = response_decoder.decode_response(read_response, 0, baud_rate)?;
381 assert_eq!(String::from_utf8(decoded), Ok(expected));
382 Ok(())
383 }
384
385 #[test]
386 fn smoke() -> Result<()> {
387 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
389 let decoder = UartBitbangDecoder::new(config);
390 sample_and_decode(
391 decoder,
392 true,
393 START_RESPONSE.clone(),
394 &EVENT_TIMESTAMPS,
395 READ_RESPONSE_TIMESTAMP,
396 BAUD_RATE,
397 EXPECTED_RESPONSE.into(),
398 )
399 }
400
401 #[test]
402 fn baud_rates() -> Result<()> {
403 fn modify_timestamp(timestamp: u64, first_edge_timestamp: u64, divider: u32) -> u64 {
405 let delta = timestamp - first_edge_timestamp;
406 let new_delta = delta * divider as u64;
407 first_edge_timestamp + new_delta
408 }
409
410 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
411 let first_edge_timestamp = EVENT_TIMESTAMPS[0];
412 for divider in 1..=10u32 {
413 let modified_timestamps = EVENT_TIMESTAMPS
414 .iter()
415 .map(|timestamp| modify_timestamp(*timestamp, first_edge_timestamp, divider))
416 .collect::<Vec<_>>();
417 let modified_baud = BAUD_RATE / divider;
418 let modified_response_timestamp =
419 modify_timestamp(READ_RESPONSE_TIMESTAMP, first_edge_timestamp, divider);
420 let decoder = UartBitbangDecoder::new(config.clone());
421 sample_and_decode(
422 decoder,
423 true,
424 START_RESPONSE.clone(),
425 &modified_timestamps,
426 modified_response_timestamp,
427 modified_baud,
428 EXPECTED_RESPONSE.into(),
429 )?;
430 }
431 Ok(())
432 }
433
434 #[test]
435 fn clock_jitter_and_skew() -> Result<()> {
436 const BAUD_DIVIDER: u32 = 8;
439
440 fn modify_timestamp(
441 timestamp: u64,
442 first_edge_timestamp: u64,
443 period_ns: u64,
444 skew_pc: i32,
445 jitter_pc: i32,
446 ) -> u64 {
447 let delta = timestamp - first_edge_timestamp;
448 let new_delta = delta * BAUD_DIVIDER as u64;
449 let skew_delta = new_delta * ((100i32 + skew_pc) as u64) / 100u64;
450 let jittered_delta =
451 (skew_delta as i64) + ((period_ns as i64) * jitter_pc as i64) / 100i64;
452 (first_edge_timestamp as i64 + jittered_delta) as u64
453 }
454
455 fn clock_test(skew_pc: i32, jitter_pc: i32) -> Result<()> {
456 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
457 let modified_baud = BAUD_RATE / BAUD_DIVIDER;
458 let period_ns = 1_000_000_000u64 / modified_baud as u64;
459 let first_edge_timestamp = EVENT_TIMESTAMPS[0];
460
461 let modified_timestamps = EVENT_TIMESTAMPS
462 .iter()
463 .map(|timestamp| {
464 modify_timestamp(
465 *timestamp,
466 first_edge_timestamp,
467 period_ns,
468 skew_pc,
469 jitter_pc,
470 )
471 })
472 .collect::<Vec<_>>();
473 let modified_response_timestamp = modify_timestamp(
474 READ_RESPONSE_TIMESTAMP,
475 first_edge_timestamp,
476 period_ns,
477 skew_pc,
478 jitter_pc,
479 );
480 let decoder = UartBitbangDecoder::new(config.clone());
481 sample_and_decode(
482 decoder,
483 true,
484 START_RESPONSE.clone(),
485 &modified_timestamps,
486 modified_response_timestamp,
487 modified_baud,
488 EXPECTED_RESPONSE.into(),
489 )?;
490 Ok(())
491 }
492
493 for jitter_pc in -20..=20i32 {
495 clock_test(0i32, jitter_pc)?;
496 }
497
498 for skew_pc in -4..=4i32 {
502 clock_test(skew_pc, 0i32)?;
503 }
504
505 for jitter_pc in -5..=5i32 {
507 for skew_pc in -2..=2i32 {
508 clock_test(skew_pc, jitter_pc)?;
509 }
510 }
511
512 Ok(())
513 }
514
515 #[test]
516 fn start_during_break() -> Result<()> {
517 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
519 let decoder = UartBitbangDecoder::new(config);
520
521 let bit_time = EVENT_TIMESTAMPS[1] - EVENT_TIMESTAMPS[0];
523 let before_timestamp = EVENT_TIMESTAMPS[0] - bit_time;
524 let mut events = vec![before_timestamp];
525 events.extend_from_slice(&EVENT_TIMESTAMPS);
526 sample_and_decode(
527 decoder,
528 false,
529 START_RESPONSE.clone(),
530 &events,
531 READ_RESPONSE_TIMESTAMP,
532 BAUD_RATE,
533 EXPECTED_RESPONSE.into(),
534 )
535 }
536
537 #[test]
538 fn start_mid_transmission() -> Result<()> {
539 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
541 let decoder = UartBitbangDecoder::new(config.clone());
542
543 let bit_time = EVENT_TIMESTAMPS[1] - EVENT_TIMESTAMPS[0];
547 let start_response = MonitoringStartResponse {
548 timestamp: EVENT_TIMESTAMPS[0] - bit_time * 24,
549 initial_levels: vec![true],
550 };
551 let mut events = vec![
552 EVENT_TIMESTAMPS[0] - bit_time * 23,
553 EVENT_TIMESTAMPS[0] - bit_time * 21,
554 EVENT_TIMESTAMPS[0] - bit_time * 20,
555 ];
556 events.extend_from_slice(&EVENT_TIMESTAMPS);
557 sample_and_decode(
558 decoder,
559 false,
560 start_response,
561 &events,
562 READ_RESPONSE_TIMESTAMP,
563 BAUD_RATE,
564 EXPECTED_RESPONSE.into(),
565 )?;
566
567 let decoder = UartBitbangDecoder::new(config);
571 let start_response = MonitoringStartResponse {
572 timestamp: EVENT_TIMESTAMPS[0] - bit_time * 5,
573 initial_levels: vec![true],
574 };
575 let mut events = vec![
576 EVENT_TIMESTAMPS[0] - bit_time * 4,
577 EVENT_TIMESTAMPS[0] - bit_time * 2,
578 EVENT_TIMESTAMPS[0] - bit_time,
579 ];
580 events.extend_from_slice(&EVENT_TIMESTAMPS);
581 let empty_response = String::new();
582 sample_and_decode(
583 decoder,
584 false,
585 start_response,
586 &events,
587 READ_RESPONSE_TIMESTAMP,
588 BAUD_RATE,
589 empty_response,
590 )
591 }
592
593 #[test]
594 fn partial_responses() -> Result<()> {
595 let config = UartBitbangConfig::new(8, UartStopBits::Stop1, 2, Parity::None)?;
597 let decoder = UartBitbangDecoder::new(config.clone());
598 let edges = [Edge::Falling, Edge::Rising];
599 let events = EVENT_TIMESTAMPS
600 .iter()
601 .enumerate()
602 .map(|(i, t)| edge(0, edges[i % 2], *t))
603 .collect::<Vec<_>>();
604 let mut response_decoder =
605 UartRxMonitoringDecoder::new(decoder, CLOCK_NATURE, START_RESPONSE.clone())?;
606
607 let mut decoded = Vec::new();
609 for partial_edges in events[..60].chunks(3) {
610 let timestamp = partial_edges.last().unwrap().timestamp + 1;
612 let read_response = MonitoringReadResponse {
613 events: Vec::from(partial_edges),
614 timestamp,
615 };
616 decoded.extend(response_decoder.decode_response(read_response, 0, BAUD_RATE)?);
617 }
618
619 for partial_edges in events[60..].chunks(20) {
621 let timestamp = partial_edges.last().unwrap().timestamp + 1;
622 let read_response = MonitoringReadResponse {
623 events: Vec::from(partial_edges),
624 timestamp,
625 };
626 decoded.extend(response_decoder.decode_response(read_response, 0, BAUD_RATE)?);
627 }
628
629 let read_response = MonitoringReadResponse {
631 events: Vec::new(),
632 timestamp: READ_RESPONSE_TIMESTAMP,
633 };
634 decoded.extend(response_decoder.decode_response(read_response, 0, BAUD_RATE)?);
635 assert_eq!(
636 String::from_utf8(decoded),
637 Ok(String::from(EXPECTED_RESPONSE))
638 );
639 Ok(())
640 }
641}