From 5db6b4874def68a5cd1fe25e75327cf0abdbaa59 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 29 Oct 2024 17:13:09 +0100 Subject: [PATCH 1/4] Expose async functions for QSPI --- embassy-stm32/src/qspi/mod.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 308947e99..715c260e9 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -353,6 +353,21 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { /// Blocking read data, using DMA. pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) { + let transfer = self.start_read_transfer(transaction, buf); + transfer.blocking_wait(); + } + + /// Blocking read data, using DMA. + pub async fn read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) { + let transfer = self.start_read_transfer(transaction, buf); + transfer.await; + } + + fn start_read_transfer<'a>( + &'a mut self, + transaction: TransferConfig, + buf: &'a mut [u8], + ) -> crate::dma::Transfer<'a> { self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); T::REGS.ccr().modify(|v| { @@ -373,12 +388,22 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { // STM32H7 does not have dmaen #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); - - transfer.blocking_wait(); + transfer } /// Blocking write data, using DMA. pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) { + let transfer = self.start_write_transfer(transaction, buf); + transfer.blocking_wait(); + } + + /// Async write data, using DMA. + pub async fn write_dma(&mut self, buf: &[u8], transaction: TransferConfig) { + let transfer = self.start_write_transfer(transaction, buf); + transfer.await; + } + + fn start_write_transfer<'a>(&'a mut self, transaction: TransferConfig, buf: &'a [u8]) -> crate::dma::Transfer<'a> { self.setup_transaction(QspiMode::IndirectWrite, &transaction, Some(buf.len())); T::REGS.ccr().modify(|v| { @@ -395,8 +420,7 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { // STM32H7 does not have dmaen #[cfg(not(stm32h7))] T::REGS.cr().modify(|v| v.set_dmaen(true)); - - transfer.blocking_wait(); + transfer } } From 2d899a17e727a9b68ce01090b412c8211f055293 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 29 Oct 2024 17:26:35 +0100 Subject: [PATCH 2/4] Add some sanity checks --- embassy-stm32/src/qspi/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 715c260e9..6530b75b1 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -202,6 +202,18 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { } fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option) { + if let (Some(_), QspiWidth::NONE) = (transaction.address, transaction.awidth) { + panic!("QSPI address can't be sent with an address width of NONE"); + } + + if let (Some(_), QspiWidth::NONE) = (data_len, transaction.dwidth) { + panic!("QSPI data can't be sent with a data width of NONE"); + } + + if let Some(0) = data_len { + panic!("QSPI data must be at least one byte"); + } + T::REGS.fcr().modify(|v| { v.set_csmf(true); v.set_ctcf(true); From 9fdfe5e99bfd28c18af287e6351d556ff5458025 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 29 Oct 2024 17:50:46 +0100 Subject: [PATCH 3/4] Fix typo --- embassy-stm32/src/qspi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 6530b75b1..40c064d57 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -369,7 +369,7 @@ impl<'d, T: Instance> Qspi<'d, T, Async> { transfer.blocking_wait(); } - /// Blocking read data, using DMA. + /// Async read data, using DMA. pub async fn read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) { let transfer = self.start_read_transfer(transaction, buf); transfer.await; From a3bbb3b43abd61ce86d6cd7b949a115f243e5dba Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 29 Oct 2024 23:35:28 +0100 Subject: [PATCH 4/4] Add check for the flipside of the coin too --- embassy-stm32/src/qspi/mod.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs index 40c064d57..10b1cbc70 100644 --- a/embassy-stm32/src/qspi/mod.rs +++ b/embassy-stm32/src/qspi/mod.rs @@ -202,16 +202,19 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { } fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig, data_len: Option) { - if let (Some(_), QspiWidth::NONE) = (transaction.address, transaction.awidth) { - panic!("QSPI address can't be sent with an address width of NONE"); + match (transaction.address, transaction.awidth) { + (Some(_), QspiWidth::NONE) => panic!("QSPI address can't be sent with an address width of NONE"), + (Some(_), _) => {} + (None, QspiWidth::NONE) => {} + (None, _) => panic!("QSPI address is not set, so the address width should be NONE"), } - if let (Some(_), QspiWidth::NONE) = (data_len, transaction.dwidth) { - panic!("QSPI data can't be sent with a data width of NONE"); - } - - if let Some(0) = data_len { - panic!("QSPI data must be at least one byte"); + match (data_len, transaction.dwidth) { + (Some(0), _) => panic!("QSPI data must be at least one byte"), + (Some(_), QspiWidth::NONE) => panic!("QSPI data can't be sent with a data width of NONE"), + (Some(_), _) => {} + (None, QspiWidth::NONE) => {} + (None, _) => panic!("QSPI data is empty, so the data width should be NONE"), } T::REGS.fcr().modify(|v| {