@@ -572,63 +572,128 @@ macro_rules! spi_dma {
572
572
573
573
impl <PINS > dma:: TransferPayload for SpiRxDma <$SPIX, PINS , $RX_CH> {
574
574
fn start( & mut self ) {
575
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
576
+ // DMA (direct memory addressing)".
577
+ // It is mandatory to follow these steps in order:
578
+ //
579
+ // 0. SPI disabled during setup.
580
+ // 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CR2 register, if DMA Rx is used.
581
+ // 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
582
+ // 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
583
+ // 4. Enable the SPI by setting the SPE bit.
584
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 0.
575
585
self . payload
576
586
. spi
577
587
. spi
578
588
. cr2
579
- . modify( |_, w| w. rxdmaen( ) . set_bit( ) ) ;
580
- self . channel. start( ) ;
589
+ . modify( |_, w| w. rxdmaen( ) . set_bit( ) ) ; // 1.
590
+ self . channel. start( ) ; // 2.
591
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . set_bit( ) ) ; // 4.
581
592
}
582
593
583
594
fn stop( & mut self ) {
584
- self . channel. stop( ) ;
595
+ // Stop DMA channels in accordance with RM 40.4.9, subheading "Communication using
596
+ // DMA (direct memory addressing)".
597
+ // It is mandatory to follow these steps in order:
598
+ //
599
+ // 1. Disable DMA streams for Tx and Rx in the DMA registers, if the streams are used.
600
+ // 2. Disable the SPI by following the SPI disable procedure.
601
+ // 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
602
+ // SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
603
+ self . channel. stop( ) ; // 1.
604
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 2.
585
605
self . payload
586
606
. spi
587
607
. spi
588
608
. cr2
589
- . modify( |_, w| w. rxdmaen( ) . clear_bit( ) ) ;
609
+ . modify( |_, w| w. rxdmaen( ) . clear_bit( ) ) ; // 3.
590
610
}
591
611
}
592
612
593
613
impl <PINS > dma:: TransferPayload for SpiTxDma <$SPIX, PINS , $TX_CH> {
594
614
fn start( & mut self ) {
615
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
616
+ // DMA (direct memory addressing)".
617
+ // It is mandatory to follow these steps in order:
618
+ //
619
+ // 0. SPI disabled during setup.
620
+ // 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CR2 register, if DMA Rx is used.
621
+ // 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
622
+ // 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
623
+ // 4. Enable the SPI by setting the SPE bit.
624
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 0.
625
+ self . channel. start( ) ; // 2.
595
626
self . payload
596
627
. spi
597
628
. spi
598
629
. cr2
599
- . modify( |_, w| w. txdmaen( ) . set_bit( ) ) ;
600
- self . channel . start ( ) ;
630
+ . modify( |_, w| w. txdmaen( ) . set_bit( ) ) ; // 3.
631
+ self . payload . spi . spi . cr1 . modify ( |_ , w| w . spe ( ) . set_bit ( ) ) ; // 4.
601
632
}
602
633
603
634
fn stop( & mut self ) {
604
- self . channel. stop( ) ;
635
+ // Stop DMA channels in accordance with RM 40.4.9, subheading "Communication using
636
+ // DMA (direct memory addressing)".
637
+ // It is mandatory to follow these steps in order:
638
+ //
639
+ // 1. Disable DMA streams for Tx and Rx in the DMA registers, if the streams are used.
640
+ // 2. Disable the SPI by following the SPI disable procedure.
641
+ // 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
642
+ // SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
643
+ self . channel. stop( ) ; // 1.
644
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 2.
605
645
self . payload
606
646
. spi
607
647
. spi
608
648
. cr2
609
- . modify( |_, w| w. txdmaen( ) . clear_bit( ) ) ;
649
+ . modify( |_, w| w. txdmaen( ) . clear_bit( ) ) ; // 3.
610
650
}
611
651
}
612
652
613
653
impl <PINS > dma:: TransferPayload for SpiRxTxDma <$SPIX, PINS , $RX_CH, $TX_CH> {
614
654
fn start( & mut self ) {
655
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
656
+ // DMA (direct memory addressing)".
657
+ // It is mandatory to follow these steps in order:
658
+ //
659
+ // 0. SPI disabled during setup.
660
+ // 1. Enable DMA Rx buffer in the RXDMAEN bit in the SPI_CR2 register, if DMA Rx is used.
661
+ // 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
662
+ // 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
663
+ // 4. Enable the SPI by setting the SPE bit.
664
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 0.
665
+ self . payload
666
+ . spi
667
+ . spi
668
+ . cr2
669
+ . modify( |_, w| w. rxdmaen( ) . set_bit( ) ) ; // 1.
670
+ self . rx_channel. start( ) ; // 2.
671
+ self . tx_channel. start( ) ; // 2.
615
672
self . payload
616
673
. spi
617
674
. spi
618
675
. cr2
619
- . modify( |_, w| w. rxdmaen( ) . set_bit( ) . txdmaen( ) . set_bit( ) ) ;
620
- self . rx_channel. start( ) ;
621
- self . tx_channel. start( ) ;
676
+ . modify( |_, w| w. txdmaen( ) . set_bit( ) ) ; // 3.
677
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . set_bit( ) ) ; // 4.
622
678
}
623
679
624
680
fn stop( & mut self ) {
625
- self . tx_channel. stop( ) ;
626
- self . rx_channel. stop( ) ;
681
+ // Stop DMA channels in accordance with RM 40.4.9, subheading "Communication using
682
+ // DMA (direct memory addressing)".
683
+ // It is mandatory to follow these steps in order:
684
+ //
685
+ // 1. Disable DMA streams for Tx and Rx in the DMA registers, if the streams are used.
686
+ // 2. Disable the SPI by following the SPI disable procedure.
687
+ // 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
688
+ // SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
689
+ self . tx_channel. stop( ) ; // 1.
690
+ self . rx_channel. stop( ) ; // 1.
691
+ self . payload. spi. spi. cr1. modify( |_, w| w. spe( ) . clear_bit( ) ) ; // 2.
627
692
self . payload
628
693
. spi
629
694
. spi
630
695
. cr2
631
- . modify( |_, w| w. rxdmaen( ) . clear_bit( ) . txdmaen( ) . clear_bit( ) ) ;
696
+ . modify( |_, w| w. rxdmaen( ) . clear_bit( ) . txdmaen( ) . clear_bit( ) ) ; // 3.
632
697
}
633
698
}
634
699
@@ -637,11 +702,14 @@ macro_rules! spi_dma {
637
702
B : StaticWriteBuffer <Word = u8 >,
638
703
{
639
704
fn read( mut self , mut buffer: B ) -> dma:: Transfer <dma:: W , B , Self > {
705
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
706
+ // DMA (direct memory addressing)"
707
+
640
708
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
641
709
// until the end of the transfer.
642
710
let ( ptr, len) = unsafe { buffer. static_write_buffer( ) } ;
643
711
644
- // Setup RX channel
712
+ // Setup RX channel addresses and length
645
713
self . channel. set_memory_address( ptr as u32 , true ) ;
646
714
self . channel. set_transfer_length( len as u16 ) ;
647
715
@@ -658,11 +726,14 @@ macro_rules! spi_dma {
658
726
B : StaticReadBuffer <Word = u8 >,
659
727
{
660
728
fn write( mut self , buffer: B ) -> dma:: Transfer <dma:: R , B , Self > {
729
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
730
+ // DMA (direct memory addressing)"
731
+
661
732
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
662
733
// until the end of the transfer.
663
734
let ( ptr, len) = unsafe { buffer. static_read_buffer( ) } ;
664
735
665
- // Setup TX channel
736
+ // Setup TX channel addresses and length
666
737
self . channel. set_memory_address( ptr as u32 , true ) ;
667
738
self . channel. set_transfer_length( len as u16 ) ;
668
739
@@ -679,17 +750,20 @@ macro_rules! spi_dma {
679
750
B : StaticWriteBuffer <Word = u8 >,
680
751
{
681
752
fn transfer( mut self , mut buffer: B ) -> dma:: Transfer <dma:: RW , B , Self > {
753
+ // Setup DMA channels in accordance with RM 40.4.9, subheading "Communication using
754
+ // DMA (direct memory addressing)"
755
+
682
756
// Transfer: we use the same buffer for RX and TX
683
757
684
758
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
685
759
// until the end of the transfer.
686
760
let ( ptr, len) = unsafe { buffer. static_write_buffer( ) } ;
687
761
688
- // Setup RX channel
762
+ // Setup RX channel addresses and length
689
763
self . rx_channel. set_memory_address( ptr as u32 , true ) ;
690
764
self . rx_channel. set_transfer_length( len as u16 ) ;
691
765
692
- // Setup TX channel
766
+ // Setup TX channel addresses and length
693
767
self . tx_channel. set_memory_address( ptr as u32 , true ) ;
694
768
self . tx_channel. set_transfer_length( len as u16 ) ;
695
769
0 commit comments