1 | //! Serial Peripheral Interface |
2 | |
3 | use nb; |
4 | |
5 | /// Full duplex (master mode) |
6 | /// |
7 | /// # Notes |
8 | /// |
9 | /// - It's the task of the user of this interface to manage the slave select lines |
10 | /// |
11 | /// - Due to how full duplex SPI works each `read` call must be preceded by a `send` call. |
12 | /// |
13 | /// - Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different |
14 | /// `Word` types to allow operation in both modes. |
15 | pub trait FullDuplex<Word> { |
16 | /// An enumeration of SPI errors |
17 | type Error; |
18 | |
19 | /// Reads the word stored in the shift register |
20 | /// |
21 | /// **NOTE** A word must be sent to the slave before attempting to call this |
22 | /// method. |
23 | fn read(&mut self) -> nb::Result<Word, Self::Error>; |
24 | |
25 | /// Sends a word to the slave |
26 | fn send(&mut self, word: Word) -> nb::Result<(), Self::Error>; |
27 | } |
28 | |
29 | /// Clock polarity |
30 | #[derive (Clone, Copy, PartialEq, Eq)] |
31 | pub enum Polarity { |
32 | /// Clock signal low when idle |
33 | IdleLow, |
34 | /// Clock signal high when idle |
35 | IdleHigh, |
36 | } |
37 | |
38 | /// Clock phase |
39 | #[derive (Clone, Copy, PartialEq, Eq)] |
40 | pub enum Phase { |
41 | /// Data in "captured" on the first clock transition |
42 | CaptureOnFirstTransition, |
43 | /// Data in "captured" on the second clock transition |
44 | CaptureOnSecondTransition, |
45 | } |
46 | |
47 | /// SPI mode |
48 | #[derive (Clone, Copy, PartialEq, Eq)] |
49 | pub struct Mode { |
50 | /// Clock polarity |
51 | pub polarity: Polarity, |
52 | /// Clock phase |
53 | pub phase: Phase, |
54 | } |
55 | |
56 | /// Helper for CPOL = 0, CPHA = 0 |
57 | pub const MODE_0: Mode = Mode { |
58 | polarity: Polarity::IdleLow, |
59 | phase: Phase::CaptureOnFirstTransition, |
60 | }; |
61 | |
62 | /// Helper for CPOL = 0, CPHA = 1 |
63 | pub const MODE_1: Mode = Mode { |
64 | polarity: Polarity::IdleLow, |
65 | phase: Phase::CaptureOnSecondTransition, |
66 | }; |
67 | |
68 | /// Helper for CPOL = 1, CPHA = 0 |
69 | pub const MODE_2: Mode = Mode { |
70 | polarity: Polarity::IdleHigh, |
71 | phase: Phase::CaptureOnFirstTransition, |
72 | }; |
73 | |
74 | /// Helper for CPOL = 1, CPHA = 1 |
75 | pub const MODE_3: Mode = Mode { |
76 | polarity: Polarity::IdleHigh, |
77 | phase: Phase::CaptureOnSecondTransition, |
78 | }; |
79 | |