Merge pull request #3541 from elagil/avoid_sai_start_before_write

Disallow SAI start without an initial write
This commit is contained in:
Dario Nieuwenhuis 2024-11-16 22:36:41 +00:00 committed by GitHub
commit 8d8cd78f63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 18 deletions

View File

@ -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)
}

View File

@ -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::<T>();
}
/// 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),

View File

@ -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];