diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs index cdc603e2c..08c7a5508 100644 --- a/embassy-stm32/src/dma/dma_bdma.rs +++ b/embassy-stm32/src/dma/dma_bdma.rs @@ -828,7 +828,6 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> { /// You must call this after creating it for it to work. pub fn start(&mut self) { self.channel.start(); - self.clear(); } /// Clear all data in the ring buffer. @@ -981,7 +980,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { /// You must call this after creating it for it to work. pub fn start(&mut self) { self.channel.start(); - self.clear(); } /// Clear all data in the ring buffer. @@ -991,7 +989,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { /// Write elements directly to the raw buffer. /// This can be used to fill the buffer before starting the DMA transfer. - #[allow(dead_code)] pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> { self.ringbuf.write_immediate(buf) } diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 62b44b77f..057b21980 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -958,13 +958,14 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { } /// Start the SAI driver. - pub fn start(&mut self) { + /// + /// Only receivers can be started. Transmitters are started on the first writing operation. + pub fn start(&mut self) -> Result<(), Error> { match self.ring_buffer { - RingBuffer::Writable(ref mut rb) => { - rb.start(); - } + RingBuffer::Writable(_) => Err(Error::NotAReceiver), RingBuffer::Readable(ref mut rb) => { rb.start(); + Ok(()) } } } @@ -981,14 +982,6 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { rcc::enable_and_reset::(); } - /// Flush. - pub fn flush(&mut self) { - let ch = T::REGS.ch(self.sub_block as usize); - ch.cr1().modify(|w| w.set_saien(false)); - ch.cr2().modify(|w| w.set_fflush(true)); - ch.cr1().modify(|w| w.set_saien(true)); - } - /// Enable or disable mute. pub fn set_mute(&mut self, value: bool) { let ch = T::REGS.ch(self.sub_block as usize); @@ -1012,6 +1005,9 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { /// Write data to the SAI ringbuffer. /// + /// The first write starts the DMA after filling the ring buffer with the provided data. + /// This ensures that the DMA does not run before data is available in the ring buffer. + /// /// This appends the data to the buffer and returns immediately. The /// data will be transmitted in the background. /// @@ -1019,7 +1015,12 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { pub async fn write(&mut self, data: &[W]) -> Result<(), Error> { match &mut self.ring_buffer { RingBuffer::Writable(buffer) => { - buffer.write_exact(data).await?; + if buffer.is_running() { + buffer.write_exact(data).await?; + } else { + buffer.write_immediate(data)?; + buffer.start(); + } Ok(()) } _ => return Err(Error::NotATransmitter), diff --git a/examples/stm32h7/src/bin/sai.rs b/examples/stm32h7/src/bin/sai.rs index 04d14bd6b..95ffe257a 100644 --- a/examples/stm32h7/src/bin/sai.rs +++ b/examples/stm32h7/src/bin/sai.rs @@ -107,8 +107,7 @@ async fn main(_spawner: Spawner) { let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config); - sai_receiver.start(); - sai_transmitter.start(); + sai_receiver.start().unwrap(); let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH];