aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-21 20:46:03 +0000
committerGitHub <[email protected]>2024-05-21 20:46:03 +0000
commita636bace984c8fddeb6d6ac0b8f8a61bffce3673 (patch)
tree2e78cd716988fc5ec04950cb5cfe3dda80d3669f
parent2da2e57b38e31059d752cc2e39ec3db96c8bb1d0 (diff)
parent45a12fd41f1f6230a4aabbfe87552adc610fdc99 (diff)
Merge pull request #2974 from embassy-rs/spi-nogenerics
stm32/i2c: remove peripheral generic param.
-rw-r--r--embassy-stm32/build.rs6
-rw-r--r--embassy-stm32/src/i2c/mod.rs68
-rw-r--r--embassy-stm32/src/i2c/v1.rs184
-rw-r--r--embassy-stm32/src/i2c/v2.rs129
-rw-r--r--embassy-stm32/src/i2s.rs4
-rw-r--r--embassy-stm32/src/macros.rs29
-rw-r--r--embassy-stm32/src/rcc/mod.rs5
-rw-r--r--embassy-stm32/src/spi/mod.rs122
-rw-r--r--examples/stm32h7/src/bin/i2c_shared.rs5
-rw-r--r--examples/stm32l4/src/bin/spe_adin1110_http_server.rs2
10 files changed, 291 insertions, 263 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index f17c6bef6..e615c6307 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -653,9 +653,9 @@ fn main() {
653 crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); 653 crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
654 #decr_stop_refcount 654 #decr_stop_refcount
655 } 655 }
656 fn enable_bit() -> crate::rcc::ClockEnableBit { 656
657 unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) } 657 const ENABLE_BIT: crate::rcc::ClockEnableBit =
658 } 658 unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) };
659 } 659 }
660 660
661 impl crate::rcc::RccPeripheral for peripherals::#pname {} 661 impl crate::rcc::RccPeripheral for peripherals::#pname {}
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 0b2a56305..ef5fd0972 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -9,7 +9,7 @@ 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, PeripheralRef}; 12use embassy_hal_internal::{into_ref, Peripheral};
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};
@@ -18,6 +18,7 @@ use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, Pull}; 18use crate::gpio::{AFType, Pull};
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::{ClockEnableBit, SealedRccPeripheral};
21use crate::time::Hertz; 22use crate::time::Hertz;
22use crate::{interrupt, peripherals}; 23use crate::{interrupt, peripherals};
23 24
@@ -72,8 +73,10 @@ impl Default for Config {
72} 73}
73 74
74/// I2C driver. 75/// I2C driver.
75pub struct I2c<'d, T: Instance, M: Mode> { 76pub struct I2c<'d, M: Mode> {
76 _peri: PeripheralRef<'d, T>, 77 info: &'static Info,
78 state: &'static State,
79 kernel_clock: Hertz,
77 tx_dma: Option<ChannelAndRequest<'d>>, 80 tx_dma: Option<ChannelAndRequest<'d>>,
78 rx_dma: Option<ChannelAndRequest<'d>>, 81 rx_dma: Option<ChannelAndRequest<'d>>,
79 #[cfg(feature = "time")] 82 #[cfg(feature = "time")]
@@ -81,9 +84,9 @@ pub struct I2c<'d, T: Instance, M: Mode> {
81 _phantom: PhantomData<M>, 84 _phantom: PhantomData<M>,
82} 85}
83 86
84impl<'d, T: Instance> I2c<'d, T, Async> { 87impl<'d> I2c<'d, Async> {
85 /// Create a new I2C driver. 88 /// Create a new I2C driver.
86 pub fn new( 89 pub fn new<T: Instance>(
87 peri: impl Peripheral<P = T> + 'd, 90 peri: impl Peripheral<P = T> + 'd,
88 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 91 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
89 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 92 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
@@ -99,9 +102,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
99 } 102 }
100} 103}
101 104
102impl<'d, T: Instance> I2c<'d, T, Blocking> { 105impl<'d> I2c<'d, Blocking> {
103 /// Create a new blocking I2C driver. 106 /// Create a new blocking I2C driver.
104 pub fn new_blocking( 107 pub fn new_blocking<T: Instance>(
105 peri: impl Peripheral<P = T> + 'd, 108 peri: impl Peripheral<P = T> + 'd,
106 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 109 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
107 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 110 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
@@ -112,10 +115,10 @@ impl<'d, T: Instance> I2c<'d, T, Blocking> {
112 } 115 }
113} 116}
114 117
115impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { 118impl<'d, M: Mode> I2c<'d, M> {
116 /// Create a new I2C driver. 119 /// Create a new I2C driver.
117 fn new_inner( 120 fn new_inner<T: Instance>(
118 peri: impl Peripheral<P = T> + 'd, 121 _peri: impl Peripheral<P = T> + 'd,
119 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 122 scl: impl Peripheral<P = impl SclPin<T>> + 'd,
120 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 123 sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
121 tx_dma: Option<ChannelAndRequest<'d>>, 124 tx_dma: Option<ChannelAndRequest<'d>>,
@@ -123,7 +126,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
123 freq: Hertz, 126 freq: Hertz,
124 config: Config, 127 config: Config,
125 ) -> Self { 128 ) -> Self {
126 into_ref!(peri, scl, sda); 129 into_ref!(scl, sda);
127 130
128 T::enable_and_reset(); 131 T::enable_and_reset();
129 132
@@ -148,7 +151,9 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
148 unsafe { T::ErrorInterrupt::enable() }; 151 unsafe { T::ErrorInterrupt::enable() };
149 152
150 let mut this = Self { 153 let mut this = Self {
151 _peri: peri, 154 info: T::info(),
155 state: T::state(),
156 kernel_clock: T::frequency(),
152 tx_dma, 157 tx_dma,
153 rx_dma, 158 rx_dma,
154 #[cfg(feature = "time")] 159 #[cfg(feature = "time")]
@@ -217,19 +222,14 @@ impl State {
217 } 222 }
218} 223}
219 224
220trait SealedInstance: crate::rcc::RccPeripheral { 225struct Info {
221 fn regs() -> crate::pac::i2c::I2c; 226 regs: crate::pac::i2c::I2c,
222 fn state() -> &'static State; 227 pub(crate) enable_bit: ClockEnableBit,
223} 228}
224 229
225/// I2C peripheral instance 230peri_trait!(
226#[allow(private_bounds)] 231 irqs: [EventInterrupt, ErrorInterrupt],
227pub trait Instance: SealedInstance + 'static { 232);
228 /// Event interrupt for this instance
229 type EventInterrupt: interrupt::typelevel::Interrupt;
230 /// Error interrupt for this instance
231 type ErrorInterrupt: interrupt::typelevel::Interrupt;
232}
233 233
234pin_trait!(SclPin, Instance); 234pin_trait!(SclPin, Instance);
235pin_trait!(SdaPin, Instance); 235pin_trait!(SdaPin, Instance);
@@ -260,11 +260,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte
260 260
261foreach_peripheral!( 261foreach_peripheral!(
262 (i2c, $inst:ident) => { 262 (i2c, $inst:ident) => {
263 #[allow(private_interfaces)]
263 impl SealedInstance for peripherals::$inst { 264 impl SealedInstance for peripherals::$inst {
264 fn regs() -> crate::pac::i2c::I2c { 265 fn info() -> &'static Info {
265 crate::pac::$inst 266 static INFO: Info = Info{
267 regs: crate::pac::$inst,
268 enable_bit: crate::peripherals::$inst::ENABLE_BIT,
269 };
270 &INFO
266 } 271 }
267
268 fn state() -> &'static State { 272 fn state() -> &'static State {
269 static STATE: State = State::new(); 273 static STATE: State = State::new();
270 &STATE 274 &STATE
@@ -278,7 +282,7 @@ foreach_peripheral!(
278 }; 282 };
279); 283);
280 284
281impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> { 285impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M> {
282 type Error = Error; 286 type Error = Error;
283 287
284 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { 288 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
@@ -286,7 +290,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d,
286 } 290 }
287} 291}
288 292
289impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> { 293impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M> {
290 type Error = Error; 294 type Error = Error;
291 295
292 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { 296 fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
@@ -294,7 +298,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d,
294 } 298 }
295} 299}
296 300
297impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> { 301impl<'d, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M> {
298 type Error = Error; 302 type Error = Error;
299 303
300 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { 304 fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
@@ -318,11 +322,11 @@ impl embedded_hal_1::i2c::Error for Error {
318 } 322 }
319} 323}
320 324
321impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> { 325impl<'d, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, M> {
322 type Error = Error; 326 type Error = Error;
323} 327}
324 328
325impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> { 329impl<'d, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, M> {
326 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 330 fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
327 self.blocking_read(address, read) 331 self.blocking_read(address, read)
328 } 332 }
@@ -344,7 +348,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> {
344 } 348 }
345} 349}
346 350
347impl<'d, T: Instance> embedded_hal_async::i2c::I2c for I2c<'d, T, Async> { 351impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> {
348 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { 352 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
349 self.read(address, read).await 353 self.read(address, read).await
350 } 354 }
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index ac4fa1b9e..0269e53aa 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -28,7 +28,7 @@ use crate::pac::i2c;
28// There's some more details there, and we might have a fix for you. But please let us know if you 28// There's some more details there, and we might have a fix for you. But please let us know if you
29// hit a case like this! 29// hit a case like this!
30pub unsafe fn on_interrupt<T: Instance>() { 30pub unsafe fn on_interrupt<T: Instance>() {
31 let regs = T::regs(); 31 let regs = T::info().regs;
32 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of 32 // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
33 // other stuff, so we wake the task on every interrupt. 33 // other stuff, so we wake the task on every interrupt.
34 T::state().waker.wake(); 34 T::state().waker.wake();
@@ -41,9 +41,9 @@ pub unsafe fn on_interrupt<T: Instance>() {
41 }); 41 });
42} 42}
43 43
44impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { 44impl<'d, M: PeriMode> I2c<'d, M> {
45 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 45 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
46 T::regs().cr1().modify(|reg| { 46 self.info.regs.cr1().modify(|reg| {
47 reg.set_pe(false); 47 reg.set_pe(false);
48 //reg.set_anfoff(false); 48 //reg.set_anfoff(false);
49 }); 49 });
@@ -67,39 +67,39 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
67 // 67 //
68 // This presents as an ~infinite hang on read or write, as the START condition 68 // This presents as an ~infinite hang on read or write, as the START condition
69 // is never generated, meaning the start event is never generated. 69 // is never generated, meaning the start event is never generated.
70 T::regs().cr1().modify(|reg| { 70 self.info.regs.cr1().modify(|reg| {
71 reg.set_swrst(true); 71 reg.set_swrst(true);
72 }); 72 });
73 T::regs().cr1().modify(|reg| { 73 self.info.regs.cr1().modify(|reg| {
74 reg.set_swrst(false); 74 reg.set_swrst(false);
75 }); 75 });
76 76
77 let timings = Timings::new(T::frequency(), freq); 77 let timings = Timings::new(self.kernel_clock, freq);
78 78
79 T::regs().cr2().modify(|reg| { 79 self.info.regs.cr2().modify(|reg| {
80 reg.set_freq(timings.freq); 80 reg.set_freq(timings.freq);
81 }); 81 });
82 T::regs().ccr().modify(|reg| { 82 self.info.regs.ccr().modify(|reg| {
83 reg.set_f_s(timings.mode.f_s()); 83 reg.set_f_s(timings.mode.f_s());
84 reg.set_duty(timings.duty.duty()); 84 reg.set_duty(timings.duty.duty());
85 reg.set_ccr(timings.ccr); 85 reg.set_ccr(timings.ccr);
86 }); 86 });
87 T::regs().trise().modify(|reg| { 87 self.info.regs.trise().modify(|reg| {
88 reg.set_trise(timings.trise); 88 reg.set_trise(timings.trise);
89 }); 89 });
90 90
91 T::regs().cr1().modify(|reg| { 91 self.info.regs.cr1().modify(|reg| {
92 reg.set_pe(true); 92 reg.set_pe(true);
93 }); 93 });
94 } 94 }
95 95
96 fn check_and_clear_error_flags() -> Result<i2c::regs::Sr1, Error> { 96 fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> {
97 // Note that flags should only be cleared once they have been registered. If flags are 97 // Note that flags should only be cleared once they have been registered. If flags are
98 // cleared otherwise, there may be an inherent race condition and flags may be missed. 98 // cleared otherwise, there may be an inherent race condition and flags may be missed.
99 let sr1 = T::regs().sr1().read(); 99 let sr1 = info.regs.sr1().read();
100 100
101 if sr1.timeout() { 101 if sr1.timeout() {
102 T::regs().sr1().write(|reg| { 102 info.regs.sr1().write(|reg| {
103 reg.0 = !0; 103 reg.0 = !0;
104 reg.set_timeout(false); 104 reg.set_timeout(false);
105 }); 105 });
@@ -107,7 +107,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
107 } 107 }
108 108
109 if sr1.pecerr() { 109 if sr1.pecerr() {
110 T::regs().sr1().write(|reg| { 110 info.regs.sr1().write(|reg| {
111 reg.0 = !0; 111 reg.0 = !0;
112 reg.set_pecerr(false); 112 reg.set_pecerr(false);
113 }); 113 });
@@ -115,7 +115,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
115 } 115 }
116 116
117 if sr1.ovr() { 117 if sr1.ovr() {
118 T::regs().sr1().write(|reg| { 118 info.regs.sr1().write(|reg| {
119 reg.0 = !0; 119 reg.0 = !0;
120 reg.set_ovr(false); 120 reg.set_ovr(false);
121 }); 121 });
@@ -123,7 +123,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
123 } 123 }
124 124
125 if sr1.af() { 125 if sr1.af() {
126 T::regs().sr1().write(|reg| { 126 info.regs.sr1().write(|reg| {
127 reg.0 = !0; 127 reg.0 = !0;
128 reg.set_af(false); 128 reg.set_af(false);
129 }); 129 });
@@ -131,7 +131,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
131 } 131 }
132 132
133 if sr1.arlo() { 133 if sr1.arlo() {
134 T::regs().sr1().write(|reg| { 134 info.regs.sr1().write(|reg| {
135 reg.0 = !0; 135 reg.0 = !0;
136 reg.set_arlo(false); 136 reg.set_arlo(false);
137 }); 137 });
@@ -141,7 +141,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
141 // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and 141 // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and
142 // clearing the BERR bit instead. 142 // clearing the BERR bit instead.
143 if sr1.berr() { 143 if sr1.berr() {
144 T::regs().sr1().write(|reg| { 144 info.regs.sr1().write(|reg| {
145 reg.0 = !0; 145 reg.0 = !0;
146 reg.set_berr(false); 146 reg.set_berr(false);
147 }); 147 });
@@ -154,32 +154,32 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
154 if frame.send_start() { 154 if frame.send_start() {
155 // Send a START condition 155 // Send a START condition
156 156
157 T::regs().cr1().modify(|reg| { 157 self.info.regs.cr1().modify(|reg| {
158 reg.set_start(true); 158 reg.set_start(true);
159 }); 159 });
160 160
161 // Wait until START condition was generated 161 // Wait until START condition was generated
162 while !Self::check_and_clear_error_flags()?.start() { 162 while !Self::check_and_clear_error_flags(self.info)?.start() {
163 timeout.check()?; 163 timeout.check()?;
164 } 164 }
165 165
166 // Check if we were the ones to generate START 166 // Check if we were the ones to generate START
167 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { 167 if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
168 return Err(Error::Arbitration); 168 return Err(Error::Arbitration);
169 } 169 }
170 170
171 // Set up current address we're trying to talk to 171 // Set up current address we're trying to talk to
172 T::regs().dr().write(|reg| reg.set_dr(addr << 1)); 172 self.info.regs.dr().write(|reg| reg.set_dr(addr << 1));
173 173
174 // Wait until address was sent 174 // Wait until address was sent
175 // Wait for the address to be acknowledged 175 // Wait for the address to be acknowledged
176 // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. 176 // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
177 while !Self::check_and_clear_error_flags()?.addr() { 177 while !Self::check_and_clear_error_flags(self.info)?.addr() {
178 timeout.check()?; 178 timeout.check()?;
179 } 179 }
180 180
181 // Clear condition by reading SR2 181 // Clear condition by reading SR2
182 let _ = T::regs().sr2().read(); 182 let _ = self.info.regs.sr2().read();
183 } 183 }
184 184
185 // Send bytes 185 // Send bytes
@@ -189,7 +189,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
189 189
190 if frame.send_stop() { 190 if frame.send_stop() {
191 // Send a STOP condition 191 // Send a STOP condition
192 T::regs().cr1().modify(|reg| reg.set_stop(true)); 192 self.info.regs.cr1().modify(|reg| reg.set_stop(true));
193 } 193 }
194 194
195 // Fallthrough is success 195 // Fallthrough is success
@@ -200,18 +200,18 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
200 // Wait until we're ready for sending 200 // Wait until we're ready for sending
201 while { 201 while {
202 // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. 202 // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set.
203 !Self::check_and_clear_error_flags()?.txe() 203 !Self::check_and_clear_error_flags(self.info)?.txe()
204 } { 204 } {
205 timeout.check()?; 205 timeout.check()?;
206 } 206 }
207 207
208 // Push out a byte of data 208 // Push out a byte of data
209 T::regs().dr().write(|reg| reg.set_dr(byte)); 209 self.info.regs.dr().write(|reg| reg.set_dr(byte));
210 210
211 // Wait until byte is transferred 211 // Wait until byte is transferred
212 while { 212 while {
213 // Check for any potential error conditions. 213 // Check for any potential error conditions.
214 !Self::check_and_clear_error_flags()?.btf() 214 !Self::check_and_clear_error_flags(self.info)?.btf()
215 } { 215 } {
216 timeout.check()?; 216 timeout.check()?;
217 } 217 }
@@ -222,14 +222,14 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
222 fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> { 222 fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> {
223 while { 223 while {
224 // Check for any potential error conditions. 224 // Check for any potential error conditions.
225 Self::check_and_clear_error_flags()?; 225 Self::check_and_clear_error_flags(self.info)?;
226 226
227 !T::regs().sr1().read().rxne() 227 !self.info.regs.sr1().read().rxne()
228 } { 228 } {
229 timeout.check()?; 229 timeout.check()?;
230 } 230 }
231 231
232 let value = T::regs().dr().read().dr(); 232 let value = self.info.regs.dr().read().dr();
233 Ok(value) 233 Ok(value)
234 } 234 }
235 235
@@ -246,32 +246,32 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
246 246
247 if frame.send_start() { 247 if frame.send_start() {
248 // Send a START condition and set ACK bit 248 // Send a START condition and set ACK bit
249 T::regs().cr1().modify(|reg| { 249 self.info.regs.cr1().modify(|reg| {
250 reg.set_start(true); 250 reg.set_start(true);
251 reg.set_ack(true); 251 reg.set_ack(true);
252 }); 252 });
253 253
254 // Wait until START condition was generated 254 // Wait until START condition was generated
255 while !Self::check_and_clear_error_flags()?.start() { 255 while !Self::check_and_clear_error_flags(self.info)?.start() {
256 timeout.check()?; 256 timeout.check()?;
257 } 257 }
258 258
259 // Check if we were the ones to generate START 259 // Check if we were the ones to generate START
260 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { 260 if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
261 return Err(Error::Arbitration); 261 return Err(Error::Arbitration);
262 } 262 }
263 263
264 // Set up current address we're trying to talk to 264 // Set up current address we're trying to talk to
265 T::regs().dr().write(|reg| reg.set_dr((addr << 1) + 1)); 265 self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1));
266 266
267 // Wait until address was sent 267 // Wait until address was sent
268 // Wait for the address to be acknowledged 268 // Wait for the address to be acknowledged
269 while !Self::check_and_clear_error_flags()?.addr() { 269 while !Self::check_and_clear_error_flags(self.info)?.addr() {
270 timeout.check()?; 270 timeout.check()?;
271 } 271 }
272 272
273 // Clear condition by reading SR2 273 // Clear condition by reading SR2
274 let _ = T::regs().sr2().read(); 274 let _ = self.info.regs.sr2().read();
275 } 275 }
276 276
277 // Receive bytes into buffer 277 // Receive bytes into buffer
@@ -280,7 +280,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
280 } 280 }
281 281
282 // Prepare to send NACK then STOP after next byte 282 // Prepare to send NACK then STOP after next byte
283 T::regs().cr1().modify(|reg| { 283 self.info.regs.cr1().modify(|reg| {
284 if frame.send_nack() { 284 if frame.send_nack() {
285 reg.set_ack(false); 285 reg.set_ack(false);
286 } 286 }
@@ -346,17 +346,17 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> {
346 // Async 346 // Async
347 347
348 #[inline] // pretty sure this should always be inlined 348 #[inline] // pretty sure this should always be inlined
349 fn enable_interrupts() -> () { 349 fn enable_interrupts(info: &'static Info) -> () {
350 T::regs().cr2().modify(|w| { 350 info.regs.cr2().modify(|w| {
351 w.set_iterren(true); 351 w.set_iterren(true);
352 w.set_itevten(true); 352 w.set_itevten(true);
353 }); 353 });
354 } 354 }
355} 355}
356 356
357impl<'d, T: Instance> I2c<'d, T, Async> { 357impl<'d> I2c<'d, Async> {
358 async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { 358 async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> {
359 T::regs().cr2().modify(|w| { 359 self.info.regs.cr2().modify(|w| {
360 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for 360 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
361 // reception. 361 // reception.
362 w.set_itbufen(false); 362 w.set_itbufen(false);
@@ -370,33 +370,31 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
370 // Sentinel to disable transfer when an error occurs or future is canceled. 370 // Sentinel to disable transfer when an error occurs or future is canceled.
371 // TODO: Generate STOP condition on cancel? 371 // TODO: Generate STOP condition on cancel?
372 let on_drop = OnDrop::new(|| { 372 let on_drop = OnDrop::new(|| {
373 T::regs().cr2().modify(|w| { 373 self.info.regs.cr2().modify(|w| {
374 w.set_dmaen(false); 374 w.set_dmaen(false);
375 w.set_iterren(false); 375 w.set_iterren(false);
376 w.set_itevten(false); 376 w.set_itevten(false);
377 }) 377 })
378 }); 378 });
379 379
380 let state = T::state();
381
382 if frame.send_start() { 380 if frame.send_start() {
383 // Send a START condition 381 // Send a START condition
384 T::regs().cr1().modify(|reg| { 382 self.info.regs.cr1().modify(|reg| {
385 reg.set_start(true); 383 reg.set_start(true);
386 }); 384 });
387 385
388 // Wait until START condition was generated 386 // Wait until START condition was generated
389 poll_fn(|cx| { 387 poll_fn(|cx| {
390 state.waker.register(cx.waker()); 388 self.state.waker.register(cx.waker());
391 389
392 match Self::check_and_clear_error_flags() { 390 match Self::check_and_clear_error_flags(self.info) {
393 Err(e) => Poll::Ready(Err(e)), 391 Err(e) => Poll::Ready(Err(e)),
394 Ok(sr1) => { 392 Ok(sr1) => {
395 if sr1.start() { 393 if sr1.start() {
396 Poll::Ready(Ok(())) 394 Poll::Ready(Ok(()))
397 } else { 395 } else {
398 // When pending, (re-)enable interrupts to wake us up. 396 // When pending, (re-)enable interrupts to wake us up.
399 Self::enable_interrupts(); 397 Self::enable_interrupts(self.info);
400 Poll::Pending 398 Poll::Pending
401 } 399 }
402 } 400 }
@@ -405,25 +403,25 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
405 .await?; 403 .await?;
406 404
407 // Check if we were the ones to generate START 405 // Check if we were the ones to generate START
408 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { 406 if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
409 return Err(Error::Arbitration); 407 return Err(Error::Arbitration);
410 } 408 }
411 409
412 // Set up current address we're trying to talk to 410 // Set up current address we're trying to talk to
413 T::regs().dr().write(|reg| reg.set_dr(address << 1)); 411 self.info.regs.dr().write(|reg| reg.set_dr(address << 1));
414 412
415 // Wait for the address to be acknowledged 413 // Wait for the address to be acknowledged
416 poll_fn(|cx| { 414 poll_fn(|cx| {
417 state.waker.register(cx.waker()); 415 self.state.waker.register(cx.waker());
418 416
419 match Self::check_and_clear_error_flags() { 417 match Self::check_and_clear_error_flags(self.info) {
420 Err(e) => Poll::Ready(Err(e)), 418 Err(e) => Poll::Ready(Err(e)),
421 Ok(sr1) => { 419 Ok(sr1) => {
422 if sr1.addr() { 420 if sr1.addr() {
423 Poll::Ready(Ok(())) 421 Poll::Ready(Ok(()))
424 } else { 422 } else {
425 // When pending, (re-)enable interrupts to wake us up. 423 // When pending, (re-)enable interrupts to wake us up.
426 Self::enable_interrupts(); 424 Self::enable_interrupts(self.info);
427 Poll::Pending 425 Poll::Pending
428 } 426 }
429 } 427 }
@@ -432,26 +430,26 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
432 .await?; 430 .await?;
433 431
434 // Clear condition by reading SR2 432 // Clear condition by reading SR2
435 T::regs().sr2().read(); 433 self.info.regs.sr2().read();
436 } 434 }
437 435
438 let dma_transfer = unsafe { 436 let dma_transfer = unsafe {
439 // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to 437 // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to
440 // this address from the memory after each TxE event. 438 // this address from the memory after each TxE event.
441 let dst = T::regs().dr().as_ptr() as *mut u8; 439 let dst = self.info.regs.dr().as_ptr() as *mut u8;
442 440
443 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) 441 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
444 }; 442 };
445 443
446 // Wait for bytes to be sent, or an error to occur. 444 // Wait for bytes to be sent, or an error to occur.
447 let poll_error = poll_fn(|cx| { 445 let poll_error = poll_fn(|cx| {
448 state.waker.register(cx.waker()); 446 self.state.waker.register(cx.waker());
449 447
450 match Self::check_and_clear_error_flags() { 448 match Self::check_and_clear_error_flags(self.info) {
451 Err(e) => Poll::Ready(Err::<(), Error>(e)), 449 Err(e) => Poll::Ready(Err::<(), Error>(e)),
452 Ok(_) => { 450 Ok(_) => {
453 // When pending, (re-)enable interrupts to wake us up. 451 // When pending, (re-)enable interrupts to wake us up.
454 Self::enable_interrupts(); 452 Self::enable_interrupts(self.info);
455 Poll::Pending 453 Poll::Pending
456 } 454 }
457 } 455 }
@@ -463,7 +461,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
463 _ => Ok(()), 461 _ => Ok(()),
464 }?; 462 }?;
465 463
466 T::regs().cr2().modify(|w| { 464 self.info.regs.cr2().modify(|w| {
467 w.set_dmaen(false); 465 w.set_dmaen(false);
468 }); 466 });
469 467
@@ -473,16 +471,16 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
473 // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA 471 // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA
474 // requests then wait for a BTF event before programming the Stop condition.” 472 // requests then wait for a BTF event before programming the Stop condition.”
475 poll_fn(|cx| { 473 poll_fn(|cx| {
476 state.waker.register(cx.waker()); 474 self.state.waker.register(cx.waker());
477 475
478 match Self::check_and_clear_error_flags() { 476 match Self::check_and_clear_error_flags(self.info) {
479 Err(e) => Poll::Ready(Err(e)), 477 Err(e) => Poll::Ready(Err(e)),
480 Ok(sr1) => { 478 Ok(sr1) => {
481 if sr1.btf() { 479 if sr1.btf() {
482 Poll::Ready(Ok(())) 480 Poll::Ready(Ok(()))
483 } else { 481 } else {
484 // When pending, (re-)enable interrupts to wake us up. 482 // When pending, (re-)enable interrupts to wake us up.
485 Self::enable_interrupts(); 483 Self::enable_interrupts(self.info);
486 Poll::Pending 484 Poll::Pending
487 } 485 }
488 } 486 }
@@ -490,7 +488,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
490 }) 488 })
491 .await?; 489 .await?;
492 490
493 T::regs().cr1().modify(|w| { 491 self.info.regs.cr1().modify(|w| {
494 w.set_stop(true); 492 w.set_stop(true);
495 }); 493 });
496 } 494 }
@@ -525,7 +523,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
525 // Some branches below depend on whether the buffer contains only a single byte. 523 // Some branches below depend on whether the buffer contains only a single byte.
526 let single_byte = buffer.len() == 1; 524 let single_byte = buffer.len() == 1;
527 525
528 T::regs().cr2().modify(|w| { 526 self.info.regs.cr2().modify(|w| {
529 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for 527 // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
530 // reception. 528 // reception.
531 w.set_itbufen(false); 529 w.set_itbufen(false);
@@ -541,34 +539,32 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
541 // Sentinel to disable transfer when an error occurs or future is canceled. 539 // Sentinel to disable transfer when an error occurs or future is canceled.
542 // TODO: Generate STOP condition on cancel? 540 // TODO: Generate STOP condition on cancel?
543 let on_drop = OnDrop::new(|| { 541 let on_drop = OnDrop::new(|| {
544 T::regs().cr2().modify(|w| { 542 self.info.regs.cr2().modify(|w| {
545 w.set_dmaen(false); 543 w.set_dmaen(false);
546 w.set_iterren(false); 544 w.set_iterren(false);
547 w.set_itevten(false); 545 w.set_itevten(false);
548 }) 546 })
549 }); 547 });
550 548
551 let state = T::state();
552
553 if frame.send_start() { 549 if frame.send_start() {
554 // Send a START condition and set ACK bit 550 // Send a START condition and set ACK bit
555 T::regs().cr1().modify(|reg| { 551 self.info.regs.cr1().modify(|reg| {
556 reg.set_start(true); 552 reg.set_start(true);
557 reg.set_ack(true); 553 reg.set_ack(true);
558 }); 554 });
559 555
560 // Wait until START condition was generated 556 // Wait until START condition was generated
561 poll_fn(|cx| { 557 poll_fn(|cx| {
562 state.waker.register(cx.waker()); 558 self.state.waker.register(cx.waker());
563 559
564 match Self::check_and_clear_error_flags() { 560 match Self::check_and_clear_error_flags(self.info) {
565 Err(e) => Poll::Ready(Err(e)), 561 Err(e) => Poll::Ready(Err(e)),
566 Ok(sr1) => { 562 Ok(sr1) => {
567 if sr1.start() { 563 if sr1.start() {
568 Poll::Ready(Ok(())) 564 Poll::Ready(Ok(()))
569 } else { 565 } else {
570 // When pending, (re-)enable interrupts to wake us up. 566 // When pending, (re-)enable interrupts to wake us up.
571 Self::enable_interrupts(); 567 Self::enable_interrupts(self.info);
572 Poll::Pending 568 Poll::Pending
573 } 569 }
574 } 570 }
@@ -577,25 +573,25 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
577 .await?; 573 .await?;
578 574
579 // Check if we were the ones to generate START 575 // Check if we were the ones to generate START
580 if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { 576 if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() {
581 return Err(Error::Arbitration); 577 return Err(Error::Arbitration);
582 } 578 }
583 579
584 // Set up current address we're trying to talk to 580 // Set up current address we're trying to talk to
585 T::regs().dr().write(|reg| reg.set_dr((address << 1) + 1)); 581 self.info.regs.dr().write(|reg| reg.set_dr((address << 1) + 1));
586 582
587 // Wait for the address to be acknowledged 583 // Wait for the address to be acknowledged
588 poll_fn(|cx| { 584 poll_fn(|cx| {
589 state.waker.register(cx.waker()); 585 self.state.waker.register(cx.waker());
590 586
591 match Self::check_and_clear_error_flags() { 587 match Self::check_and_clear_error_flags(self.info) {
592 Err(e) => Poll::Ready(Err(e)), 588 Err(e) => Poll::Ready(Err(e)),
593 Ok(sr1) => { 589 Ok(sr1) => {
594 if sr1.addr() { 590 if sr1.addr() {
595 Poll::Ready(Ok(())) 591 Poll::Ready(Ok(()))
596 } else { 592 } else {
597 // When pending, (re-)enable interrupts to wake us up. 593 // When pending, (re-)enable interrupts to wake us up.
598 Self::enable_interrupts(); 594 Self::enable_interrupts(self.info);
599 Poll::Pending 595 Poll::Pending
600 } 596 }
601 } 597 }
@@ -606,18 +602,18 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
606 // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6 602 // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6
607 // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag. 603 // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag.
608 if frame.send_nack() && single_byte { 604 if frame.send_nack() && single_byte {
609 T::regs().cr1().modify(|w| { 605 self.info.regs.cr1().modify(|w| {
610 w.set_ack(false); 606 w.set_ack(false);
611 }); 607 });
612 } 608 }
613 609
614 // Clear condition by reading SR2 610 // Clear condition by reading SR2
615 T::regs().sr2().read(); 611 self.info.regs.sr2().read();
616 } else { 612 } else {
617 // Before starting reception of single byte (but without START condition, i.e. in case 613 // Before starting reception of single byte (but without START condition, i.e. in case
618 // of continued frame), program NACK to emit at end of this byte. 614 // of continued frame), program NACK to emit at end of this byte.
619 if frame.send_nack() && single_byte { 615 if frame.send_nack() && single_byte {
620 T::regs().cr1().modify(|w| { 616 self.info.regs.cr1().modify(|w| {
621 w.set_ack(false); 617 w.set_ack(false);
622 }); 618 });
623 } 619 }
@@ -627,7 +623,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
627 // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt 623 // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt
628 // routine. 624 // routine.
629 if frame.send_stop() && single_byte { 625 if frame.send_stop() && single_byte {
630 T::regs().cr1().modify(|w| { 626 self.info.regs.cr1().modify(|w| {
631 w.set_stop(true); 627 w.set_stop(true);
632 }); 628 });
633 } 629 }
@@ -635,20 +631,20 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
635 let dma_transfer = unsafe { 631 let dma_transfer = unsafe {
636 // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved 632 // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved
637 // from this address from the memory after each RxE event. 633 // from this address from the memory after each RxE event.
638 let src = T::regs().dr().as_ptr() as *mut u8; 634 let src = self.info.regs.dr().as_ptr() as *mut u8;
639 635
640 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) 636 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
641 }; 637 };
642 638
643 // Wait for bytes to be received, or an error to occur. 639 // Wait for bytes to be received, or an error to occur.
644 let poll_error = poll_fn(|cx| { 640 let poll_error = poll_fn(|cx| {
645 state.waker.register(cx.waker()); 641 self.state.waker.register(cx.waker());
646 642
647 match Self::check_and_clear_error_flags() { 643 match Self::check_and_clear_error_flags(self.info) {
648 Err(e) => Poll::Ready(Err::<(), Error>(e)), 644 Err(e) => Poll::Ready(Err::<(), Error>(e)),
649 _ => { 645 _ => {
650 // When pending, (re-)enable interrupts to wake us up. 646 // When pending, (re-)enable interrupts to wake us up.
651 Self::enable_interrupts(); 647 Self::enable_interrupts(self.info);
652 Poll::Pending 648 Poll::Pending
653 } 649 }
654 } 650 }
@@ -659,12 +655,12 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
659 _ => Ok(()), 655 _ => Ok(()),
660 }?; 656 }?;
661 657
662 T::regs().cr2().modify(|w| { 658 self.info.regs.cr2().modify(|w| {
663 w.set_dmaen(false); 659 w.set_dmaen(false);
664 }); 660 });
665 661
666 if frame.send_stop() && !single_byte { 662 if frame.send_stop() && !single_byte {
667 T::regs().cr1().modify(|w| { 663 self.info.regs.cr1().modify(|w| {
668 w.set_stop(true); 664 w.set_stop(true);
669 }); 665 });
670 } 666 }
@@ -704,9 +700,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
704 } 700 }
705} 701}
706 702
707impl<'d, T: Instance, M: PeriMode> Drop for I2c<'d, T, M> { 703impl<'d, M: PeriMode> Drop for I2c<'d, M> {
708 fn drop(&mut self) { 704 fn drop(&mut self) {
709 T::disable(); 705 self.info.enable_bit.disable()
710 } 706 }
711} 707}
712 708
@@ -810,20 +806,20 @@ impl Timings {
810 } 806 }
811} 807}
812 808
813impl<'d, T: Instance, M: PeriMode> SetConfig for I2c<'d, T, M> { 809impl<'d, M: PeriMode> SetConfig for I2c<'d, M> {
814 type Config = Hertz; 810 type Config = Hertz;
815 type ConfigError = (); 811 type ConfigError = ();
816 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 812 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
817 let timings = Timings::new(T::frequency(), *config); 813 let timings = Timings::new(self.kernel_clock, *config);
818 T::regs().cr2().modify(|reg| { 814 self.info.regs.cr2().modify(|reg| {
819 reg.set_freq(timings.freq); 815 reg.set_freq(timings.freq);
820 }); 816 });
821 T::regs().ccr().modify(|reg| { 817 self.info.regs.ccr().modify(|reg| {
822 reg.set_f_s(timings.mode.f_s()); 818 reg.set_f_s(timings.mode.f_s());
823 reg.set_duty(timings.duty.duty()); 819 reg.set_duty(timings.duty.duty());
824 reg.set_ccr(timings.ccr); 820 reg.set_ccr(timings.ccr);
825 }); 821 });
826 T::regs().trise().modify(|reg| { 822 self.info.regs.trise().modify(|reg| {
827 reg.set_trise(timings.trise); 823 reg.set_trise(timings.trise);
828 }); 824 });
829 825
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 12df98534..aa6daf786 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -10,7 +10,7 @@ use super::*;
10use crate::pac::i2c; 10use crate::pac::i2c;
11 11
12pub(crate) unsafe fn on_interrupt<T: Instance>() { 12pub(crate) unsafe fn on_interrupt<T: Instance>() {
13 let regs = T::regs(); 13 let regs = T::info().regs;
14 let isr = regs.isr().read(); 14 let isr = regs.isr().read();
15 15
16 if isr.tcr() || isr.tc() { 16 if isr.tcr() || isr.tc() {
@@ -23,16 +23,16 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() {
23 }); 23 });
24} 24}
25 25
26impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { 26impl<'d, M: Mode> I2c<'d, M> {
27 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { 27 pub(crate) fn init(&mut self, freq: Hertz, _config: Config) {
28 T::regs().cr1().modify(|reg| { 28 self.info.regs.cr1().modify(|reg| {
29 reg.set_pe(false); 29 reg.set_pe(false);
30 reg.set_anfoff(false); 30 reg.set_anfoff(false);
31 }); 31 });
32 32
33 let timings = Timings::new(T::frequency(), freq.into()); 33 let timings = Timings::new(self.kernel_clock, freq.into());
34 34
35 T::regs().timingr().write(|reg| { 35 self.info.regs.timingr().write(|reg| {
36 reg.set_presc(timings.prescale); 36 reg.set_presc(timings.prescale);
37 reg.set_scll(timings.scll); 37 reg.set_scll(timings.scll);
38 reg.set_sclh(timings.sclh); 38 reg.set_sclh(timings.sclh);
@@ -40,16 +40,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
40 reg.set_scldel(timings.scldel); 40 reg.set_scldel(timings.scldel);
41 }); 41 });
42 42
43 T::regs().cr1().modify(|reg| { 43 self.info.regs.cr1().modify(|reg| {
44 reg.set_pe(true); 44 reg.set_pe(true);
45 }); 45 });
46 } 46 }
47 47
48 fn master_stop(&mut self) { 48 fn master_stop(&mut self) {
49 T::regs().cr2().write(|w| w.set_stop(true)); 49 self.info.regs.cr2().write(|w| w.set_stop(true));
50 } 50 }
51 51
52 fn master_read( 52 fn master_read(
53 info: &'static Info,
53 address: u8, 54 address: u8,
54 length: usize, 55 length: usize,
55 stop: Stop, 56 stop: Stop,
@@ -63,7 +64,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
63 // Wait for any previous address sequence to end 64 // Wait for any previous address sequence to end
64 // automatically. This could be up to 50% of a bus 65 // automatically. This could be up to 50% of a bus
65 // cycle (ie. up to 0.5/freq) 66 // cycle (ie. up to 0.5/freq)
66 while T::regs().cr2().read().start() { 67 while info.regs.cr2().read().start() {
67 timeout.check()?; 68 timeout.check()?;
68 } 69 }
69 } 70 }
@@ -78,7 +79,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
78 i2c::vals::Reload::COMPLETED 79 i2c::vals::Reload::COMPLETED
79 }; 80 };
80 81
81 T::regs().cr2().modify(|w| { 82 info.regs.cr2().modify(|w| {
82 w.set_sadd((address << 1 | 0) as u16); 83 w.set_sadd((address << 1 | 0) as u16);
83 w.set_add10(i2c::vals::Addmode::BIT7); 84 w.set_add10(i2c::vals::Addmode::BIT7);
84 w.set_dir(i2c::vals::Dir::READ); 85 w.set_dir(i2c::vals::Dir::READ);
@@ -91,13 +92,20 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
91 Ok(()) 92 Ok(())
92 } 93 }
93 94
94 fn master_write(address: u8, length: usize, stop: Stop, reload: bool, timeout: Timeout) -> Result<(), Error> { 95 fn master_write(
96 info: &'static Info,
97 address: u8,
98 length: usize,
99 stop: Stop,
100 reload: bool,
101 timeout: Timeout,
102 ) -> Result<(), Error> {
95 assert!(length < 256); 103 assert!(length < 256);
96 104
97 // Wait for any previous address sequence to end 105 // Wait for any previous address sequence to end
98 // automatically. This could be up to 50% of a bus 106 // automatically. This could be up to 50% of a bus
99 // cycle (ie. up to 0.5/freq) 107 // cycle (ie. up to 0.5/freq)
100 while T::regs().cr2().read().start() { 108 while info.regs.cr2().read().start() {
101 timeout.check()?; 109 timeout.check()?;
102 } 110 }
103 111
@@ -110,7 +118,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
110 // Set START and prepare to send `bytes`. The 118 // Set START and prepare to send `bytes`. The
111 // START bit can be set even if the bus is BUSY or 119 // START bit can be set even if the bus is BUSY or
112 // I2C is in slave mode. 120 // I2C is in slave mode.
113 T::regs().cr2().modify(|w| { 121 info.regs.cr2().modify(|w| {
114 w.set_sadd((address << 1 | 0) as u16); 122 w.set_sadd((address << 1 | 0) as u16);
115 w.set_add10(i2c::vals::Addmode::BIT7); 123 w.set_add10(i2c::vals::Addmode::BIT7);
116 w.set_dir(i2c::vals::Dir::WRITE); 124 w.set_dir(i2c::vals::Dir::WRITE);
@@ -123,10 +131,10 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
123 Ok(()) 131 Ok(())
124 } 132 }
125 133
126 fn master_continue(length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { 134 fn master_continue(info: &'static Info, length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> {
127 assert!(length < 256 && length > 0); 135 assert!(length < 256 && length > 0);
128 136
129 while !T::regs().isr().read().tcr() { 137 while !info.regs.isr().read().tcr() {
130 timeout.check()?; 138 timeout.check()?;
131 } 139 }
132 140
@@ -136,7 +144,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
136 i2c::vals::Reload::COMPLETED 144 i2c::vals::Reload::COMPLETED
137 }; 145 };
138 146
139 T::regs().cr2().modify(|w| { 147 info.regs.cr2().modify(|w| {
140 w.set_nbytes(length as u8); 148 w.set_nbytes(length as u8);
141 w.set_reload(reload); 149 w.set_reload(reload);
142 }); 150 });
@@ -145,27 +153,27 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
145 } 153 }
146 154
147 fn flush_txdr(&self) { 155 fn flush_txdr(&self) {
148 if T::regs().isr().read().txis() { 156 if self.info.regs.isr().read().txis() {
149 T::regs().txdr().write(|w| w.set_txdata(0)); 157 self.info.regs.txdr().write(|w| w.set_txdata(0));
150 } 158 }
151 if !T::regs().isr().read().txe() { 159 if !self.info.regs.isr().read().txe() {
152 T::regs().isr().modify(|w| w.set_txe(true)) 160 self.info.regs.isr().modify(|w| w.set_txe(true))
153 } 161 }
154 } 162 }
155 163
156 fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> { 164 fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> {
157 loop { 165 loop {
158 let isr = T::regs().isr().read(); 166 let isr = self.info.regs.isr().read();
159 if isr.txe() { 167 if isr.txe() {
160 return Ok(()); 168 return Ok(());
161 } else if isr.berr() { 169 } else if isr.berr() {
162 T::regs().icr().write(|reg| reg.set_berrcf(true)); 170 self.info.regs.icr().write(|reg| reg.set_berrcf(true));
163 return Err(Error::Bus); 171 return Err(Error::Bus);
164 } else if isr.arlo() { 172 } else if isr.arlo() {
165 T::regs().icr().write(|reg| reg.set_arlocf(true)); 173 self.info.regs.icr().write(|reg| reg.set_arlocf(true));
166 return Err(Error::Arbitration); 174 return Err(Error::Arbitration);
167 } else if isr.nackf() { 175 } else if isr.nackf() {
168 T::regs().icr().write(|reg| reg.set_nackcf(true)); 176 self.info.regs.icr().write(|reg| reg.set_nackcf(true));
169 self.flush_txdr(); 177 self.flush_txdr();
170 return Err(Error::Nack); 178 return Err(Error::Nack);
171 } 179 }
@@ -176,17 +184,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
176 184
177 fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> { 185 fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> {
178 loop { 186 loop {
179 let isr = T::regs().isr().read(); 187 let isr = self.info.regs.isr().read();
180 if isr.rxne() { 188 if isr.rxne() {
181 return Ok(()); 189 return Ok(());
182 } else if isr.berr() { 190 } else if isr.berr() {
183 T::regs().icr().write(|reg| reg.set_berrcf(true)); 191 self.info.regs.icr().write(|reg| reg.set_berrcf(true));
184 return Err(Error::Bus); 192 return Err(Error::Bus);
185 } else if isr.arlo() { 193 } else if isr.arlo() {
186 T::regs().icr().write(|reg| reg.set_arlocf(true)); 194 self.info.regs.icr().write(|reg| reg.set_arlocf(true));
187 return Err(Error::Arbitration); 195 return Err(Error::Arbitration);
188 } else if isr.nackf() { 196 } else if isr.nackf() {
189 T::regs().icr().write(|reg| reg.set_nackcf(true)); 197 self.info.regs.icr().write(|reg| reg.set_nackcf(true));
190 self.flush_txdr(); 198 self.flush_txdr();
191 return Err(Error::Nack); 199 return Err(Error::Nack);
192 } 200 }
@@ -197,17 +205,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
197 205
198 fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> { 206 fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> {
199 loop { 207 loop {
200 let isr = T::regs().isr().read(); 208 let isr = self.info.regs.isr().read();
201 if isr.tc() { 209 if isr.tc() {
202 return Ok(()); 210 return Ok(());
203 } else if isr.berr() { 211 } else if isr.berr() {
204 T::regs().icr().write(|reg| reg.set_berrcf(true)); 212 self.info.regs.icr().write(|reg| reg.set_berrcf(true));
205 return Err(Error::Bus); 213 return Err(Error::Bus);
206 } else if isr.arlo() { 214 } else if isr.arlo() {
207 T::regs().icr().write(|reg| reg.set_arlocf(true)); 215 self.info.regs.icr().write(|reg| reg.set_arlocf(true));
208 return Err(Error::Arbitration); 216 return Err(Error::Arbitration);
209 } else if isr.nackf() { 217 } else if isr.nackf() {
210 T::regs().icr().write(|reg| reg.set_nackcf(true)); 218 self.info.regs.icr().write(|reg| reg.set_nackcf(true));
211 self.flush_txdr(); 219 self.flush_txdr();
212 return Err(Error::Nack); 220 return Err(Error::Nack);
213 } 221 }
@@ -226,6 +234,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
226 let last_chunk_idx = total_chunks.saturating_sub(1); 234 let last_chunk_idx = total_chunks.saturating_sub(1);
227 235
228 Self::master_read( 236 Self::master_read(
237 self.info,
229 address, 238 address,
230 read.len().min(255), 239 read.len().min(255),
231 Stop::Automatic, 240 Stop::Automatic,
@@ -236,14 +245,14 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
236 245
237 for (number, chunk) in read.chunks_mut(255).enumerate() { 246 for (number, chunk) in read.chunks_mut(255).enumerate() {
238 if number != 0 { 247 if number != 0 {
239 Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; 248 Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
240 } 249 }
241 250
242 for byte in chunk { 251 for byte in chunk {
243 // Wait until we have received something 252 // Wait until we have received something
244 self.wait_rxne(timeout)?; 253 self.wait_rxne(timeout)?;
245 254
246 *byte = T::regs().rxdr().read().rxdata(); 255 *byte = self.info.regs.rxdr().read().rxdata();
247 } 256 }
248 } 257 }
249 Ok(()) 258 Ok(())
@@ -262,6 +271,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
262 // 271 //
263 // ST SAD+W 272 // ST SAD+W
264 if let Err(err) = Self::master_write( 273 if let Err(err) = Self::master_write(
274 self.info,
265 address, 275 address,
266 write.len().min(255), 276 write.len().min(255),
267 Stop::Software, 277 Stop::Software,
@@ -276,7 +286,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
276 286
277 for (number, chunk) in write.chunks(255).enumerate() { 287 for (number, chunk) in write.chunks(255).enumerate() {
278 if number != 0 { 288 if number != 0 {
279 Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; 289 Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?;
280 } 290 }
281 291
282 for byte in chunk { 292 for byte in chunk {
@@ -290,7 +300,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
290 return Err(err); 300 return Err(err);
291 } 301 }
292 302
293 T::regs().txdr().write(|w| w.set_txdata(*byte)); 303 self.info.regs.txdr().write(|w| w.set_txdata(*byte));
294 } 304 }
295 } 305 }
296 // Wait until the write finishes 306 // Wait until the write finishes
@@ -348,6 +358,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
348 let last_slice_index = write.len() - 1; 358 let last_slice_index = write.len() - 1;
349 359
350 if let Err(err) = Self::master_write( 360 if let Err(err) = Self::master_write(
361 self.info,
351 address, 362 address,
352 first_length.min(255), 363 first_length.min(255),
353 Stop::Software, 364 Stop::Software,
@@ -370,6 +381,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
370 381
371 if idx != 0 { 382 if idx != 0 {
372 if let Err(err) = Self::master_continue( 383 if let Err(err) = Self::master_continue(
384 self.info,
373 slice_len.min(255), 385 slice_len.min(255),
374 (idx != last_slice_index) || (slice_len > 255), 386 (idx != last_slice_index) || (slice_len > 255),
375 timeout, 387 timeout,
@@ -382,6 +394,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
382 for (number, chunk) in slice.chunks(255).enumerate() { 394 for (number, chunk) in slice.chunks(255).enumerate() {
383 if number != 0 { 395 if number != 0 {
384 if let Err(err) = Self::master_continue( 396 if let Err(err) = Self::master_continue(
397 self.info,
385 chunk.len(), 398 chunk.len(),
386 (number != last_chunk_idx) || (idx != last_slice_index), 399 (number != last_chunk_idx) || (idx != last_slice_index),
387 timeout, 400 timeout,
@@ -402,7 +415,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
402 415
403 // Put byte on the wire 416 // Put byte on the wire
404 //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); 417 //self.i2c.txdr.write(|w| w.txdata().bits(*byte));
405 T::regs().txdr().write(|w| w.set_txdata(*byte)); 418 self.info.regs.txdr().write(|w| w.set_txdata(*byte));
406 } 419 }
407 } 420 }
408 } 421 }
@@ -413,7 +426,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> {
413 } 426 }
414} 427}
415 428
416impl<'d, T: Instance> I2c<'d, T, Async> { 429impl<'d> I2c<'d, Async> {
417 async fn write_dma_internal( 430 async fn write_dma_internal(
418 &mut self, 431 &mut self,
419 address: u8, 432 address: u8,
@@ -425,7 +438,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
425 let total_len = write.len(); 438 let total_len = write.len();
426 439
427 let dma_transfer = unsafe { 440 let dma_transfer = unsafe {
428 let regs = T::regs(); 441 let regs = self.info.regs;
429 regs.cr1().modify(|w| { 442 regs.cr1().modify(|w| {
430 w.set_txdmaen(true); 443 w.set_txdmaen(true);
431 if first_slice { 444 if first_slice {
@@ -437,11 +450,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
437 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) 450 self.tx_dma.as_mut().unwrap().write(write, dst, Default::default())
438 }; 451 };
439 452
440 let state = T::state();
441 let mut remaining_len = total_len; 453 let mut remaining_len = total_len;
442 454
443 let on_drop = OnDrop::new(|| { 455 let on_drop = OnDrop::new(|| {
444 let regs = T::regs(); 456 let regs = self.info.regs;
445 regs.cr1().modify(|w| { 457 regs.cr1().modify(|w| {
446 if last_slice { 458 if last_slice {
447 w.set_txdmaen(false); 459 w.set_txdmaen(false);
@@ -451,12 +463,13 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
451 }); 463 });
452 464
453 poll_fn(|cx| { 465 poll_fn(|cx| {
454 state.waker.register(cx.waker()); 466 self.state.waker.register(cx.waker());
455 467
456 let isr = T::regs().isr().read(); 468 let isr = self.info.regs.isr().read();
457 if remaining_len == total_len { 469 if remaining_len == total_len {
458 if first_slice { 470 if first_slice {
459 Self::master_write( 471 Self::master_write(
472 self.info,
460 address, 473 address,
461 total_len.min(255), 474 total_len.min(255),
462 Stop::Software, 475 Stop::Software,
@@ -464,8 +477,8 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
464 timeout, 477 timeout,
465 )?; 478 )?;
466 } else { 479 } else {
467 Self::master_continue(total_len.min(255), (total_len > 255) || !last_slice, timeout)?; 480 Self::master_continue(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?;
468 T::regs().cr1().modify(|w| w.set_tcie(true)); 481 self.info.regs.cr1().modify(|w| w.set_tcie(true));
469 } 482 }
470 } else if !(isr.tcr() || isr.tc()) { 483 } else if !(isr.tcr() || isr.tc()) {
471 // poll_fn was woken without an interrupt present 484 // poll_fn was woken without an interrupt present
@@ -475,10 +488,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
475 } else { 488 } else {
476 let last_piece = (remaining_len <= 255) && last_slice; 489 let last_piece = (remaining_len <= 255) && last_slice;
477 490
478 if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { 491 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) {
479 return Poll::Ready(Err(e)); 492 return Poll::Ready(Err(e));
480 } 493 }
481 T::regs().cr1().modify(|w| w.set_tcie(true)); 494 self.info.regs.cr1().modify(|w| w.set_tcie(true));
482 } 495 }
483 496
484 remaining_len = remaining_len.saturating_sub(255); 497 remaining_len = remaining_len.saturating_sub(255);
@@ -509,7 +522,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
509 let total_len = buffer.len(); 522 let total_len = buffer.len();
510 523
511 let dma_transfer = unsafe { 524 let dma_transfer = unsafe {
512 let regs = T::regs(); 525 let regs = self.info.regs;
513 regs.cr1().modify(|w| { 526 regs.cr1().modify(|w| {
514 w.set_rxdmaen(true); 527 w.set_rxdmaen(true);
515 w.set_tcie(true); 528 w.set_tcie(true);
@@ -519,11 +532,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
519 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) 532 self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default())
520 }; 533 };
521 534
522 let state = T::state();
523 let mut remaining_len = total_len; 535 let mut remaining_len = total_len;
524 536
525 let on_drop = OnDrop::new(|| { 537 let on_drop = OnDrop::new(|| {
526 let regs = T::regs(); 538 let regs = self.info.regs;
527 regs.cr1().modify(|w| { 539 regs.cr1().modify(|w| {
528 w.set_rxdmaen(false); 540 w.set_rxdmaen(false);
529 w.set_tcie(false); 541 w.set_tcie(false);
@@ -531,11 +543,12 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
531 }); 543 });
532 544
533 poll_fn(|cx| { 545 poll_fn(|cx| {
534 state.waker.register(cx.waker()); 546 self.state.waker.register(cx.waker());
535 547
536 let isr = T::regs().isr().read(); 548 let isr = self.info.regs.isr().read();
537 if remaining_len == total_len { 549 if remaining_len == total_len {
538 Self::master_read( 550 Self::master_read(
551 self.info,
539 address, 552 address,
540 total_len.min(255), 553 total_len.min(255),
541 Stop::Software, 554 Stop::Software,
@@ -551,10 +564,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
551 } else { 564 } else {
552 let last_piece = remaining_len <= 255; 565 let last_piece = remaining_len <= 255;
553 566
554 if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { 567 if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) {
555 return Poll::Ready(Err(e)); 568 return Poll::Ready(Err(e));
556 } 569 }
557 T::regs().cr1().modify(|w| w.set_tcie(true)); 570 self.info.regs.cr1().modify(|w| w.set_tcie(true));
558 } 571 }
559 572
560 remaining_len = remaining_len.saturating_sub(255); 573 remaining_len = remaining_len.saturating_sub(255);
@@ -658,9 +671,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
658 } 671 }
659} 672}
660 673
661impl<'d, T: Instance, M: Mode> Drop for I2c<'d, T, M> { 674impl<'d, M: Mode> Drop for I2c<'d, M> {
662 fn drop(&mut self) { 675 fn drop(&mut self) {
663 T::disable(); 676 self.info.enable_bit.disable();
664 } 677 }
665} 678}
666 679
@@ -788,12 +801,12 @@ impl Timings {
788 } 801 }
789} 802}
790 803
791impl<'d, T: Instance, M: Mode> SetConfig for I2c<'d, T, M> { 804impl<'d, M: Mode> SetConfig for I2c<'d, M> {
792 type Config = Hertz; 805 type Config = Hertz;
793 type ConfigError = (); 806 type ConfigError = ();
794 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { 807 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
795 let timings = Timings::new(T::frequency(), *config); 808 let timings = Timings::new(self.kernel_clock, *config);
796 T::regs().timingr().write(|reg| { 809 self.info.regs.timingr().write(|reg| {
797 reg.set_presc(timings.prescale); 810 reg.set_presc(timings.prescale);
798 reg.set_scll(timings.scll); 811 reg.set_scll(timings.scll);
799 reg.set_sclh(timings.sclh); 812 reg.set_sclh(timings.sclh);
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs
index c102c0035..c78810a38 100644
--- a/embassy-stm32/src/i2s.rs
+++ b/embassy-stm32/src/i2s.rs
@@ -208,7 +208,7 @@ impl<'d> I2S<'d> {
208 // rate to reach the proper audio sample frequency. The ODD bit in the SPI_I2SPR 208 // rate to reach the proper audio sample frequency. The ODD bit in the SPI_I2SPR
209 // register also has to be defined. 209 // register also has to be defined.
210 210
211 spi.regs.i2spr().modify(|w| { 211 spi.info.regs.i2spr().modify(|w| {
212 w.set_i2sdiv(div); 212 w.set_i2sdiv(div);
213 w.set_odd(match odd { 213 w.set_odd(match odd {
214 true => Odd::ODD, 214 true => Odd::ODD,
@@ -235,7 +235,7 @@ impl<'d> I2S<'d> {
235 235
236 // 5. The I2SE bit in SPI_I2SCFGR register must be set. 236 // 5. The I2SE bit in SPI_I2SCFGR register must be set.
237 237
238 spi.regs.i2scfgr().modify(|w| { 238 spi.info.regs.i2scfgr().modify(|w| {
239 w.set_ckpol(config.clock_polarity.ckpol()); 239 w.set_ckpol(config.clock_polarity.ckpol());
240 240
241 w.set_i2smod(true); 241 w.set_i2smod(true);
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs
index 9c459a932..7f8076043 100644
--- a/embassy-stm32/src/macros.rs
+++ b/embassy-stm32/src/macros.rs
@@ -1,16 +1,25 @@
1#![macro_use] 1#![macro_use]
2 2
3macro_rules! peri_trait { 3macro_rules! peri_trait {
4 () => { 4 (
5 $(irqs: [$($irq:ident),*],)?
6 ) => {
5 #[allow(private_interfaces)] 7 #[allow(private_interfaces)]
6 pub(crate) trait SealedInstance { 8 pub(crate) trait SealedInstance {
7 const INFO: Info; 9 #[allow(unused)]
8 const STATE: &'static State; 10 fn info() -> &'static Info;
11 #[allow(unused)]
12 fn state() -> &'static State;
9 } 13 }
10 14
11 /// SPI instance trait. 15 /// Peripheral instance trait.
12 #[allow(private_bounds)] 16 #[allow(private_bounds)]
13 pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} 17 pub trait Instance: crate::Peripheral<P = Self> + SealedInstance + crate::rcc::RccPeripheral {
18 $($(
19 /// Interrupt for this peripheral.
20 type $irq: crate::interrupt::typelevel::Interrupt;
21 )*)?
22 }
14 }; 23 };
15} 24}
16 25
@@ -18,8 +27,14 @@ macro_rules! peri_trait_impl {
18 ($instance:ident, $info:expr) => { 27 ($instance:ident, $info:expr) => {
19 #[allow(private_interfaces)] 28 #[allow(private_interfaces)]
20 impl SealedInstance for crate::peripherals::$instance { 29 impl SealedInstance for crate::peripherals::$instance {
21 const INFO: Info = $info; 30 fn info() -> &'static Info {
22 const STATE: &'static State = &State::new(); 31 static INFO: Info = $info;
32 &INFO
33 }
34 fn state() -> &'static State {
35 static STATE: State = State::new();
36 &STATE
37 }
23 } 38 }
24 impl Instance for crate::peripherals::$instance {} 39 impl Instance for crate::peripherals::$instance {}
25 }; 40 };
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index c413b62ef..28816256c 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -67,10 +67,11 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
67} 67}
68 68
69pub(crate) trait SealedRccPeripheral { 69pub(crate) trait SealedRccPeripheral {
70 const ENABLE_BIT: ClockEnableBit;
71
70 fn frequency() -> Hertz; 72 fn frequency() -> Hertz;
71 fn enable_and_reset_with_cs(cs: CriticalSection); 73 fn enable_and_reset_with_cs(cs: CriticalSection);
72 fn disable_with_cs(cs: CriticalSection); 74 fn disable_with_cs(cs: CriticalSection);
73 fn enable_bit() -> ClockEnableBit;
74 75
75 fn enable_and_reset() { 76 fn enable_and_reset() {
76 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) 77 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
@@ -151,7 +152,7 @@ pub(crate) struct ClockEnableBit {
151 152
152impl ClockEnableBit { 153impl ClockEnableBit {
153 /// Safety: offset+bit must correspond to a valid xxxEN bit. 154 /// Safety: offset+bit must correspond to a valid xxxEN bit.
154 pub(crate) unsafe fn new(offset: u8, bit: u8) -> Self { 155 pub(crate) const unsafe fn new(offset: u8, bit: u8) -> Self {
155 Self { offset, bit } 156 Self { offset, bit }
156 } 157 }
157 158
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 5a2ee105d..0875cfe41 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -13,7 +13,7 @@ use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 15use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::{ClockEnableBit, RccPeripheral}; 16use crate::rcc::{ClockEnableBit, SealedRccPeripheral};
17use crate::time::Hertz; 17use crate::time::Hertz;
18use crate::Peripheral; 18use crate::Peripheral;
19 19
@@ -93,8 +93,7 @@ impl Config {
93} 93}
94/// SPI driver. 94/// SPI driver.
95pub struct Spi<'d, M: PeriMode> { 95pub struct Spi<'d, M: PeriMode> {
96 pub(crate) regs: Regs, 96 pub(crate) info: &'static Info,
97 enable_bit: ClockEnableBit,
98 kernel_clock: Hertz, 97 kernel_clock: Hertz,
99 sck: Option<PeripheralRef<'d, AnyPin>>, 98 sck: Option<PeripheralRef<'d, AnyPin>>,
100 mosi: Option<PeripheralRef<'d, AnyPin>>, 99 mosi: Option<PeripheralRef<'d, AnyPin>>,
@@ -115,7 +114,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
115 rx_dma: Option<ChannelAndRequest<'d>>, 114 rx_dma: Option<ChannelAndRequest<'d>>,
116 config: Config, 115 config: Config,
117 ) -> Self { 116 ) -> Self {
118 let regs = T::INFO.regs; 117 let regs = T::info().regs;
119 let kernel_clock = T::frequency(); 118 let kernel_clock = T::frequency();
120 let br = compute_baud_rate(kernel_clock, config.frequency); 119 let br = compute_baud_rate(kernel_clock, config.frequency);
121 120
@@ -205,8 +204,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
205 } 204 }
206 205
207 Self { 206 Self {
208 regs, 207 info: T::info(),
209 enable_bit: T::enable_bit(),
210 kernel_clock, 208 kernel_clock,
211 sck, 209 sck,
212 mosi, 210 mosi,
@@ -228,7 +226,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
228 let br = compute_baud_rate(self.kernel_clock, config.frequency); 226 let br = compute_baud_rate(self.kernel_clock, config.frequency);
229 227
230 #[cfg(any(spi_v1, spi_f1, spi_v2))] 228 #[cfg(any(spi_v1, spi_f1, spi_v2))]
231 self.regs.cr1().modify(|w| { 229 self.info.regs.cr1().modify(|w| {
232 w.set_cpha(cpha); 230 w.set_cpha(cpha);
233 w.set_cpol(cpol); 231 w.set_cpol(cpol);
234 w.set_br(br); 232 w.set_br(br);
@@ -237,12 +235,12 @@ impl<'d, M: PeriMode> Spi<'d, M> {
237 235
238 #[cfg(any(spi_v3, spi_v4, spi_v5))] 236 #[cfg(any(spi_v3, spi_v4, spi_v5))]
239 { 237 {
240 self.regs.cfg2().modify(|w| { 238 self.info.regs.cfg2().modify(|w| {
241 w.set_cpha(cpha); 239 w.set_cpha(cpha);
242 w.set_cpol(cpol); 240 w.set_cpol(cpol);
243 w.set_lsbfirst(lsbfirst); 241 w.set_lsbfirst(lsbfirst);
244 }); 242 });
245 self.regs.cfg1().modify(|w| { 243 self.info.regs.cfg1().modify(|w| {
246 w.set_mbr(br); 244 w.set_mbr(br);
247 }); 245 });
248 } 246 }
@@ -252,11 +250,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
252 /// Get current SPI configuration. 250 /// Get current SPI configuration.
253 pub fn get_current_config(&self) -> Config { 251 pub fn get_current_config(&self) -> Config {
254 #[cfg(any(spi_v1, spi_f1, spi_v2))] 252 #[cfg(any(spi_v1, spi_f1, spi_v2))]
255 let cfg = self.regs.cr1().read(); 253 let cfg = self.info.regs.cr1().read();
256 #[cfg(any(spi_v3, spi_v4, spi_v5))] 254 #[cfg(any(spi_v3, spi_v4, spi_v5))]
257 let cfg = self.regs.cfg2().read(); 255 let cfg = self.info.regs.cfg2().read();
258 #[cfg(any(spi_v3, spi_v4, spi_v5))] 256 #[cfg(any(spi_v3, spi_v4, spi_v5))]
259 let cfg1 = self.regs.cfg1().read(); 257 let cfg1 = self.info.regs.cfg1().read();
260 258
261 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { 259 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW {
262 Polarity::IdleLow 260 Polarity::IdleLow
@@ -296,40 +294,40 @@ impl<'d, M: PeriMode> Spi<'d, M> {
296 294
297 #[cfg(any(spi_v1, spi_f1))] 295 #[cfg(any(spi_v1, spi_f1))]
298 { 296 {
299 self.regs.cr1().modify(|reg| { 297 self.info.regs.cr1().modify(|reg| {
300 reg.set_spe(false); 298 reg.set_spe(false);
301 reg.set_dff(word_size) 299 reg.set_dff(word_size)
302 }); 300 });
303 self.regs.cr1().modify(|reg| { 301 self.info.regs.cr1().modify(|reg| {
304 reg.set_spe(true); 302 reg.set_spe(true);
305 }); 303 });
306 } 304 }
307 #[cfg(spi_v2)] 305 #[cfg(spi_v2)]
308 { 306 {
309 self.regs.cr1().modify(|w| { 307 self.info.regs.cr1().modify(|w| {
310 w.set_spe(false); 308 w.set_spe(false);
311 }); 309 });
312 self.regs.cr2().modify(|w| { 310 self.info.regs.cr2().modify(|w| {
313 w.set_frxth(word_size.1); 311 w.set_frxth(word_size.1);
314 w.set_ds(word_size.0); 312 w.set_ds(word_size.0);
315 }); 313 });
316 self.regs.cr1().modify(|w| { 314 self.info.regs.cr1().modify(|w| {
317 w.set_spe(true); 315 w.set_spe(true);
318 }); 316 });
319 } 317 }
320 #[cfg(any(spi_v3, spi_v4, spi_v5))] 318 #[cfg(any(spi_v3, spi_v4, spi_v5))]
321 { 319 {
322 self.regs.cr1().modify(|w| { 320 self.info.regs.cr1().modify(|w| {
323 w.set_csusp(true); 321 w.set_csusp(true);
324 }); 322 });
325 while self.regs.sr().read().eot() {} 323 while self.info.regs.sr().read().eot() {}
326 self.regs.cr1().modify(|w| { 324 self.info.regs.cr1().modify(|w| {
327 w.set_spe(false); 325 w.set_spe(false);
328 }); 326 });
329 self.regs.cfg1().modify(|w| { 327 self.info.regs.cfg1().modify(|w| {
330 w.set_dsize(word_size); 328 w.set_dsize(word_size);
331 }); 329 });
332 self.regs.cr1().modify(|w| { 330 self.info.regs.cr1().modify(|w| {
333 w.set_csusp(false); 331 w.set_csusp(false);
334 w.set_spe(true); 332 w.set_spe(true);
335 }); 333 });
@@ -340,22 +338,22 @@ impl<'d, M: PeriMode> Spi<'d, M> {
340 338
341 /// Blocking write. 339 /// Blocking write.
342 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { 340 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> {
343 self.regs.cr1().modify(|w| w.set_spe(true)); 341 self.info.regs.cr1().modify(|w| w.set_spe(true));
344 flush_rx_fifo(self.regs); 342 flush_rx_fifo(self.info.regs);
345 self.set_word_size(W::CONFIG); 343 self.set_word_size(W::CONFIG);
346 for word in words.iter() { 344 for word in words.iter() {
347 let _ = transfer_word(self.regs, *word)?; 345 let _ = transfer_word(self.info.regs, *word)?;
348 } 346 }
349 Ok(()) 347 Ok(())
350 } 348 }
351 349
352 /// Blocking read. 350 /// Blocking read.
353 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 351 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
354 self.regs.cr1().modify(|w| w.set_spe(true)); 352 self.info.regs.cr1().modify(|w| w.set_spe(true));
355 flush_rx_fifo(self.regs); 353 flush_rx_fifo(self.info.regs);
356 self.set_word_size(W::CONFIG); 354 self.set_word_size(W::CONFIG);
357 for word in words.iter_mut() { 355 for word in words.iter_mut() {
358 *word = transfer_word(self.regs, W::default())?; 356 *word = transfer_word(self.info.regs, W::default())?;
359 } 357 }
360 Ok(()) 358 Ok(())
361 } 359 }
@@ -364,11 +362,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
364 /// 362 ///
365 /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. 363 /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time.
366 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 364 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
367 self.regs.cr1().modify(|w| w.set_spe(true)); 365 self.info.regs.cr1().modify(|w| w.set_spe(true));
368 flush_rx_fifo(self.regs); 366 flush_rx_fifo(self.info.regs);
369 self.set_word_size(W::CONFIG); 367 self.set_word_size(W::CONFIG);
370 for word in words.iter_mut() { 368 for word in words.iter_mut() {
371 *word = transfer_word(self.regs, *word)?; 369 *word = transfer_word(self.info.regs, *word)?;
372 } 370 }
373 Ok(()) 371 Ok(())
374 } 372 }
@@ -380,13 +378,13 @@ impl<'d, M: PeriMode> Spi<'d, M> {
380 /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. 378 /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored.
381 /// If `write` is shorter it is padded with zero bytes. 379 /// If `write` is shorter it is padded with zero bytes.
382 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { 380 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
383 self.regs.cr1().modify(|w| w.set_spe(true)); 381 self.info.regs.cr1().modify(|w| w.set_spe(true));
384 flush_rx_fifo(self.regs); 382 flush_rx_fifo(self.info.regs);
385 self.set_word_size(W::CONFIG); 383 self.set_word_size(W::CONFIG);
386 let len = read.len().max(write.len()); 384 let len = read.len().max(write.len());
387 for i in 0..len { 385 for i in 0..len {
388 let wb = write.get(i).copied().unwrap_or_default(); 386 let wb = write.get(i).copied().unwrap_or_default();
389 let rb = transfer_word(self.regs, wb)?; 387 let rb = transfer_word(self.info.regs, wb)?;
390 if let Some(r) = read.get_mut(i) { 388 if let Some(r) = read.get_mut(i) {
391 *r = rb; 389 *r = rb;
392 } 390 }
@@ -588,25 +586,25 @@ impl<'d> Spi<'d, Async> {
588 } 586 }
589 587
590 self.set_word_size(W::CONFIG); 588 self.set_word_size(W::CONFIG);
591 self.regs.cr1().modify(|w| { 589 self.info.regs.cr1().modify(|w| {
592 w.set_spe(false); 590 w.set_spe(false);
593 }); 591 });
594 592
595 let tx_dst = self.regs.tx_ptr(); 593 let tx_dst = self.info.regs.tx_ptr();
596 let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; 594 let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) };
597 595
598 set_txdmaen(self.regs, true); 596 set_txdmaen(self.info.regs, true);
599 self.regs.cr1().modify(|w| { 597 self.info.regs.cr1().modify(|w| {
600 w.set_spe(true); 598 w.set_spe(true);
601 }); 599 });
602 #[cfg(any(spi_v3, spi_v4, spi_v5))] 600 #[cfg(any(spi_v3, spi_v4, spi_v5))]
603 self.regs.cr1().modify(|w| { 601 self.info.regs.cr1().modify(|w| {
604 w.set_cstart(true); 602 w.set_cstart(true);
605 }); 603 });
606 604
607 tx_f.await; 605 tx_f.await;
608 606
609 finish_dma(self.regs); 607 finish_dma(self.info.regs);
610 608
611 Ok(()) 609 Ok(())
612 } 610 }
@@ -618,22 +616,22 @@ impl<'d> Spi<'d, Async> {
618 } 616 }
619 617
620 self.set_word_size(W::CONFIG); 618 self.set_word_size(W::CONFIG);
621 self.regs.cr1().modify(|w| { 619 self.info.regs.cr1().modify(|w| {
622 w.set_spe(false); 620 w.set_spe(false);
623 }); 621 });
624 622
625 // SPIv3 clears rxfifo on SPE=0 623 // SPIv3 clears rxfifo on SPE=0
626 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 624 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))]
627 flush_rx_fifo(self.regs); 625 flush_rx_fifo(self.info.regs);
628 626
629 set_rxdmaen(self.regs, true); 627 set_rxdmaen(self.info.regs, true);
630 628
631 let clock_byte_count = data.len(); 629 let clock_byte_count = data.len();
632 630
633 let rx_src = self.regs.rx_ptr(); 631 let rx_src = self.info.regs.rx_ptr();
634 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; 632 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) };
635 633
636 let tx_dst = self.regs.tx_ptr(); 634 let tx_dst = self.info.regs.tx_ptr();
637 let clock_byte = 0x00u8; 635 let clock_byte = 0x00u8;
638 let tx_f = unsafe { 636 let tx_f = unsafe {
639 self.tx_dma 637 self.tx_dma
@@ -642,18 +640,18 @@ impl<'d> Spi<'d, Async> {
642 .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) 640 .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default())
643 }; 641 };
644 642
645 set_txdmaen(self.regs, true); 643 set_txdmaen(self.info.regs, true);
646 self.regs.cr1().modify(|w| { 644 self.info.regs.cr1().modify(|w| {
647 w.set_spe(true); 645 w.set_spe(true);
648 }); 646 });
649 #[cfg(any(spi_v3, spi_v4, spi_v5))] 647 #[cfg(any(spi_v3, spi_v4, spi_v5))]
650 self.regs.cr1().modify(|w| { 648 self.info.regs.cr1().modify(|w| {
651 w.set_cstart(true); 649 w.set_cstart(true);
652 }); 650 });
653 651
654 join(tx_f, rx_f).await; 652 join(tx_f, rx_f).await;
655 653
656 finish_dma(self.regs); 654 finish_dma(self.info.regs);
657 655
658 Ok(()) 656 Ok(())
659 } 657 }
@@ -667,20 +665,20 @@ impl<'d> Spi<'d, Async> {
667 } 665 }
668 666
669 self.set_word_size(W::CONFIG); 667 self.set_word_size(W::CONFIG);
670 self.regs.cr1().modify(|w| { 668 self.info.regs.cr1().modify(|w| {
671 w.set_spe(false); 669 w.set_spe(false);
672 }); 670 });
673 671
674 // SPIv3 clears rxfifo on SPE=0 672 // SPIv3 clears rxfifo on SPE=0
675 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 673 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))]
676 flush_rx_fifo(self.regs); 674 flush_rx_fifo(self.info.regs);
677 675
678 set_rxdmaen(self.regs, true); 676 set_rxdmaen(self.info.regs, true);
679 677
680 let rx_src = self.regs.rx_ptr(); 678 let rx_src = self.info.regs.rx_ptr();
681 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; 679 let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
682 680
683 let tx_dst = self.regs.tx_ptr(); 681 let tx_dst = self.info.regs.tx_ptr();
684 let tx_f = unsafe { 682 let tx_f = unsafe {
685 self.tx_dma 683 self.tx_dma
686 .as_mut() 684 .as_mut()
@@ -688,18 +686,18 @@ impl<'d> Spi<'d, Async> {
688 .write_raw(write, tx_dst, Default::default()) 686 .write_raw(write, tx_dst, Default::default())
689 }; 687 };
690 688
691 set_txdmaen(self.regs, true); 689 set_txdmaen(self.info.regs, true);
692 self.regs.cr1().modify(|w| { 690 self.info.regs.cr1().modify(|w| {
693 w.set_spe(true); 691 w.set_spe(true);
694 }); 692 });
695 #[cfg(any(spi_v3, spi_v4, spi_v5))] 693 #[cfg(any(spi_v3, spi_v4, spi_v5))]
696 self.regs.cr1().modify(|w| { 694 self.info.regs.cr1().modify(|w| {
697 w.set_cstart(true); 695 w.set_cstart(true);
698 }); 696 });
699 697
700 join(tx_f, rx_f).await; 698 join(tx_f, rx_f).await;
701 699
702 finish_dma(self.regs); 700 finish_dma(self.info.regs);
703 701
704 Ok(()) 702 Ok(())
705 } 703 }
@@ -728,7 +726,7 @@ impl<'d, M: PeriMode> Drop for Spi<'d, M> {
728 self.mosi.as_ref().map(|x| x.set_as_disconnected()); 726 self.mosi.as_ref().map(|x| x.set_as_disconnected());
729 self.miso.as_ref().map(|x| x.set_as_disconnected()); 727 self.miso.as_ref().map(|x| x.set_as_disconnected());
730 728
731 self.enable_bit.disable(); 729 self.info.enable_bit.disable();
732 } 730 }
733} 731}
734 732
@@ -1106,8 +1104,9 @@ mod word_impl {
1106 impl_word!(u32, 32 - 1); 1104 impl_word!(u32, 32 - 1);
1107} 1105}
1108 1106
1109struct Info { 1107pub(crate) struct Info {
1110 regs: Regs, 1108 pub(crate) regs: Regs,
1109 pub(crate) enable_bit: ClockEnableBit,
1111} 1110}
1112 1111
1113struct State {} 1112struct State {}
@@ -1134,6 +1133,7 @@ foreach_peripheral!(
1134 (spi, $inst:ident) => { 1133 (spi, $inst:ident) => {
1135 peri_trait_impl!($inst, Info { 1134 peri_trait_impl!($inst, Info {
1136 regs: crate::pac::$inst, 1135 regs: crate::pac::$inst,
1136 enable_bit: crate::peripherals::$inst::ENABLE_BIT,
1137 }); 1137 });
1138 }; 1138 };
1139); 1139);
diff --git a/examples/stm32h7/src/bin/i2c_shared.rs b/examples/stm32h7/src/bin/i2c_shared.rs
index 79d213ae4..6f4815582 100644
--- a/examples/stm32h7/src/bin/i2c_shared.rs
+++ b/examples/stm32h7/src/bin/i2c_shared.rs
@@ -6,11 +6,10 @@ use core::cell::RefCell;
6use defmt::*; 6use defmt::*;
7use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; 7use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::bind_interrupts;
10use embassy_stm32::i2c::{self, I2c}; 9use embassy_stm32::i2c::{self, I2c};
11use embassy_stm32::mode::Async; 10use embassy_stm32::mode::Async;
12use embassy_stm32::peripherals::{self, I2C1};
13use embassy_stm32::time::Hertz; 11use embassy_stm32::time::Hertz;
12use embassy_stm32::{bind_interrupts, peripherals};
14use embassy_sync::blocking_mutex::NoopMutex; 13use embassy_sync::blocking_mutex::NoopMutex;
15use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
16use static_cell::StaticCell; 15use static_cell::StaticCell;
@@ -24,7 +23,7 @@ const SHTC3_WAKEUP: [u8; 2] = [0x35, 0x17];
24const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24]; 23const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24];
25const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98]; 24const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98];
26 25
27static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, I2C1, Async>>>> = StaticCell::new(); 26static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, Async>>>> = StaticCell::new();
28 27
29bind_interrupts!(struct Irqs { 28bind_interrupts!(struct Irqs {
30 I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; 29 I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>;
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
index 985ac8171..33149144c 100644
--- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
+++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs
@@ -60,7 +60,7 @@ pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>;
60pub type SpeInt = exti::ExtiInput<'static>; 60pub type SpeInt = exti::ExtiInput<'static>;
61pub type SpeRst = Output<'static>; 61pub type SpeRst = Output<'static>;
62pub type Adin1110T = ADIN1110<SpeSpiCs>; 62pub type Adin1110T = ADIN1110<SpeSpiCs>;
63pub type TempSensI2c = I2c<'static, peripherals::I2C3, Async>; 63pub type TempSensI2c = I2c<'static, Async>;
64 64
65static TEMP: AtomicI32 = AtomicI32::new(0); 65static TEMP: AtomicI32 = AtomicI32::new(0);
66 66