Merge pull request #3545 from elagil/feat_wait_for_sai_ringbuf_write_error

Add a function that waits for any SAI/ringbuffer write error
This commit is contained in:
Henrik Alsér 2024-11-17 23:11:31 +00:00 committed by GitHub
commit b793d31f25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 36 additions and 0 deletions

View File

@ -1006,6 +1006,13 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
.await .await
} }
/// Wait for any ring buffer write error.
pub async fn wait_write_error(&mut self) -> Result<usize, Error> {
self.ringbuf
.wait_write_error(&mut DmaCtrlImpl(self.channel.reborrow()))
.await
}
/// The current length of the ringbuffer /// The current length of the ringbuffer
pub fn len(&mut self) -> Result<usize, Error> { pub fn len(&mut self) -> Result<usize, Error> {
Ok(self.ringbuf.len(&mut DmaCtrlImpl(self.channel.reborrow()))?) Ok(self.ringbuf.len(&mut DmaCtrlImpl(self.channel.reborrow()))?)

View File

@ -260,6 +260,19 @@ impl<'a, W: Word> WritableDmaRingBuffer<'a, W> {
Ok((written, self.cap() - written)) Ok((written, self.cap() - written))
} }
/// Wait for any ring buffer write error.
pub async fn wait_write_error(&mut self, dma: &mut impl DmaCtrl) -> Result<usize, Error> {
poll_fn(|cx| {
dma.set_waker(cx.waker());
match self.len(dma) {
Ok(_) => Poll::Pending,
Err(e) => Poll::Ready(Err(e)),
}
})
.await
}
/// Write an exact number of elements to the ringbuffer. /// Write an exact number of elements to the ringbuffer.
pub async fn write_exact(&mut self, dma: &mut impl DmaCtrl, buffer: &[W]) -> Result<usize, Error> { pub async fn write_exact(&mut self, dma: &mut impl DmaCtrl, buffer: &[W]) -> Result<usize, Error> {
let mut written_data = 0; let mut written_data = 0;

View File

@ -1003,6 +1003,22 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
} }
} }
/// Wait until any SAI write error occurs.
///
/// One useful application for this is stopping playback as soon as the SAI
/// experiences an overrun of the ring buffer. Then, instead of letting
/// the SAI peripheral play the last written buffer over and over again, SAI
/// can be muted or dropped instead.
pub async fn wait_write_error(&mut self) -> Result<(), Error> {
match &mut self.ring_buffer {
RingBuffer::Writable(buffer) => {
buffer.wait_write_error().await?;
Ok(())
}
_ => return Err(Error::NotATransmitter),
}
}
/// Write data to the SAI ringbuffer. /// Write data to the SAI ringbuffer.
/// ///
/// The first write starts the DMA after filling the ring buffer with the provided data. /// The first write starts the DMA after filling the ring buffer with the provided data.