fix(SAI): disallow start without initial write

This commit is contained in:
elagil 2024-11-16 15:02:32 +01:00
parent 6c4b3d82b6
commit d592875ca6
3 changed files with 14 additions and 17 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. /// You must call this after creating it for it to work.
pub fn start(&mut self) { pub fn start(&mut self) {
self.channel.start(); self.channel.start();
self.clear();
} }
/// Clear all data in the ring buffer. /// 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. /// You must call this after creating it for it to work.
pub fn start(&mut self) { pub fn start(&mut self) {
self.channel.start(); self.channel.start();
self.clear();
} }
/// Clear all data in the ring buffer. /// 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. /// Write elements directly to the raw buffer.
/// This can be used to fill the buffer before starting the DMA transfer. /// 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> { pub fn write_immediate(&mut self, buf: &[W]) -> Result<(usize, usize), Error> {
self.ringbuf.write_immediate(buf) 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. /// 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 { match self.ring_buffer {
RingBuffer::Writable(ref mut rb) => { RingBuffer::Writable(_) => Err(Error::NotAReceiver),
rb.start();
}
RingBuffer::Readable(ref mut rb) => { RingBuffer::Readable(ref mut rb) => {
rb.start(); rb.start();
Ok(())
} }
} }
} }
@ -981,14 +982,6 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
rcc::enable_and_reset::<T>(); 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. /// Enable or disable mute.
pub fn set_mute(&mut self, value: bool) { pub fn set_mute(&mut self, value: bool) {
let ch = T::REGS.ch(self.sub_block as usize); 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. /// 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 /// This appends the data to the buffer and returns immediately. The
/// data will be transmitted in the background. /// 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> { pub async fn write(&mut self, data: &[W]) -> Result<(), Error> {
match &mut self.ring_buffer { match &mut self.ring_buffer {
RingBuffer::Writable(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(()) Ok(())
} }
_ => return Err(Error::NotATransmitter), _ => return Err(Error::NotATransmitter),

View File

@ -108,7 +108,6 @@ async fn main(_spawner: Spawner) {
let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config); let mut sai_receiver = Sai::new_synchronous(sub_block_rx, p.PE3, p.DMA1_CH1, rx_buffer, rx_config);
sai_receiver.start(); sai_receiver.start();
sai_transmitter.start();
let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH]; let mut buf = [0u32; HALF_DMA_BUFFER_LENGTH];