esp_hal/spi/mod.rs
1//! Serial Peripheral Interface (SPI)
2//!
3//! ## Overview
4//! The Serial Peripheral Interface (SPI) is a synchronous serial interface
5//! useful for communication with external peripherals.
6//!
7//! ## Configuration
8//! This peripheral is capable of operating in either master or slave mode. For
9//! more information on these modes, please refer to the documentation in their
10//! respective modules.
11
12use crate::dma::{DmaEligible, DmaError};
13
14pub mod master;
15
16crate::unstable_module! {
17 pub mod slave;
18}
19
20/// SPI errors
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22#[cfg_attr(feature = "defmt", derive(defmt::Format))]
23#[non_exhaustive]
24pub enum Error {
25 /// Error occurred due to a DMA-related issue.
26 #[cfg(any(doc, feature = "unstable"))]
27 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
28 #[allow(clippy::enum_variant_names, reason = "DMA is unstable")]
29 DmaError(DmaError),
30 /// Error indicating that the maximum DMA transfer size was exceeded.
31 MaxDmaTransferSizeExceeded,
32 /// Error indicating that the FIFO size was exceeded during SPI
33 /// communication.
34 FifoSizeExeeded,
35 /// Error indicating that the operation is unsupported by the current
36 /// implementation or for the given arguments.
37 Unsupported,
38 /// An unknown error occurred during SPI communication.
39 Unknown,
40}
41
42#[doc(hidden)]
43#[cfg(feature = "unstable")]
44impl From<DmaError> for Error {
45 fn from(value: DmaError) -> Self {
46 Error::DmaError(value)
47 }
48}
49
50#[doc(hidden)]
51#[cfg(not(any(doc, feature = "unstable")))]
52impl From<DmaError> for Error {
53 fn from(_value: DmaError) -> Self {
54 Error::Unknown
55 }
56}
57
58impl embedded_hal::spi::Error for Error {
59 fn kind(&self) -> embedded_hal::spi::ErrorKind {
60 embedded_hal::spi::ErrorKind::Other
61 }
62}
63
64/// SPI communication modes, defined by clock polarity (CPOL) and clock phase
65/// (CPHA).
66///
67/// These modes control the clock signal's idle state and when data is sampled
68/// and shifted.
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70#[cfg_attr(feature = "defmt", derive(defmt::Format))]
71pub enum Mode {
72 /// Mode 0 (CPOL = 0, CPHA = 0): Clock is low when idle, data is captured on
73 /// the rising edge and propagated on the falling edge.
74 _0,
75 /// Mode 1 (CPOL = 0, CPHA = 1): Clock is low when idle, data is captured on
76 /// the falling edge and propagated on the rising edge.
77 _1,
78 /// Mode 2 (CPOL = 1, CPHA = 0): Clock is high when idle, data is captured
79 /// on the falling edge and propagated on the rising edge.
80 _2,
81 /// Mode 3 (CPOL = 1, CPHA = 1): Clock is high when idle, data is captured
82 /// on the rising edge and propagated on the falling edge.
83 _3,
84}
85
86/// SPI Bit Order
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
88#[cfg_attr(feature = "defmt", derive(defmt::Format))]
89pub enum BitOrder {
90 /// Most Significant Bit (MSB) is transmitted first.
91 MsbFirst,
92 /// Least Significant Bit (LSB) is transmitted first.
93 LsbFirst,
94}
95
96/// SPI data mode
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
98#[cfg_attr(feature = "defmt", derive(defmt::Format))]
99#[instability::unstable]
100pub enum DataMode {
101 /// 1 bit, two data lines. (MOSI, MISO)
102 SingleTwoDataLines,
103 /// 1 bit, 1 data line (SIO0)
104 Single,
105 /// 2 bits, two data lines. (SIO0, SIO1)
106 Dual,
107 /// 4 bit, 4 data lines. (SIO0 .. SIO3)
108 Quad,
109 #[cfg(spi_octal)]
110 /// 8 bit, 8 data lines. (SIO0 .. SIO7)
111 Octal,
112}
113
114crate::any_peripheral! {
115 /// Any SPI peripheral.
116 pub peripheral AnySpi {
117 #[cfg(spi2)]
118 Spi2(crate::peripherals::SPI2),
119 #[cfg(spi3)]
120 Spi3(crate::peripherals::SPI3),
121 }
122}
123
124impl DmaEligible for AnySpi {
125 #[cfg(gdma)]
126 type Dma = crate::dma::AnyGdmaChannel;
127 #[cfg(pdma)]
128 type Dma = crate::dma::AnySpiDmaChannel;
129
130 fn dma_peripheral(&self) -> crate::dma::DmaPeripheral {
131 match &self.0 {
132 #[cfg(spi2)]
133 AnySpiInner::Spi2(_) => crate::dma::DmaPeripheral::Spi2,
134 #[cfg(spi3)]
135 AnySpiInner::Spi3(_) => crate::dma::DmaPeripheral::Spi3,
136 }
137 }
138}