aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/spi
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-01 00:05:20 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-05 16:01:29 +0200
commit683ca6595ff7f4c6f0e70e90d3cdeab13d0b1c07 (patch)
tree7c2d714f4ae66d12e66742f7b316b14d5451514f /embassy-stm32/src/spi
parent90d403fd0a33ac7a3cde4fe9c417b5976b924020 (diff)
stm32/spi: update for new version numbering, add i2s support for all versions.
Diffstat (limited to 'embassy-stm32/src/spi')
-rw-r--r--embassy-stm32/src/spi/mod.rs134
1 files changed, 67 insertions, 67 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 4c5308eba..a49ebcbee 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -174,7 +174,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
174 self.info.rcc.enable_and_reset(); 174 self.info.rcc.enable_and_reset();
175 175
176 let regs = self.info.regs; 176 let regs = self.info.regs;
177 #[cfg(any(spi_v1, spi_f1))] 177 #[cfg(any(spi_v1, spi_v2))]
178 { 178 {
179 regs.cr2().modify(|w| { 179 regs.cr2().modify(|w| {
180 w.set_ssoe(false); 180 w.set_ssoe(false);
@@ -198,7 +198,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
198 w.set_dff(<u8 as SealedWord>::CONFIG) 198 w.set_dff(<u8 as SealedWord>::CONFIG)
199 }); 199 });
200 } 200 }
201 #[cfg(spi_v2)] 201 #[cfg(spi_v3)]
202 { 202 {
203 regs.cr2().modify(|w| { 203 regs.cr2().modify(|w| {
204 let (ds, frxth) = <u8 as SealedWord>::CONFIG; 204 let (ds, frxth) = <u8 as SealedWord>::CONFIG;
@@ -220,7 +220,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
220 w.set_spe(true); 220 w.set_spe(true);
221 }); 221 });
222 } 222 }
223 #[cfg(any(spi_v3, spi_v4, spi_v5))] 223 #[cfg(any(spi_v4, spi_v5, spi_v6))]
224 { 224 {
225 regs.ifcr().write(|w| w.0 = 0xffff_ffff); 225 regs.ifcr().write(|w| w.0 = 0xffff_ffff);
226 regs.cfg2().modify(|w| { 226 regs.cfg2().modify(|w| {
@@ -274,7 +274,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
274 } 274 }
275 } 275 }
276 276
277 #[cfg(any(spi_v1, spi_f1, spi_v2))] 277 #[cfg(any(spi_v1, spi_v2, spi_v3))]
278 self.info.regs.cr1().modify(|w| { 278 self.info.regs.cr1().modify(|w| {
279 w.set_cpha(cpha); 279 w.set_cpha(cpha);
280 w.set_cpol(cpol); 280 w.set_cpol(cpol);
@@ -282,7 +282,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
282 w.set_lsbfirst(lsbfirst); 282 w.set_lsbfirst(lsbfirst);
283 }); 283 });
284 284
285 #[cfg(any(spi_v3, spi_v4, spi_v5))] 285 #[cfg(any(spi_v4, spi_v5, spi_v6))]
286 { 286 {
287 self.info.regs.cr1().modify(|w| { 287 self.info.regs.cr1().modify(|w| {
288 w.set_spe(false); 288 w.set_spe(false);
@@ -306,11 +306,11 @@ impl<'d, M: PeriMode> Spi<'d, M> {
306 306
307 /// Get current SPI configuration. 307 /// Get current SPI configuration.
308 pub fn get_current_config(&self) -> Config { 308 pub fn get_current_config(&self) -> Config {
309 #[cfg(any(spi_v1, spi_f1, spi_v2))] 309 #[cfg(any(spi_v1, spi_v2, spi_v3))]
310 let cfg = self.info.regs.cr1().read(); 310 let cfg = self.info.regs.cr1().read();
311 #[cfg(any(spi_v3, spi_v4, spi_v5))] 311 #[cfg(any(spi_v4, spi_v5, spi_v6))]
312 let cfg = self.info.regs.cfg2().read(); 312 let cfg = self.info.regs.cfg2().read();
313 #[cfg(any(spi_v3, spi_v4, spi_v5))] 313 #[cfg(any(spi_v4, spi_v5, spi_v6))]
314 let cfg1 = self.info.regs.cfg1().read(); 314 let cfg1 = self.info.regs.cfg1().read();
315 315
316 let polarity = if cfg.cpol() == vals::Cpol::IDLE_LOW { 316 let polarity = if cfg.cpol() == vals::Cpol::IDLE_LOW {
@@ -335,9 +335,9 @@ impl<'d, M: PeriMode> Spi<'d, M> {
335 Some(pin) => pin.pull(), 335 Some(pin) => pin.pull(),
336 }; 336 };
337 337
338 #[cfg(any(spi_v1, spi_f1, spi_v2))] 338 #[cfg(any(spi_v1, spi_v2, spi_v3))]
339 let br = cfg.br(); 339 let br = cfg.br();
340 #[cfg(any(spi_v3, spi_v4, spi_v5))] 340 #[cfg(any(spi_v4, spi_v5, spi_v6))]
341 let br = cfg1.mbr(); 341 let br = cfg1.mbr();
342 342
343 let frequency = compute_frequency(self.kernel_clock, br); 343 let frequency = compute_frequency(self.kernel_clock, br);
@@ -360,16 +360,16 @@ impl<'d, M: PeriMode> Spi<'d, M> {
360 w.set_spe(false); 360 w.set_spe(false);
361 }); 361 });
362 362
363 #[cfg(any(spi_v1, spi_f1))] 363 #[cfg(any(spi_v1, spi_v2))]
364 self.info.regs.cr1().modify(|reg| { 364 self.info.regs.cr1().modify(|reg| {
365 reg.set_dff(word_size); 365 reg.set_dff(word_size);
366 }); 366 });
367 #[cfg(spi_v2)] 367 #[cfg(spi_v3)]
368 self.info.regs.cr2().modify(|w| { 368 self.info.regs.cr2().modify(|w| {
369 w.set_frxth(word_size.1); 369 w.set_frxth(word_size.1);
370 w.set_ds(word_size.0); 370 w.set_ds(word_size.0);
371 }); 371 });
372 #[cfg(any(spi_v3, spi_v4, spi_v5))] 372 #[cfg(any(spi_v4, spi_v5, spi_v6))]
373 self.info.regs.cfg1().modify(|w| { 373 self.info.regs.cfg1().modify(|w| {
374 w.set_dsize(word_size); 374 w.set_dsize(word_size);
375 }); 375 });
@@ -380,7 +380,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
380 /// Blocking write. 380 /// Blocking write.
381 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { 381 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> {
382 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...? 382 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...?
383 #[cfg(any(spi_v3, spi_v4, spi_v5))] 383 #[cfg(any(spi_v4, spi_v5, spi_v6))]
384 self.info.regs.cr1().modify(|w| w.set_spe(false)); 384 self.info.regs.cr1().modify(|w| w.set_spe(false));
385 self.set_word_size(W::CONFIG); 385 self.set_word_size(W::CONFIG);
386 self.info.regs.cr1().modify(|w| w.set_spe(true)); 386 self.info.regs.cr1().modify(|w| w.set_spe(true));
@@ -391,7 +391,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
391 // This is the case when the SPI has been created with `new_(blocking_?)txonly_nosck`. 391 // This is the case when the SPI has been created with `new_(blocking_?)txonly_nosck`.
392 // See https://github.com/embassy-rs/embassy/issues/2902 392 // See https://github.com/embassy-rs/embassy/issues/2902
393 // This is not documented as an errata by ST, and I've been unable to find anything online... 393 // This is not documented as an errata by ST, and I've been unable to find anything online...
394 #[cfg(not(any(spi_v1, spi_f1)))] 394 #[cfg(not(any(spi_v1, spi_v2)))]
395 write_word(self.info.regs, *word)?; 395 write_word(self.info.regs, *word)?;
396 396
397 // if we're doing tx only, after writing the last byte to FIFO we have to wait 397 // if we're doing tx only, after writing the last byte to FIFO we have to wait
@@ -401,14 +401,14 @@ impl<'d, M: PeriMode> Spi<'d, M> {
401 // Luckily this doesn't affect SPIv2+. 401 // Luckily this doesn't affect SPIv2+.
402 // See http://efton.sk/STM32/gotcha/g68.html 402 // See http://efton.sk/STM32/gotcha/g68.html
403 // ST doesn't seem to document this in errata sheets (?) 403 // ST doesn't seem to document this in errata sheets (?)
404 #[cfg(any(spi_v1, spi_f1))] 404 #[cfg(any(spi_v1, spi_v2))]
405 transfer_word(self.info.regs, *word)?; 405 transfer_word(self.info.regs, *word)?;
406 } 406 }
407 407
408 // wait until last word is transmitted. (except on v1, see above) 408 // wait until last word is transmitted. (except on v1, see above)
409 #[cfg(not(any(spi_v1, spi_f1, spi_v2)))] 409 #[cfg(not(any(spi_v1, spi_v2, spi_v3)))]
410 while !self.info.regs.sr().read().txc() {} 410 while !self.info.regs.sr().read().txc() {}
411 #[cfg(spi_v2)] 411 #[cfg(spi_v3)]
412 while self.info.regs.sr().read().bsy() {} 412 while self.info.regs.sr().read().bsy() {}
413 413
414 Ok(()) 414 Ok(())
@@ -417,7 +417,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
417 /// Blocking read. 417 /// Blocking read.
418 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 418 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
419 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...? 419 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...?
420 #[cfg(any(spi_v3, spi_v4, spi_v5))] 420 #[cfg(any(spi_v4, spi_v5, spi_v6))]
421 self.info.regs.cr1().modify(|w| w.set_spe(false)); 421 self.info.regs.cr1().modify(|w| w.set_spe(false));
422 self.set_word_size(W::CONFIG); 422 self.set_word_size(W::CONFIG);
423 self.info.regs.cr1().modify(|w| w.set_spe(true)); 423 self.info.regs.cr1().modify(|w| w.set_spe(true));
@@ -433,7 +433,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
433 /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. 433 /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time.
434 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 434 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
435 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...? 435 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...?
436 #[cfg(any(spi_v3, spi_v4, spi_v5))] 436 #[cfg(any(spi_v4, spi_v5, spi_v6))]
437 self.info.regs.cr1().modify(|w| w.set_spe(false)); 437 self.info.regs.cr1().modify(|w| w.set_spe(false));
438 self.set_word_size(W::CONFIG); 438 self.set_word_size(W::CONFIG);
439 self.info.regs.cr1().modify(|w| w.set_spe(true)); 439 self.info.regs.cr1().modify(|w| w.set_spe(true));
@@ -452,7 +452,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
452 /// If `write` is shorter it is padded with zero bytes. 452 /// If `write` is shorter it is padded with zero bytes.
453 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { 453 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
454 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...? 454 // needed in v3+ to avoid overrun causing the SPI RX state machine to get stuck...?
455 #[cfg(any(spi_v3, spi_v4, spi_v5))] 455 #[cfg(any(spi_v4, spi_v5, spi_v6))]
456 self.info.regs.cr1().modify(|w| w.set_spe(false)); 456 self.info.regs.cr1().modify(|w| w.set_spe(false));
457 self.set_word_size(W::CONFIG); 457 self.set_word_size(W::CONFIG);
458 self.info.regs.cr1().modify(|w| w.set_spe(true)); 458 self.info.regs.cr1().modify(|w| w.set_spe(true));
@@ -572,7 +572,7 @@ impl<'d> Spi<'d, Async> {
572 peri: Peri<'d, T>, 572 peri: Peri<'d, T>,
573 sck: Peri<'d, impl SckPin<T>>, 573 sck: Peri<'d, impl SckPin<T>>,
574 miso: Peri<'d, impl MisoPin<T>>, 574 miso: Peri<'d, impl MisoPin<T>>,
575 #[cfg(any(spi_v1, spi_f1, spi_v2))] tx_dma: Peri<'d, impl TxDma<T>>, 575 #[cfg(any(spi_v1, spi_v2, spi_v3))] tx_dma: Peri<'d, impl TxDma<T>>,
576 rx_dma: Peri<'d, impl RxDma<T>>, 576 rx_dma: Peri<'d, impl RxDma<T>>,
577 config: Config, 577 config: Config,
578 ) -> Self { 578 ) -> Self {
@@ -581,9 +581,9 @@ impl<'d> Spi<'d, Async> {
581 new_pin!(sck, config.sck_af()), 581 new_pin!(sck, config.sck_af()),
582 None, 582 None,
583 new_pin!(miso, AfType::input(config.miso_pull)), 583 new_pin!(miso, AfType::input(config.miso_pull)),
584 #[cfg(any(spi_v1, spi_f1, spi_v2))] 584 #[cfg(any(spi_v1, spi_v2, spi_v3))]
585 new_dma!(tx_dma), 585 new_dma!(tx_dma),
586 #[cfg(any(spi_v3, spi_v4, spi_v5))] 586 #[cfg(any(spi_v4, spi_v5, spi_v6))]
587 None, 587 None,
588 new_dma!(rx_dma), 588 new_dma!(rx_dma),
589 config, 589 config,
@@ -677,7 +677,7 @@ impl<'d> Spi<'d, Async> {
677 self.info.regs.cr1().modify(|w| { 677 self.info.regs.cr1().modify(|w| {
678 w.set_spe(true); 678 w.set_spe(true);
679 }); 679 });
680 #[cfg(any(spi_v3, spi_v4, spi_v5))] 680 #[cfg(any(spi_v4, spi_v5, spi_v6))]
681 self.info.regs.cr1().modify(|w| { 681 self.info.regs.cr1().modify(|w| {
682 w.set_cstart(true); 682 w.set_cstart(true);
683 }); 683 });
@@ -690,7 +690,7 @@ impl<'d> Spi<'d, Async> {
690 } 690 }
691 691
692 /// SPI read, using DMA. 692 /// SPI read, using DMA.
693 #[cfg(any(spi_v3, spi_v4, spi_v5))] 693 #[cfg(any(spi_v4, spi_v5, spi_v6))]
694 pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> { 694 pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> {
695 if data.is_empty() { 695 if data.is_empty() {
696 return Ok(()); 696 return Ok(());
@@ -710,7 +710,7 @@ impl<'d> Spi<'d, Async> {
710 prev 710 prev
711 }); 711 });
712 712
713 #[cfg(spi_v3)] 713 #[cfg(spi_v4)]
714 let i2scfg = regs.i2scfgr().modify(|w| { 714 let i2scfg = regs.i2scfgr().modify(|w| {
715 w.i2smod().then(|| { 715 w.i2smod().then(|| {
716 let prev = w.i2scfg(); 716 let prev = w.i2scfg();
@@ -766,7 +766,7 @@ impl<'d> Spi<'d, Async> {
766 w.set_tsize(0); 766 w.set_tsize(0);
767 }); 767 });
768 768
769 #[cfg(spi_v3)] 769 #[cfg(spi_v4)]
770 if let Some(i2scfg) = i2scfg { 770 if let Some(i2scfg) = i2scfg {
771 regs.i2scfgr().modify(|w| { 771 regs.i2scfgr().modify(|w| {
772 w.set_i2scfg(i2scfg); 772 w.set_i2scfg(i2scfg);
@@ -777,7 +777,7 @@ impl<'d> Spi<'d, Async> {
777 } 777 }
778 778
779 /// SPI read, using DMA. 779 /// SPI read, using DMA.
780 #[cfg(any(spi_v1, spi_f1, spi_v2))] 780 #[cfg(any(spi_v1, spi_v2, spi_v3))]
781 pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> { 781 pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error> {
782 if data.is_empty() { 782 if data.is_empty() {
783 return Ok(()); 783 return Ok(());
@@ -790,7 +790,7 @@ impl<'d> Spi<'d, Async> {
790 self.set_word_size(W::CONFIG); 790 self.set_word_size(W::CONFIG);
791 791
792 // SPIv3 clears rxfifo on SPE=0 792 // SPIv3 clears rxfifo on SPE=0
793 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 793 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
794 flush_rx_fifo(self.info.regs); 794 flush_rx_fifo(self.info.regs);
795 795
796 set_rxdmaen(self.info.regs, true); 796 set_rxdmaen(self.info.regs, true);
@@ -813,7 +813,7 @@ impl<'d> Spi<'d, Async> {
813 self.info.regs.cr1().modify(|w| { 813 self.info.regs.cr1().modify(|w| {
814 w.set_spe(true); 814 w.set_spe(true);
815 }); 815 });
816 #[cfg(any(spi_v3, spi_v4, spi_v5))] 816 #[cfg(any(spi_v4, spi_v5, spi_v6))]
817 self.info.regs.cr1().modify(|w| { 817 self.info.regs.cr1().modify(|w| {
818 w.set_cstart(true); 818 w.set_cstart(true);
819 }); 819 });
@@ -838,7 +838,7 @@ impl<'d> Spi<'d, Async> {
838 self.set_word_size(W::CONFIG); 838 self.set_word_size(W::CONFIG);
839 839
840 // SPIv3 clears rxfifo on SPE=0 840 // SPIv3 clears rxfifo on SPE=0
841 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 841 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
842 flush_rx_fifo(self.info.regs); 842 flush_rx_fifo(self.info.regs);
843 843
844 set_rxdmaen(self.info.regs, true); 844 set_rxdmaen(self.info.regs, true);
@@ -858,7 +858,7 @@ impl<'d> Spi<'d, Async> {
858 self.info.regs.cr1().modify(|w| { 858 self.info.regs.cr1().modify(|w| {
859 w.set_spe(true); 859 w.set_spe(true);
860 }); 860 });
861 #[cfg(any(spi_v3, spi_v4, spi_v5))] 861 #[cfg(any(spi_v4, spi_v5, spi_v6))]
862 self.info.regs.cr1().modify(|w| { 862 self.info.regs.cr1().modify(|w| {
863 w.set_cstart(true); 863 w.set_cstart(true);
864 }); 864 });
@@ -898,9 +898,9 @@ impl<'d, M: PeriMode> Drop for Spi<'d, M> {
898 } 898 }
899} 899}
900 900
901#[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 901#[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
902use vals::Br; 902use vals::Br;
903#[cfg(any(spi_v3, spi_v4, spi_v5))] 903#[cfg(any(spi_v4, spi_v5, spi_v6))]
904use vals::Mbr as Br; 904use vals::Mbr as Br;
905 905
906fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br { 906fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br {
@@ -941,21 +941,21 @@ pub(crate) trait RegsExt {
941 941
942impl RegsExt for Regs { 942impl RegsExt for Regs {
943 fn tx_ptr<W>(&self) -> *mut W { 943 fn tx_ptr<W>(&self) -> *mut W {
944 #[cfg(any(spi_v1, spi_f1))] 944 #[cfg(any(spi_v1, spi_v2))]
945 let dr = self.dr(); 945 let dr = self.dr();
946 #[cfg(spi_v2)] 946 #[cfg(spi_v3)]
947 let dr = self.dr16(); 947 let dr = self.dr16();
948 #[cfg(any(spi_v3, spi_v4, spi_v5))] 948 #[cfg(any(spi_v4, spi_v5, spi_v6))]
949 let dr = self.txdr32(); 949 let dr = self.txdr32();
950 dr.as_ptr() as *mut W 950 dr.as_ptr() as *mut W
951 } 951 }
952 952
953 fn rx_ptr<W>(&self) -> *mut W { 953 fn rx_ptr<W>(&self) -> *mut W {
954 #[cfg(any(spi_v1, spi_f1))] 954 #[cfg(any(spi_v1, spi_v2))]
955 let dr = self.dr(); 955 let dr = self.dr();
956 #[cfg(spi_v2)] 956 #[cfg(spi_v3)]
957 let dr = self.dr16(); 957 let dr = self.dr16();
958 #[cfg(any(spi_v3, spi_v4, spi_v5))] 958 #[cfg(any(spi_v4, spi_v5, spi_v6))]
959 let dr = self.rxdr32(); 959 let dr = self.rxdr32();
960 dr.as_ptr() as *mut W 960 dr.as_ptr() as *mut W
961 } 961 }
@@ -965,22 +965,22 @@ fn check_error_flags(sr: regs::Sr, ovr: bool) -> Result<(), Error> {
965 if sr.ovr() && ovr { 965 if sr.ovr() && ovr {
966 return Err(Error::Overrun); 966 return Err(Error::Overrun);
967 } 967 }
968 #[cfg(not(any(spi_f1, spi_v3, spi_v4, spi_v5)))] 968 #[cfg(not(any(spi_v1, spi_v4, spi_v5, spi_v6)))]
969 if sr.fre() { 969 if sr.fre() {
970 return Err(Error::Framing); 970 return Err(Error::Framing);
971 } 971 }
972 #[cfg(any(spi_v3, spi_v4, spi_v5))] 972 #[cfg(any(spi_v4, spi_v5, spi_v6))]
973 if sr.tifre() { 973 if sr.tifre() {
974 return Err(Error::Framing); 974 return Err(Error::Framing);
975 } 975 }
976 if sr.modf() { 976 if sr.modf() {
977 return Err(Error::ModeFault); 977 return Err(Error::ModeFault);
978 } 978 }
979 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 979 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
980 if sr.crcerr() { 980 if sr.crcerr() {
981 return Err(Error::Crc); 981 return Err(Error::Crc);
982 } 982 }
983 #[cfg(any(spi_v3, spi_v4, spi_v5))] 983 #[cfg(any(spi_v4, spi_v5, spi_v6))]
984 if sr.crce() { 984 if sr.crce() {
985 return Err(Error::Crc); 985 return Err(Error::Crc);
986 } 986 }
@@ -994,11 +994,11 @@ fn spin_until_tx_ready(regs: Regs, ovr: bool) -> Result<(), Error> {
994 994
995 check_error_flags(sr, ovr)?; 995 check_error_flags(sr, ovr)?;
996 996
997 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 997 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
998 if sr.txe() { 998 if sr.txe() {
999 return Ok(()); 999 return Ok(());
1000 } 1000 }
1001 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1001 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1002 if sr.txp() { 1002 if sr.txp() {
1003 return Ok(()); 1003 return Ok(());
1004 } 1004 }
@@ -1011,11 +1011,11 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> {
1011 1011
1012 check_error_flags(sr, true)?; 1012 check_error_flags(sr, true)?;
1013 1013
1014 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1014 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1015 if sr.rxne() { 1015 if sr.rxne() {
1016 return Ok(()); 1016 return Ok(());
1017 } 1017 }
1018 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1018 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1019 if sr.rxp() { 1019 if sr.rxp() {
1020 return Ok(()); 1020 return Ok(());
1021 } 1021 }
@@ -1023,46 +1023,46 @@ fn spin_until_rx_ready(regs: Regs) -> Result<(), Error> {
1023} 1023}
1024 1024
1025pub(crate) fn flush_rx_fifo(regs: Regs) { 1025pub(crate) fn flush_rx_fifo(regs: Regs) {
1026 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1026 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1027 while regs.sr().read().rxne() { 1027 while regs.sr().read().rxne() {
1028 #[cfg(not(spi_v2))] 1028 #[cfg(not(spi_v3))]
1029 let _ = regs.dr().read(); 1029 let _ = regs.dr().read();
1030 #[cfg(spi_v2)] 1030 #[cfg(spi_v3)]
1031 let _ = regs.dr16().read(); 1031 let _ = regs.dr16().read();
1032 } 1032 }
1033 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1033 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1034 while regs.sr().read().rxp() { 1034 while regs.sr().read().rxp() {
1035 let _ = regs.rxdr32().read(); 1035 let _ = regs.rxdr32().read();
1036 } 1036 }
1037} 1037}
1038 1038
1039pub(crate) fn set_txdmaen(regs: Regs, val: bool) { 1039pub(crate) fn set_txdmaen(regs: Regs, val: bool) {
1040 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1040 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1041 regs.cr2().modify(|reg| { 1041 regs.cr2().modify(|reg| {
1042 reg.set_txdmaen(val); 1042 reg.set_txdmaen(val);
1043 }); 1043 });
1044 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1044 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1045 regs.cfg1().modify(|reg| { 1045 regs.cfg1().modify(|reg| {
1046 reg.set_txdmaen(val); 1046 reg.set_txdmaen(val);
1047 }); 1047 });
1048} 1048}
1049 1049
1050pub(crate) fn set_rxdmaen(regs: Regs, val: bool) { 1050pub(crate) fn set_rxdmaen(regs: Regs, val: bool) {
1051 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1051 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1052 regs.cr2().modify(|reg| { 1052 regs.cr2().modify(|reg| {
1053 reg.set_rxdmaen(val); 1053 reg.set_rxdmaen(val);
1054 }); 1054 });
1055 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1055 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1056 regs.cfg1().modify(|reg| { 1056 regs.cfg1().modify(|reg| {
1057 reg.set_rxdmaen(val); 1057 reg.set_rxdmaen(val);
1058 }); 1058 });
1059} 1059}
1060 1060
1061fn finish_dma(regs: Regs) { 1061fn finish_dma(regs: Regs) {
1062 #[cfg(spi_v2)] 1062 #[cfg(spi_v3)]
1063 while regs.sr().read().ftlvl().to_bits() > 0 {} 1063 while regs.sr().read().ftlvl().to_bits() > 0 {}
1064 1064
1065 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1065 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1066 { 1066 {
1067 if regs.cr2().read().tsize() == 0 { 1067 if regs.cr2().read().tsize() == 0 {
1068 while !regs.sr().read().txc() {} 1068 while !regs.sr().read().txc() {}
@@ -1070,7 +1070,7 @@ fn finish_dma(regs: Regs) {
1070 while !regs.sr().read().eot() {} 1070 while !regs.sr().read().eot() {}
1071 } 1071 }
1072 } 1072 }
1073 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1073 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1074 while regs.sr().read().bsy() {} 1074 while regs.sr().read().bsy() {}
1075 1075
1076 // Disable the spi peripheral 1076 // Disable the spi peripheral
@@ -1080,12 +1080,12 @@ fn finish_dma(regs: Regs) {
1080 1080
1081 // The peripheral automatically disables the DMA stream on completion without error, 1081 // The peripheral automatically disables the DMA stream on completion without error,
1082 // but it does not clear the RXDMAEN/TXDMAEN flag in CR2. 1082 // but it does not clear the RXDMAEN/TXDMAEN flag in CR2.
1083 #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] 1083 #[cfg(not(any(spi_v4, spi_v5, spi_v6)))]
1084 regs.cr2().modify(|reg| { 1084 regs.cr2().modify(|reg| {
1085 reg.set_txdmaen(false); 1085 reg.set_txdmaen(false);
1086 reg.set_rxdmaen(false); 1086 reg.set_rxdmaen(false);
1087 }); 1087 });
1088 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1088 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1089 regs.cfg1().modify(|reg| { 1089 regs.cfg1().modify(|reg| {
1090 reg.set_txdmaen(false); 1090 reg.set_txdmaen(false);
1091 reg.set_rxdmaen(false); 1091 reg.set_rxdmaen(false);
@@ -1098,7 +1098,7 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> {
1098 unsafe { 1098 unsafe {
1099 ptr::write_volatile(regs.tx_ptr(), tx_word); 1099 ptr::write_volatile(regs.tx_ptr(), tx_word);
1100 1100
1101 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1101 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1102 regs.cr1().modify(|reg| reg.set_cstart(true)); 1102 regs.cr1().modify(|reg| reg.set_cstart(true));
1103 } 1103 }
1104 1104
@@ -1117,7 +1117,7 @@ fn write_word<W: Word>(regs: Regs, tx_word: W) -> Result<(), Error> {
1117 unsafe { 1117 unsafe {
1118 ptr::write_volatile(regs.tx_ptr(), tx_word); 1118 ptr::write_volatile(regs.tx_ptr(), tx_word);
1119 1119
1120 #[cfg(any(spi_v3, spi_v4, spi_v5))] 1120 #[cfg(any(spi_v4, spi_v5, spi_v6))]
1121 regs.cr1().modify(|reg| reg.set_cstart(true)); 1121 regs.cr1().modify(|reg| reg.set_cstart(true));
1122 } 1122 }
1123 Ok(()) 1123 Ok(())
@@ -1225,7 +1225,7 @@ macro_rules! impl_word {
1225 }; 1225 };
1226} 1226}
1227 1227
1228#[cfg(any(spi_v1, spi_f1))] 1228#[cfg(any(spi_v1, spi_v2))]
1229mod word_impl { 1229mod word_impl {
1230 use super::*; 1230 use super::*;
1231 1231
@@ -1235,7 +1235,7 @@ mod word_impl {
1235 impl_word!(u16, vals::Dff::BITS16); 1235 impl_word!(u16, vals::Dff::BITS16);
1236} 1236}
1237 1237
1238#[cfg(spi_v2)] 1238#[cfg(spi_v3)]
1239mod word_impl { 1239mod word_impl {
1240 use super::*; 1240 use super::*;
1241 1241
@@ -1256,7 +1256,7 @@ mod word_impl {
1256 impl_word!(u16, (vals::Ds::BITS16, vals::Frxth::HALF)); 1256 impl_word!(u16, (vals::Ds::BITS16, vals::Frxth::HALF));
1257} 1257}
1258 1258
1259#[cfg(any(spi_v3, spi_v4, spi_v5))] 1259#[cfg(any(spi_v4, spi_v5, spi_v6))]
1260mod word_impl { 1260mod word_impl {
1261 use super::*; 1261 use super::*;
1262 1262