1 | //! Blocking SPI API |
2 | |
3 | /// Blocking transfer |
4 | pub trait Transfer<W> { |
5 | /// Error type |
6 | type Error; |
7 | |
8 | /// Sends `words` to the slave. Returns the `words` received from the slave |
9 | fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>; |
10 | } |
11 | |
12 | /// Blocking write |
13 | pub trait Write<W> { |
14 | /// Error type |
15 | type Error; |
16 | |
17 | /// Sends `words` to the slave, ignoring all the incoming words |
18 | fn write(&mut self, words: &[W]) -> Result<(), Self::Error>; |
19 | } |
20 | |
21 | /// Blocking write (iterator version) |
22 | #[cfg (feature = "unproven" )] |
23 | pub trait WriteIter<W> { |
24 | /// Error type |
25 | type Error; |
26 | |
27 | /// Sends `words` to the slave, ignoring all the incoming words |
28 | fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error> |
29 | where |
30 | WI: IntoIterator<Item = W>; |
31 | } |
32 | |
33 | /// Blocking transfer |
34 | pub mod transfer { |
35 | /// Default implementation of `blocking::spi::Transfer<W>` for implementers of |
36 | /// `spi::FullDuplex<W>` |
37 | pub trait Default<W>: ::spi::FullDuplex<W> {} |
38 | |
39 | impl<W, S> ::blocking::spi::Transfer<W> for S |
40 | where |
41 | S: Default<W>, |
42 | W: Clone, |
43 | { |
44 | type Error = S::Error; |
45 | |
46 | fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], S::Error> { |
47 | for word: &mut W in words.iter_mut() { |
48 | block!(self.send(word.clone()))?; |
49 | *word = block!(self.read())?; |
50 | } |
51 | |
52 | Ok(words) |
53 | } |
54 | } |
55 | } |
56 | |
57 | /// Blocking write |
58 | pub mod write { |
59 | /// Default implementation of `blocking::spi::Write<W>` for implementers of `spi::FullDuplex<W>` |
60 | pub trait Default<W>: ::spi::FullDuplex<W> {} |
61 | |
62 | impl<W, S> ::blocking::spi::Write<W> for S |
63 | where |
64 | S: Default<W>, |
65 | W: Clone, |
66 | { |
67 | type Error = S::Error; |
68 | |
69 | fn write(&mut self, words: &[W]) -> Result<(), S::Error> { |
70 | for word: &W in words { |
71 | block!(self.send(word.clone()))?; |
72 | block!(self.read())?; |
73 | } |
74 | |
75 | Ok(()) |
76 | } |
77 | } |
78 | } |
79 | |
80 | /// Blocking write (iterator version) |
81 | #[cfg (feature = "unproven" )] |
82 | pub mod write_iter { |
83 | /// Default implementation of `blocking::spi::WriteIter<W>` for implementers of |
84 | /// `spi::FullDuplex<W>` |
85 | pub trait Default<W>: ::spi::FullDuplex<W> {} |
86 | |
87 | impl<W, S> ::blocking::spi::WriteIter<W> for S |
88 | where |
89 | S: Default<W>, |
90 | W: Clone, |
91 | { |
92 | type Error = S::Error; |
93 | |
94 | fn write_iter<WI>(&mut self, words: WI) -> Result<(), S::Error> |
95 | where |
96 | WI: IntoIterator<Item = W>, |
97 | { |
98 | for word in words.into_iter() { |
99 | block!(self.send(word.clone()))?; |
100 | block!(self.read())?; |
101 | } |
102 | |
103 | Ok(()) |
104 | } |
105 | } |
106 | } |
107 | |
108 | /// Operation for transactional SPI trait |
109 | /// |
110 | /// This allows composition of SPI operations into a single bus transaction |
111 | #[derive (Debug, PartialEq)] |
112 | pub enum Operation<'a, W: 'static> { |
113 | /// Write data from the provided buffer, discarding read data |
114 | Write(&'a [W]), |
115 | /// Write data out while reading data into the provided buffer |
116 | Transfer(&'a mut [W]), |
117 | } |
118 | |
119 | /// Transactional trait allows multiple actions to be executed |
120 | /// as part of a single SPI transaction |
121 | pub trait Transactional<W: 'static> { |
122 | /// Associated error type |
123 | type Error; |
124 | |
125 | /// Execute the provided transactions |
126 | fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Self::Error>; |
127 | } |
128 | |