Skip to content

Commit e64497b

Browse files
authored
Keep peripheral enabled when converting from SpiRxTxDma back to Spi. (#317)
1 parent 7bbecc1 commit e64497b

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/spi.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ pub struct Spi<SPI, PINS> {
7070
macro_rules! hal {
7171
($($SPIX:ident: ($spiX:ident, $spiX_slave:ident, $pclkX:ident),)+) => {
7272
$(
73+
impl<PINS> Spi<$SPIX, PINS> {
74+
/// Enable the SPI peripheral.
75+
#[allow(unused)] // Only used for DMA.
76+
#[inline]
77+
fn enable(&mut self) {
78+
self.spi.cr1.modify(|_, w| w.spe().set_bit());
79+
}
80+
81+
/// Disable the SPI peripheral.
82+
#[inline]
83+
fn disable(&mut self) {
84+
self.spi.cr1.modify(|_, w| w.spe().clear_bit());
85+
}
86+
}
87+
7388
impl<SCK, MISO, MOSI> Spi<$SPIX, (SCK, MISO, MOSI)> {
7489
/// Configures the SPI peripheral to operate in full duplex master mode
7590
#[allow(unused_unsafe)] // Necessary for stm32l4r9
@@ -192,7 +207,7 @@ macro_rules! hal {
192207
/// Change the baud rate of the SPI
193208
#[allow(unused_unsafe)] // Necessary for stm32l4r9
194209
pub fn reclock(&mut self, freq: Hertz, clocks: Clocks) {
195-
self.spi.cr1.modify(|_, w| w.spe().clear_bit());
210+
self.disable();
196211
self.spi.cr1.modify(|_, w| unsafe {
197212
w.br().bits(Self::compute_baud_rate(clocks.$pclkX(), freq));
198213
w.spe().set_bit()
@@ -543,21 +558,30 @@ macro_rules! spi_dma {
543558
impl<PINS> SpiRxDma<$SPIX, PINS, $RX_CH> {
544559
pub fn split(mut self) -> (Spi<$SPIX, PINS>, $RX_CH) {
545560
self.stop();
546-
(self.payload.spi, self.channel)
561+
let mut spi = self.payload.spi;
562+
// Keep the peripheral itself enabled after stopping DMA.
563+
spi.enable();
564+
(spi, self.channel)
547565
}
548566
}
549567

550568
impl<PINS> SpiTxDma<$SPIX, PINS, $TX_CH> {
551569
pub fn split(mut self) -> (Spi<$SPIX, PINS>, $TX_CH) {
552570
self.stop();
553-
(self.payload.spi, self.channel)
571+
let mut spi = self.payload.spi;
572+
// Keep the peripheral itself enabled after stopping DMA.
573+
spi.enable();
574+
(spi, self.channel)
554575
}
555576
}
556577

557578
impl<PINS> SpiRxTxDma<$SPIX, PINS, $RX_CH, $TX_CH> {
558579
pub fn split(mut self) -> (Spi<$SPIX, PINS>, $RX_CH, $TX_CH) {
559580
self.stop();
560-
(self.payload.spi, self.rx_channel, self.tx_channel)
581+
let mut spi = self.payload.spi;
582+
// Keep the peripheral itself enabled after stopping DMA.
583+
spi.enable();
584+
(spi, self.rx_channel, self.tx_channel)
561585
}
562586
}
563587

@@ -572,14 +596,14 @@ macro_rules! spi_dma {
572596
// 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
573597
// 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
574598
// 4. Enable the SPI by setting the SPE bit.
575-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 0.
599+
self.payload.spi.disable(); // 0.
576600
self.payload
577601
.spi
578602
.spi
579603
.cr2
580604
.modify(|_, w| w.rxdmaen().set_bit()); // 1.
581605
self.channel.start(); // 2.
582-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().set_bit()); // 4.
606+
self.payload.spi.enable(); // 4.
583607
}
584608

585609
fn stop(&mut self) {
@@ -592,7 +616,7 @@ macro_rules! spi_dma {
592616
// 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
593617
// SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
594618
self.channel.stop(); // 1.
595-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 2.
619+
self.payload.spi.disable(); // 2.
596620
self.payload
597621
.spi
598622
.spi
@@ -612,14 +636,14 @@ macro_rules! spi_dma {
612636
// 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
613637
// 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
614638
// 4. Enable the SPI by setting the SPE bit.
615-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 0.
639+
self.payload.spi.disable(); // 0.
616640
self.channel.start(); // 2.
617641
self.payload
618642
.spi
619643
.spi
620644
.cr2
621645
.modify(|_, w| w.txdmaen().set_bit()); // 3.
622-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().set_bit()); // 4.
646+
self.payload.spi.enable(); // 4.
623647
}
624648

625649
fn stop(&mut self) {
@@ -632,7 +656,7 @@ macro_rules! spi_dma {
632656
// 3. Disable DMA Tx and Rx buffers by clearing the TXDMAEN and RXDMAEN bits in the
633657
// SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
634658
self.channel.stop(); // 1.
635-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 2.
659+
self.payload.spi.disable(); // 2.
636660
self.payload
637661
.spi
638662
.spi
@@ -652,7 +676,7 @@ macro_rules! spi_dma {
652676
// 2. Enable DMA streams for Tx and Rx in DMA registers, if the streams are used.
653677
// 3. Enable DMA Tx buffer in the TXDMAEN bit in the SPI_CR2 register, if DMA Tx is used.
654678
// 4. Enable the SPI by setting the SPE bit.
655-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 0.
679+
self.payload.spi.disable(); // 0.
656680
self.payload
657681
.spi
658682
.spi
@@ -665,7 +689,7 @@ macro_rules! spi_dma {
665689
.spi
666690
.cr2
667691
.modify(|_, w| w.txdmaen().set_bit()); // 3.
668-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().set_bit()); // 4.
692+
self.payload.spi.enable(); // 4.
669693
}
670694

671695
fn stop(&mut self) {
@@ -679,7 +703,7 @@ macro_rules! spi_dma {
679703
// SPI_CR2 register, if DMA Tx and/or DMA Rx are used.
680704
self.tx_channel.stop(); // 1.
681705
self.rx_channel.stop(); // 1.
682-
self.payload.spi.spi.cr1.modify(|_, w| w.spe().clear_bit()); // 2.
706+
self.payload.spi.disable(); // 2.
683707
self.payload
684708
.spi
685709
.spi

0 commit comments

Comments
 (0)