aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-21 01:24:10 +0200
committerDario Nieuwenhuis <[email protected]>2024-05-21 01:24:10 +0200
commit6a508b32101b0af1a77624ef0a22c72c972b1b74 (patch)
treec3ce31065078063c768b9f94d6faacea2fe2e80b
parent2b09f9efd7e621708cd00bc512ce981735907103 (diff)
stm32: use funcs for info/state, const for ENABLE_BIT.
-rw-r--r--embassy-stm32/build.rs6
-rw-r--r--embassy-stm32/src/i2s.rs4
-rw-r--r--embassy-stm32/src/macros.rs16
-rw-r--r--embassy-stm32/src/rcc/mod.rs5
-rw-r--r--embassy-stm32/src/spi/mod.rs122
5 files changed, 81 insertions, 72 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/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..6a5691181 100644
--- a/embassy-stm32/src/macros.rs
+++ b/embassy-stm32/src/macros.rs
@@ -4,8 +4,10 @@ macro_rules! peri_trait {
4 () => { 4 () => {
5 #[allow(private_interfaces)] 5 #[allow(private_interfaces)]
6 pub(crate) trait SealedInstance { 6 pub(crate) trait SealedInstance {
7 const INFO: Info; 7 #[allow(unused)]
8 const STATE: &'static State; 8 fn info() -> &'static Info;
9 #[allow(unused)]
10 fn state() -> &'static State;
9 } 11 }
10 12
11 /// SPI instance trait. 13 /// SPI instance trait.
@@ -18,8 +20,14 @@ macro_rules! peri_trait_impl {
18 ($instance:ident, $info:expr) => { 20 ($instance:ident, $info:expr) => {
19 #[allow(private_interfaces)] 21 #[allow(private_interfaces)]
20 impl SealedInstance for crate::peripherals::$instance { 22 impl SealedInstance for crate::peripherals::$instance {
21 const INFO: Info = $info; 23 fn info() -> &'static Info {
22 const STATE: &'static State = &State::new(); 24 static INFO: Info = $info;
25 &INFO
26 }
27 fn state() -> &'static State {
28 static STATE: State = State::new();
29 &STATE
30 }
23 } 31 }
24 impl Instance for crate::peripherals::$instance {} 32 impl Instance for crate::peripherals::$instance {}
25 }; 33 };
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);