1use std::time::Duration;
2
3use rppal::gpio::Level;
4
5use crate::{errors::Result, hardware::HardwareInput};
6
7pub struct Scanner {
8 input: HardwareInput,
9}
10
11struct Pulse {
12 value: Level,
13 length: u128,
14}
15
16impl Scanner {
17 pub fn new(input: HardwareInput) -> Self {
18 Self { input }
19 }
20
21 pub fn scan_blocking(&self) -> Result<u64> {
22 let mut command: Vec<Pulse> = Vec::with_capacity(80);
23 let mut count1 = 0u32;
24 let mut previous = Level::Low;
25 let mut value = self.input.read_value()?;
26
27 while self.input.read_value()? == Level::High {
28 spin_sleep::sleep(Duration::from_micros(100))
29 }
30
31 let mut start_time = std::time::Instant::now();
32
33 loop {
34 spin_sleep::sleep(Duration::from_nanos(50));
35
36 if value != previous {
37 let pulse_length = start_time.elapsed();
38 start_time = std::time::Instant::now();
39
40 command.push(Pulse {
41 value: previous,
42 length: pulse_length.as_micros(),
43 });
44 }
45
46 if value == Level::High {
47 count1 += 1;
48 }
49
50 previous = value;
51 value = self.input.read_value()?;
52
53 if count1 > 10000 {
54 break;
55 }
56 }
57
58 let mut binary = 0u64;
59 let mut bin_length = 0u8;
60
61 for item in command {
62 if item.value == Level::Low {
63 continue;
64 }
65 if item.length > 1000 {
66 binary = binary << 2 | 1;
67 bin_length += 1;
68 } else {
69 binary <<= 1;
70 bin_length += 1;
71 }
72
73 if bin_length > 34 {
74 break;
75 }
76 }
77
78 Ok(binary)
79 }
80}