diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-24 02:38:31 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-02-24 02:41:41 +0100 |
| commit | e67dfcb04f79aebed52a357b867d418e0ff476af (patch) | |
| tree | 82d1fb2b40b71a6dd62bfbe79596d61cbb6ce7c8 /embassy-stm32/src/sai | |
| parent | f77d59500e9bbc0282f1ba4b6b27507f83f9d974 (diff) | |
stm32/dma: add AnyChannel, add support for BDMA on H7.
Diffstat (limited to 'embassy-stm32/src/sai')
| -rw-r--r-- | embassy-stm32/src/sai/mod.rs | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 5e647612c..b6c3e4028 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs | |||
| @@ -501,9 +501,9 @@ impl Config { | |||
| 501 | } | 501 | } |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | enum RingBuffer<'d, C: Channel, W: word::Word> { | 504 | enum RingBuffer<'d, W: word::Word> { |
| 505 | Writable(WritableRingBuffer<'d, C, W>), | 505 | Writable(WritableRingBuffer<'d, W>), |
| 506 | Readable(ReadableRingBuffer<'d, C, W>), | 506 | Readable(ReadableRingBuffer<'d, W>), |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] | 509 | #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] |
| @@ -528,13 +528,13 @@ fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) { | |||
| 528 | ) | 528 | ) |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>( | 531 | fn get_ring_buffer<'d, T: Instance, W: word::Word>( |
| 532 | dma: impl Peripheral<P = C> + 'd, | 532 | dma: impl Peripheral<P = impl Channel> + 'd, |
| 533 | dma_buf: &'d mut [W], | 533 | dma_buf: &'d mut [W], |
| 534 | request: Request, | 534 | request: Request, |
| 535 | sub_block: WhichSubBlock, | 535 | sub_block: WhichSubBlock, |
| 536 | tx_rx: TxRx, | 536 | tx_rx: TxRx, |
| 537 | ) -> RingBuffer<'d, C, W> { | 537 | ) -> RingBuffer<'d, W> { |
| 538 | let opts = TransferOptions { | 538 | let opts = TransferOptions { |
| 539 | half_transfer_ir: true, | 539 | half_transfer_ir: true, |
| 540 | //the new_write() and new_read() always use circular mode | 540 | //the new_write() and new_read() always use circular mode |
| @@ -593,17 +593,17 @@ pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (S | |||
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | /// SAI sub-block driver. | 595 | /// SAI sub-block driver. |
| 596 | pub struct Sai<'d, T: Instance, C: Channel, W: word::Word> { | 596 | pub struct Sai<'d, T: Instance, W: word::Word> { |
| 597 | _peri: PeripheralRef<'d, T>, | 597 | _peri: PeripheralRef<'d, T>, |
| 598 | sd: Option<PeripheralRef<'d, AnyPin>>, | 598 | sd: Option<PeripheralRef<'d, AnyPin>>, |
| 599 | fs: Option<PeripheralRef<'d, AnyPin>>, | 599 | fs: Option<PeripheralRef<'d, AnyPin>>, |
| 600 | sck: Option<PeripheralRef<'d, AnyPin>>, | 600 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 601 | mclk: Option<PeripheralRef<'d, AnyPin>>, | 601 | mclk: Option<PeripheralRef<'d, AnyPin>>, |
| 602 | ring_buffer: RingBuffer<'d, C, W>, | 602 | ring_buffer: RingBuffer<'d, W>, |
| 603 | sub_block: WhichSubBlock, | 603 | sub_block: WhichSubBlock, |
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | 606 | impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { |
| 607 | /// Create a new SAI driver in asynchronous mode with MCLK. | 607 | /// Create a new SAI driver in asynchronous mode with MCLK. |
| 608 | /// | 608 | /// |
| 609 | /// You can obtain the [`SubBlock`] with [`split_subblocks`]. | 609 | /// You can obtain the [`SubBlock`] with [`split_subblocks`]. |
| @@ -613,13 +613,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 613 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, | 613 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 614 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, | 614 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, |
| 615 | mclk: impl Peripheral<P = impl MclkPin<T, S>> + 'd, | 615 | mclk: impl Peripheral<P = impl MclkPin<T, S>> + 'd, |
| 616 | dma: impl Peripheral<P = C> + 'd, | 616 | dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, |
| 617 | dma_buf: &'d mut [W], | 617 | dma_buf: &'d mut [W], |
| 618 | mut config: Config, | 618 | mut config: Config, |
| 619 | ) -> Self | 619 | ) -> Self { |
| 620 | where | ||
| 621 | C: Channel + Dma<T, S>, | ||
| 622 | { | ||
| 623 | into_ref!(mclk); | 620 | into_ref!(mclk); |
| 624 | 621 | ||
| 625 | let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); | 622 | let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); |
| @@ -642,13 +639,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 642 | sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, | 639 | sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, |
| 643 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, | 640 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 644 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, | 641 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, |
| 645 | dma: impl Peripheral<P = C> + 'd, | 642 | dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, |
| 646 | dma_buf: &'d mut [W], | 643 | dma_buf: &'d mut [W], |
| 647 | config: Config, | 644 | config: Config, |
| 648 | ) -> Self | 645 | ) -> Self { |
| 649 | where | ||
| 650 | C: Channel + Dma<T, S>, | ||
| 651 | { | ||
| 652 | let peri = peri.peri; | 646 | let peri = peri.peri; |
| 653 | into_ref!(peri, dma, sck, sd, fs); | 647 | into_ref!(peri, dma, sck, sd, fs); |
| 654 | 648 | ||
| @@ -671,7 +665,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 671 | None, | 665 | None, |
| 672 | Some(sd.map_into()), | 666 | Some(sd.map_into()), |
| 673 | Some(fs.map_into()), | 667 | Some(fs.map_into()), |
| 674 | get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx), | 668 | get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx), |
| 675 | config, | 669 | config, |
| 676 | ) | 670 | ) |
| 677 | } | 671 | } |
| @@ -682,13 +676,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 682 | pub fn new_synchronous<S: SubBlockInstance>( | 676 | pub fn new_synchronous<S: SubBlockInstance>( |
| 683 | peri: SubBlock<'d, T, S>, | 677 | peri: SubBlock<'d, T, S>, |
| 684 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, | 678 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 685 | dma: impl Peripheral<P = C> + 'd, | 679 | dma: impl Peripheral<P = impl Channel + Dma<T, S>> + 'd, |
| 686 | dma_buf: &'d mut [W], | 680 | dma_buf: &'d mut [W], |
| 687 | mut config: Config, | 681 | mut config: Config, |
| 688 | ) -> Self | 682 | ) -> Self { |
| 689 | where | ||
| 690 | C: Channel + Dma<T, S>, | ||
| 691 | { | ||
| 692 | update_synchronous_config(&mut config); | 683 | update_synchronous_config(&mut config); |
| 693 | 684 | ||
| 694 | let peri = peri.peri; | 685 | let peri = peri.peri; |
| @@ -709,7 +700,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 709 | None, | 700 | None, |
| 710 | Some(sd.map_into()), | 701 | Some(sd.map_into()), |
| 711 | None, | 702 | None, |
| 712 | get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx), | 703 | get_ring_buffer::<T, W>(dma, dma_buf, request, sub_block, config.tx_rx), |
| 713 | config, | 704 | config, |
| 714 | ) | 705 | ) |
| 715 | } | 706 | } |
| @@ -721,7 +712,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 721 | mclk: Option<PeripheralRef<'d, AnyPin>>, | 712 | mclk: Option<PeripheralRef<'d, AnyPin>>, |
| 722 | sd: Option<PeripheralRef<'d, AnyPin>>, | 713 | sd: Option<PeripheralRef<'d, AnyPin>>, |
| 723 | fs: Option<PeripheralRef<'d, AnyPin>>, | 714 | fs: Option<PeripheralRef<'d, AnyPin>>, |
| 724 | ring_buffer: RingBuffer<'d, C, W>, | 715 | ring_buffer: RingBuffer<'d, W>, |
| 725 | config: Config, | 716 | config: Config, |
| 726 | ) -> Self { | 717 | ) -> Self { |
| 727 | #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] | 718 | #[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] |
| @@ -830,7 +821,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 830 | } | 821 | } |
| 831 | } | 822 | } |
| 832 | 823 | ||
| 833 | fn is_transmitter(ring_buffer: &RingBuffer<C, W>) -> bool { | 824 | fn is_transmitter(ring_buffer: &RingBuffer<W>) -> bool { |
| 834 | match ring_buffer { | 825 | match ring_buffer { |
| 835 | RingBuffer::Writable(_) => true, | 826 | RingBuffer::Writable(_) => true, |
| 836 | _ => false, | 827 | _ => false, |
| @@ -889,7 +880,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { | |||
| 889 | } | 880 | } |
| 890 | } | 881 | } |
| 891 | 882 | ||
| 892 | impl<'d, T: Instance, C: Channel, W: word::Word> Drop for Sai<'d, T, C, W> { | 883 | impl<'d, T: Instance, W: word::Word> Drop for Sai<'d, T, W> { |
| 893 | fn drop(&mut self) { | 884 | fn drop(&mut self) { |
| 894 | let ch = T::REGS.ch(self.sub_block as usize); | 885 | let ch = T::REGS.ch(self.sub_block as usize); |
| 895 | ch.cr1().modify(|w| w.set_saien(false)); | 886 | ch.cr1().modify(|w| w.set_saien(false)); |
