stm32_rust_template/driver/spi/
mod.rs

1//! # SPI Driver
2//!
3//! Provides a hardware abstraction layer for Serial Peripheral Interface (SPI)
4//! communication on STM32 microcontrollers.
5//!
6//! This module defines the SPI trait and supporting types for configuring
7//! master/slave modes, frame formats, and data transfer operations across
8//! different STM32 families.
9#![allow(dead_code)]
10
11use bitflags::bitflags;
12use core::ops::FnMut;
13
14/// Defines the operational mode of the SPI peripheral.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Mode {
17    Inactive,
18    Master,
19    Slave,
20}
21
22/// Defines the SPI frame format.
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum FrameFormat {
25    /// Clock Polarity 0, Clock Phase 0 (default)
26    CPOL0_CPHA0,
27    /// Clock Polarity 0, Clock Phase 1
28    CPOL0_CPHA1,
29    /// Clock Polarity 1, Clock Phase 0
30    CPOL1_CPHA0,
31    /// Clock Polarity 1, Clock Phase 1
32    CPOL1_CPHA1,
33    /// Texas Instruments Frame Format
34    TI_SSI,
35    /// National Semiconductor Microwire Frame Format
36    Microwire,
37}
38
39/// Defines the bit order for data transfers.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum BitOrder {
42    /// MSB to LSB (default)
43    MSB_LSB,
44    /// LSB to MSB
45    LSB_MSB,
46}
47
48/// Defines the slave select mode.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum SlaveSelectMode {
51    /// Not used (default)
52    MasterUnused,
53    /// Software controlled
54    MasterSoftware,
55    /// Hardware controlled Output
56    MasterHwOutput,
57    /// Hardware monitored Input
58    MasterHwInput,
59    /// Hardware monitored (default for slave)
60    SlaveHardware,
61    /// Software controlled
62    SlaveSoftware,
63}
64
65/// Represents the status of the SPI peripheral.
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub struct Status {
68    /// Transmitter/Receiver busy flag
69    pub busy: bool,
70    /// Data lost: Receive overflow / Transmit underflow
71    pub data_lost: bool,
72    /// Mode fault detected
73    pub mode_fault: bool,
74}
75
76bitflags! {
77    /// Represents SPI communication events.
78    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
79    pub struct Event: u32 {
80        /// Data Transfer completed
81        const TRANSFER_COMPLETE = (1 << 0);
82        /// Data lost: Receive overflow / Transmit underflow
83        const DATA_LOST = (1 << 1);
84        /// Master Mode Fault (SS deactivated when Master)
85        const MODE_FAULT = (1 << 2);
86    }
87}
88
89/// A generic error type for the SPI driver, using i32 for error codes.
90pub type Error = i32;
91
92/// A specialized Result type for SPI operations.
93pub type Result<T> = core::result::Result<T, Error>;
94
95/// Holds the configuration for a SPI peripheral.
96#[derive(Debug, Clone, PartialEq, Eq)]
97pub struct Config {
98    pub mode: Mode,
99    pub frame_format: FrameFormat,
100    pub bit_order: BitOrder,
101    pub slave_select_mode: SlaveSelectMode,
102    pub bus_speed_hz: u32,
103    pub data_bits: u8,
104}
105
106impl Default for Config {
107    fn default() -> Self {
108        Self {
109            mode: Mode::Master,
110            frame_format: FrameFormat::CPOL0_CPHA0,
111            bit_order: BitOrder::MSB_LSB,
112            slave_select_mode: SlaveSelectMode::MasterHwOutput,
113            bus_speed_hz: 1_000_000, // 1 MHz
114            data_bits: 8,
115        }
116    }
117}
118
119/// A trait that defines a standard interface for a SPI driver.
120pub trait Spi<'a> {
121    /// Initializes the SPI peripheral.
122    fn initialize(&mut self, callback: impl FnMut(Event) + 'a) -> Result<()>;
123
124    /// De-initializes the SPI peripheral.
125    fn uninitialize(&mut self) -> Result<()>;
126
127    /// Configures the SPI peripheral.
128    fn configure(&mut self, config: &Config) -> Result<()>;
129
130    /// Transmits data over the SPI bus.
131    fn send(&mut self, data: &[u8]) -> Result<()>;
132
133    /// Receives data from the SPI bus.
134    fn receive(&mut self, data: &mut [u8]) -> Result<()>;
135
136    /// Simultaneously sends and receives data.
137    fn transfer(&mut self, data_out: &[u8], data_in: &mut [u8]) -> Result<()>;
138
139    /// Gets the number of bytes transferred in the last transaction.
140    fn get_data_count(&self) -> u32;
141
142    /// Gets the current status of the SPI peripheral.
143    fn get_status(&self) -> Status;
144
145    /// Controls the slave select line in software-controlled modes.
146    fn control_slave_select(&mut self, active: bool) -> Result<()>;
147}
148
149#[cfg(feature = "stm32f407")]
150pub mod stm32f407;
151
152#[cfg(feature = "stm32f401")]
153pub mod stm32f401;
154
155#[cfg(feature = "stm32f411")]
156pub mod stm32f411;
157
158#[cfg(feature = "stm32f103")]
159pub mod stm32f103;