jtag_scanner/protocols/
pin.rs1use std::{cell::RefCell, rc::Rc};
6
7use embedded_hal::digital::{
8 OutputPin,
9 PinState::{High, Low},
10};
11
12use crate::{Error, ErrorKind::WrongPinType, PinId, PinScanner};
13
14impl embedded_hal::digital::Error for Error {
15 fn kind(&self) -> embedded_hal::digital::ErrorKind {
16 embedded_hal::digital::ErrorKind::Other
17 }
18}
19
20pub struct In {
22 scanner: Rc<RefCell<PinScanner>>,
23 pin_id: PinId,
24}
25
26impl In {
27 pub fn new(scanner: &Rc<RefCell<PinScanner>>, pin_id: PinId) -> Result<Self, Error> {
29 if !pin_id.is_input() {
30 return Error::result(WrongPinType, "not input pin");
31 }
32 Ok(Self {
33 scanner: scanner.clone(),
34 pin_id,
35 })
36 }
37}
38
39impl embedded_hal::digital::ErrorType for In {
40 type Error = Error;
41}
42
43impl embedded_hal::digital::InputPin for In {
44 fn is_high(&mut self) -> Result<bool, Self::Error> {
45 let mut scanner = self.scanner.try_borrow_mut()?;
46 scanner.update()?;
47 scanner
48 .get_pin_state(&self.pin_id)
49 .map(|st| st.input.unwrap())
50 }
51 fn is_low(&mut self) -> Result<bool, Self::Error> {
52 self.is_high().map(|v| !v)
53 }
54}
55
56pub struct Out {
58 scanner: Rc<RefCell<PinScanner>>,
59 pin_id: PinId,
60}
61
62impl Out {
63 pub fn new(scanner: &Rc<RefCell<PinScanner>>, pin_id: PinId) -> Result<Self, Error> {
65 if !pin_id.is_output() {
66 return Error::result(WrongPinType, "not output pin");
67 }
68 Ok(Self {
69 scanner: scanner.clone(),
70 pin_id,
71 })
72 }
73}
74
75impl embedded_hal::digital::ErrorType for Out {
76 type Error = Error;
77}
78
79impl embedded_hal::digital::OutputPin for Out {
80 fn set_high(&mut self) -> Result<(), Self::Error> {
81 self.set_state(High)
82 }
83 fn set_low(&mut self) -> Result<(), Self::Error> {
84 self.set_state(Low)
85 }
86 fn set_state(&mut self, state: embedded_hal::digital::PinState) -> Result<(), Self::Error> {
87 let mut scanner = self.scanner.try_borrow_mut()?;
88 scanner.set_pin_state(&self.pin_id, Some(state == High))?;
89 scanner.write_update()
90 }
91}
92
93pub struct InOut {
96 scanner: Rc<RefCell<PinScanner>>,
97 pin_id: PinId,
98
99 output_enable: bool,
101
102 output_value: Option<bool>,
105}
106
107impl InOut {
108 pub fn new(
113 scanner: &Rc<RefCell<PinScanner>>,
114 pin_id: PinId,
115 init_val: Option<bool>,
116 ) -> Result<Self, Error> {
117 if !pin_id.is_input() || !pin_id.is_output() {
118 return Error::result(WrongPinType, "not input + output pin");
119 }
120
121 let mut sc = scanner.try_borrow_mut()?;
122 sc.set_pin_state(&pin_id, init_val)?;
123 sc.write_update()?;
124
125 Ok(Self {
126 scanner: scanner.clone(),
127 pin_id,
128 output_enable: init_val.is_some(),
129 output_value: init_val,
130 })
131 }
132
133 pub fn set_output_enable(&mut self, enable: bool) -> Result<(), Error> {
141 if enable == self.output_enable {
142 return Ok(());
143 }
144 if !self.pin_id.is_tristates() {
145 if !enable {
146 return Error::result(WrongPinType, "not tristated pin");
147 }
148 return Ok(());
149 }
150 if enable {
151 self.output_enable = true;
152 if let Some(&last_output) = self.output_value.as_ref() {
153 self.set_state(if last_output { High } else { Low })?;
154 }
155 } else {
156 let mut sc = self.scanner.try_borrow_mut()?;
157 sc.set_pin_state(&self.pin_id, None)?;
158 sc.write_update()?;
159 self.output_enable = false;
160 }
161 Ok(())
162 }
163}
164
165impl embedded_hal::digital::ErrorType for InOut {
166 type Error = Error;
167}
168
169impl embedded_hal::digital::InputPin for InOut {
170 fn is_high(&mut self) -> Result<bool, Self::Error> {
171 let mut scanner = self.scanner.try_borrow_mut()?;
172 scanner.update()?;
173 scanner
174 .get_pin_state(&self.pin_id)
175 .map(|st| st.input.unwrap())
176 }
177 fn is_low(&mut self) -> Result<bool, Self::Error> {
178 self.is_high().map(|v| !v)
179 }
180}
181
182impl embedded_hal::digital::OutputPin for InOut {
183 fn set_high(&mut self) -> Result<(), Self::Error> {
184 self.set_state(High)
185 }
186 fn set_low(&mut self) -> Result<(), Self::Error> {
187 self.set_state(Low)
188 }
189 fn set_state(&mut self, state: embedded_hal::digital::PinState) -> Result<(), Self::Error> {
190 self.output_value = Some(state == High);
191 if self.output_enable {
192 let mut scanner = self.scanner.try_borrow_mut()?;
193 scanner.set_pin_state(&self.pin_id, self.output_value)?;
194 scanner.write_update()?;
195 }
196 Ok(())
197 }
198}