| 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 | |