1use crate::error::Error;
2use crate::{FtInner, PinUse};
3use ftdi_mpsse::{MpsseCmdBuilder, MpsseCmdExecutor};
4use std::sync::{Arc, Mutex};
5
6#[derive(Debug, Copy, Clone)]
8pub(crate) enum Pin {
9 Lower(u8),
10 Upper(u8),
11}
12
13#[derive(Debug)]
20pub struct OutputPin<Device: MpsseCmdExecutor> {
21 mtx: Arc<Mutex<FtInner<Device>>>,
23 pin: Pin,
25}
26
27impl<Device, E> OutputPin<Device>
28where
29 Device: MpsseCmdExecutor<Error = E>,
30 E: std::error::Error,
31 Error<E>: From<E>,
32{
33 pub(crate) fn new(
34 mtx: Arc<Mutex<FtInner<Device>>>,
35 pin: Pin,
36 ) -> Result<OutputPin<Device>, Error<E>> {
37 {
38 let mut lock = mtx.lock().expect("Failed to aquire FTDI mutex");
39
40 lock.allocate_pin_any(pin, PinUse::Output);
41
42 let (byte, idx) = match pin {
43 Pin::Lower(idx) => (&mut lock.lower, idx),
44 Pin::Upper(idx) => (&mut lock.upper, idx),
45 };
46 byte.direction |= 1 << idx;
47 let cmd = MpsseCmdBuilder::new();
48 let cmd = match pin {
49 Pin::Lower(_) => cmd.set_gpio_lower(byte.value, byte.direction),
50 Pin::Upper(_) => cmd.set_gpio_upper(byte.value, byte.direction),
51 }
52 .send_immediate();
53 lock.ft.send(cmd.as_slice())?;
54 }
55 Ok(OutputPin { mtx, pin })
56 }
57
58 pub(crate) fn set(&self, state: bool) -> Result<(), Error<E>> {
59 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
60
61 let byte = match self.pin {
62 Pin::Lower(_) => &mut lock.lower,
63 Pin::Upper(_) => &mut lock.upper,
64 };
65
66 if state {
67 byte.value |= self.mask();
68 } else {
69 byte.value &= !self.mask();
70 };
71
72 let cmd = MpsseCmdBuilder::new();
73 let cmd = match self.pin {
74 Pin::Lower(_) => cmd.set_gpio_lower(byte.value, byte.direction),
75 Pin::Upper(_) => cmd.set_gpio_upper(byte.value, byte.direction),
76 }
77 .send_immediate();
78 lock.ft.send(cmd.as_slice())?;
79
80 Ok(())
81 }
82}
83
84impl<Device: MpsseCmdExecutor> OutputPin<Device> {
85 pub(crate) fn mask(&self) -> u8 {
87 let idx = match self.pin {
88 Pin::Lower(idx) => idx,
89 Pin::Upper(idx) => idx,
90 };
91 1 << idx
92 }
93}
94
95impl<Device, E> eh1::digital::ErrorType for OutputPin<Device>
96where
97 Device: MpsseCmdExecutor<Error = E>,
98 E: std::error::Error,
99 Error<E>: From<E>,
100{
101 type Error = Error<E>;
102}
103
104impl<Device, E> eh1::digital::OutputPin for OutputPin<Device>
105where
106 Device: MpsseCmdExecutor<Error = E>,
107 E: std::error::Error,
108 Error<E>: From<E>,
109{
110 fn set_low(&mut self) -> Result<(), Error<E>> {
111 self.set(false)
112 }
113
114 fn set_high(&mut self) -> Result<(), Error<E>> {
115 self.set(true)
116 }
117}
118
119impl<Device, E> eh0::digital::v2::OutputPin for OutputPin<Device>
120where
121 Device: MpsseCmdExecutor<Error = E>,
122 E: std::error::Error,
123 Error<E>: From<E>,
124{
125 type Error = Error<E>;
126
127 fn set_low(&mut self) -> Result<(), Error<E>> {
128 self.set(false)
129 }
130
131 fn set_high(&mut self) -> Result<(), Error<E>> {
132 self.set(true)
133 }
134}
135
136#[derive(Debug)]
143pub struct InputPin<Device: MpsseCmdExecutor> {
144 mtx: Arc<Mutex<FtInner<Device>>>,
146 pin: Pin,
148}
149
150impl<Device, E> InputPin<Device>
151where
152 Device: MpsseCmdExecutor<Error = E>,
153 E: std::error::Error,
154 Error<E>: From<E>,
155{
156 pub(crate) fn new(
157 mtx: Arc<Mutex<FtInner<Device>>>,
158 pin: Pin,
159 ) -> Result<InputPin<Device>, Error<E>> {
160 {
161 let mut lock = mtx.lock().expect("Failed to aquire FTDI mutex");
162
163 lock.allocate_pin_any(pin, PinUse::Input);
164
165 let (byte, idx) = match pin {
166 Pin::Lower(idx) => (&mut lock.lower, idx),
167 Pin::Upper(idx) => (&mut lock.upper, idx),
168 };
169 byte.direction &= !(1 << idx);
170 let cmd = MpsseCmdBuilder::new();
171 let cmd = match pin {
172 Pin::Lower(_) => cmd.set_gpio_lower(byte.value, byte.direction),
173 Pin::Upper(_) => cmd.set_gpio_upper(byte.value, byte.direction),
174 }
175 .send_immediate();
176 lock.ft.send(cmd.as_slice())?;
177 }
178 Ok(InputPin { mtx, pin })
179 }
180
181 pub(crate) fn get(&self) -> Result<bool, Error<E>> {
182 let mut lock = self.mtx.lock().expect("Failed to aquire FTDI mutex");
183
184 let mut buffer = [0u8; 1];
185 let cmd = MpsseCmdBuilder::new();
186 let cmd = match self.pin {
187 Pin::Lower(_) => cmd.gpio_lower(),
188 Pin::Upper(_) => cmd.gpio_upper(),
189 }
190 .send_immediate();
191 lock.ft.send(cmd.as_slice())?;
192 lock.ft.recv(&mut buffer)?;
193
194 Ok((buffer[0] & self.mask()) != 0)
195 }
196}
197
198impl<Device: MpsseCmdExecutor> InputPin<Device> {
199 pub(crate) fn mask(&self) -> u8 {
201 let idx = match self.pin {
202 Pin::Lower(idx) => idx,
203 Pin::Upper(idx) => idx,
204 };
205 1 << idx
206 }
207}
208
209impl<Device, E> eh1::digital::ErrorType for InputPin<Device>
210where
211 Device: MpsseCmdExecutor<Error = E>,
212 E: std::error::Error,
213 Error<E>: From<E>,
214{
215 type Error = Error<E>;
216}
217
218impl<Device, E> eh1::digital::InputPin for InputPin<Device>
219where
220 Device: MpsseCmdExecutor<Error = E>,
221 E: std::error::Error,
222 Error<E>: From<E>,
223{
224 fn is_high(&mut self) -> Result<bool, Self::Error> {
225 self.get()
226 }
227
228 fn is_low(&mut self) -> Result<bool, Self::Error> {
229 self.get().map(|res| !res)
230 }
231}
232
233impl<Device, E> eh0::digital::v2::InputPin for InputPin<Device>
234where
235 Device: MpsseCmdExecutor<Error = E>,
236 E: std::error::Error,
237 Error<E>: From<E>,
238{
239 type Error = Error<E>;
240
241 fn is_high(&self) -> Result<bool, Self::Error> {
242 self.get()
243 }
244
245 fn is_low(&self) -> Result<bool, Self::Error> {
246 self.get().map(|res| !res)
247 }
248}