aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelagil <[email protected]>2024-11-17 23:09:51 +0100
committerelagil <[email protected]>2024-11-17 23:10:11 +0100
commit7ae28163414d0042c4e06cc02de900e67b62df01 (patch)
tree4cbc9fbdf85cfcdc5f812fb208a650a366a7874f
parentf99d733b616e748eb9c7122b77d6521297d53171 (diff)
feat: SAI/ringbuffer add function to wait for any write error
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs7
-rw-r--r--embassy-stm32/src/dma/ringbuffer/mod.rs13
-rw-r--r--embassy-stm32/src/sai/mod.rs16
3 files changed, 36 insertions, 0 deletions
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs
index 08c7a5508..90160ed50 100644
--- a/embassy-stm32/src/dma/dma_bdma.rs
+++ b/embassy-stm32/src/dma/dma_bdma.rs
@@ -1006,6 +1006,13 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
1006 .await 1006 .await
1007 } 1007 }
1008 1008
1009 /// Wait for any ring buffer write error.
1010 pub async fn write_error(&mut self) -> Result<usize, Error> {
1011 self.ringbuf
1012 .write_error(&mut DmaCtrlImpl(self.channel.reborrow()))
1013 .await
1014 }
1015
1009 /// The current length of the ringbuffer 1016 /// The current length of the ringbuffer
1010 pub fn len(&mut self) -> Result<usize, Error> { 1017 pub fn len(&mut self) -> Result<usize, Error> {
1011 Ok(self.ringbuf.len(&mut DmaCtrlImpl(self.channel.reborrow()))?) 1018 Ok(self.ringbuf.len(&mut DmaCtrlImpl(self.channel.reborrow()))?)
diff --git a/embassy-stm32/src/dma/ringbuffer/mod.rs b/embassy-stm32/src/dma/ringbuffer/mod.rs
index 0da8c374f..b7f98fbce 100644
--- a/embassy-stm32/src/dma/ringbuffer/mod.rs
+++ b/embassy-stm32/src/dma/ringbuffer/mod.rs
@@ -260,6 +260,19 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
260 Ok((written, self.cap() - written)) 260 Ok((written, self.cap() - written))
261 } 261 }
262 262
263 /// Wait for any ring buffer write error.
264 pub async fn write_error(&mut self, dma: &mut impl DmaCtrl) -> Result<usize, Error> {
265 poll_fn(|cx| {
266 dma.set_waker(cx.waker());
267
268 match self.len(dma) {
269 Ok(_) => Poll::Pending,
270 Err(e) => Poll::Ready(Err(e)),
271 }
272 })
273 .await
274 }
275
263 /// Write an exact number of elements to the ringbuffer. 276 /// Write an exact number of elements to the ringbuffer.
264 pub async fn write_exact(&mut self, dma: &mut impl DmaCtrl, buffer: &[W]) -> Result<usize, Error> { 277 pub async fn write_exact(&mut self, dma: &mut impl DmaCtrl, buffer: &[W]) -> Result<usize, Error> {
265 let mut written_data = 0; 278 let mut written_data = 0;
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 057b21980..fd61e5339 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -1003,6 +1003,22 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
1003 } 1003 }
1004 } 1004 }
1005 1005
1006 /// Wait until any SAI write error occurs.
1007 ///
1008 /// One useful application for this is stopping playback as soon as the SAI
1009 /// experiences an overrun of the ring buffer. Then, instead of letting
1010 /// the SAI peripheral play the last written buffer over and over again, SAI
1011 /// can be muted or dropped instead.
1012 pub async fn write_error(&mut self) -> Result<(), Error> {
1013 match &mut self.ring_buffer {
1014 RingBuffer::Writable(buffer) => {
1015 buffer.write_error().await?;
1016 Ok(())
1017 }
1018 _ => return Err(Error::NotATransmitter),
1019 }
1020 }
1021
1006 /// Write data to the SAI ringbuffer. 1022 /// Write data to the SAI ringbuffer.
1007 /// 1023 ///
1008 /// The first write starts the DMA after filling the ring buffer with the provided data. 1024 /// The first write starts the DMA after filling the ring buffer with the provided data.