embedded_hal_compat/
reverse.rs

1//! Embedded HAL Reverse compatibility shim
2//! A compatibility layer to alleviate (some) of the issues resolving from changes to embedded-hal
3// Copyright 2021 Ryan Kurte
4
5use core::cell::RefCell;
6use core::fmt::Debug;
7
8/// Reverse compatibility container object.
9/// This is generic over different E-H types and will provide adaption
10/// depending on the bound type.
11pub struct Reverse<T> {
12    inner: T,
13}
14
15/// Convert a type into a reverse compatibility wrapper object
16/// call `.reverse()` on `e-h@1.0.x` types to create an `e-h@0.2.x` compatible wrapper object
17pub trait ReverseCompat<T> {
18    /// Create an e-h-c reverse compatibility wrapper from an existing type
19    fn reverse(self) -> Reverse<T>;
20
21    /// Create an e-h-c reverse compatibility wrapper using a ref-cell for interior mutability
22    /// (required for InputPin types)
23    fn reverse_cell(self) -> Reverse<RefCell<T>>;
24}
25
26impl<T> ReverseCompat<T> for T {
27    /// Create an e-h-c wrapper around and e-h object
28    /// Available methods depend on the wrapped type
29    fn reverse(self) -> Reverse<T> {
30        Reverse::new(self)
31    }
32
33    /// Create an e-h-c reverse compatibility wrapper using a ref-cell for interior mutability
34    /// (required for InputPin types)
35    fn reverse_cell(self) -> Reverse<RefCell<T>> {
36        Reverse::new(RefCell::new(self))
37    }
38}
39
40impl<T> Reverse<T> {
41    /// Create a new compatibility wrapper object
42    pub fn new(inner: T) -> Reverse<T> {
43        Reverse { inner }
44    }
45
46    /// Fetch a reference to the wrapped object
47    pub fn inner(&self) -> &T {
48        &self.inner
49    }
50
51    /// Fetch a mutable reference to the wrapped object
52    pub fn inner_mut(&mut self) -> &mut T {
53        &mut self.inner
54    }
55
56    /// Destroy the compatibility wrapper, returning the wrapped object
57    pub fn unwrap(self) -> T {
58        self.inner
59    }
60}
61
62// note that implementations over Reverse cannot be generic over word type
63// etc. due to orphan rules (ie. what happens if someone else defines a word type?)
64
65// Digital / GPIOs
66mod digital {
67    use super::{Debug, Reverse};
68    use core::cell::RefCell;
69
70    impl<T, E> eh0_2::digital::v2::InputPin for Reverse<RefCell<T>>
71    where
72        T: eh1_0::digital::InputPin<Error = E>,
73        E: Debug,
74    {
75        type Error = E;
76
77        /// Is the input pin high?
78        fn is_high(&self) -> Result<bool, Self::Error> {
79            self.inner.borrow_mut().is_high()
80        }
81
82        /// Is the input pin low?
83        fn is_low(&self) -> Result<bool, Self::Error> {
84            self.inner.borrow_mut().is_low()
85        }
86    }
87
88    impl<T, E> eh0_2::digital::v2::OutputPin for Reverse<RefCell<T>>
89    where
90        T: eh1_0::digital::OutputPin<Error = E>,
91        E: Debug,
92    {
93        type Error = E;
94
95        /// Set the output as high
96        fn set_high(&mut self) -> Result<(), Self::Error> {
97            self.inner.borrow_mut().set_high()
98        }
99
100        /// Set the output as low
101        fn set_low(&mut self) -> Result<(), Self::Error> {
102            self.inner.borrow_mut().set_low()
103        }
104    }
105}
106
107/// Delays (blocking)
108mod delay {
109    use super::Reverse;
110
111    impl<T> eh0_2::blocking::delay::DelayMs<u32> for Reverse<T>
112    where
113        T: eh1_0::delay::DelayNs,
114    {
115        fn delay_ms(&mut self, ms: u32) {
116            self.inner.delay_us(ms * 1000)
117        }
118    }
119
120    impl<T> eh0_2::blocking::delay::DelayMs<u16> for Reverse<T>
121    where
122        T: eh1_0::delay::DelayNs,
123    {
124        fn delay_ms(&mut self, ms: u16) {
125            self.inner.delay_us(ms as u32 * 1000)
126        }
127    }
128
129    impl<T> eh0_2::blocking::delay::DelayUs<u32> for Reverse<T>
130    where
131        T: eh1_0::delay::DelayNs,
132    {
133        fn delay_us(&mut self, us: u32) {
134            self.inner.delay_us(us)
135        }
136    }
137
138    impl<T> eh0_2::blocking::delay::DelayUs<u16> for Reverse<T>
139    where
140        T: eh1_0::delay::DelayNs,
141    {
142        fn delay_us(&mut self, us: u16) {
143            self.inner.delay_us(us as u32)
144        }
145    }
146}
147
148/// SPI (blocking)
149mod spi {
150    use super::{Debug, Reverse};
151
152    impl<T, E> eh0_2::blocking::spi::Write<u8> for Reverse<T>
153    where
154        T: eh1_0::spi::SpiBus<u8, Error = E>,
155        E: Debug,
156    {
157        type Error = E;
158
159        fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
160            self.inner.write(words)
161        }
162    }
163
164    impl<T, E> eh0_2::blocking::spi::Transfer<u8> for Reverse<T>
165    where
166        T: eh1_0::spi::SpiBus<u8, Error = E>,
167        E: Debug,
168    {
169        type Error = E;
170
171        fn transfer<'a>(&mut self, words: &'a mut [u8]) -> Result<&'a [u8], Self::Error> {
172            self.inner.transfer_in_place(words)?;
173            Ok(words)
174        }
175    }
176
177    impl<T, E> eh0_2::blocking::spi::WriteIter<u8> for Reverse<T>
178    where
179        T: eh1_0::spi::SpiBus<u8, Error = E>,
180        E: Debug,
181    {
182        type Error = E;
183
184        fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
185        where
186            WI: IntoIterator<Item = u8>,
187        {
188            for word in words.into_iter() {
189                self.inner.write(&[word])?;
190            }
191            Ok(())
192        }
193    }
194
195    impl<T, E> eh0_2::spi::FullDuplex<u8> for Reverse<T>
196    where
197        T: eh1_0::spi::SpiBus<u8, Error = E>,
198        E: Debug,
199    {
200        type Error = E;
201        fn read(&mut self) -> nb::Result<u8, Self::Error> {
202            let mut data = [0];
203            match self.inner.read(&mut data) {
204                Ok(_) => Ok(data[0]),
205                Err(e) => Err(nb::Error::Other(e)),
206            }
207        }
208        fn send(&mut self, word: u8) -> nb::Result<(), Self::Error> {
209            self.inner.write(&[word]).map_err(nb::Error::Other)
210        }
211    }
212
213    #[cfg(feature = "alloc")]
214    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
215    extern crate alloc;
216    #[cfg(feature = "alloc")]
217    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
218    impl<T, E> eh0_2::blocking::spi::Transactional<u8> for Reverse<T>
219    where
220        T: eh1_0::spi::SpiBus<Error = E>,
221        E: Debug,
222    {
223        type Error = E;
224
225        fn exec(
226            &mut self,
227            operations: &mut [eh0_2::blocking::spi::Operation<u8>],
228        ) -> Result<(), Self::Error> {
229            let mut data = alloc::vec::Vec::<u8>::new();
230            for op in operations.iter() {
231                match op {
232                    eh0_2::blocking::spi::Operation::Transfer(buf) => data.extend_from_slice(buf),
233                    eh0_2::blocking::spi::Operation::Write(buf) => data.extend_from_slice(buf),
234                }
235            }
236            let result = self.inner.transfer_in_place(&mut data);
237            let mut data_iter = data.iter();
238            for op in operations.iter_mut() {
239                match op {
240                    eh0_2::blocking::spi::Operation::Transfer(buf) => {
241                        buf.copy_from_slice(&data_iter.as_slice()[0..buf.len()]);
242                        if !buf.is_empty() {
243                            data_iter.nth(buf.len() - 1);
244                        }
245                    }
246                    eh0_2::blocking::spi::Operation::Write(buf) => {
247                        if !buf.is_empty() {
248                            data_iter.nth(buf.len() - 1);
249                        }
250                    }
251                }
252            }
253            result
254        }
255    }
256}
257
258// I2C (blocking)
259mod i2c {
260    use super::{Debug, Reverse};
261    use eh1_0::i2c::SevenBitAddress;
262
263    impl<T, E> eh0_2::blocking::i2c::Read for Reverse<T>
264    where
265        T: eh1_0::i2c::I2c<SevenBitAddress, Error = E>,
266        E: Debug,
267    {
268        type Error = E;
269
270        fn read(&mut self, address: SevenBitAddress, words: &mut [u8]) -> Result<(), Self::Error> {
271            self.inner.read(address, words)
272        }
273    }
274
275    impl<T, E> eh0_2::blocking::i2c::Write for Reverse<T>
276    where
277        T: eh1_0::i2c::I2c<SevenBitAddress, Error = E>,
278        E: Debug,
279    {
280        type Error = E;
281
282        fn write(&mut self, address: SevenBitAddress, words: &[u8]) -> Result<(), Self::Error> {
283            self.inner.write(address, words)
284        }
285    }
286
287    impl<T, E> eh0_2::blocking::i2c::WriteRead for Reverse<T>
288    where
289        T: eh1_0::i2c::I2c<SevenBitAddress, Error = E>,
290        E: Debug,
291    {
292        type Error = E;
293
294        fn write_read(
295            &mut self,
296            address: SevenBitAddress,
297            bytes: &[u8],
298            buffer: &mut [u8],
299        ) -> Result<(), Self::Error> {
300            self.inner.write_read(address, bytes, buffer)
301        }
302    }
303
304    #[cfg(feature = "alloc")]
305    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
306    extern crate alloc;
307    #[cfg(feature = "alloc")]
308    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
309    impl<T, E> eh0_2::blocking::i2c::Transactional for Reverse<T>
310    where
311        T: eh1_0::i2c::I2c<SevenBitAddress, Error = E>,
312        E: Debug,
313    {
314        type Error = E;
315
316        fn exec(
317            &mut self,
318            address: u8,
319            operations: &mut [eh0_2::blocking::i2c::Operation],
320        ) -> Result<(), Self::Error> {
321            let mut ops: alloc::vec::Vec<eh1_0::i2c::Operation> = operations
322                .iter_mut()
323                .map(|op| match op {
324                    eh0_2::blocking::i2c::Operation::Read(ref mut buff) => {
325                        eh1_0::i2c::Operation::Read(buff)
326                    }
327                    eh0_2::blocking::i2c::Operation::Write(buff) => {
328                        eh1_0::i2c::Operation::Write(buff)
329                    }
330                })
331                .collect();
332            self.inner.transaction(address, &mut ops)
333        }
334    }
335}
336
337/// Serial (UART etc.)
338#[cfg(feature = "embedded-io")]
339#[cfg_attr(docsrs, doc(cfg(feature = "embedded-io")))]
340mod serial {
341    use super::{Debug, Reverse};
342
343    impl<T, E> eh0_2::blocking::serial::Write<u8> for Reverse<T>
344    where
345        T: embedded_io::Write<Error = E>,
346        E: Debug,
347    {
348        type Error = E;
349
350        fn bwrite_all(&mut self, words: &[u8]) -> Result<(), Self::Error> {
351            self.inner.write(words).map(drop)
352        }
353
354        fn bflush(&mut self) -> Result<(), Self::Error> {
355            self.inner.flush()
356        }
357    }
358
359    impl<T, E> eh0_2::serial::Write<u8> for Reverse<T>
360    where
361        T: embedded_io::Write<Error = E>,
362        E: Debug,
363    {
364        type Error = E;
365
366        fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
367            self.inner
368                .write(&[word])
369                .map_err(nb::Error::Other)
370                .map(drop)
371        }
372
373        fn flush(&mut self) -> nb::Result<(), Self::Error> {
374            self.inner.flush().map_err(nb::Error::Other)
375        }
376    }
377}