embedded_hal/blocking/
spi.rs

1//! Blocking SPI API
2
3/// Blocking transfer
4pub 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
13pub 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")]
23pub 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
34pub 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 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
58pub 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 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")]
82pub 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)]
112pub 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
121pub 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}