embassy_stm32_plus/builder/spi/spi1/
mod.rs

1use embassy_stm32::mode::{Async, Blocking};
2use embassy_stm32::Peripheral;
3#[cfg(not(STM32C0))]
4use embassy_stm32::peripherals::{DMA1_CH2, DMA1_CH3};
5use embassy_stm32::peripherals::SPI1;
6#[cfg(SPI1_PA1)]
7use embassy_stm32::peripherals::PA1;
8#[cfg(SPI1_PA5)]
9use embassy_stm32::peripherals::PA5;
10#[cfg(SPI1_PB3)]
11use embassy_stm32::peripherals::PB3;
12#[cfg(SPI1_PB6)]
13use embassy_stm32::peripherals::PB6;
14use embassy_stm32::spi::{Config, MisoPin, MosiPin, Spi};
15#[cfg(STM32C0)]
16use embassy_stm32::spi::{RxDma, TxDma};
17use crate::builder::spi::base::SpiBase;
18use crate::builder::spi::spi1::rx::{Spi1Miso, Spi1RxBuilder};
19use crate::builder::spi::spi1::tx::Spi1Mosi;
20
21pub mod rx;
22pub mod tx;
23
24/// spi1 sck pin
25pub enum Spi1Sck {
26    #[cfg(SPI1_PA1)]
27    PA1(PA1),
28    #[cfg(SPI1_PA5)]
29    PA5(PA5),
30    #[cfg(SPI1_PB3)]
31    PB3(PB3),
32    #[cfg(SPI1_PB6)]
33    PB6(PB6),
34}
35
36/// spi1 builder
37pub struct Spi1Builder {
38    /// spi device
39    pub base: SpiBase<SPI1>,
40    /// sck pin
41    pub sck: Spi1Sck,
42    /// mosi pin
43    pub mosi: Spi1Mosi,
44    /// miso pin
45    pub miso: Spi1Miso,
46}
47
48/// spi1 build
49macro_rules! spi1_build {
50    ($tx_dma:ty,$rx_dma:ty) => {
51        /// Create a new SPI driver.<br />
52        /// more see [`Spi::<Async>::new`]
53        pub fn build(self, tx_dma: $tx_dma, rx_dma: $rx_dma) -> Spi<'static, Async> {
54            let Self { base, sck, mosi, miso } = self;
55            let rx = Spi1RxBuilder { base, sck, miso };
56            match mosi {
57                #[cfg(SPI1_PA2)]
58                Spi1Mosi::PA2(pa2) => { Self::build_rx(rx, pa2, tx_dma, rx_dma) }
59                #[cfg(SPI1_PA7)]
60                Spi1Mosi::PA7(pa7) => { Self::build_rx(rx, pa7, tx_dma, rx_dma) }
61                #[cfg(SPI1_PA12)]
62                Spi1Mosi::PA12(pa12) => { Self::build_rx(rx, pa12, tx_dma, rx_dma) }
63                #[cfg(SPI1_PB5)]
64                Spi1Mosi::PB5(pb5) => { Self::build_rx(rx, pb5, tx_dma, rx_dma) }
65                #[cfg(SPI1_PB6)]
66                Spi1Mosi::PB6(pb6) => { Self::build_rx(rx, pb6, tx_dma, rx_dma) }
67            }
68        }
69
70        /// build by rx
71        fn build_rx(
72            rx: Spi1RxBuilder,
73            mosi: impl Peripheral<P=impl MosiPin<SPI1>> + 'static,
74            tx_dma: $tx_dma,
75            rx_dma: $rx_dma) -> Spi<'static, Async> {
76            let Spi1RxBuilder { base, sck, miso } = rx;
77            match miso {
78                #[cfg(SPI1_PA6)]
79                Spi1Miso::PA6(pa6) => { Self::build_sck(base, sck, mosi, pa6, tx_dma, rx_dma) }
80                #[cfg(SPI1_PA11)]
81                Spi1Miso::PA11(pa11) => { Self::build_sck(base, sck, mosi, pa11, tx_dma, rx_dma) }
82                #[cfg(SPI1_PB4)]
83                Spi1Miso::PB4(pb4) => { Self::build_sck(base, sck, mosi, pb4, tx_dma, rx_dma) }
84                #[cfg(SPI1_PB6)]
85                Spi1Miso::PB6(pb6) => { Self::build_sck(base, sck, mosi, pb6, tx_dma, rx_dma) }
86            }
87        }
88
89        /// build by sck
90        fn build_sck(
91            base: SpiBase<SPI1>,
92            sck: Spi1Sck,
93            mosi: impl Peripheral<P=impl MosiPin<SPI1>> + 'static,
94            miso: impl Peripheral<P=impl MisoPin<SPI1>> + 'static,
95            tx_dma: $tx_dma,
96            rx_dma: $rx_dma) -> Spi<'static, Async> {
97            match sck {
98                #[cfg(SPI1_PA1)]
99                Spi1Sck::PA1(pa1) => { Spi::new(base.spi, pa1, mosi, miso, tx_dma, rx_dma, base.config.unwrap_or_default()) }
100                #[cfg(SPI1_PA5)]
101                Spi1Sck::PA5(pa5) => { Spi::new(base.spi, pa5, mosi, miso, tx_dma, rx_dma, base.config.unwrap_or_default()) }
102                #[cfg(SPI1_PB3)]
103                Spi1Sck::PB3(pb3) => { Spi::new(base.spi, pb3, mosi, miso, tx_dma, rx_dma, base.config.unwrap_or_default()) }
104                #[cfg(SPI1_PB6)]
105                Spi1Sck::PB6(pb6) => { Spi::new(base.spi, pb6, mosi, miso, tx_dma, rx_dma, base.config.unwrap_or_default()) }
106            }
107        }
108    };
109}
110
111/// custom method
112impl Spi1Builder {
113    /// create builder
114    #[inline]
115    pub fn new(spi: SPI1, sck: Spi1Sck, mosi: Spi1Mosi, miso: Spi1Miso) -> Self {
116        Self { base: SpiBase::new(spi), sck, mosi, miso }
117    }
118
119    /// set spi config
120    #[inline]
121    pub fn config(mut self, config: Config) -> Self {
122        self.base.set_config(config);
123        self
124    }
125
126    /// Create a new blocking SPI driver.<br />
127    /// more see [`Spi::<Blocking>::new_blocking`]
128    pub fn build_blocking(self) -> Spi<'static, Blocking> {
129        let Self { base, sck, mosi, miso } = self;
130        let rx = Spi1RxBuilder { base, sck, miso };
131        match mosi {
132            #[cfg(SPI1_PA2)]
133            Spi1Mosi::PA2(pa2) => { Self::build_blocking_rx(rx, pa2) }
134            #[cfg(SPI1_PA7)]
135            Spi1Mosi::PA7(pa7) => { Self::build_blocking_rx(rx, pa7) }
136            #[cfg(SPI1_PA12)]
137            Spi1Mosi::PA12(pa12) => { Self::build_blocking_rx(rx, pa12) }
138            #[cfg(SPI1_PB5)]
139            Spi1Mosi::PB5(pb5) => { Self::build_blocking_rx(rx, pb5) }
140            #[cfg(SPI1_PB6)]
141            Spi1Mosi::PB6(pb6) => { Self::build_blocking_rx(rx, pb6) }
142        }
143    }
144
145    /// build blocking by rx
146    fn build_blocking_rx(rx: Spi1RxBuilder, mosi: impl Peripheral<P=impl MosiPin<SPI1>> + 'static) -> Spi<'static, Blocking> {
147        let Spi1RxBuilder { base, sck, miso } = rx;
148        match miso {
149            #[cfg(SPI1_PA6)]
150            Spi1Miso::PA6(pa6) => { Self::build_blocking_sck(base, sck, mosi, pa6) }
151            #[cfg(SPI1_PA11)]
152            Spi1Miso::PA11(pa11) => { Self::build_blocking_sck(base, sck, mosi, pa11) }
153            #[cfg(SPI1_PB4)]
154            Spi1Miso::PB4(pb4) => { Self::build_blocking_sck(base, sck, mosi, pb4) }
155            #[cfg(SPI1_PB6)]
156            Spi1Miso::PB6(pb6) => { Self::build_blocking_sck(base, sck, mosi, pb6) }
157        }
158    }
159
160    /// build blocking by sck
161    fn build_blocking_sck(
162        base: SpiBase<SPI1>,
163        sck: Spi1Sck,
164        mosi: impl Peripheral<P=impl MosiPin<SPI1>> + 'static,
165        miso: impl Peripheral<P=impl MisoPin<SPI1>> + 'static) -> Spi<'static, Blocking> {
166        match sck {
167            #[cfg(SPI1_PA1)]
168            Spi1Sck::PA1(pa1) => { Spi::new_blocking(base.spi, pa1, mosi, miso, base.config.unwrap_or_default()) }
169            #[cfg(SPI1_PA5)]
170            Spi1Sck::PA5(pa5) => { Spi::new_blocking(base.spi, pa5, mosi, miso, base.config.unwrap_or_default()) }
171            #[cfg(SPI1_PB3)]
172            Spi1Sck::PB3(pb3) => { Spi::new_blocking(base.spi, pb3, mosi, miso, base.config.unwrap_or_default()) }
173            #[cfg(SPI1_PB6)]
174            Spi1Sck::PB6(pb6) => { Spi::new_blocking(base.spi, pb6, mosi, miso, base.config.unwrap_or_default()) }
175        }
176    }
177
178    #[cfg(STM32C0)]
179    spi1_build!(impl Peripheral<P = impl TxDma<SPI1>> + 'static,impl Peripheral<P = impl RxDma<SPI1>> + 'static);
180    #[cfg(not(STM32C0))]
181    spi1_build!(DMA1_CH3,DMA1_CH2);
182}