Skip to content

Commit 1aacc2c

Browse files
committed
Alignment with RM
1 parent 07b82b0 commit 1aacc2c

File tree

1 file changed

+92
-18
lines changed

1 file changed

+92
-18
lines changed

src/spi.rs

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -572,63 +572,128 @@ macro_rules! spi_dma {
572572

573573
impl<PINS> dma::TransferPayload for SpiRxDma<$SPIX, PINS, $RX_CH> {
574574
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.
575585
self.payload
576586
.spi
577587
.spi
578588
.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.
581592
}
582593

583594
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.
585605
self.payload
586606
.spi
587607
.spi
588608
.cr2
589-
.modify(|_, w| w.rxdmaen().clear_bit());
609+
.modify(|_, w| w.rxdmaen().clear_bit()); // 3.
590610
}
591611
}
592612

593613
impl<PINS> dma::TransferPayload for SpiTxDma<$SPIX, PINS, $TX_CH> {
594614
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.
595626
self.payload
596627
.spi
597628
.spi
598629
.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.
601632
}
602633

603634
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.
605645
self.payload
606646
.spi
607647
.spi
608648
.cr2
609-
.modify(|_, w| w.txdmaen().clear_bit());
649+
.modify(|_, w| w.txdmaen().clear_bit()); // 3.
610650
}
611651
}
612652

613653
impl<PINS> dma::TransferPayload for SpiRxTxDma<$SPIX, PINS, $RX_CH, $TX_CH> {
614654
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.
615672
self.payload
616673
.spi
617674
.spi
618675
.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.
622678
}
623679

624680
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.
627692
self.payload
628693
.spi
629694
.spi
630695
.cr2
631-
.modify(|_, w| w.rxdmaen().clear_bit().txdmaen().clear_bit());
696+
.modify(|_, w| w.rxdmaen().clear_bit().txdmaen().clear_bit()); // 3.
632697
}
633698
}
634699

@@ -637,11 +702,14 @@ macro_rules! spi_dma {
637702
B: StaticWriteBuffer<Word = u8>,
638703
{
639704
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+
640708
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
641709
// until the end of the transfer.
642710
let (ptr, len) = unsafe { buffer.static_write_buffer() };
643711

644-
// Setup RX channel
712+
// Setup RX channel addresses and length
645713
self.channel.set_memory_address(ptr as u32, true);
646714
self.channel.set_transfer_length(len as u16);
647715

@@ -658,11 +726,14 @@ macro_rules! spi_dma {
658726
B: StaticReadBuffer<Word = u8>,
659727
{
660728
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+
661732
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
662733
// until the end of the transfer.
663734
let (ptr, len) = unsafe { buffer.static_read_buffer() };
664735

665-
// Setup TX channel
736+
// Setup TX channel addresses and length
666737
self.channel.set_memory_address(ptr as u32, true);
667738
self.channel.set_transfer_length(len as u16);
668739

@@ -679,17 +750,20 @@ macro_rules! spi_dma {
679750
B: StaticWriteBuffer<Word = u8>,
680751
{
681752
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+
682756
// Transfer: we use the same buffer for RX and TX
683757

684758
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
685759
// until the end of the transfer.
686760
let (ptr, len) = unsafe { buffer.static_write_buffer() };
687761

688-
// Setup RX channel
762+
// Setup RX channel addresses and length
689763
self.rx_channel.set_memory_address(ptr as u32, true);
690764
self.rx_channel.set_transfer_length(len as u16);
691765

692-
// Setup TX channel
766+
// Setup TX channel addresses and length
693767
self.tx_channel.set_memory_address(ptr as u32, true);
694768
self.tx_channel.set_transfer_length(len as u16);
695769

0 commit comments

Comments
 (0)