aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-14 22:20:52 +0000
committerGitHub <[email protected]>2022-03-14 22:20:52 +0000
commit064170fce0494f51e91163aa4ec9e1009c7f6a62 (patch)
tree20b00fe176c4218a1f87cdde212ea3dd4ba0b3ce
parent3ae0923d453d4f7f38326d136aa00246ae63c53d (diff)
parent6e00c5885459927ab79aa31bf9b0c1564d70c35b (diff)
Merge #662
662: stm32: Finish unifying spi versions r=Dirbaio a=GrantM11235 Notable changes: - `set_word_size` is always called before disabling SPE. This is important because `set_word_size` may or may not re-enable SPE. - The rx buffer is flushed on v1 as well. I don't know if this is required. - All functions are now generic over word size Co-authored-by: Grant Miller <[email protected]>
-rw-r--r--embassy-stm32/src/spi/mod.rs279
-rw-r--r--embassy-stm32/src/spi/v1.rs138
-rw-r--r--embassy-stm32/src/spi/v2.rs148
-rw-r--r--embassy-stm32/src/spi/v3.rs157
4 files changed, 212 insertions, 510 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 3352b24d2..3b39f0fd2 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -4,11 +4,13 @@ use core::marker::PhantomData;
4use core::ptr; 4use core::ptr;
5use embassy::util::Unborrow; 5use embassy::util::Unborrow;
6use embassy_hal_common::unborrow; 6use embassy_hal_common::unborrow;
7use futures::future::join;
7 8
8use self::sealed::WordSize; 9use self::sealed::WordSize;
9use crate::dma::NoDma; 10use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, NoDma, Transfer};
10use crate::gpio::sealed::{AFType, Pin as _}; 11use crate::gpio::sealed::{AFType, Pin as _};
11use crate::gpio::AnyPin; 12use crate::gpio::AnyPin;
13use crate::pac::spi::Spi as Regs;
12use crate::pac::spi::{regs, vals}; 14use crate::pac::spi::{regs, vals};
13use crate::peripherals; 15use crate::peripherals;
14use crate::rcc::RccPeripheral; 16use crate::rcc::RccPeripheral;
@@ -16,14 +18,6 @@ use crate::time::Hertz;
16 18
17pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 19pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
18 20
19#[cfg_attr(spi_v1, path = "v1.rs")]
20#[cfg_attr(spi_f1, path = "v1.rs")]
21#[cfg_attr(spi_v2, path = "v2.rs")]
22#[cfg_attr(spi_v3, path = "v3.rs")]
23mod _version;
24
25type Regs = &'static crate::pac::spi::Spi;
26
27#[derive(Debug)] 21#[derive(Debug)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))] 22#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum Error { 23pub enum Error {
@@ -224,10 +218,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
224 218
225 #[cfg(any(spi_v1, spi_f1))] 219 #[cfg(any(spi_v1, spi_f1))]
226 unsafe { 220 unsafe {
227 T::regs().cr2().modify(|w| { 221 T::REGS.cr2().modify(|w| {
228 w.set_ssoe(false); 222 w.set_ssoe(false);
229 }); 223 });
230 T::regs().cr1().modify(|w| { 224 T::REGS.cr1().modify(|w| {
231 w.set_cpha(cpha); 225 w.set_cpha(cpha);
232 w.set_cpol(cpol); 226 w.set_cpol(cpol);
233 227
@@ -247,12 +241,12 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
247 } 241 }
248 #[cfg(spi_v2)] 242 #[cfg(spi_v2)]
249 unsafe { 243 unsafe {
250 T::regs().cr2().modify(|w| { 244 T::REGS.cr2().modify(|w| {
251 w.set_frxth(WordSize::EightBit.frxth()); 245 w.set_frxth(WordSize::EightBit.frxth());
252 w.set_ds(WordSize::EightBit.ds()); 246 w.set_ds(WordSize::EightBit.ds());
253 w.set_ssoe(false); 247 w.set_ssoe(false);
254 }); 248 });
255 T::regs().cr1().modify(|w| { 249 T::REGS.cr1().modify(|w| {
256 w.set_cpha(cpha); 250 w.set_cpha(cpha);
257 w.set_cpol(cpol); 251 w.set_cpol(cpol);
258 252
@@ -268,8 +262,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
268 } 262 }
269 #[cfg(spi_v3)] 263 #[cfg(spi_v3)]
270 unsafe { 264 unsafe {
271 T::regs().ifcr().write(|w| w.0 = 0xffff_ffff); 265 T::REGS.ifcr().write(|w| w.0 = 0xffff_ffff);
272 T::regs().cfg2().modify(|w| { 266 T::REGS.cfg2().modify(|w| {
273 //w.set_ssoe(true); 267 //w.set_ssoe(true);
274 w.set_ssoe(false); 268 w.set_ssoe(false);
275 w.set_cpha(cpha); 269 w.set_cpha(cpha);
@@ -284,16 +278,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
284 w.set_afcntr(vals::Afcntr::CONTROLLED); 278 w.set_afcntr(vals::Afcntr::CONTROLLED);
285 w.set_ssiop(vals::Ssiop::ACTIVEHIGH); 279 w.set_ssiop(vals::Ssiop::ACTIVEHIGH);
286 }); 280 });
287 T::regs().cfg1().modify(|w| { 281 T::REGS.cfg1().modify(|w| {
288 w.set_crcen(false); 282 w.set_crcen(false);
289 w.set_mbr(br); 283 w.set_mbr(br);
290 w.set_dsize(WordSize::EightBit.dsize()); 284 w.set_dsize(WordSize::EightBit.dsize());
291 }); 285 });
292 T::regs().cr2().modify(|w| { 286 T::REGS.cr2().modify(|w| {
293 w.set_tsize(0); 287 w.set_tsize(0);
294 w.set_tser(0); 288 w.set_tser(0);
295 }); 289 });
296 T::regs().cr1().modify(|w| { 290 T::REGS.cr1().modify(|w| {
297 w.set_ssi(false); 291 w.set_ssi(false);
298 w.set_spe(true); 292 w.set_spe(true);
299 }); 293 });
@@ -319,7 +313,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
319 313
320 #[cfg(any(spi_v1, spi_f1, spi_v2))] 314 #[cfg(any(spi_v1, spi_f1, spi_v2))]
321 unsafe { 315 unsafe {
322 T::regs().cr1().modify(|w| { 316 T::REGS.cr1().modify(|w| {
323 w.set_cpha(cpha); 317 w.set_cpha(cpha);
324 w.set_cpol(cpol); 318 w.set_cpol(cpol);
325 w.set_lsbfirst(lsbfirst); 319 w.set_lsbfirst(lsbfirst);
@@ -328,7 +322,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
328 322
329 #[cfg(spi_v3)] 323 #[cfg(spi_v3)]
330 unsafe { 324 unsafe {
331 T::regs().cfg2().modify(|w| { 325 T::REGS.cfg2().modify(|w| {
332 w.set_cpha(cpha); 326 w.set_cpha(cpha);
333 w.set_cpol(cpol); 327 w.set_cpol(cpol);
334 w.set_lsbfirst(lsbfirst); 328 w.set_lsbfirst(lsbfirst);
@@ -338,9 +332,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
338 332
339 pub fn get_current_config(&self) -> Config { 333 pub fn get_current_config(&self) -> Config {
340 #[cfg(any(spi_v1, spi_f1, spi_v2))] 334 #[cfg(any(spi_v1, spi_f1, spi_v2))]
341 let cfg = unsafe { T::regs().cr1().read() }; 335 let cfg = unsafe { T::REGS.cr1().read() };
342 #[cfg(spi_v3)] 336 #[cfg(spi_v3)]
343 let cfg = unsafe { T::regs().cfg2().read() }; 337 let cfg = unsafe { T::REGS.cfg2().read() };
344 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { 338 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW {
345 Polarity::IdleLow 339 Polarity::IdleLow
346 } else { 340 } else {
@@ -371,40 +365,40 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
371 365
372 #[cfg(any(spi_v1, spi_f1))] 366 #[cfg(any(spi_v1, spi_f1))]
373 unsafe { 367 unsafe {
374 T::regs().cr1().modify(|reg| { 368 T::REGS.cr1().modify(|reg| {
375 reg.set_spe(false); 369 reg.set_spe(false);
376 reg.set_dff(word_size.dff()) 370 reg.set_dff(word_size.dff())
377 }); 371 });
378 T::regs().cr1().modify(|reg| { 372 T::REGS.cr1().modify(|reg| {
379 reg.set_spe(true); 373 reg.set_spe(true);
380 }); 374 });
381 } 375 }
382 #[cfg(spi_v2)] 376 #[cfg(spi_v2)]
383 unsafe { 377 unsafe {
384 T::regs().cr1().modify(|w| { 378 T::REGS.cr1().modify(|w| {
385 w.set_spe(false); 379 w.set_spe(false);
386 }); 380 });
387 T::regs().cr2().modify(|w| { 381 T::REGS.cr2().modify(|w| {
388 w.set_frxth(word_size.frxth()); 382 w.set_frxth(word_size.frxth());
389 w.set_ds(word_size.ds()); 383 w.set_ds(word_size.ds());
390 }); 384 });
391 T::regs().cr1().modify(|w| { 385 T::REGS.cr1().modify(|w| {
392 w.set_spe(true); 386 w.set_spe(true);
393 }); 387 });
394 } 388 }
395 #[cfg(spi_v3)] 389 #[cfg(spi_v3)]
396 unsafe { 390 unsafe {
397 T::regs().cr1().modify(|w| { 391 T::REGS.cr1().modify(|w| {
398 w.set_csusp(true); 392 w.set_csusp(true);
399 }); 393 });
400 while T::regs().sr().read().eot() {} 394 while T::REGS.sr().read().eot() {}
401 T::regs().cr1().modify(|w| { 395 T::REGS.cr1().modify(|w| {
402 w.set_spe(false); 396 w.set_spe(false);
403 }); 397 });
404 T::regs().cfg1().modify(|w| { 398 T::REGS.cfg1().modify(|w| {
405 w.set_dsize(word_size.dsize()); 399 w.set_dsize(word_size.dsize());
406 }); 400 });
407 T::regs().cr1().modify(|w| { 401 T::REGS.cr1().modify(|w| {
408 w.set_csusp(false); 402 w.set_csusp(false);
409 w.set_spe(true); 403 w.set_spe(true);
410 }); 404 });
@@ -413,64 +407,172 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
413 self.current_word_size = word_size; 407 self.current_word_size = word_size;
414 } 408 }
415 409
416 pub async fn write(&mut self, data: &[u8]) -> Result<(), Error> 410 pub async fn write<W: Word>(&mut self, data: &[W]) -> Result<(), Error>
417 where 411 where
418 Tx: TxDma<T>, 412 Tx: TxDma<T>,
419 { 413 {
420 self.write_dma_u8(data).await 414 self.set_word_size(W::WORDSIZE);
415 unsafe {
416 T::REGS.cr1().modify(|w| {
417 w.set_spe(false);
418 });
419 }
420
421 // TODO: This is unnecessary in some versions because
422 // clearing SPE automatically clears the fifos
423 flush_rx_fifo(T::REGS);
424
425 let tx_request = self.txdma.request();
426 let tx_dst = T::REGS.tx_ptr();
427 unsafe { self.txdma.start_write(tx_request, data, tx_dst) }
428 let tx_f = Transfer::new(&mut self.txdma);
429
430 unsafe {
431 set_txdmaen(T::REGS, true);
432 T::REGS.cr1().modify(|w| {
433 w.set_spe(true);
434 });
435 #[cfg(spi_v3)]
436 T::REGS.cr1().modify(|w| {
437 w.set_cstart(true);
438 });
439 }
440
441 tx_f.await;
442
443 finish_dma(T::REGS);
444
445 Ok(())
421 } 446 }
422 447
423 pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> 448 pub async fn read<W: Word>(&mut self, data: &mut [W]) -> Result<(), Error>
424 where 449 where
425 Tx: TxDma<T>, 450 Tx: TxDma<T>,
426 Rx: RxDma<T>, 451 Rx: RxDma<T>,
427 { 452 {
428 self.read_dma_u8(data).await 453 self.set_word_size(W::WORDSIZE);
454 unsafe {
455 T::REGS.cr1().modify(|w| {
456 w.set_spe(false);
457 });
458 set_rxdmaen(T::REGS, true);
459 }
460
461 let (_, clock_byte_count) = slice_ptr_parts_mut(data);
462
463 let rx_request = self.rxdma.request();
464 let rx_src = T::REGS.rx_ptr();
465 unsafe { self.rxdma.start_read(rx_request, rx_src, data) };
466 let rx_f = Transfer::new(&mut self.rxdma);
467
468 let tx_request = self.txdma.request();
469 let tx_dst = T::REGS.tx_ptr();
470 let clock_byte = 0x00u8;
471 let tx_f = crate::dma::write_repeated(
472 &mut self.txdma,
473 tx_request,
474 clock_byte,
475 clock_byte_count,
476 tx_dst,
477 );
478
479 unsafe {
480 set_txdmaen(T::REGS, true);
481 T::REGS.cr1().modify(|w| {
482 w.set_spe(true);
483 });
484 #[cfg(spi_v3)]
485 T::REGS.cr1().modify(|w| {
486 w.set_cstart(true);
487 });
488 }
489
490 join(tx_f, rx_f).await;
491
492 finish_dma(T::REGS);
493
494 Ok(())
429 } 495 }
430 496
431 pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> 497 pub async fn transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error>
432 where 498 where
433 Tx: TxDma<T>, 499 Tx: TxDma<T>,
434 Rx: RxDma<T>, 500 Rx: RxDma<T>,
435 { 501 {
436 self.transfer_dma_u8(read, write).await 502 let (_, rx_len) = slice_ptr_parts(read);
503 let (_, tx_len) = slice_ptr_parts(write);
504 assert_eq!(rx_len, tx_len);
505
506 self.set_word_size(W::WORDSIZE);
507 unsafe {
508 T::REGS.cr1().modify(|w| {
509 w.set_spe(false);
510 });
511 set_rxdmaen(T::REGS, true);
512 }
513
514 // TODO: This is unnecessary in some versions because
515 // clearing SPE automatically clears the fifos
516 flush_rx_fifo(T::REGS);
517
518 let rx_request = self.rxdma.request();
519 let rx_src = T::REGS.rx_ptr();
520 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
521 let rx_f = Transfer::new(&mut self.rxdma);
522
523 let tx_request = self.txdma.request();
524 let tx_dst = T::REGS.tx_ptr();
525 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
526 let tx_f = Transfer::new(&mut self.txdma);
527
528 unsafe {
529 set_txdmaen(T::REGS, true);
530 T::REGS.cr1().modify(|w| {
531 w.set_spe(true);
532 });
533 #[cfg(spi_v3)]
534 T::REGS.cr1().modify(|w| {
535 w.set_cstart(true);
536 });
537 }
538
539 join(tx_f, rx_f).await;
540
541 finish_dma(T::REGS);
542
543 Ok(())
437 } 544 }
438 545
439 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { 546 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> {
440 self.set_word_size(W::WORDSIZE); 547 self.set_word_size(W::WORDSIZE);
441 let regs = T::regs();
442 for word in words.iter() { 548 for word in words.iter() {
443 let _ = transfer_word(regs, *word)?; 549 let _ = transfer_word(T::REGS, *word)?;
444 } 550 }
445 Ok(()) 551 Ok(())
446 } 552 }
447 553
448 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 554 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
449 self.set_word_size(W::WORDSIZE); 555 self.set_word_size(W::WORDSIZE);
450 let regs = T::regs();
451 for word in words.iter_mut() { 556 for word in words.iter_mut() {
452 *word = transfer_word(regs, W::default())?; 557 *word = transfer_word(T::REGS, W::default())?;
453 } 558 }
454 Ok(()) 559 Ok(())
455 } 560 }
456 561
457 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 562 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
458 self.set_word_size(W::WORDSIZE); 563 self.set_word_size(W::WORDSIZE);
459 let regs = T::regs();
460 for word in words.iter_mut() { 564 for word in words.iter_mut() {
461 *word = transfer_word(regs, *word)?; 565 *word = transfer_word(T::REGS, *word)?;
462 } 566 }
463 Ok(()) 567 Ok(())
464 } 568 }
465 569
466 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { 570 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
467 self.set_word_size(W::WORDSIZE); 571 self.set_word_size(W::WORDSIZE);
468 let regs = T::regs();
469
470 let len = read.len().max(write.len()); 572 let len = read.len().max(write.len());
471 for i in 0..len { 573 for i in 0..len {
472 let wb = write.get(i).copied().unwrap_or_default(); 574 let wb = write.get(i).copied().unwrap_or_default();
473 let rb = transfer_word(regs, wb)?; 575 let rb = transfer_word(T::REGS, wb)?;
474 if let Some(r) = read.get_mut(i) { 576 if let Some(r) = read.get_mut(i) {
475 *r = rb; 577 *r = rb;
476 } 578 }
@@ -515,7 +617,7 @@ trait RegsExt {
515 fn rx_ptr<W>(&self) -> *mut W; 617 fn rx_ptr<W>(&self) -> *mut W;
516} 618}
517 619
518impl RegsExt for crate::pac::spi::Spi { 620impl RegsExt for Regs {
519 fn tx_ptr<W>(&self) -> *mut W { 621 fn tx_ptr<W>(&self) -> *mut W {
520 #[cfg(not(spi_v3))] 622 #[cfg(not(spi_v3))]
521 let dr = self.dr(); 623 let dr = self.dr();
@@ -614,6 +716,45 @@ fn spin_until_idle(regs: Regs) {
614 } 716 }
615} 717}
616 718
719fn flush_rx_fifo(regs: Regs) {
720 unsafe {
721 #[cfg(not(spi_v3))]
722 while regs.sr().read().rxne() {
723 let _ = regs.dr().read();
724 }
725 #[cfg(spi_v3)]
726 while regs.sr().read().rxp() {
727 let _ = regs.rxdr().read();
728 }
729 }
730}
731
732fn set_txdmaen(regs: Regs, val: bool) {
733 unsafe {
734 #[cfg(not(spi_v3))]
735 regs.cr2().modify(|reg| {
736 reg.set_txdmaen(val);
737 });
738 #[cfg(spi_v3)]
739 regs.cfg1().modify(|reg| {
740 reg.set_txdmaen(val);
741 });
742 }
743}
744
745fn set_rxdmaen(regs: Regs, val: bool) {
746 unsafe {
747 #[cfg(not(spi_v3))]
748 regs.cr2().modify(|reg| {
749 reg.set_rxdmaen(val);
750 });
751 #[cfg(spi_v3)]
752 regs.cfg1().modify(|reg| {
753 reg.set_rxdmaen(val);
754 });
755 }
756}
757
617fn finish_dma(regs: Regs) { 758fn finish_dma(regs: Regs) {
618 spin_until_idle(regs); 759 spin_until_idle(regs);
619 760
@@ -699,24 +840,30 @@ mod eh1 {
699 } 840 }
700 } 841 }
701 842
702 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusRead<u8> for Spi<'d, T, NoDma, NoDma> { 843 impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBusRead<W>
703 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 844 for Spi<'d, T, NoDma, NoDma>
845 {
846 fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
704 self.blocking_read(words) 847 self.blocking_read(words)
705 } 848 }
706 } 849 }
707 850
708 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBusWrite<u8> for Spi<'d, T, NoDma, NoDma> { 851 impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBusWrite<W>
709 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 852 for Spi<'d, T, NoDma, NoDma>
853 {
854 fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
710 self.blocking_write(words) 855 self.blocking_write(words)
711 } 856 }
712 } 857 }
713 858
714 impl<'d, T: Instance> embedded_hal_1::spi::blocking::SpiBus<u8> for Spi<'d, T, NoDma, NoDma> { 859 impl<'d, T: Instance, W: Word> embedded_hal_1::spi::blocking::SpiBus<W>
715 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { 860 for Spi<'d, T, NoDma, NoDma>
861 {
862 fn transfer(&mut self, read: &mut [W], write: &[W]) -> Result<(), Self::Error> {
716 self.blocking_transfer(read, write) 863 self.blocking_transfer(read, write)
717 } 864 }
718 865
719 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { 866 fn transfer_in_place(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
720 self.blocking_transfer_in_place(words) 867 self.blocking_transfer_in_place(words)
721 } 868 }
722 } 869 }
@@ -744,32 +891,32 @@ cfg_if::cfg_if! {
744 } 891 }
745 } 892 }
746 893
747 impl<'d, T: Instance, Tx: TxDma<T>, Rx> embedded_hal_async::spi::SpiBusWrite<u8> 894 impl<'d, T: Instance, Tx: TxDma<T>, Rx, W: Word> embedded_hal_async::spi::SpiBusWrite<W>
748 for Spi<'d, T, Tx, Rx> 895 for Spi<'d, T, Tx, Rx>
749 { 896 {
750 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; 897 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
751 898
752 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { 899 fn write<'a>(&'a mut self, data: &'a [W]) -> Self::WriteFuture<'a> {
753 self.write(data) 900 self.write(data)
754 } 901 }
755 } 902 }
756 903
757 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBusRead<u8> 904 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::spi::SpiBusRead<W>
758 for Spi<'d, T, Tx, Rx> 905 for Spi<'d, T, Tx, Rx>
759 { 906 {
760 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; 907 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
761 908
762 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { 909 fn read<'a>(&'a mut self, data: &'a mut [W]) -> Self::ReadFuture<'a> {
763 self.read(data) 910 self.read(data)
764 } 911 }
765 } 912 }
766 913
767 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>> embedded_hal_async::spi::SpiBus<u8> 914 impl<'d, T: Instance, Tx: TxDma<T>, Rx: RxDma<T>, W: Word> embedded_hal_async::spi::SpiBus<W>
768 for Spi<'d, T, Tx, Rx> 915 for Spi<'d, T, Tx, Rx>
769 { 916 {
770 type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; 917 type TransferFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
771 918
772 fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { 919 fn transfer<'a>(&'a mut self, rx: &'a mut [W], tx: &'a [W]) -> Self::TransferFuture<'a> {
773 self.transfer(rx, tx) 920 self.transfer(rx, tx)
774 } 921 }
775 922
@@ -777,7 +924,7 @@ cfg_if::cfg_if! {
777 924
778 fn transfer_in_place<'a>( 925 fn transfer_in_place<'a>(
779 &'a mut self, 926 &'a mut self,
780 words: &'a mut [u8], 927 words: &'a mut [W],
781 ) -> Self::TransferInPlaceFuture<'a> { 928 ) -> Self::TransferInPlaceFuture<'a> {
782 // TODO: Implement async version 929 // TODO: Implement async version
783 let result = self.blocking_transfer_in_place(words); 930 let result = self.blocking_transfer_in_place(words);
@@ -791,7 +938,7 @@ pub(crate) mod sealed {
791 use super::*; 938 use super::*;
792 939
793 pub trait Instance { 940 pub trait Instance {
794 fn regs() -> &'static crate::pac::spi::Spi; 941 const REGS: Regs;
795 } 942 }
796 943
797 pub trait Word: Copy + 'static { 944 pub trait Word: Copy + 'static {
@@ -854,7 +1001,7 @@ pub(crate) mod sealed {
854 } 1001 }
855} 1002}
856 1003
857pub trait Word: Copy + 'static + sealed::Word + Default {} 1004pub trait Word: Copy + 'static + sealed::Word + Default + crate::dma::Word {}
858 1005
859impl Word for u8 {} 1006impl Word for u8 {}
860impl Word for u16 {} 1007impl Word for u16 {}
@@ -869,9 +1016,7 @@ dma_trait!(TxDma, Instance);
869foreach_peripheral!( 1016foreach_peripheral!(
870 (spi, $inst:ident) => { 1017 (spi, $inst:ident) => {
871 impl sealed::Instance for peripherals::$inst { 1018 impl sealed::Instance for peripherals::$inst {
872 fn regs() -> &'static crate::pac::spi::Spi { 1019 const REGS: Regs = crate::pac::$inst;
873 &crate::pac::$inst
874 }
875 } 1020 }
876 1021
877 impl Instance for peripherals::$inst {} 1022 impl Instance for peripherals::$inst {}
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
deleted file mode 100644
index 5dd4dc2db..000000000
--- a/embassy-stm32/src/spi/v1.rs
+++ /dev/null
@@ -1,138 +0,0 @@
1#![macro_use]
2
3use futures::future::join;
4
5use super::*;
6use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
7
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where
11 Tx: TxDma<T>,
12 {
13 unsafe {
14 T::regs().cr1().modify(|w| {
15 w.set_spe(false);
16 });
17 }
18 self.set_word_size(WordSize::EightBit);
19
20 let tx_request = self.txdma.request();
21 let tx_dst = T::regs().tx_ptr();
22 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
23 let tx_f = Transfer::new(&mut self.txdma);
24
25 unsafe {
26 T::regs().cr2().modify(|reg| {
27 reg.set_txdmaen(true);
28 });
29 T::regs().cr1().modify(|w| {
30 w.set_spe(true);
31 });
32 }
33
34 tx_f.await;
35
36 finish_dma(T::regs());
37
38 Ok(())
39 }
40
41 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
42 where
43 Tx: TxDma<T>,
44 Rx: RxDma<T>,
45 {
46 unsafe {
47 T::regs().cr1().modify(|w| {
48 w.set_spe(false);
49 });
50 T::regs().cr2().modify(|reg| {
51 reg.set_rxdmaen(true);
52 });
53 }
54 self.set_word_size(WordSize::EightBit);
55
56 let (_, clock_byte_count) = slice_ptr_parts_mut(read);
57
58 let rx_request = self.rxdma.request();
59 let rx_src = T::regs().rx_ptr();
60 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
61 let rx_f = Transfer::new(&mut self.rxdma);
62
63 let tx_request = self.txdma.request();
64 let tx_dst = T::regs().tx_ptr();
65 let clock_byte = 0x00u8;
66 let tx_f = crate::dma::write_repeated(
67 &mut self.txdma,
68 tx_request,
69 clock_byte,
70 clock_byte_count,
71 tx_dst,
72 );
73
74 unsafe {
75 T::regs().cr2().modify(|reg| {
76 reg.set_txdmaen(true);
77 });
78 T::regs().cr1().modify(|w| {
79 w.set_spe(true);
80 });
81 }
82
83 join(tx_f, rx_f).await;
84
85 finish_dma(T::regs());
86
87 Ok(())
88 }
89
90 pub(super) async fn transfer_dma_u8(
91 &mut self,
92 read: *mut [u8],
93 write: *const [u8],
94 ) -> Result<(), Error>
95 where
96 Tx: TxDma<T>,
97 Rx: RxDma<T>,
98 {
99 let (_, rx_len) = slice_ptr_parts(read);
100 let (_, tx_len) = slice_ptr_parts(write);
101 assert_eq!(rx_len, tx_len);
102
103 unsafe {
104 T::regs().cr1().modify(|w| {
105 w.set_spe(false);
106 });
107 T::regs().cr2().modify(|reg| {
108 reg.set_rxdmaen(true);
109 });
110 }
111 self.set_word_size(WordSize::EightBit);
112
113 let rx_request = self.rxdma.request();
114 let rx_src = T::regs().rx_ptr();
115 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
116 let rx_f = Transfer::new(&mut self.rxdma);
117
118 let tx_request = self.txdma.request();
119 let tx_dst = T::regs().tx_ptr();
120 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
121 let tx_f = Transfer::new(&mut self.txdma);
122
123 unsafe {
124 T::regs().cr2().modify(|reg| {
125 reg.set_txdmaen(true);
126 });
127 T::regs().cr1().modify(|w| {
128 w.set_spe(true);
129 });
130 }
131
132 join(tx_f, rx_f).await;
133
134 finish_dma(T::regs());
135
136 Ok(())
137 }
138}
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
deleted file mode 100644
index 3820fcac1..000000000
--- a/embassy-stm32/src/spi/v2.rs
+++ /dev/null
@@ -1,148 +0,0 @@
1#![macro_use]
2
3use futures::future::join;
4
5use super::*;
6use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
7
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where
11 Tx: TxDma<T>,
12 {
13 unsafe {
14 T::regs().cr1().modify(|w| {
15 w.set_spe(false);
16 });
17
18 // Flush the read buffer to avoid errornous data from being read
19 while T::regs().sr().read().rxne() {
20 let _ = T::regs().dr().read();
21 }
22 }
23 self.set_word_size(WordSize::EightBit);
24
25 let tx_request = self.txdma.request();
26 let tx_dst = T::regs().tx_ptr();
27 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
28 let tx_f = Transfer::new(&mut self.txdma);
29
30 unsafe {
31 T::regs().cr2().modify(|reg| {
32 reg.set_txdmaen(true);
33 });
34 T::regs().cr1().modify(|w| {
35 w.set_spe(true);
36 });
37 }
38
39 tx_f.await;
40
41 finish_dma(T::regs());
42
43 Ok(())
44 }
45
46 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
47 where
48 Tx: TxDma<T>,
49 Rx: RxDma<T>,
50 {
51 unsafe {
52 T::regs().cr1().modify(|w| {
53 w.set_spe(false);
54 });
55 T::regs().cr2().modify(|reg| {
56 reg.set_rxdmaen(true);
57 });
58 }
59 self.set_word_size(WordSize::EightBit);
60
61 let (_, clock_byte_count) = slice_ptr_parts_mut(read);
62
63 let rx_request = self.rxdma.request();
64 let rx_src = T::regs().rx_ptr();
65 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
66 let rx_f = Transfer::new(&mut self.rxdma);
67
68 let tx_request = self.txdma.request();
69 let tx_dst = T::regs().tx_ptr();
70 let clock_byte = 0x00u8;
71 let tx_f = crate::dma::write_repeated(
72 &mut self.txdma,
73 tx_request,
74 clock_byte,
75 clock_byte_count,
76 tx_dst,
77 );
78
79 unsafe {
80 T::regs().cr2().modify(|reg| {
81 reg.set_txdmaen(true);
82 });
83 T::regs().cr1().modify(|w| {
84 w.set_spe(true);
85 });
86 }
87
88 join(tx_f, rx_f).await;
89
90 finish_dma(T::regs());
91
92 Ok(())
93 }
94
95 pub(super) async fn transfer_dma_u8(
96 &mut self,
97 read: *mut [u8],
98 write: *const [u8],
99 ) -> Result<(), Error>
100 where
101 Tx: TxDma<T>,
102 Rx: RxDma<T>,
103 {
104 let (_, rx_len) = slice_ptr_parts(read);
105 let (_, tx_len) = slice_ptr_parts(write);
106 assert_eq!(rx_len, tx_len);
107
108 unsafe {
109 T::regs().cr1().modify(|w| {
110 w.set_spe(false);
111 });
112 T::regs().cr2().modify(|reg| {
113 reg.set_rxdmaen(true);
114 });
115
116 // Flush the read buffer to avoid errornous data from being read
117 while T::regs().sr().read().rxne() {
118 let _ = T::regs().dr().read();
119 }
120 }
121 self.set_word_size(WordSize::EightBit);
122
123 let rx_request = self.rxdma.request();
124 let rx_src = T::regs().rx_ptr();
125 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
126 let rx_f = Transfer::new(&mut self.rxdma);
127
128 let tx_request = self.txdma.request();
129 let tx_dst = T::regs().tx_ptr();
130 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
131 let tx_f = Transfer::new(&mut self.txdma);
132
133 unsafe {
134 T::regs().cr2().modify(|reg| {
135 reg.set_txdmaen(true);
136 });
137 T::regs().cr1().modify(|w| {
138 w.set_spe(true);
139 });
140 }
141
142 join(tx_f, rx_f).await;
143
144 finish_dma(T::regs());
145
146 Ok(())
147 }
148}
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs
deleted file mode 100644
index 9e766cfdb..000000000
--- a/embassy-stm32/src/spi/v3.rs
+++ /dev/null
@@ -1,157 +0,0 @@
1#![macro_use]
2
3use futures::future::join;
4
5use super::*;
6use crate::dma::{slice_ptr_parts, slice_ptr_parts_mut, Transfer};
7
8impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
9 pub(super) async fn write_dma_u8(&mut self, write: *const [u8]) -> Result<(), Error>
10 where
11 Tx: TxDma<T>,
12 {
13 self.set_word_size(WordSize::EightBit);
14 unsafe {
15 T::regs().cr1().modify(|w| {
16 w.set_spe(false);
17 });
18
19 // Flush the read buffer to avoid errornous data from being read
20 while T::regs().sr().read().rxp() {
21 let _ = T::regs().rxdr().read();
22 }
23 }
24
25 let tx_request = self.txdma.request();
26 let tx_dst = T::regs().tx_ptr();
27 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
28 let tx_f = Transfer::new(&mut self.txdma);
29
30 unsafe {
31 T::regs().cfg1().modify(|reg| {
32 reg.set_txdmaen(true);
33 });
34 T::regs().cr1().modify(|w| {
35 w.set_spe(true);
36 });
37 T::regs().cr1().modify(|w| {
38 w.set_cstart(true);
39 });
40 }
41
42 tx_f.await;
43
44 finish_dma(T::regs());
45
46 Ok(())
47 }
48
49 pub(super) async fn read_dma_u8(&mut self, read: *mut [u8]) -> Result<(), Error>
50 where
51 Tx: TxDma<T>,
52 Rx: RxDma<T>,
53 {
54 self.set_word_size(WordSize::EightBit);
55 unsafe {
56 T::regs().cr1().modify(|w| {
57 w.set_spe(false);
58 });
59 T::regs().cfg1().modify(|reg| {
60 reg.set_rxdmaen(true);
61 });
62 }
63
64 let (_, clock_byte_count) = slice_ptr_parts_mut(read);
65
66 let rx_request = self.rxdma.request();
67 let rx_src = T::regs().rx_ptr();
68 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
69 let rx_f = Transfer::new(&mut self.rxdma);
70
71 let tx_request = self.txdma.request();
72 let tx_dst = T::regs().tx_ptr();
73 let clock_byte = 0x00u8;
74 let tx_f = crate::dma::write_repeated(
75 &mut self.txdma,
76 tx_request,
77 clock_byte,
78 clock_byte_count,
79 tx_dst,
80 );
81
82 unsafe {
83 T::regs().cfg1().modify(|reg| {
84 reg.set_txdmaen(true);
85 });
86 T::regs().cr1().modify(|w| {
87 w.set_spe(true);
88 });
89 T::regs().cr1().modify(|w| {
90 w.set_cstart(true);
91 });
92 }
93
94 join(tx_f, rx_f).await;
95
96 finish_dma(T::regs());
97
98 Ok(())
99 }
100
101 pub(super) async fn transfer_dma_u8(
102 &mut self,
103 read: *mut [u8],
104 write: *const [u8],
105 ) -> Result<(), Error>
106 where
107 Tx: TxDma<T>,
108 Rx: RxDma<T>,
109 {
110 let (_, rx_len) = slice_ptr_parts(read);
111 let (_, tx_len) = slice_ptr_parts(write);
112 assert_eq!(rx_len, tx_len);
113
114 self.set_word_size(WordSize::EightBit);
115 unsafe {
116 T::regs().cr1().modify(|w| {
117 w.set_spe(false);
118 });
119 T::regs().cfg1().modify(|reg| {
120 reg.set_rxdmaen(true);
121 });
122
123 // Flush the read buffer to avoid errornous data from being read
124 while T::regs().sr().read().rxp() {
125 let _ = T::regs().rxdr().read();
126 }
127 }
128
129 let rx_request = self.rxdma.request();
130 let rx_src = T::regs().rx_ptr();
131 unsafe { self.rxdma.start_read(rx_request, rx_src, read) };
132 let rx_f = Transfer::new(&mut self.rxdma);
133
134 let tx_request = self.txdma.request();
135 let tx_dst = T::regs().tx_ptr();
136 unsafe { self.txdma.start_write(tx_request, write, tx_dst) }
137 let tx_f = Transfer::new(&mut self.txdma);
138
139 unsafe {
140 T::regs().cfg1().modify(|reg| {
141 reg.set_txdmaen(true);
142 });
143 T::regs().cr1().modify(|w| {
144 w.set_spe(true);
145 });
146 T::regs().cr1().modify(|w| {
147 w.set_cstart(true);
148 });
149 }
150
151 join(tx_f, rx_f).await;
152
153 finish_dma(T::regs());
154
155 Ok(())
156 }
157}