1use eh0 as embedded_hal;
47use embedded_hal::{blocking::spi, spi::FullDuplex};
48
49use super::error::MockError;
50use crate::common::Generic;
51
52#[derive(Clone, Debug, PartialEq, Eq)]
54pub enum Mode {
55 Write,
57 Transfer,
59 Send,
61 Read,
63}
64
65#[derive(Clone, Debug, PartialEq, Eq)]
69pub struct Transaction {
70 expected_mode: Mode,
71 expected_data: Vec<u8>,
72 response: Vec<u8>,
73}
74
75impl Transaction {
76 pub fn write(expected: Vec<u8>) -> Transaction {
78 Transaction {
79 expected_mode: Mode::Write,
80 expected_data: expected,
81 response: Vec::new(),
82 }
83 }
84
85 pub fn transfer(expected: Vec<u8>, response: Vec<u8>) -> Transaction {
87 Transaction {
88 expected_mode: Mode::Transfer,
89 expected_data: expected,
90 response,
91 }
92 }
93
94 pub fn send(expected: u8) -> Transaction {
96 Transaction {
97 expected_mode: Mode::Send,
98 expected_data: [expected].to_vec(),
99 response: Vec::new(),
100 }
101 }
102
103 pub fn read(response: u8) -> Transaction {
105 Transaction {
106 expected_mode: Mode::Read,
107 expected_data: Vec::new(),
108 response: [response].to_vec(),
109 }
110 }
111}
112
113pub type Mock = Generic<Transaction>;
122
123impl spi::Write<u8> for Mock {
124 type Error = MockError;
125
126 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
130 let w = self.next().expect("no expectation for spi::write call");
131 assert_eq!(w.expected_mode, Mode::Write, "spi::write unexpected mode");
132 assert_eq!(
133 &w.expected_data, &buffer,
134 "spi::write data does not match expectation"
135 );
136 Ok(())
137 }
138}
139
140impl FullDuplex<u8> for Mock {
141 type Error = MockError;
142 fn send(&mut self, buffer: u8) -> nb::Result<(), Self::Error> {
146 let data = self.next().expect("no expectation for spi::send call");
147 assert_eq!(data.expected_mode, Mode::Send, "spi::send unexpected mode");
148 assert_eq!(
149 data.expected_data[0], buffer,
150 "spi::send data does not match expectation"
151 );
152 Ok(())
153 }
154
155 fn read(&mut self) -> nb::Result<u8, Self::Error> {
159 let w = self.next().expect("no expectation for spi::read call");
160 assert_eq!(w.expected_mode, Mode::Read, "spi::Read unexpected mode");
161 assert_eq!(
162 1,
163 w.response.len(),
164 "mismatched response length for spi::read"
165 );
166 let buffer: u8 = w.response[0];
167 Ok(buffer)
168 }
169}
170
171impl spi::Transfer<u8> for Mock {
172 type Error = MockError;
173
174 fn transfer<'w>(&mut self, buffer: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
178 let w = self.next().expect("no expectation for spi::transfer call");
179 assert_eq!(
180 w.expected_mode,
181 Mode::Transfer,
182 "spi::transfer unexpected mode"
183 );
184 assert_eq!(
185 &w.expected_data, &buffer,
186 "spi::transfer write data does not match expectation"
187 );
188 assert_eq!(
189 buffer.len(),
190 w.response.len(),
191 "mismatched response length for spi::transfer"
192 );
193 buffer.copy_from_slice(&w.response);
194 Ok(buffer)
195 }
196}
197
198impl spi::WriteIter<u8> for Mock {
199 type Error = MockError;
200
201 fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
202 where
203 WI: IntoIterator<Item = u8>,
204 {
205 let w = self
206 .next()
207 .expect("no expectation for spi::write_iter call");
208 let buffer = words.into_iter().collect::<Vec<_>>();
209 assert_eq!(
210 w.expected_mode,
211 Mode::Write,
212 "spi::write_iter unexpected mode"
213 );
214 assert_eq!(
215 &w.expected_data, &buffer,
216 "spi::write_iter data does not match expectation"
217 );
218 Ok(())
219 }
220}
221
222#[cfg(test)]
223mod test {
224 use eh0 as embedded_hal;
225 use embedded_hal::blocking::spi::{Transfer, Write, WriteIter};
226
227 use super::*;
228
229 #[test]
230 fn test_spi_mock_send() {
231 let mut spi = Mock::new(&[Transaction::send(10)]);
232
233 let _ = spi.send(10).unwrap();
234
235 spi.done();
236 }
237
238 #[test]
239 fn test_spi_mock_read() {
240 let mut spi = Mock::new(&[Transaction::read(10)]);
241
242 let ans = spi.read().unwrap();
243
244 assert_eq!(ans, 10);
245
246 spi.done();
247 }
248
249 #[test]
250 fn test_spi_mock_multiple1() {
251 let expectations = [
252 Transaction::write(vec![1, 2]),
253 Transaction::send(9),
254 Transaction::read(10),
255 Transaction::send(0xFE),
256 Transaction::read(0xFF),
257 Transaction::transfer(vec![3, 4], vec![5, 6]),
258 ];
259 let mut spi = Mock::new(&expectations);
260
261 spi.write(&vec![1, 2]).unwrap();
262
263 let _ = spi.send(0x09);
264 assert_eq!(spi.read().unwrap(), 0x0a);
265 let _ = spi.send(0xfe);
266 assert_eq!(spi.read().unwrap(), 0xFF);
267 let mut v = vec![3, 4];
268 spi.transfer(&mut v).unwrap();
269
270 assert_eq!(v, vec![5, 6]);
271
272 spi.done();
273 }
274
275 #[test]
276 fn test_spi_mock_write() {
277 let expectations = [Transaction::write(vec![10, 12])];
278 let mut spi = Mock::new(&expectations);
279
280 spi.write(&vec![10, 12]).unwrap();
281
282 spi.done();
283 }
284
285 #[test]
286 fn test_spi_mock_write_iter() {
287 let expectations = [Transaction::write(vec![10, 12])];
288 let mut spi = Mock::new(&expectations);
289
290 spi.write_iter(vec![10, 12u8]).unwrap();
291
292 spi.done();
293 }
294
295 #[test]
296 fn test_spi_mock_transfer() {
297 let expectations = [Transaction::transfer(vec![10, 12], vec![12, 13])];
298 let mut spi = Mock::new(&expectations);
299
300 let mut v = vec![10, 12];
301 spi.transfer(&mut v).unwrap();
302
303 assert_eq!(v, vec![12, 13]);
304
305 spi.done();
306 }
307
308 #[test]
309 fn test_spi_mock_multiple() {
310 let expectations = [
311 Transaction::write(vec![1, 2]),
312 Transaction::transfer(vec![3, 4], vec![5, 6]),
313 ];
314 let mut spi = Mock::new(&expectations);
315
316 spi.write(&vec![1, 2]).unwrap();
317
318 let mut v = vec![3, 4];
319 spi.transfer(&mut v).unwrap();
320
321 assert_eq!(v, vec![5, 6]);
322
323 spi.done();
324 }
325
326 #[test]
327 #[should_panic(expected = "spi::write data does not match expectation")]
328 fn test_spi_mock_write_err() {
329 let expectations = [Transaction::write(vec![10, 12])];
330 let mut spi = Mock::new(&expectations);
331 spi.write(&vec![10, 12, 12]).unwrap();
332 }
333
334 #[test]
335 #[should_panic(expected = "spi::write_iter data does not match expectation")]
336 fn test_spi_mock_write_iter_err() {
337 let expectations = [Transaction::write(vec![10, 12])];
338 let mut spi = Mock::new(&expectations);
339 spi.write_iter(vec![10, 12, 12u8]).unwrap();
340 }
341
342 #[test]
343 #[should_panic(expected = "spi::transfer write data does not match expectation")]
344 fn test_spi_mock_transfer_err() {
345 let expectations = [Transaction::transfer(vec![10, 12], vec![12, 15])];
346 let mut spi = Mock::new(&expectations);
347 spi.transfer(&mut vec![10, 13]).unwrap();
348 }
349
350 #[test]
351 #[should_panic(expected = "spi::write data does not match expectation")]
352 fn test_spi_mock_multiple_transaction_err() {
353 let expectations = [
354 Transaction::write(vec![10, 12]),
355 Transaction::write(vec![10, 12]),
356 ];
357 let mut spi = Mock::new(&expectations);
358 spi.write(&vec![10, 12, 10]).unwrap();
359 }
360
361 #[test]
362 #[should_panic(expected = "spi::write unexpected mode")]
363 fn test_spi_mock_mode_err() {
364 let expectations = [Transaction::transfer(vec![10, 12], vec![])];
365 let mut spi = Mock::new(&expectations);
366 spi.write(&vec![10, 12, 12]).unwrap();
368 }
369}