From da9ee837561694a7749e17d727e56da7ddb3e9b2 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 23 Dec 2022 09:32:18 +0100 Subject: [PATCH 1/5] fix(stm32): Fix write buffer lifetime for repeated writes --- embassy-stm32/src/dma/bdma.rs | 5 ++--- embassy-stm32/src/dma/dma.rs | 5 ++--- embassy-stm32/src/dma/gpdma.rs | 5 ++--- embassy-stm32/src/dma/mod.rs | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index e6ce05b7b..7da22ec12 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -78,8 +78,7 @@ foreach_dma_channel! { ); } - unsafe fn start_write_repeated(&mut self, _request: Request, repeated: W, count: usize, reg_addr: *mut W, options: TransferOptions) { - let buf = [repeated]; + unsafe fn start_write_repeated(&mut self, _request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, @@ -87,7 +86,7 @@ foreach_dma_channel! { _request, vals::Dir::FROMMEMORY, reg_addr as *const u32, - buf.as_ptr() as *mut u32, + repeated.as_ptr() as *mut u32, count, false, vals::Size::from(W::bits()), diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 97a3df088..45a38dda4 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -102,15 +102,14 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W, options: TransferOptions) { - let buf = [repeated]; + unsafe fn start_write_repeated(&mut self, request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, request, vals::Dir::MEMORYTOPERIPHERAL, reg_addr as *const u32, - buf.as_ptr() as *mut u32, + repeated.as_ptr() as *mut u32, count, false, vals::Size::from(W::bits()), diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index bde8c3ef3..46d8715b9 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -75,15 +75,14 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: W, count: usize, reg_addr: *mut W, options: TransferOptions) { - let buf = [repeated]; + unsafe fn start_write_repeated(&mut self, request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, request, low_level_api::Dir::MemoryToPeripheral, reg_addr as *const u32, - buf.as_ptr() as *mut u32, + repeated.as_ptr() as *mut u32, count, false, W::bits(), diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 74bce6aa9..31f55b868 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -59,7 +59,7 @@ pub(crate) mod sealed { unsafe fn start_write_repeated( &mut self, request: Request, - repeated: W, + repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions, @@ -246,7 +246,7 @@ mod transfers { pub fn write_repeated<'a, W: Word>( channel: impl Peripheral

+ 'a, request: Request, - repeated: W, + repeated: &[W; 1], count: usize, reg_addr: *mut W, ) -> impl Future + 'a { From 2457fcaa35f7ceafcaee44f5e4b2a63c83674c89 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 23 Dec 2022 09:33:34 +0100 Subject: [PATCH 2/5] fix(stm32): Align with updated dma::write_repeated signature --- embassy-stm32/src/spi/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index ab4352a5c..1d4baf46d 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -473,8 +473,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_request = self.txdma.request(); let tx_dst = T::REGS.tx_ptr(); - let clock_byte = 0x00u8; - let tx_f = crate::dma::write_repeated(&mut self.txdma, tx_request, clock_byte, clock_byte_count, tx_dst); + let clock_byte = [0x00u8]; + let tx_f = crate::dma::write_repeated(&mut self.txdma, tx_request, &clock_byte, clock_byte_count, tx_dst); unsafe { set_txdmaen(T::REGS, true); From 662bb5797f7723f16b0d5211c17e6a9fdeb2cf50 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 23 Dec 2022 09:34:42 +0100 Subject: [PATCH 3/5] fix(stm32): Ensure that gpio speed is VeryHigh for all spi versions This fixes #1095 --- embassy-stm32/src/spi/mod.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 1d4baf46d..439d92b97 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -95,13 +95,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { into_ref!(peri, sck, mosi, miso); unsafe { sck.set_as_af(sck.af_num(), AFType::OutputPushPull); - #[cfg(any(spi_v2, spi_v3, spi_v4))] sck.set_speed(crate::gpio::Speed::VeryHigh); mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull); - #[cfg(any(spi_v2, spi_v3, spi_v4))] mosi.set_speed(crate::gpio::Speed::VeryHigh); miso.set_as_af(miso.af_num(), AFType::Input); - #[cfg(any(spi_v2, spi_v3, spi_v4))] miso.set_speed(crate::gpio::Speed::VeryHigh); } @@ -129,10 +126,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { into_ref!(sck, miso); unsafe { sck.set_as_af(sck.af_num(), AFType::OutputPushPull); - #[cfg(any(spi_v2, spi_v3, spi_v4))] sck.set_speed(crate::gpio::Speed::VeryHigh); miso.set_as_af(miso.af_num(), AFType::Input); - #[cfg(any(spi_v2, spi_v3, spi_v4))] miso.set_speed(crate::gpio::Speed::VeryHigh); } @@ -160,10 +155,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { into_ref!(sck, mosi); unsafe { sck.set_as_af(sck.af_num(), AFType::OutputPushPull); - #[cfg(any(spi_v2, spi_v3, spi_v4))] sck.set_speed(crate::gpio::Speed::VeryHigh); mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull); - #[cfg(any(spi_v2, spi_v3, spi_v4))] mosi.set_speed(crate::gpio::Speed::VeryHigh); } @@ -772,10 +765,13 @@ fn finish_dma(regs: Regs) { #[cfg(not(any(spi_v3, spi_v4)))] while regs.sr().read().bsy() {} + // Disable the spi peripheral regs.cr1().modify(|w| { w.set_spe(false); }); + // The peripheral automatically disables the DMA stream on completion without error, + // but it does not clear the RXDMAEN/TXDMAEN flag in CR2. #[cfg(not(any(spi_v3, spi_v4)))] regs.cr2().modify(|reg| { reg.set_txdmaen(false); From e9a2c4a9e38ada8a6927e6dba66d486d190edf21 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 23 Dec 2022 15:40:09 +0100 Subject: [PATCH 4/5] Let start_write_repeated accept pointer instead of slice --- embassy-stm32/src/dma/bdma.rs | 4 ++-- embassy-stm32/src/dma/dma.rs | 4 ++-- embassy-stm32/src/dma/gpdma.rs | 4 ++-- embassy-stm32/src/dma/mod.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index 7da22ec12..bc51cdc43 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -78,7 +78,7 @@ foreach_dma_channel! { ); } - unsafe fn start_write_repeated(&mut self, _request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, _request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, @@ -86,7 +86,7 @@ foreach_dma_channel! { _request, vals::Dir::FROMMEMORY, reg_addr as *const u32, - repeated.as_ptr() as *mut u32, + repeated as *mut u32, count, false, vals::Size::from(W::bits()), diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 45a38dda4..250505859 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -102,14 +102,14 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, request, vals::Dir::MEMORYTOPERIPHERAL, reg_addr as *const u32, - repeated.as_ptr() as *mut u32, + repeated as *mut u32, count, false, vals::Size::from(W::bits()), diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 46d8715b9..87c0dfdf0 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -75,14 +75,14 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: &[W; 1], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, request, low_level_api::Dir::MemoryToPeripheral, reg_addr as *const u32, - repeated.as_ptr() as *mut u32, + repeated as *mut u32, count, false, W::bits(), diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 31f55b868..706bcff30 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -59,7 +59,7 @@ pub(crate) mod sealed { unsafe fn start_write_repeated( &mut self, request: Request, - repeated: &[W; 1], + repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions, @@ -246,7 +246,7 @@ mod transfers { pub fn write_repeated<'a, W: Word>( channel: impl Peripheral

+ 'a, request: Request, - repeated: &[W; 1], + repeated: *const [W], count: usize, reg_addr: *mut W, ) -> impl Future + 'a { From 47a0769fc287afa8c982514ea34de0d4f18a3f99 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Fri, 23 Dec 2022 15:49:22 +0100 Subject: [PATCH 5/5] Let repeated clock byte be singular pointer and not array pointer --- embassy-stm32/src/dma/bdma.rs | 2 +- embassy-stm32/src/dma/dma.rs | 2 +- embassy-stm32/src/dma/gpdma.rs | 2 +- embassy-stm32/src/dma/mod.rs | 4 ++-- embassy-stm32/src/spi/mod.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index bc51cdc43..6160b9f40 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -78,7 +78,7 @@ foreach_dma_channel! { ); } - unsafe fn start_write_repeated(&mut self, _request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, _request: Request, repeated: *const W, count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 250505859..fec60f708 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -102,7 +102,7 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const W, count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 87c0dfdf0..d252cef3e 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs @@ -75,7 +75,7 @@ foreach_dma_channel! { ) } - unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const [W], count: usize, reg_addr: *mut W, options: TransferOptions) { + unsafe fn start_write_repeated(&mut self, request: Request, repeated: *const W, count: usize, reg_addr: *mut W, options: TransferOptions) { low_level_api::start_transfer( pac::$dma_peri, $channel_num, diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 706bcff30..b51e0d40b 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs @@ -59,7 +59,7 @@ pub(crate) mod sealed { unsafe fn start_write_repeated( &mut self, request: Request, - repeated: *const [W], + repeated: *const W, count: usize, reg_addr: *mut W, options: TransferOptions, @@ -246,7 +246,7 @@ mod transfers { pub fn write_repeated<'a, W: Word>( channel: impl Peripheral

+ 'a, request: Request, - repeated: *const [W], + repeated: *const W, count: usize, reg_addr: *mut W, ) -> impl Future + 'a { diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 439d92b97..5b81c791a 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -466,7 +466,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { let tx_request = self.txdma.request(); let tx_dst = T::REGS.tx_ptr(); - let clock_byte = [0x00u8]; + let clock_byte = 0x00u8; let tx_f = crate::dma::write_repeated(&mut self.txdma, tx_request, &clock_byte, clock_byte_count, tx_dst); unsafe {