diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-01 00:05:20 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 16:01:29 +0200 |
| commit | 683ca6595ff7f4c6f0e70e90d3cdeab13d0b1c07 (patch) | |
| tree | 7c2d714f4ae66d12e66742f7b316b14d5451514f /embassy-stm32/src/spi | |
| parent | 90d403fd0a33ac7a3cde4fe9c417b5976b924020 (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.rs | 134 |
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)))] |
| 902 | use vals::Br; | 902 | use vals::Br; |
| 903 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 903 | #[cfg(any(spi_v4, spi_v5, spi_v6))] |
| 904 | use vals::Mbr as Br; | 904 | use vals::Mbr as Br; |
| 905 | 905 | ||
| 906 | fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br { | 906 | fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br { |
| @@ -941,21 +941,21 @@ pub(crate) trait RegsExt { | |||
| 941 | 941 | ||
| 942 | impl RegsExt for Regs { | 942 | impl 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 | ||
| 1025 | pub(crate) fn flush_rx_fifo(regs: Regs) { | 1025 | pub(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 | ||
| 1039 | pub(crate) fn set_txdmaen(regs: Regs, val: bool) { | 1039 | pub(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 | ||
| 1050 | pub(crate) fn set_rxdmaen(regs: Regs, val: bool) { | 1050 | pub(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 | ||
| 1061 | fn finish_dma(regs: Regs) { | 1061 | fn 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))] |
| 1229 | mod word_impl { | 1229 | mod 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)] |
| 1239 | mod word_impl { | 1239 | mod 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))] |
| 1260 | mod word_impl { | 1260 | mod word_impl { |
| 1261 | use super::*; | 1261 | use super::*; |
| 1262 | 1262 | ||
