aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Špaček <[email protected]>2024-05-26 15:40:42 +0200
committerJan Špaček <[email protected]>2024-06-01 19:46:39 +0200
commit41711195e305e45caec3ff8316688a6b6d6af955 (patch)
tree3db99b131e6af753db05517f1aa8bb7ffc705be3
parentca3c15658dfb75945506c15070fd0deeb1583aa3 (diff)
stm32/i2c: use new_pin! macro
-rw-r--r--embassy-stm32/src/i2c/mod.rs89
-rw-r--r--embassy-stm32/src/i2c/v1.rs6
-rw-r--r--embassy-stm32/src/i2c/v2.rs6
3 files changed, 58 insertions, 43 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 0bf57ef8a..6d12af2cc 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -9,16 +9,16 @@ use core::future::Future;
9use core::iter; 9use core::iter;
10use core::marker::PhantomData; 10use core::marker::PhantomData;
11 11
12use embassy_hal_internal::{into_ref, Peripheral}; 12use embassy_hal_internal::{Peripheral, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
16 16
17use crate::dma::ChannelAndRequest; 17use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, Pull}; 18use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
19use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
20use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
21use crate::rcc::{self, RccInfo, SealedRccPeripheral}; 21use crate::rcc::{RccInfo, SealedRccPeripheral};
22use crate::time::Hertz; 22use crate::time::Hertz;
23use crate::{interrupt, peripherals}; 23use crate::{interrupt, peripherals};
24 24
@@ -72,11 +72,29 @@ impl Default for Config {
72 } 72 }
73} 73}
74 74
75impl Config {
76 fn scl_pull_mode(&self) -> Pull {
77 match self.scl_pullup {
78 true => Pull::Up,
79 false => Pull::Down,
80 }
81 }
82
83 fn sda_pull_mode(&self) -> Pull {
84 match self.sda_pullup {
85 true => Pull::Up,
86 false => Pull::Down,
87 }
88 }
89}
90
75/// I2C driver. 91/// I2C driver.
76pub struct I2c<'d, M: Mode> { 92pub struct I2c<'d, M: Mode> {
77 info: &'static Info, 93 info: &'static Info,
78 state: &'static State, 94 state: &'static State,
79 kernel_clock: Hertz, 95 kernel_clock: Hertz,
96 scl: Option<PeripheralRef<'d, AnyPin>>,
97 sda: Option<PeripheralRef<'d, AnyPin>>,
80 tx_dma: Option<ChannelAndRequest<'d>>, 98 tx_dma: Option<ChannelAndRequest<'d>>,
81 rx_dma: Option<ChannelAndRequest<'d>>, 99 rx_dma: Option<ChannelAndRequest<'d>>,
82 #[cfg(feature = "time")] 100 #[cfg(feature = "time")]
@@ -98,7 +116,15 @@ impl<'d> I2c<'d, Async> {
98 freq: Hertz, 116 freq: Hertz,
99 config: Config, 117 config: Config,
100 ) -> Self { 118 ) -> Self {
101 Self::new_inner(peri, scl, sda, new_dma!(tx_dma), new_dma!(rx_dma), freq, config) 119 Self::new_inner(
120 peri,
121 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
122 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
123 new_dma!(tx_dma),
124 new_dma!(rx_dma),
125 freq,
126 config,
127 )
102 } 128 }
103} 129}
104 130
@@ -111,7 +137,15 @@ impl<'d> I2c<'d, Blocking> {
111 freq: Hertz, 137 freq: Hertz,
112 config: Config, 138 config: Config,
113 ) -> Self { 139 ) -> Self {
114 Self::new_inner(peri, scl, sda, None, None, freq, config) 140 Self::new_inner(
141 peri,
142 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
143 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
144 None,
145 None,
146 freq,
147 config,
148 )
115 } 149 }
116} 150}
117 151
@@ -119,34 +153,13 @@ impl<'d, M: Mode> I2c<'d, M> {
119 /// Create a new I2C driver. 153 /// Create a new I2C driver.
120 fn new_inner<T: Instance>( 154 fn new_inner<T: Instance>(
121 _peri: impl Peripheral<P = T> + 'd, 155 _peri: impl Peripheral<P = T> + 'd,
122 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 156 scl: Option<PeripheralRef<'d, AnyPin>>,
123 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 157 sda: Option<PeripheralRef<'d, AnyPin>>,
124 tx_dma: Option<ChannelAndRequest<'d>>, 158 tx_dma: Option<ChannelAndRequest<'d>>,
125 rx_dma: Option<ChannelAndRequest<'d>>, 159 rx_dma: Option<ChannelAndRequest<'d>>,
126 freq: Hertz, 160 freq: Hertz,
127 config: Config, 161 config: Config,
128 ) -> Self { 162 ) -> Self {
129 into_ref!(scl, sda);
130
131 rcc::enable_and_reset::<T>();
132
133 scl.set_as_af_pull(
134 scl.af_num(),
135 AFType::OutputOpenDrain,
136 match config.scl_pullup {
137 true => Pull::Up,
138 false => Pull::None,
139 },
140 );
141 sda.set_as_af_pull(
142 sda.af_num(),
143 AFType::OutputOpenDrain,
144 match config.sda_pullup {
145 true => Pull::Up,
146 false => Pull::None,
147 },
148 );
149
150 unsafe { T::EventInterrupt::enable() }; 163 unsafe { T::EventInterrupt::enable() };
151 unsafe { T::ErrorInterrupt::enable() }; 164 unsafe { T::ErrorInterrupt::enable() };
152 165
@@ -154,18 +167,23 @@ impl<'d, M: Mode> I2c<'d, M> {
154 info: T::info(), 167 info: T::info(),
155 state: T::state(), 168 state: T::state(),
156 kernel_clock: T::frequency(), 169 kernel_clock: T::frequency(),
170 scl,
171 sda,
157 tx_dma, 172 tx_dma,
158 rx_dma, 173 rx_dma,
159 #[cfg(feature = "time")] 174 #[cfg(feature = "time")]
160 timeout: config.timeout, 175 timeout: config.timeout,
161 _phantom: PhantomData, 176 _phantom: PhantomData,
162 }; 177 };
163 178 this.enable_and_init(freq, config);
164 this.init(freq, config);
165
166 this 179 this
167 } 180 }
168 181
182 fn enable_and_init(&mut self, freq: Hertz, config: Config) {
183 self.info.rcc.enable_and_reset();
184 self.init(freq, config);
185 }
186
169 fn timeout(&self) -> Timeout { 187 fn timeout(&self) -> Timeout {
170 Timeout { 188 Timeout {
171 #[cfg(feature = "time")] 189 #[cfg(feature = "time")]
@@ -174,6 +192,15 @@ impl<'d, M: Mode> I2c<'d, M> {
174 } 192 }
175} 193}
176 194
195impl<'d, M: Mode> Drop for I2c<'d, M> {
196 fn drop(&mut self) {
197 self.scl.as_ref().map(|x| x.set_as_disconnected());
198 self.sda.as_ref().map(|x| x.set_as_disconnected());
199
200 self.info.rcc.disable()
201 }
202}
203
177#[derive(Copy, Clone)] 204#[derive(Copy, Clone)]
178struct Timeout { 205struct Timeout {
179 #[cfg(feature = "time")] 206 #[cfg(feature = "time")]
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 0e2bd2e40..28026f83c 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -700,12 +700,6 @@ impl<'d> I2c<'d, Async> {
700 } 700 }
701} 701}
702 702
703impl<'d, M: PeriMode> Drop for I2c<'d, M> {
704 fn drop(&mut self) {
705 self.info.rcc.disable()
706 }
707}
708
709enum Mode { 703enum Mode {
710 Fast, 704 Fast,
711 Standard, 705 Standard,
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 193f29733..80163c287 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -671,12 +671,6 @@ impl<'d> I2c<'d, Async> {
671 } 671 }
672} 672}
673 673
674impl<'d, M: Mode> Drop for I2c<'d, M> {
675 fn drop(&mut self) {
676 self.info.rcc.disable();
677 }
678}
679
680/// I2C Stop Configuration 674/// I2C Stop Configuration
681/// 675///
682/// Peripheral options for generating the STOP condition 676/// Peripheral options for generating the STOP condition