diff --git a/src/chip/dma.rs b/src/chip/dma.rs index c214e700..4fa17b68 100644 --- a/src/chip/dma.rs +++ b/src/chip/dma.rs @@ -174,10 +174,6 @@ unsafe impl peripheral::Destination for lpspi::Lpspi unsafe impl peripheral::Bidirectional for lpspi::Lpspi {} impl lpspi::Lpspi { - fn wait_for_transmit_fifo_space(&self) -> Result<(), lpspi::LpspiError> { - crate::spin_on(self.spin_for_fifo_space()) - } - /// Use a DMA channel to write data to the LPSPI peripheral. /// /// The future completes when all data in `buffer` has been written to the diff --git a/src/common/lpspi.rs b/src/common/lpspi.rs index 7eb18a36..497c32a5 100644 --- a/src/common/lpspi.rs +++ b/src/common/lpspi.rs @@ -631,6 +631,10 @@ impl Lpspi { .await } + pub(crate) fn wait_for_transmit_fifo_space(&self) -> Result<(), LpspiError> { + crate::spin_on(self.spin_for_fifo_space()) + } + /// Wait for receive data in a (concurrent) spin loop. /// /// This future does not care about the RX FIFO watermark. Instead, it @@ -653,19 +657,6 @@ impl Lpspi { .await } - /// Start a spinning transaction. - /// - /// This shouldn't run concurrently with any of the other spinning tasks. - /// Instead, it should be executed before the I/O futures. - async fn spin_start_transaction( - &mut self, - transaction: &Transaction, - ) -> Result<(), LpspiError> { - self.spin_for_fifo_space().await?; - self.enqueue_transaction(transaction); - Ok(()) - } - /// Send `len` LPSPI words (u32s) out of the peripheral. /// /// Expected to run in a (concurrent) spin loop, possibly with @@ -766,15 +757,22 @@ impl Lpspi { let mut transaction = Transaction::new_words(data)?; transaction.bit_order = self.bit_order(); - crate::spin_on(async { - self.spin_start_transaction(&transaction).await?; - self.spin_exchange_no_start(data).await?; - Ok(()) - }) + self.wait_for_transmit_fifo_space()?; + self.enqueue_transaction(&transaction); + + let word_count = word_count(data); + let (tx, rx) = transfer_in_place(data); + + crate::spin_on(futures::future::try_join( + self.spin_transmit(tx, word_count), + self.spin_receive(rx, word_count), + )) .map_err(|err| { self.recover_from_error(); err - }) + })?; + + Ok(()) } fn write_no_read(&mut self, data: &[W]) -> Result<(), LpspiError> { @@ -786,12 +784,13 @@ impl Lpspi { transaction.receive_data_mask = true; transaction.bit_order = self.bit_order(); - crate::spin_on(async { - self.spin_start_transaction(&transaction).await?; - self.spin_write_no_start(data).await?; - Ok(()) - }) - .map_err(|err| { + self.wait_for_transmit_fifo_space()?; + self.enqueue_transaction(&transaction); + + let word_count = word_count(data); + let tx = TransmitBuffer::new(data); + + crate::spin_on(self.spin_transmit(tx, word_count)).map_err(|err| { self.recover_from_error(); err }) @@ -912,29 +911,6 @@ impl Lpspi { set_watermark(&self.lpspi, direction, watermark) } - /// Perform a spinning write, assuming that the transaction - /// has already started. - /// - /// This implementation requires that the transaction's receive mask - /// is enabled. - async fn spin_write_no_start(&mut self, words: &[W]) -> Result<(), LpspiError> { - let word_count = word_count(words); - self.spin_transmit(TransmitBuffer::new(words), word_count) - .await?; - Ok(()) - } - - /// Exhange data within a buffer, assuming the transaction has started. - async fn spin_exchange_no_start(&mut self, words: &mut [W]) -> Result<(), LpspiError> { - let word_count = word_count(words); - let (tx, rx) = transfer_in_place(words); - futures::try_join!( - self.spin_transmit(tx, word_count), - self.spin_receive(rx, word_count), - )?; - Ok(()) - } - /// Recover from a transaction error. fn recover_from_error(&mut self) { // Resets the peripheral and flushes whatever is in the FIFOs.