embassy_stm32_plus/builder/i2c/
i2c1.rs

1use embassy_stm32::i2c::{Config, I2c, SclPin};
2#[cfg(STM32C0)]
3use embassy_stm32::i2c::{RxDma, TxDma};
4use embassy_stm32::{bind_interrupts, i2c, Peripheral};
5use embassy_stm32::mode::{Async, Blocking};
6#[cfg(not(STM32C0))]
7use embassy_stm32::peripherals::{DMA1_CH6, DMA1_CH7};
8use embassy_stm32::peripherals::{I2C1, PB6, PB7};
9#[cfg(I2C1_PA9)]
10use embassy_stm32::peripherals::PA9;
11#[cfg(I2C1_PA10)]
12use embassy_stm32::peripherals::PA10;
13#[cfg(PB8)]
14use embassy_stm32::peripherals::PB8;
15#[cfg(PB9)]
16use embassy_stm32::peripherals::PB9;
17#[cfg(I2C1_PC14)]
18use embassy_stm32::peripherals::PC14;
19use embassy_stm32::time::Hertz;
20use crate::builder::i2c::base::I2cBase;
21
22bind_interrupts!(struct Irqs {
23    #[cfg(STM32C0)]
24    I2C1 => i2c::ErrorInterruptHandler<I2C1>,i2c::EventInterruptHandler<I2C1>;
25    #[cfg(not(STM32C0))]
26    I2C1_ER => i2c::ErrorInterruptHandler<I2C1>;
27    #[cfg(not(STM32C0))]
28    I2C1_EV => i2c::EventInterruptHandler<I2C1>;
29});
30
31/// i2c1 scl pin
32pub enum I2c1Scl {
33    #[cfg(I2C1_PA9)]
34    PA9(PA9),
35    PB6(PB6),
36    #[cfg(I2C1_SCL_PB7)]
37    PB7(PB7),
38    #[cfg(PB8)]
39    PB8(PB8),
40}
41
42/// i2c1 sda pin
43pub enum I2c1Sda {
44    #[cfg(I2C1_PA10)]
45    PA10(PA10),
46    PB7(PB7),
47    #[cfg(PB9)]
48    PB9(PB9),
49    #[cfg(I2C1_PC14)]
50    PC14(PC14),
51}
52
53/// i2c1 builder
54pub struct I2c1Builder {
55    /// i2c base
56    pub base: I2cBase<I2C1>,
57    /// scl pin
58    pub scl: I2c1Scl,
59    /// sda pin
60    pub sda: I2c1Sda,
61}
62
63/// i2c1 build method
64macro_rules! i2c1_build {
65    ($tx_dma:ty,$rx_dma:ty) => {
66        /// Create a new I2C driver, more see [`I2c::<Async>::new`]
67        pub fn build(self, tx_dma: $tx_dma, rx_dma: $rx_dma) -> I2c<'static, Async> {
68            match self.scl {
69                #[cfg(I2C1_PA9)]
70                I2c1Scl::PA9(pa9) => { Self::build_sda(pa9, self.sda, self.base, tx_dma, rx_dma) }
71                I2c1Scl::PB6(pb6) => { Self::build_sda(pb6, self.sda, self.base, tx_dma, rx_dma) }
72                #[cfg(I2C1_SCL_PB7)]
73                I2c1Scl::PB7(pb7) => { Self::build_sda(pb7, self.sda, self.base, tx_dma, rx_dma) }
74                #[cfg(PB8)]
75                I2c1Scl::PB8(pb8) => { Self::build_sda(pb8, self.sda, self.base, tx_dma, rx_dma) }
76            }
77        }
78
79        /// build by sda
80        pub fn build_sda(
81            scl: impl Peripheral<P=impl SclPin<I2C1>> + 'static,
82            sda: I2c1Sda,
83            base: I2cBase<I2C1>,
84            tx_dma: $tx_dma,
85            rx_dma: $rx_dma) -> I2c<'static, Async> {
86            match sda {
87                #[cfg(I2C1_PA10)]
88                I2c1Sda::PA10(pa10) => { I2c::new(base.i2c, scl, pa10, Irqs, tx_dma, rx_dma, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
89                I2c1Sda::PB7(pb7) => { I2c::new(base.i2c, scl, pb7, Irqs, tx_dma, rx_dma, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
90                #[cfg(PB9)]
91                I2c1Sda::PB9(pb9) => { I2c::new(base.i2c, scl, pb9, Irqs, tx_dma, rx_dma, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
92                #[cfg(I2C1_PC14)]
93                I2c1Sda::PC14(pc14) => { I2c::new(base.i2c, scl, pc14, Irqs, tx_dma, rx_dma, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
94            }
95        }
96    };
97}
98
99/// custom method
100impl I2c1Builder {
101    /// create builder
102    #[inline]
103    pub fn new(i2c: I2C1, scl: I2c1Scl, sda: I2c1Sda) -> Self {
104        Self { base: I2cBase::new(i2c), scl, sda }
105    }
106
107    /// set i2c freq hertz
108    #[inline]
109    pub fn freq(mut self, freq: Hertz) -> Self {
110        self.base.set_freq(freq);
111        self
112    }
113
114    /// set i2c config
115    #[inline]
116    pub fn config(mut self, config: Config) -> Self {
117        self.base.set_config(config);
118        self
119    }
120
121    #[cfg(STM32C0)]
122    i2c1_build!(impl Peripheral<P = impl TxDma<I2C1>> + 'static,impl Peripheral<P = impl RxDma<I2C1>> + 'static);
123    #[cfg(not(STM32C0))]
124    i2c1_build!(DMA1_CH6,DMA1_CH7);
125
126    /// Create a new I2C driver, more see [`I2c::<Blocking>::new_blocking`]
127    pub fn build_blocking(self) -> I2c<'static, Blocking> {
128        match self.scl {
129            #[cfg(I2C1_PA9)]
130            I2c1Scl::PA9(pa9) => { Self::build_blocking_sda(pa9, self.sda, self.base) }
131            I2c1Scl::PB6(pb6) => { Self::build_blocking_sda(pb6, self.sda, self.base) }
132            #[cfg(I2C1_SCL_PB7)]
133            I2c1Scl::PB7(pb7) => { Self::build_blocking_sda(pb7, self.sda, self.base) }
134            #[cfg(PB8)]
135            I2c1Scl::PB8(pb8) => { Self::build_blocking_sda(pb8, self.sda, self.base) }
136        }
137    }
138
139    /// build by sda
140    pub fn build_blocking_sda(
141        scl: impl Peripheral<P=impl SclPin<I2C1>> + 'static,
142        sda: I2c1Sda,
143        base: I2cBase<I2C1>) -> I2c<'static, Blocking> {
144        match sda {
145            #[cfg(I2C1_PA10)]
146            I2c1Sda::PA10(pa10) => { I2c::new_blocking(base.i2c, scl, pa10, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
147            I2c1Sda::PB7(pb7) => { I2c::new_blocking(base.i2c, scl, pb7, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
148            #[cfg(PB9)]
149            I2c1Sda::PB9(pb9) => { I2c::new_blocking(base.i2c, scl, pb9, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
150            #[cfg(I2C1_PC14)]
151            I2c1Sda::PC14(pc14) => { I2c::new_blocking(base.i2c, scl, pc14, base.freq.unwrap_or_else(|| { Hertz(1) }), base.config.unwrap_or_default()) }
152        }
153    }
154}