aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Miller <[email protected]>2021-12-06 23:29:16 -0600
committerGrant Miller <[email protected]>2021-12-07 00:03:52 -0600
commit79baa041184d8837a26c9e4b07230b1cdd8cb5b3 (patch)
treef66884f697286ace5a4726d9e7c1fa40d8f57589
parentbf1f80afa1bde29963fb41008bb44349b5f464d7 (diff)
Implement blocking traits with a macro
-rw-r--r--embassy-stm32/src/spi/mod.rs89
1 files changed, 38 insertions, 51 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index d3d78e2a8..5d919f923 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -439,10 +439,16 @@ fn spin_until_rx_ready(regs: &'static crate::pac::spi::Spi) -> Result<(), Error>
439 } 439 }
440} 440}
441 441
442trait Word {} 442trait Word {
443 const WORDSIZE: WordSize;
444}
443 445
444impl Word for u8 {} 446impl Word for u8 {
445impl Word for u16 {} 447 const WORDSIZE: WordSize = WordSize::EightBit;
448}
449impl Word for u16 {
450 const WORDSIZE: WordSize = WordSize::SixteenBit;
451}
446 452
447fn transfer_word<W: Word>(regs: &'static crate::pac::spi::Spi, tx_word: W) -> Result<W, Error> { 453fn transfer_word<W: Word>(regs: &'static crate::pac::spi::Spi, tx_word: W) -> Result<W, Error> {
448 spin_until_tx_ready(regs)?; 454 spin_until_tx_ready(regs)?;
@@ -460,65 +466,46 @@ fn transfer_word<W: Word>(regs: &'static crate::pac::spi::Spi, tx_word: W) -> Re
460 return Ok(rx_word); 466 return Ok(rx_word);
461} 467}
462 468
463impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> { 469// Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with
464 type Error = Error; 470// some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289
465 471macro_rules! impl_blocking {
466 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 472 ($w:ident) => {
467 self.set_word_size(WordSize::EightBit); 473 impl<'d, T: Instance> embedded_hal::blocking::spi::Write<$w> for Spi<'d, T, NoDma, NoDma> {
468 let regs = T::regs(); 474 type Error = Error;
469 475
470 for word in words.iter() { 476 fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> {
471 let _ = transfer_word(regs, *word)?; 477 self.set_word_size($w::WORDSIZE);
472 } 478 let regs = T::regs();
473 479
474 Ok(()) 480 for word in words.iter() {
475 } 481 let _ = transfer_word(regs, *word)?;
476} 482 }
477
478impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> {
479 type Error = Error;
480
481 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
482 self.set_word_size(WordSize::EightBit);
483 let regs = T::regs();
484 483
485 for word in words.iter_mut() { 484 Ok(())
486 *word = transfer_word(regs, *word)?; 485 }
487 } 486 }
488 487
489 Ok(words) 488 impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<$w>
490 } 489 for Spi<'d, T, NoDma, NoDma>
491} 490 {
491 type Error = Error;
492 492
493impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, NoDma> { 493 fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> {
494 type Error = Error; 494 self.set_word_size($w::WORDSIZE);
495 let regs = T::regs();
495 496
496 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { 497 for word in words.iter_mut() {
497 self.set_word_size(WordSize::SixteenBit); 498 *word = transfer_word(regs, *word)?;
498 let regs = T::regs(); 499 }
499 500
500 for word in words.iter() { 501 Ok(words)
501 let _ = transfer_word(regs, *word)?; 502 }
502 } 503 }
503 504 };
504 Ok(())
505 }
506} 505}
507 506
508impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> { 507impl_blocking!(u8);
509 type Error = Error; 508impl_blocking!(u16);
510
511 fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
512 self.set_word_size(WordSize::SixteenBit);
513 let regs = T::regs();
514
515 for word in words.iter_mut() {
516 *word = transfer_word(regs, *word)?;
517 }
518
519 Ok(words)
520 }
521}
522 509
523impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { 510impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> {
524 type Error = Error; 511 type Error = Error;