mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
Merge pull request #3541 from elagil/avoid_sai_start_before_write
Disallow SAI start without an initial write
This commit is contained in:
commit
8d8cd78f63
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user