Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disallow SAI start without an initial write #3541

Merged
merged 2 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions embassy-stm32/src/dma/dma_bdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear on start conflicts with write_immediate. With clear in place, write_immediate would have no effect.

}

/// Clear all data in the ring buffer.
Expand Down Expand Up @@ -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.
Expand All @@ -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)
}
Expand Down
27 changes: 14 additions & 13 deletions embassy-stm32/src/sai/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
}
}
Expand All @@ -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);
Expand All @@ -1012,14 +1005,22 @@ 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.
///
/// If there's no space in the buffer, this waits until there is.
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),
Expand Down
3 changes: 1 addition & 2 deletions examples/stm32h7/src/bin/sai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down