diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-12-18 23:49:37 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-12-19 00:06:30 +0100 |
| commit | 4deae51e656e46e18840bf30e68a976aaaf8ad20 (patch) | |
| tree | 272a12b6568e5ec49d81c77497e7fc0854d6b620 /embassy-stm32/src/sai | |
| parent | c952ae0f49a21ade19758e4f6f1e2bec503e413e (diff) | |
stm32/sai: deduplicate code for subblocks A/B.
Diffstat (limited to 'embassy-stm32/src/sai')
| -rw-r--r-- | embassy-stm32/src/sai/mod.rs | 331 |
1 files changed, 108 insertions, 223 deletions
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 96acd9e48..e03497529 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | ||
| 4 | |||
| 3 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 5 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 4 | 6 | ||
| 7 | use self::sealed::WhichSubBlock; | ||
| 5 | pub use crate::dma::word; | 8 | pub use crate::dma::word; |
| 6 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; | 9 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; |
| 7 | use crate::gpio::sealed::{AFType, Pin as _}; | 10 | use crate::gpio::sealed::{AFType, Pin as _}; |
| @@ -500,23 +503,10 @@ impl Default for Config { | |||
| 500 | } | 503 | } |
| 501 | 504 | ||
| 502 | impl Config { | 505 | impl Config { |
| 503 | pub fn new_i2s() -> Self { | 506 | /// Create a new config with all default values. |
| 507 | pub fn new() -> Self { | ||
| 504 | return Default::default(); | 508 | return Default::default(); |
| 505 | } | 509 | } |
| 506 | |||
| 507 | pub fn new_msb_first() -> Self { | ||
| 508 | Self { | ||
| 509 | bit_order: BitOrder::MsbFirst, | ||
| 510 | frame_sync_offset: FrameSyncOffset::OnFirstBit, | ||
| 511 | ..Default::default() | ||
| 512 | } | ||
| 513 | } | ||
| 514 | } | ||
| 515 | |||
| 516 | #[derive(Copy, Clone)] | ||
| 517 | enum WhichSubBlock { | ||
| 518 | A = 0, | ||
| 519 | B = 1, | ||
| 520 | } | 510 | } |
| 521 | 511 | ||
| 522 | enum RingBuffer<'d, C: Channel, W: word::Word> { | 512 | enum RingBuffer<'d, C: Channel, W: word::Word> { |
| @@ -530,28 +520,6 @@ fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut | |||
| 530 | ch.dr().as_ptr() as _ | 520 | ch.dr().as_ptr() as _ |
| 531 | } | 521 | } |
| 532 | 522 | ||
| 533 | pub struct SubBlock<'d, T: Instance, C: Channel, W: word::Word> { | ||
| 534 | _peri: PeripheralRef<'d, T>, | ||
| 535 | sd: Option<PeripheralRef<'d, AnyPin>>, | ||
| 536 | fs: Option<PeripheralRef<'d, AnyPin>>, | ||
| 537 | sck: Option<PeripheralRef<'d, AnyPin>>, | ||
| 538 | mclk: Option<PeripheralRef<'d, AnyPin>>, | ||
| 539 | ring_buffer: RingBuffer<'d, C, W>, | ||
| 540 | sub_block: WhichSubBlock, | ||
| 541 | } | ||
| 542 | |||
| 543 | pub struct SubBlockA {} | ||
| 544 | pub struct SubBlockB {} | ||
| 545 | |||
| 546 | pub struct SubBlockAPeripheral<'d, T>(PeripheralRef<'d, T>); | ||
| 547 | pub struct SubBlockBPeripheral<'d, T>(PeripheralRef<'d, T>); | ||
| 548 | |||
| 549 | pub struct Sai<'d, T: Instance> { | ||
| 550 | _peri: PeripheralRef<'d, T>, | ||
| 551 | sub_block_a_peri: Option<SubBlockAPeripheral<'d, T>>, | ||
| 552 | sub_block_b_peri: Option<SubBlockBPeripheral<'d, T>>, | ||
| 553 | } | ||
| 554 | |||
| 555 | // return the type for (sd, sck) | 523 | // return the type for (sd, sck) |
| 556 | fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) { | 524 | fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) { |
| 557 | ( | 525 | ( |
| @@ -590,34 +558,6 @@ fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>( | |||
| 590 | } | 558 | } |
| 591 | } | 559 | } |
| 592 | 560 | ||
| 593 | impl<'d, T: Instance> Sai<'d, T> { | ||
| 594 | pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self { | ||
| 595 | T::enable_and_reset(); | ||
| 596 | |||
| 597 | Self { | ||
| 598 | _peri: unsafe { peri.clone_unchecked().into_ref() }, | ||
| 599 | sub_block_a_peri: Some(SubBlockAPeripheral(unsafe { peri.clone_unchecked().into_ref() })), | ||
| 600 | sub_block_b_peri: Some(SubBlockBPeripheral(peri.into_ref())), | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | pub fn take_sub_block_a(self: &mut Self) -> Option<SubBlockAPeripheral<'d, T>> { | ||
| 605 | if self.sub_block_a_peri.is_some() { | ||
| 606 | self.sub_block_a_peri.take() | ||
| 607 | } else { | ||
| 608 | None | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | pub fn take_sub_block_b(self: &mut Self) -> Option<SubBlockBPeripheral<'d, T>> { | ||
| 613 | if self.sub_block_b_peri.is_some() { | ||
| 614 | self.sub_block_b_peri.take() | ||
| 615 | } else { | ||
| 616 | None | ||
| 617 | } | ||
| 618 | } | ||
| 619 | } | ||
| 620 | |||
| 621 | fn update_synchronous_config(config: &mut Config) { | 561 | fn update_synchronous_config(config: &mut Config) { |
| 622 | config.mode = Mode::Slave; | 562 | config.mode = Mode::Slave; |
| 623 | config.sync_output = false; | 563 | config.sync_output = false; |
| @@ -635,122 +575,51 @@ fn update_synchronous_config(config: &mut Config) { | |||
| 635 | } | 575 | } |
| 636 | } | 576 | } |
| 637 | 577 | ||
| 638 | impl SubBlockA { | 578 | pub struct SubBlock<'d, T, S: SubBlockInstance> { |
| 639 | pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( | 579 | peri: PeripheralRef<'d, T>, |
| 640 | peri: SubBlockAPeripheral<'d, T>, | 580 | _phantom: PhantomData<S>, |
| 641 | sck: impl Peripheral<P = impl SckAPin<T>> + 'd, | 581 | } |
| 642 | sd: impl Peripheral<P = impl SdAPin<T>> + 'd, | ||
| 643 | fs: impl Peripheral<P = impl FsAPin<T>> + 'd, | ||
| 644 | mclk: impl Peripheral<P = impl MclkAPin<T>> + 'd, | ||
| 645 | dma: impl Peripheral<P = C> + 'd, | ||
| 646 | dma_buf: &'d mut [W], | ||
| 647 | mut config: Config, | ||
| 648 | ) -> SubBlock<'d, T, C, W> | ||
| 649 | where | ||
| 650 | C: Channel + DmaA<T>, | ||
| 651 | { | ||
| 652 | into_ref!(mclk); | ||
| 653 | |||
| 654 | let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); | ||
| 655 | |||
| 656 | mclk.set_as_af(mclk.af_num(), ck_af_type); | ||
| 657 | mclk.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 658 | |||
| 659 | if config.master_clock_divider == MasterClockDivider::MasterClockDisabled { | ||
| 660 | config.master_clock_divider = MasterClockDivider::Div1; | ||
| 661 | } | ||
| 662 | |||
| 663 | Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config) | ||
| 664 | } | ||
| 665 | |||
| 666 | pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( | ||
| 667 | peri: SubBlockAPeripheral<'d, T>, | ||
| 668 | sck: impl Peripheral<P = impl SckAPin<T>> + 'd, | ||
| 669 | sd: impl Peripheral<P = impl SdAPin<T>> + 'd, | ||
| 670 | fs: impl Peripheral<P = impl FsAPin<T>> + 'd, | ||
| 671 | dma: impl Peripheral<P = C> + 'd, | ||
| 672 | dma_buf: &'d mut [W], | ||
| 673 | config: Config, | ||
| 674 | ) -> SubBlock<'d, T, C, W> | ||
| 675 | where | ||
| 676 | C: Channel + DmaA<T>, | ||
| 677 | { | ||
| 678 | let peri = peri.0; | ||
| 679 | into_ref!(peri, dma, sck, sd, fs); | ||
| 680 | |||
| 681 | let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); | ||
| 682 | sd.set_as_af(sd.af_num(), sd_af_type); | ||
| 683 | sd.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 684 | |||
| 685 | sck.set_as_af(sck.af_num(), ck_af_type); | ||
| 686 | sck.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 687 | fs.set_as_af(fs.af_num(), ck_af_type); | ||
| 688 | fs.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 689 | 582 | ||
| 690 | let sub_block = WhichSubBlock::A; | 583 | pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { |
| 691 | let request = dma.request(); | 584 | into_ref!(peri); |
| 585 | T::enable_and_reset(); | ||
| 692 | 586 | ||
| 693 | SubBlock::new_inner( | 587 | ( |
| 588 | SubBlock { | ||
| 589 | peri: unsafe { peri.clone_unchecked() }, | ||
| 590 | _phantom: PhantomData, | ||
| 591 | }, | ||
| 592 | SubBlock { | ||
| 694 | peri, | 593 | peri, |
| 695 | sub_block, | 594 | _phantom: PhantomData, |
| 696 | Some(sck.map_into()), | 595 | }, |
| 697 | None, | 596 | ) |
| 698 | Some(sd.map_into()), | 597 | } |
| 699 | Some(fs.map_into()), | ||
| 700 | get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx), | ||
| 701 | config, | ||
| 702 | ) | ||
| 703 | } | ||
| 704 | |||
| 705 | pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( | ||
| 706 | peri: SubBlockAPeripheral<'d, T>, | ||
| 707 | sd: impl Peripheral<P = impl SdAPin<T>> + 'd, | ||
| 708 | dma: impl Peripheral<P = C> + 'd, | ||
| 709 | dma_buf: &'d mut [W], | ||
| 710 | mut config: Config, | ||
| 711 | ) -> SubBlock<'d, T, C, W> | ||
| 712 | where | ||
| 713 | C: Channel + DmaA<T>, | ||
| 714 | { | ||
| 715 | update_synchronous_config(&mut config); | ||
| 716 | |||
| 717 | let peri = peri.0; | ||
| 718 | into_ref!(dma, peri, sd); | ||
| 719 | |||
| 720 | let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); | ||
| 721 | |||
| 722 | sd.set_as_af(sd.af_num(), sd_af_type); | ||
| 723 | sd.set_speed(crate::gpio::Speed::VeryHigh); | ||
| 724 | |||
| 725 | let sub_block = WhichSubBlock::A; | ||
| 726 | let request = dma.request(); | ||
| 727 | 598 | ||
| 728 | SubBlock::new_inner( | 599 | /// SAI sub-block driver |
| 729 | peri, | 600 | pub struct Sai<'d, T: Instance, C: Channel, W: word::Word> { |
| 730 | sub_block, | 601 | _peri: PeripheralRef<'d, T>, |
| 731 | None, | 602 | sd: Option<PeripheralRef<'d, AnyPin>>, |
| 732 | None, | 603 | fs: Option<PeripheralRef<'d, AnyPin>>, |
| 733 | Some(sd.map_into()), | 604 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 734 | None, | 605 | mclk: Option<PeripheralRef<'d, AnyPin>>, |
| 735 | get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx), | 606 | ring_buffer: RingBuffer<'d, C, W>, |
| 736 | config, | 607 | sub_block: WhichSubBlock, |
| 737 | ) | ||
| 738 | } | ||
| 739 | } | 608 | } |
| 740 | 609 | ||
| 741 | impl SubBlockB { | 610 | impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { |
| 742 | pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>( | 611 | pub fn new_asynchronous_with_mclk<S: SubBlockInstance>( |
| 743 | peri: SubBlockBPeripheral<'d, T>, | 612 | peri: SubBlock<'d, T, S>, |
| 744 | sck: impl Peripheral<P = impl SckBPin<T>> + 'd, | 613 | sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, |
| 745 | sd: impl Peripheral<P = impl SdBPin<T>> + 'd, | 614 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 746 | fs: impl Peripheral<P = impl FsBPin<T>> + 'd, | 615 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, |
| 747 | mclk: impl Peripheral<P = impl MclkBPin<T>> + 'd, | 616 | mclk: impl Peripheral<P = impl MclkPin<T, S>> + 'd, |
| 748 | dma: impl Peripheral<P = C> + 'd, | 617 | dma: impl Peripheral<P = C> + 'd, |
| 749 | dma_buf: &'d mut [W], | 618 | dma_buf: &'d mut [W], |
| 750 | mut config: Config, | 619 | mut config: Config, |
| 751 | ) -> SubBlock<'d, T, C, W> | 620 | ) -> Self |
| 752 | where | 621 | where |
| 753 | C: Channel + DmaB<T>, | 622 | C: Channel + Dma<T, S>, |
| 754 | { | 623 | { |
| 755 | into_ref!(mclk); | 624 | into_ref!(mclk); |
| 756 | 625 | ||
| @@ -766,23 +635,22 @@ impl SubBlockB { | |||
| 766 | Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config) | 635 | Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config) |
| 767 | } | 636 | } |
| 768 | 637 | ||
| 769 | pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>( | 638 | pub fn new_asynchronous<S: SubBlockInstance>( |
| 770 | peri: SubBlockBPeripheral<'d, T>, | 639 | peri: SubBlock<'d, T, S>, |
| 771 | sck: impl Peripheral<P = impl SckBPin<T>> + 'd, | 640 | sck: impl Peripheral<P = impl SckPin<T, S>> + 'd, |
| 772 | sd: impl Peripheral<P = impl SdBPin<T>> + 'd, | 641 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 773 | fs: impl Peripheral<P = impl FsBPin<T>> + 'd, | 642 | fs: impl Peripheral<P = impl FsPin<T, S>> + 'd, |
| 774 | dma: impl Peripheral<P = C> + 'd, | 643 | dma: impl Peripheral<P = C> + 'd, |
| 775 | dma_buf: &'d mut [W], | 644 | dma_buf: &'d mut [W], |
| 776 | config: Config, | 645 | config: Config, |
| 777 | ) -> SubBlock<'d, T, C, W> | 646 | ) -> Self |
| 778 | where | 647 | where |
| 779 | C: Channel + DmaB<T>, | 648 | C: Channel + Dma<T, S>, |
| 780 | { | 649 | { |
| 781 | let peri = peri.0; | 650 | let peri = peri.peri; |
| 782 | into_ref!(dma, peri, sck, sd, fs); | 651 | into_ref!(peri, dma, sck, sd, fs); |
| 783 | 652 | ||
| 784 | let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); | 653 | let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); |
| 785 | |||
| 786 | sd.set_as_af(sd.af_num(), sd_af_type); | 654 | sd.set_as_af(sd.af_num(), sd_af_type); |
| 787 | sd.set_speed(crate::gpio::Speed::VeryHigh); | 655 | sd.set_speed(crate::gpio::Speed::VeryHigh); |
| 788 | 656 | ||
| @@ -791,10 +659,10 @@ impl SubBlockB { | |||
| 791 | fs.set_as_af(fs.af_num(), ck_af_type); | 659 | fs.set_as_af(fs.af_num(), ck_af_type); |
| 792 | fs.set_speed(crate::gpio::Speed::VeryHigh); | 660 | fs.set_speed(crate::gpio::Speed::VeryHigh); |
| 793 | 661 | ||
| 794 | let sub_block = WhichSubBlock::B; | 662 | let sub_block = S::WHICH; |
| 795 | let request = dma.request(); | 663 | let request = dma.request(); |
| 796 | 664 | ||
| 797 | SubBlock::new_inner( | 665 | Self::new_inner( |
| 798 | peri, | 666 | peri, |
| 799 | sub_block, | 667 | sub_block, |
| 800 | Some(sck.map_into()), | 668 | Some(sck.map_into()), |
| @@ -806,18 +674,19 @@ impl SubBlockB { | |||
| 806 | ) | 674 | ) |
| 807 | } | 675 | } |
| 808 | 676 | ||
| 809 | pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>( | 677 | pub fn new_synchronous<S: SubBlockInstance>( |
| 810 | peri: SubBlockBPeripheral<'d, T>, | 678 | peri: SubBlock<'d, T, S>, |
| 811 | sd: impl Peripheral<P = impl SdBPin<T>> + 'd, | 679 | sd: impl Peripheral<P = impl SdPin<T, S>> + 'd, |
| 812 | dma: impl Peripheral<P = C> + 'd, | 680 | dma: impl Peripheral<P = C> + 'd, |
| 813 | dma_buf: &'d mut [W], | 681 | dma_buf: &'d mut [W], |
| 814 | mut config: Config, | 682 | mut config: Config, |
| 815 | ) -> SubBlock<'d, T, C, W> | 683 | ) -> Self |
| 816 | where | 684 | where |
| 817 | C: Channel + DmaB<T>, | 685 | C: Channel + Dma<T, S>, |
| 818 | { | 686 | { |
| 819 | update_synchronous_config(&mut config); | 687 | update_synchronous_config(&mut config); |
| 820 | let peri = peri.0; | 688 | |
| 689 | let peri = peri.peri; | ||
| 821 | into_ref!(dma, peri, sd); | 690 | into_ref!(dma, peri, sd); |
| 822 | 691 | ||
| 823 | let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); | 692 | let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx); |
| @@ -825,10 +694,10 @@ impl SubBlockB { | |||
| 825 | sd.set_as_af(sd.af_num(), sd_af_type); | 694 | sd.set_as_af(sd.af_num(), sd_af_type); |
| 826 | sd.set_speed(crate::gpio::Speed::VeryHigh); | 695 | sd.set_speed(crate::gpio::Speed::VeryHigh); |
| 827 | 696 | ||
| 828 | let sub_block = WhichSubBlock::B; | 697 | let sub_block = S::WHICH; |
| 829 | let request = dma.request(); | 698 | let request = dma.request(); |
| 830 | 699 | ||
| 831 | SubBlock::new_inner( | 700 | Self::new_inner( |
| 832 | peri, | 701 | peri, |
| 833 | sub_block, | 702 | sub_block, |
| 834 | None, | 703 | None, |
| @@ -839,26 +708,6 @@ impl SubBlockB { | |||
| 839 | config, | 708 | config, |
| 840 | ) | 709 | ) |
| 841 | } | 710 | } |
| 842 | } | ||
| 843 | |||
| 844 | impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { | ||
| 845 | pub fn start(self: &mut Self) { | ||
| 846 | match self.ring_buffer { | ||
| 847 | RingBuffer::Writable(ref mut rb) => { | ||
| 848 | rb.start(); | ||
| 849 | } | ||
| 850 | RingBuffer::Readable(ref mut rb) => { | ||
| 851 | rb.start(); | ||
| 852 | } | ||
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 856 | fn is_transmitter(ring_buffer: &RingBuffer<C, W>) -> bool { | ||
| 857 | match ring_buffer { | ||
| 858 | RingBuffer::Writable(_) => true, | ||
| 859 | _ => false, | ||
| 860 | } | ||
| 861 | } | ||
| 862 | 711 | ||
| 863 | fn new_inner( | 712 | fn new_inner( |
| 864 | peri: impl Peripheral<P = T> + 'd, | 713 | peri: impl Peripheral<P = T> + 'd, |
| @@ -964,6 +813,24 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { | |||
| 964 | } | 813 | } |
| 965 | } | 814 | } |
| 966 | 815 | ||
| 816 | pub fn start(&mut self) { | ||
| 817 | match self.ring_buffer { | ||
| 818 | RingBuffer::Writable(ref mut rb) => { | ||
| 819 | rb.start(); | ||
| 820 | } | ||
| 821 | RingBuffer::Readable(ref mut rb) => { | ||
| 822 | rb.start(); | ||
| 823 | } | ||
| 824 | } | ||
| 825 | } | ||
| 826 | |||
| 827 | fn is_transmitter(ring_buffer: &RingBuffer<C, W>) -> bool { | ||
| 828 | match ring_buffer { | ||
| 829 | RingBuffer::Writable(_) => true, | ||
| 830 | _ => false, | ||
| 831 | } | ||
| 832 | } | ||
| 833 | |||
| 967 | pub fn reset() { | 834 | pub fn reset() { |
| 968 | T::enable_and_reset(); | 835 | T::enable_and_reset(); |
| 969 | } | 836 | } |
| @@ -1008,7 +875,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { | |||
| 1008 | } | 875 | } |
| 1009 | } | 876 | } |
| 1010 | 877 | ||
| 1011 | impl<'d, T: Instance, C: Channel, W: word::Word> Drop for SubBlock<'d, T, C, W> { | 878 | impl<'d, T: Instance, C: Channel, W: word::Word> Drop for Sai<'d, T, C, W> { |
| 1012 | fn drop(&mut self) { | 879 | fn drop(&mut self) { |
| 1013 | let ch = T::REGS.ch(self.sub_block as usize); | 880 | let ch = T::REGS.ch(self.sub_block as usize); |
| 1014 | ch.cr1().modify(|w| w.set_saien(false)); | 881 | ch.cr1().modify(|w| w.set_saien(false)); |
| @@ -1025,22 +892,40 @@ pub(crate) mod sealed { | |||
| 1025 | pub trait Instance { | 892 | pub trait Instance { |
| 1026 | const REGS: Regs; | 893 | const REGS: Regs; |
| 1027 | } | 894 | } |
| 895 | |||
| 896 | #[derive(Copy, Clone)] | ||
| 897 | pub enum WhichSubBlock { | ||
| 898 | A = 0, | ||
| 899 | B = 1, | ||
| 900 | } | ||
| 901 | |||
| 902 | pub trait SubBlock { | ||
| 903 | const WHICH: WhichSubBlock; | ||
| 904 | } | ||
| 1028 | } | 905 | } |
| 1029 | 906 | ||
| 1030 | pub trait Word: word::Word {} | 907 | pub trait Word: word::Word {} |
| 1031 | 908 | ||
| 909 | pub trait SubBlockInstance: sealed::SubBlock {} | ||
| 910 | |||
| 911 | pub enum A {} | ||
| 912 | impl sealed::SubBlock for A { | ||
| 913 | const WHICH: WhichSubBlock = WhichSubBlock::A; | ||
| 914 | } | ||
| 915 | impl SubBlockInstance for A {} | ||
| 916 | pub enum B {} | ||
| 917 | impl sealed::SubBlock for B { | ||
| 918 | const WHICH: WhichSubBlock = WhichSubBlock::B; | ||
| 919 | } | ||
| 920 | impl SubBlockInstance for B {} | ||
| 921 | |||
| 1032 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} | 922 | pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} |
| 1033 | pin_trait!(SckAPin, Instance); | 923 | pin_trait!(SckPin, Instance, SubBlockInstance); |
| 1034 | pin_trait!(SckBPin, Instance); | 924 | pin_trait!(FsPin, Instance, SubBlockInstance); |
| 1035 | pin_trait!(FsAPin, Instance); | 925 | pin_trait!(SdPin, Instance, SubBlockInstance); |
| 1036 | pin_trait!(FsBPin, Instance); | 926 | pin_trait!(MclkPin, Instance, SubBlockInstance); |
| 1037 | pin_trait!(SdAPin, Instance); | 927 | |
| 1038 | pin_trait!(SdBPin, Instance); | 928 | dma_trait!(Dma, Instance, SubBlockInstance); |
| 1039 | pin_trait!(MclkAPin, Instance); | ||
| 1040 | pin_trait!(MclkBPin, Instance); | ||
| 1041 | |||
| 1042 | dma_trait!(DmaA, Instance); | ||
| 1043 | dma_trait!(DmaB, Instance); | ||
| 1044 | 929 | ||
| 1045 | foreach_peripheral!( | 930 | foreach_peripheral!( |
| 1046 | (sai, $inst:ident) => { | 931 | (sai, $inst:ident) => { |
