diff options
| author | Ulf Lilleengen <[email protected]> | 2022-01-26 22:39:06 +0100 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2022-01-26 22:39:06 +0100 |
| commit | 4032fc06556312eab27488f05efe1803ade47b45 (patch) | |
| tree | 0b38343758741e5c4074e86da30867595501f9b6 /embassy-stm32/src/spi | |
| parent | cd36e3f7332d08865e670ca5b515d1c6efa1bf85 (diff) | |
Support unstable-trait feature for stm32
Diffstat (limited to 'embassy-stm32/src/spi')
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 206 |
1 files changed, 148 insertions, 58 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index f1ea8592d..4cf45f6f9 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use core::future::Future; | ||
| 4 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 5 | use core::ptr; | 4 | use core::ptr; |
| 6 | use embassy::util::Unborrow; | 5 | use embassy::util::Unborrow; |
| 7 | use embassy_hal_common::unborrow; | 6 | use embassy_hal_common::unborrow; |
| 8 | use embassy_traits::spi as traits; | ||
| 9 | 7 | ||
| 10 | use self::sealed::WordSize; | 8 | use self::sealed::WordSize; |
| 11 | use crate::dma; | 9 | use crate::dma; |
| @@ -17,7 +15,7 @@ use crate::peripherals; | |||
| 17 | use crate::rcc::RccPeripheral; | 15 | use crate::rcc::RccPeripheral; |
| 18 | use crate::time::Hertz; | 16 | use crate::time::Hertz; |
| 19 | 17 | ||
| 20 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 18 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 21 | 19 | ||
| 22 | #[cfg_attr(spi_v1, path = "v1.rs")] | 20 | #[cfg_attr(spi_v1, path = "v1.rs")] |
| 23 | #[cfg_attr(spi_f1, path = "v1.rs")] | 21 | #[cfg_attr(spi_f1, path = "v1.rs")] |
| @@ -549,76 +547,168 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> { | |||
| 549 | return Ok(rx_word); | 547 | return Ok(rx_word); |
| 550 | } | 548 | } |
| 551 | 549 | ||
| 552 | // Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with | 550 | mod eh02 { |
| 553 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 | 551 | use super::*; |
| 554 | macro_rules! impl_blocking { | ||
| 555 | ($w:ident) => { | ||
| 556 | impl<'d, T: Instance> embedded_hal::blocking::spi::Write<$w> for Spi<'d, T, NoDma, NoDma> { | ||
| 557 | type Error = Error; | ||
| 558 | 552 | ||
| 559 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { | 553 | // Note: It is not possible to impl these traits generically in embedded-hal 0.2 due to a conflict with |
| 560 | self.blocking_write(words) | 554 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 |
| 555 | macro_rules! impl_blocking { | ||
| 556 | ($w:ident) => { | ||
| 557 | impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<$w> | ||
| 558 | for Spi<'d, T, NoDma, NoDma> | ||
| 559 | { | ||
| 560 | type Error = Error; | ||
| 561 | |||
| 562 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { | ||
| 563 | self.blocking_write(words) | ||
| 564 | } | ||
| 561 | } | 565 | } |
| 562 | } | ||
| 563 | 566 | ||
| 564 | impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<$w> | 567 | impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<$w> |
| 565 | for Spi<'d, T, NoDma, NoDma> | 568 | for Spi<'d, T, NoDma, NoDma> |
| 566 | { | 569 | { |
| 567 | type Error = Error; | 570 | type Error = Error; |
| 568 | 571 | ||
| 569 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { | 572 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { |
| 570 | self.blocking_transfer_in_place(words)?; | 573 | self.blocking_transfer_in_place(words)?; |
| 571 | Ok(words) | 574 | Ok(words) |
| 575 | } | ||
| 572 | } | 576 | } |
| 573 | } | 577 | }; |
| 574 | }; | 578 | } |
| 579 | |||
| 580 | impl_blocking!(u8); | ||
| 581 | impl_blocking!(u16); | ||
| 575 | } | 582 | } |
| 576 | 583 | ||
| 577 | impl_blocking!(u8); | 584 | #[cfg(feature = "unstable-traits")] |
| 578 | impl_blocking!(u16); | 585 | mod eh1 { |
| 586 | use super::*; | ||
| 587 | use core::future::Future; | ||
| 579 | 588 | ||
| 580 | impl<'d, T: Instance, Tx, Rx> traits::Spi<u8> for Spi<'d, T, Tx, Rx> { | 589 | impl<'d, T: Instance, Tx, Rx> embedded_hal_1::spi::ErrorType for Spi<'d, T, Tx, Rx> { |
| 581 | type Error = Error; | 590 | type Error = Error; |
| 582 | } | 591 | } |
| 583 | 592 | ||
| 584 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> traits::Write<u8> for Spi<'d, T, Tx, Rx> { | 593 | impl embedded_hal_1::spi::Error for Error { |
| 585 | type WriteFuture<'a> | 594 | fn kind(&self) -> embedded_hal_1::spi::ErrorKind { |
| 586 | where | 595 | match *self { |
| 587 | Self: 'a, | 596 | Self::Framing => embedded_hal_1::spi::ErrorKind::FrameFormat, |
| 588 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 597 | Self::Crc => embedded_hal_1::spi::ErrorKind::Other, |
| 598 | Self::ModeFault => embedded_hal_1::spi::ErrorKind::ModeFault, | ||
| 599 | Self::Overrun => embedded_hal_1::spi::ErrorKind::Overrun, | ||
| 600 | } | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx> embedded_hal_async::spi::Write<u8> | ||
| 605 | for Spi<'d, T, Tx, Rx> | ||
| 606 | { | ||
| 607 | type WriteFuture<'a> | ||
| 608 | where | ||
| 609 | Self: 'a, | ||
| 610 | = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 589 | 611 | ||
| 590 | fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { | 612 | fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { |
| 591 | self.write(data) | 613 | self.write(data) |
| 614 | } | ||
| 615 | |||
| 616 | type WriteTransactionFuture<'a> | ||
| 617 | where | ||
| 618 | Self: 'a, | ||
| 619 | = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 620 | |||
| 621 | fn write_transaction<'a>( | ||
| 622 | &'a mut self, | ||
| 623 | words: &'a [&'a [u8]], | ||
| 624 | ) -> Self::WriteTransactionFuture<'a> { | ||
| 625 | async move { | ||
| 626 | for buf in words { | ||
| 627 | self.write(buf).await? | ||
| 628 | } | ||
| 629 | Ok(()) | ||
| 630 | } | ||
| 631 | } | ||
| 592 | } | 632 | } |
| 593 | } | ||
| 594 | 633 | ||
| 595 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::Read<u8> | 634 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> |
| 596 | for Spi<'d, T, Tx, Rx> | 635 | embedded_hal_async::spi::Read<u8> for Spi<'d, T, Tx, Rx> |
| 597 | { | 636 | { |
| 598 | type ReadFuture<'a> | 637 | type ReadFuture<'a> |
| 599 | where | 638 | where |
| 600 | Self: 'a, | 639 | Self: 'a, |
| 601 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 640 | = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 602 | 641 | ||
| 603 | fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { | 642 | fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 604 | self.read(data) | 643 | self.read(data) |
| 644 | } | ||
| 645 | |||
| 646 | type ReadTransactionFuture<'a> | ||
| 647 | where | ||
| 648 | Self: 'a, | ||
| 649 | = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 650 | |||
| 651 | fn read_transaction<'a>( | ||
| 652 | &'a mut self, | ||
| 653 | words: &'a mut [&'a mut [u8]], | ||
| 654 | ) -> Self::ReadTransactionFuture<'a> { | ||
| 655 | async move { | ||
| 656 | for buf in words { | ||
| 657 | self.read(buf).await? | ||
| 658 | } | ||
| 659 | Ok(()) | ||
| 660 | } | ||
| 661 | } | ||
| 605 | } | 662 | } |
| 606 | } | ||
| 607 | 663 | ||
| 608 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> traits::FullDuplex<u8> | 664 | impl<'d, T: Instance, Tx: TxDmaChannel<T>, Rx: RxDmaChannel<T>> |
| 609 | for Spi<'d, T, Tx, Rx> | 665 | embedded_hal_async::spi::ReadWrite<u8> for Spi<'d, T, Tx, Rx> |
| 610 | { | 666 | { |
| 611 | type WriteReadFuture<'a> | 667 | type TransferFuture<'a> |
| 612 | where | 668 | where |
| 613 | Self: 'a, | 669 | Self: 'a, |
| 614 | = impl Future<Output = Result<(), Self::Error>> + 'a; | 670 | = impl Future<Output = Result<(), Self::Error>> + 'a; |
| 615 | 671 | ||
| 616 | fn read_write<'a>( | 672 | fn transfer<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::TransferFuture<'a> { |
| 617 | &'a mut self, | 673 | self.transfer(rx, tx) |
| 618 | read: &'a mut [u8], | 674 | } |
| 619 | write: &'a [u8], | 675 | |
| 620 | ) -> Self::WriteReadFuture<'a> { | 676 | type TransferInPlaceFuture<'a> |
| 621 | self.transfer(read, write) | 677 | where |
| 678 | Self: 'a, | ||
| 679 | = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 680 | |||
| 681 | fn transfer_in_place<'a>( | ||
| 682 | &'a mut self, | ||
| 683 | words: &'a mut [u8], | ||
| 684 | ) -> Self::TransferInPlaceFuture<'a> { | ||
| 685 | // TODO: Implement async version | ||
| 686 | let result = self.blocking_transfer_in_place(words); | ||
| 687 | async move { result } | ||
| 688 | } | ||
| 689 | |||
| 690 | type TransactionFuture<'a> | ||
| 691 | where | ||
| 692 | Self: 'a, | ||
| 693 | = impl Future<Output = Result<(), Self::Error>> + 'a; | ||
| 694 | |||
| 695 | fn transaction<'a>( | ||
| 696 | &'a mut self, | ||
| 697 | operations: &'a mut [embedded_hal_async::spi::Operation<'a, u8>], | ||
| 698 | ) -> Self::TransactionFuture<'a> { | ||
| 699 | use embedded_hal_1::spi::blocking::Operation; | ||
| 700 | async move { | ||
| 701 | for o in operations { | ||
| 702 | match o { | ||
| 703 | Operation::Read(b) => self.read(b).await?, | ||
| 704 | Operation::Write(b) => self.write(b).await?, | ||
| 705 | Operation::Transfer(r, w) => self.transfer(r, w).await?, | ||
| 706 | Operation::TransferInPlace(b) => self.transfer_in_place(b).await?, | ||
| 707 | } | ||
| 708 | } | ||
| 709 | Ok(()) | ||
| 710 | } | ||
| 711 | } | ||
| 622 | } | 712 | } |
| 623 | } | 713 | } |
| 624 | 714 | ||
