aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/sai
diff options
context:
space:
mode:
authorTyler Gilbert <[email protected]>2023-09-30 22:48:49 -0500
committerTyler Gilbert <[email protected]>2023-09-30 22:48:49 -0500
commit5dd9e9b3b75bb45f284a16b96a7ff4358bd0be31 (patch)
tree34431013ee16052ad3554705f717859661fbe6bb /embassy-stm32/src/sai
parentd42cfda2db1d2ca9d9d3c1ca0de044de1d0a5652 (diff)
issue #1986 separate blocks to prevent unsafe user code
Diffstat (limited to 'embassy-stm32/src/sai')
-rw-r--r--embassy-stm32/src/sai/mod.rs288
1 files changed, 162 insertions, 126 deletions
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index b1b5107b2..438e85b66 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -502,7 +502,7 @@ impl Config {
502} 502}
503 503
504#[derive(Copy, Clone)] 504#[derive(Copy, Clone)]
505pub enum SubBlock { 505enum WhichSubBlock {
506 A = 0, 506 A = 0,
507 B = 1, 507 B = 1,
508} 508}
@@ -513,67 +513,116 @@ enum RingBuffer<'d, C: Channel, W: word::Word> {
513} 513}
514 514
515#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] 515#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))]
516fn wdr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: SubBlock) -> *mut W { 516fn dr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: WhichSubBlock) -> *mut W {
517 let ch = w.ch(sub_block as usize); 517 let ch = w.ch(sub_block as usize);
518 ch.dr().as_ptr() as _ 518 ch.dr().as_ptr() as _
519} 519}
520 520
521#[cfg(any(sai_v1, sai_v2, sai_v3, sai_v4))] 521pub struct SubBlock<'d, T: Instance, C: Channel, W: word::Word> {
522fn rdr<W: word::Word>(w: crate::pac::sai::Sai, sub_block: SubBlock) -> *mut W {
523 let ch = w.ch(sub_block as usize);
524 ch.dr().as_ptr() as _
525}
526
527pub struct Sai<'d, T: Instance, C: Channel, W: word::Word> {
528 _peri: PeripheralRef<'d, T>, 522 _peri: PeripheralRef<'d, T>,
529 sd: Option<PeripheralRef<'d, AnyPin>>, 523 sd: Option<PeripheralRef<'d, AnyPin>>,
530 fs: Option<PeripheralRef<'d, AnyPin>>, 524 fs: Option<PeripheralRef<'d, AnyPin>>,
531 sck: Option<PeripheralRef<'d, AnyPin>>, 525 sck: Option<PeripheralRef<'d, AnyPin>>,
532 mclk: Option<PeripheralRef<'d, AnyPin>>, 526 mclk: Option<PeripheralRef<'d, AnyPin>>,
533 ring_buffer: RingBuffer<'d, C, W>, 527 ring_buffer: RingBuffer<'d, C, W>,
534 sub_block: SubBlock, 528 sub_block: WhichSubBlock,
535} 529}
536 530
537impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> { 531pub struct SubBlockA {}
538 // return the type for (sd, sck) 532pub struct SubBlockB {}
539 fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) {
540 (
541 //sd is defined by tx/rx mode
542 match tx_rx {
543 TxRx::Transmitter => AFType::OutputPushPull,
544 TxRx::Receiver => AFType::Input,
545 },
546 //clocks (mclk, sck and fs) are defined by master/slave
547 match mode {
548 Mode::Master => AFType::OutputPushPull,
549 Mode::Slave => AFType::Input,
550 },
551 )
552 }
553 533
554 fn get_ring_buffer( 534pub struct Sai<'d, T: Instance> {
555 dma: impl Peripheral<P = C> + 'd, 535 _peri: PeripheralRef<'d, T>,
556 dma_buf: &'d mut [W], 536 sub_block_a_peri: Option<PeripheralRef<'d, T>>,
557 request: Request, 537 sub_block_b_peri: Option<PeripheralRef<'d, T>>,
558 sub_block: SubBlock, 538}
559 tx_rx: TxRx, 539
560 ) -> RingBuffer<'d, C, W> { 540// return the type for (sd, sck)
561 let opts = TransferOptions { 541fn get_af_types(mode: Mode, tx_rx: TxRx) -> (AFType, AFType) {
562 half_transfer_ir: true, 542 (
563 //the new_write() and new_read() always use circular mode 543 //sd is defined by tx/rx mode
564 ..Default::default()
565 };
566 match tx_rx { 544 match tx_rx {
567 TxRx::Transmitter => RingBuffer::Writable(unsafe { 545 TxRx::Transmitter => AFType::OutputPushPull,
568 WritableRingBuffer::new_write(dma, request, wdr(T::REGS, sub_block), dma_buf, opts) 546 TxRx::Receiver => AFType::Input,
569 }), 547 },
570 TxRx::Receiver => RingBuffer::Readable(unsafe { 548 //clocks (mclk, sck and fs) are defined by master/slave
571 ReadableRingBuffer::new_read(dma, request, rdr(T::REGS, sub_block), dma_buf, opts) 549 match mode {
572 }), 550 Mode::Master => AFType::OutputPushPull,
551 Mode::Slave => AFType::Input,
552 },
553 )
554}
555
556fn get_ring_buffer<'d, T: Instance, C: Channel, W: word::Word>(
557 dma: impl Peripheral<P = C> + 'd,
558 dma_buf: &'d mut [W],
559 request: Request,
560 sub_block: WhichSubBlock,
561 tx_rx: TxRx,
562) -> RingBuffer<'d, C, W> {
563 let opts = TransferOptions {
564 half_transfer_ir: true,
565 //the new_write() and new_read() always use circular mode
566 ..Default::default()
567 };
568 match tx_rx {
569 TxRx::Transmitter => RingBuffer::Writable(unsafe {
570 WritableRingBuffer::new_write(dma, request, dr(T::REGS, sub_block), dma_buf, opts)
571 }),
572 TxRx::Receiver => RingBuffer::Readable(unsafe {
573 ReadableRingBuffer::new_read(dma, request, dr(T::REGS, sub_block), dma_buf, opts)
574 }),
575 }
576}
577
578impl<'d, T: Instance> Sai<'d, T> {
579 pub fn new(peri: impl Peripheral<P = T> + 'd) -> Self {
580 T::enable();
581 T::reset();
582
583 Self {
584 _peri: unsafe { peri.clone_unchecked().into_ref() },
585 sub_block_a_peri: Some(unsafe { peri.clone_unchecked().into_ref() }),
586 sub_block_b_peri: Some(peri.into_ref()),
573 } 587 }
574 } 588 }
575 589
576 pub fn new_asynchronous_block_a_with_mclk( 590 pub fn take_sub_block_a(self: &mut Self) -> Option<PeripheralRef<'d, T>> {
591 if self.sub_block_a_peri.is_some() {
592 self.sub_block_a_peri.take()
593 } else {
594 None
595 }
596 }
597
598 pub fn take_sub_block_b(self: &mut Self) -> Option<PeripheralRef<'d, T>> {
599 if self.sub_block_b_peri.is_some() {
600 self.sub_block_b_peri.take()
601 } else {
602 None
603 }
604 }
605}
606
607fn update_synchronous_config(config: &mut Config) {
608 config.mode = Mode::Slave;
609 config.is_sync_output = false;
610
611 #[cfg(any(sai_v1, sai_v2, sai_v3))]
612 {
613 config.sync_enable = SyncEnable::Internal;
614 }
615
616 #[cfg(any(sai_v4))]
617 {
618 //this must either be Internal or External
619 //The asynchronous sub-block on the same SAI needs to enable is_sync_output
620 assert!(config.sync_enable != SyncEnable::Asynchronous);
621 }
622}
623
624impl SubBlockA {
625 pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
577 peri: impl Peripheral<P = T> + 'd, 626 peri: impl Peripheral<P = T> + 'd,
578 sck: impl Peripheral<P = impl SckAPin<T>> + 'd, 627 sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
579 sd: impl Peripheral<P = impl SdAPin<T>> + 'd, 628 sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
@@ -582,13 +631,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
582 dma: impl Peripheral<P = C> + 'd, 631 dma: impl Peripheral<P = C> + 'd,
583 dma_buf: &'d mut [W], 632 dma_buf: &'d mut [W],
584 mut config: Config, 633 mut config: Config,
585 ) -> Self 634 ) -> SubBlock<T, C, W>
586 where 635 where
587 C: Channel + DmaA<T>, 636 C: Channel + DmaA<T>,
588 { 637 {
589 into_ref!(mclk); 638 into_ref!(mclk);
590 639
591 let (_sd_af_type, ck_af_type) = Self::get_af_types(config.mode, config.tx_rx); 640 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
592 641
593 mclk.set_as_af(mclk.af_num(), ck_af_type); 642 mclk.set_as_af(mclk.af_num(), ck_af_type);
594 mclk.set_speed(crate::gpio::Speed::VeryHigh); 643 mclk.set_speed(crate::gpio::Speed::VeryHigh);
@@ -597,10 +646,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
597 config.master_clock_divider = MasterClockDivider::Div1; 646 config.master_clock_divider = MasterClockDivider::Div1;
598 } 647 }
599 648
600 Self::new_asynchronous_block_a(peri, sck, sd, fs, dma, dma_buf, config) 649 Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
601 } 650 }
602 651
603 pub fn new_asynchronous_block_a( 652 pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
604 peri: impl Peripheral<P = T> + 'd, 653 peri: impl Peripheral<P = T> + 'd,
605 sck: impl Peripheral<P = impl SckAPin<T>> + 'd, 654 sck: impl Peripheral<P = impl SckAPin<T>> + 'd,
606 sd: impl Peripheral<P = impl SdAPin<T>> + 'd, 655 sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
@@ -608,13 +657,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
608 dma: impl Peripheral<P = C> + 'd, 657 dma: impl Peripheral<P = C> + 'd,
609 dma_buf: &'d mut [W], 658 dma_buf: &'d mut [W],
610 config: Config, 659 config: Config,
611 ) -> Self 660 ) -> SubBlock<T, C, W>
612 where 661 where
613 C: Channel + DmaA<T>, 662 C: Channel + DmaA<T>,
614 { 663 {
615 into_ref!(peri, dma, sck, sd, fs); 664 into_ref!(peri, dma, sck, sd, fs);
616 665
617 let (sd_af_type, ck_af_type) = Self::get_af_types(config.mode, config.tx_rx); 666 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
618 sd.set_as_af(sd.af_num(), sd_af_type); 667 sd.set_as_af(sd.af_num(), sd_af_type);
619 sd.set_speed(crate::gpio::Speed::VeryHigh); 668 sd.set_speed(crate::gpio::Speed::VeryHigh);
620 669
@@ -623,22 +672,58 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
623 fs.set_as_af(fs.af_num(), ck_af_type); 672 fs.set_as_af(fs.af_num(), ck_af_type);
624 fs.set_speed(crate::gpio::Speed::VeryHigh); 673 fs.set_speed(crate::gpio::Speed::VeryHigh);
625 674
626 let sub_block = SubBlock::A; 675 let sub_block = WhichSubBlock::A;
627 let request = dma.request(); 676 let request = dma.request();
628 677
629 Self::new_inner( 678 SubBlock::new_inner(
630 peri, 679 peri,
631 sub_block, 680 sub_block,
632 Some(sck.map_into()), 681 Some(sck.map_into()),
633 None, 682 None,
634 Some(sd.map_into()), 683 Some(sd.map_into()),
635 Some(fs.map_into()), 684 Some(fs.map_into()),
636 Self::get_ring_buffer(dma, dma_buf, request, sub_block, config.tx_rx), 685 get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
686 config,
687 )
688 }
689
690 pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
691 peri: impl Peripheral<P = T> + 'd,
692 sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
693 dma: impl Peripheral<P = C> + 'd,
694 dma_buf: &'d mut [W],
695 mut config: Config,
696 ) -> SubBlock<T, C, W>
697 where
698 C: Channel + DmaA<T>,
699 {
700 update_synchronous_config(&mut config);
701
702 into_ref!(dma, peri, sd);
703
704 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
705
706 sd.set_as_af(sd.af_num(), sd_af_type);
707 sd.set_speed(crate::gpio::Speed::VeryHigh);
708
709 let sub_block = WhichSubBlock::A;
710 let request = dma.request();
711
712 SubBlock::new_inner(
713 peri,
714 sub_block,
715 None,
716 None,
717 Some(sd.map_into()),
718 None,
719 get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
637 config, 720 config,
638 ) 721 )
639 } 722 }
723}
640 724
641 pub fn new_asynchronous_block_b_with_mclk( 725impl SubBlockB {
726 pub fn new_asynchronous_with_mclk<'d, T: Instance, C: Channel, W: word::Word>(
642 peri: impl Peripheral<P = T> + 'd, 727 peri: impl Peripheral<P = T> + 'd,
643 sck: impl Peripheral<P = impl SckBPin<T>> + 'd, 728 sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
644 sd: impl Peripheral<P = impl SdBPin<T>> + 'd, 729 sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
@@ -647,13 +732,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
647 dma: impl Peripheral<P = C> + 'd, 732 dma: impl Peripheral<P = C> + 'd,
648 dma_buf: &'d mut [W], 733 dma_buf: &'d mut [W],
649 mut config: Config, 734 mut config: Config,
650 ) -> Self 735 ) -> SubBlock<T, C, W>
651 where 736 where
652 C: Channel + DmaB<T>, 737 C: Channel + DmaB<T>,
653 { 738 {
654 into_ref!(mclk); 739 into_ref!(mclk);
655 740
656 let (_sd_af_type, ck_af_type) = Self::get_af_types(config.mode, config.tx_rx); 741 let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
657 742
658 mclk.set_as_af(mclk.af_num(), ck_af_type); 743 mclk.set_as_af(mclk.af_num(), ck_af_type);
659 mclk.set_speed(crate::gpio::Speed::VeryHigh); 744 mclk.set_speed(crate::gpio::Speed::VeryHigh);
@@ -662,10 +747,10 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
662 config.master_clock_divider = MasterClockDivider::Div1; 747 config.master_clock_divider = MasterClockDivider::Div1;
663 } 748 }
664 749
665 Self::new_asynchronous_block_b(peri, sck, sd, fs, dma, dma_buf, config) 750 Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config)
666 } 751 }
667 752
668 pub fn new_asynchronous_block_b( 753 pub fn new_asynchronous<'d, T: Instance, C: Channel, W: word::Word>(
669 peri: impl Peripheral<P = T> + 'd, 754 peri: impl Peripheral<P = T> + 'd,
670 sck: impl Peripheral<P = impl SckBPin<T>> + 'd, 755 sck: impl Peripheral<P = impl SckBPin<T>> + 'd,
671 sd: impl Peripheral<P = impl SdBPin<T>> + 'd, 756 sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
@@ -673,13 +758,13 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
673 dma: impl Peripheral<P = C> + 'd, 758 dma: impl Peripheral<P = C> + 'd,
674 dma_buf: &'d mut [W], 759 dma_buf: &'d mut [W],
675 config: Config, 760 config: Config,
676 ) -> Self 761 ) -> SubBlock<T, C, W>
677 where 762 where
678 C: Channel + DmaB<T>, 763 C: Channel + DmaB<T>,
679 { 764 {
680 into_ref!(dma, peri, sck, sd, fs); 765 into_ref!(dma, peri, sck, sd, fs);
681 766
682 let (sd_af_type, ck_af_type) = Self::get_af_types(config.mode, config.tx_rx); 767 let (sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx);
683 768
684 sd.set_as_af(sd.af_num(), sd_af_type); 769 sd.set_as_af(sd.af_num(), sd_af_type);
685 sd.set_speed(crate::gpio::Speed::VeryHigh); 770 sd.set_speed(crate::gpio::Speed::VeryHigh);
@@ -689,106 +774,57 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
689 fs.set_as_af(fs.af_num(), ck_af_type); 774 fs.set_as_af(fs.af_num(), ck_af_type);
690 fs.set_speed(crate::gpio::Speed::VeryHigh); 775 fs.set_speed(crate::gpio::Speed::VeryHigh);
691 776
692 let sub_block = SubBlock::B; 777 let sub_block = WhichSubBlock::B;
693 let request = dma.request(); 778 let request = dma.request();
694 779
695 Self::new_inner( 780 SubBlock::new_inner(
696 peri, 781 peri,
697 sub_block, 782 sub_block,
698 Some(sck.map_into()), 783 Some(sck.map_into()),
699 None, 784 None,
700 Some(sd.map_into()), 785 Some(sd.map_into()),
701 Some(fs.map_into()), 786 Some(fs.map_into()),
702 Self::get_ring_buffer(dma, dma_buf, request, sub_block, config.tx_rx), 787 get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
703 config, 788 config,
704 ) 789 )
705 } 790 }
706 791
707 fn update_synchronous_config(config: &mut Config) { 792 pub fn new_synchronous<'d, T: Instance, C: Channel, W: word::Word>(
708 config.mode = Mode::Slave;
709 config.is_sync_output = false;
710
711 #[cfg(any(sai_v1, sai_v2, sai_v3))]
712 {
713 config.sync_enable = SyncEnable::Internal;
714 }
715
716 #[cfg(any(sai_v4))]
717 {
718 //this must either be Internal or External
719 //The asynchronous sub-block on the same SAI needs to enable is_sync_output
720 assert!(config.sync_enable != SyncEnable::Asynchronous);
721 }
722 }
723
724 pub fn new_synchronous_block_a(
725 peri: impl Peripheral<P = T> + 'd,
726 sd: impl Peripheral<P = impl SdAPin<T>> + 'd,
727 dma: impl Peripheral<P = C> + 'd,
728 dma_buf: &'d mut [W],
729 mut config: Config,
730 ) -> Self
731 where
732 C: Channel + DmaA<T>,
733 {
734 Self::update_synchronous_config(&mut config);
735
736 into_ref!(dma, peri, sd);
737
738 let (sd_af_type, _ck_af_type) = Self::get_af_types(config.mode, config.tx_rx);
739
740 sd.set_as_af(sd.af_num(), sd_af_type);
741 sd.set_speed(crate::gpio::Speed::VeryHigh);
742
743 let sub_block = SubBlock::A;
744 let request = dma.request();
745
746 Self::new_inner(
747 peri,
748 sub_block,
749 None,
750 None,
751 Some(sd.map_into()),
752 None,
753 Self::get_ring_buffer(dma, dma_buf, request, sub_block, config.tx_rx),
754 config,
755 )
756 }
757
758 pub fn new_synchronous_block_b(
759 peri: impl Peripheral<P = T> + 'd, 793 peri: impl Peripheral<P = T> + 'd,
760 sd: impl Peripheral<P = impl SdBPin<T>> + 'd, 794 sd: impl Peripheral<P = impl SdBPin<T>> + 'd,
761 dma: impl Peripheral<P = C> + 'd, 795 dma: impl Peripheral<P = C> + 'd,
762 dma_buf: &'d mut [W], 796 dma_buf: &'d mut [W],
763 mut config: Config, 797 mut config: Config,
764 ) -> Self 798 ) -> SubBlock<T, C, W>
765 where 799 where
766 C: Channel + DmaB<T>, 800 C: Channel + DmaB<T>,
767 { 801 {
768 Self::update_synchronous_config(&mut config); 802 update_synchronous_config(&mut config);
769 803
770 into_ref!(dma, peri, sd); 804 into_ref!(dma, peri, sd);
771 805
772 let (sd_af_type, _ck_af_type) = Self::get_af_types(config.mode, config.tx_rx); 806 let (sd_af_type, _ck_af_type) = get_af_types(config.mode, config.tx_rx);
773 807
774 sd.set_as_af(sd.af_num(), sd_af_type); 808 sd.set_as_af(sd.af_num(), sd_af_type);
775 sd.set_speed(crate::gpio::Speed::VeryHigh); 809 sd.set_speed(crate::gpio::Speed::VeryHigh);
776 810
777 let sub_block = SubBlock::B; 811 let sub_block = WhichSubBlock::B;
778 let request = dma.request(); 812 let request = dma.request();
779 813
780 Self::new_inner( 814 SubBlock::new_inner(
781 peri, 815 peri,
782 sub_block, 816 sub_block,
783 None, 817 None,
784 None, 818 None,
785 Some(sd.map_into()), 819 Some(sd.map_into()),
786 None, 820 None,
787 Self::get_ring_buffer(dma, dma_buf, request, sub_block, config.tx_rx), 821 get_ring_buffer::<T, C, W>(dma, dma_buf, request, sub_block, config.tx_rx),
788 config, 822 config,
789 ) 823 )
790 } 824 }
825}
791 826
827impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> {
792 pub fn start(self: &mut Self) { 828 pub fn start(self: &mut Self) {
793 match self.ring_buffer { 829 match self.ring_buffer {
794 RingBuffer::Writable(ref mut rb) => { 830 RingBuffer::Writable(ref mut rb) => {
@@ -809,7 +845,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
809 845
810 fn new_inner( 846 fn new_inner(
811 peri: impl Peripheral<P = T> + 'd, 847 peri: impl Peripheral<P = T> + 'd,
812 sub_block: SubBlock, 848 sub_block: WhichSubBlock,
813 sck: Option<PeripheralRef<'d, AnyPin>>, 849 sck: Option<PeripheralRef<'d, AnyPin>>,
814 mclk: Option<PeripheralRef<'d, AnyPin>>, 850 mclk: Option<PeripheralRef<'d, AnyPin>>,
815 sd: Option<PeripheralRef<'d, AnyPin>>, 851 sd: Option<PeripheralRef<'d, AnyPin>>,
@@ -974,7 +1010,7 @@ impl<'d, T: Instance, C: Channel, W: word::Word> Sai<'d, T, C, W> {
974 } 1010 }
975} 1011}
976 1012
977impl<'d, T: Instance, C: Channel, W: word::Word> Drop for Sai<'d, T, C, W> { 1013impl<'d, T: Instance, C: Channel, W: word::Word> Drop for SubBlock<'d, T, C, W> {
978 fn drop(&mut self) { 1014 fn drop(&mut self) {
979 let ch = T::REGS.ch(self.sub_block as usize); 1015 let ch = T::REGS.ch(self.sub_block as usize);
980 ch.cr1().modify(|w| w.set_saien(false)); 1016 ch.cr1().modify(|w| w.set_saien(false));
@@ -1018,9 +1054,9 @@ foreach_peripheral!(
1018 }; 1054 };
1019); 1055);
1020 1056
1021impl<'d, T: Instance, C: Channel, W: word::Word> SetConfig for Sai<'d, T, C, W> { 1057impl<'d, T: Instance> SetConfig for Sai<'d, T> {
1022 type Config = Config; 1058 type Config = Config;
1023 fn set_config(&mut self, config: &Self::Config) { 1059 fn set_config(&mut self, config: &Self::Config) {
1024 self.reconfigure(*config); 1060 // self.reconfigure(*config);
1025 } 1061 }
1026} 1062}