Skip to content

Commit d32c6ba

Browse files
committed
feat: restart tx
1 parent e69a3ab commit d32c6ba

File tree

3 files changed

+52
-22
lines changed

3 files changed

+52
-22
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ impl DmaTxStreamBufView {
15401540
let dma_start = self.descriptor_idx * chunk_size + self.descriptor_offset;
15411541
let dma_end = truncate_by(dma_start + buf.len(), dma_size);
15421542

1543-
if dma_start < dma_end {
1543+
if dma_start <= dma_end {
15441544
self.buf.buffer[dma_start..dma_end].copy_from_slice(buf);
15451545
} else {
15461546
self.buf.buffer[dma_start..].copy_from_slice(&buf[..dma_size - dma_start]);
@@ -1576,11 +1576,6 @@ impl DmaTxStreamBufView {
15761576
}
15771577
}
15781578

1579-
info!(
1580-
"self.descriptor_idx: {}, self.descriptor_offset: {}, dma_start: {}, dma_end: {}",
1581-
self.descriptor_idx, self.descriptor_offset, dma_start, dma_end
1582-
);
1583-
15841579
bytes_to_fill
15851580
}
15861581
}

esp-hal/src/dma/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2987,6 +2987,13 @@ pub(crate) mod asynch {
29872987
{
29882988
self.tx.clear_out(DmaTxInterrupt::Done);
29892989
Poll::Ready(Ok(()))
2990+
} else if self
2991+
.tx
2992+
.pending_out_interrupts()
2993+
.contains(DmaTxInterrupt::TotalEof)
2994+
{
2995+
self.tx.clear_interrupts();
2996+
return Poll::Ready(Err(DmaError::Late));
29902997
} else if self
29912998
.tx
29922999
.pending_out_interrupts()
@@ -2996,8 +3003,11 @@ pub(crate) mod asynch {
29963003
Poll::Ready(Err(DmaError::DescriptorError))
29973004
} else {
29983005
self.tx.waker().register(cx.waker());
2999-
self.tx
3000-
.listen_out(DmaTxInterrupt::Done | DmaTxInterrupt::DescriptorError);
3006+
self.tx.listen_out(
3007+
DmaTxInterrupt::Done
3008+
| DmaTxInterrupt::DescriptorError
3009+
| DmaTxInterrupt::TotalEof,
3010+
);
30013011
Poll::Pending
30023012
}
30033013
}

esp-hal/src/i2s/master.rs

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,11 +1806,10 @@ pub mod asynch {
18061806
Async,
18071807
dma::{
18081808
DmaEligible,
1809-
ReadBuffer,
1809+
DmaTxBuffer,
18101810
RxCircularState,
1811-
TxCircularState,
18121811
WriteBuffer,
1813-
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
1812+
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture},
18141813
},
18151814
};
18161815

@@ -1901,17 +1900,43 @@ pub mod asynch {
19011900
Ok(self.state.push(&data[..to_send])?)
19021901
}
19031902

1904-
/// Push bytes into the DMA buffer via the given closure.
1905-
/// The closure *must* return the actual number of bytes written.
1906-
/// The closure *might* get called with a slice which is smaller than
1907-
/// the total available buffer. Only useful for circular DMA
1908-
/// transfers
1909-
pub async fn push_with(
1910-
&mut self,
1911-
f: impl FnOnce(&mut [u8]) -> usize,
1912-
) -> Result<usize, Error> {
1913-
let _avail = self.available().await;
1914-
Ok(self.state.push_with(f)?)
1903+
/// Checks if the DMA transfer is done.
1904+
pub fn is_done(&self) -> bool {
1905+
self.i2s_tx.tx_channel.is_done()
1906+
}
1907+
1908+
/// Stops and restarts the DMA transfer.
1909+
pub fn restart(self) -> Result<Self, Error> {
1910+
let (i2s, buf) = self.stop();
1911+
i2s.write(buf)
1912+
}
1913+
1914+
/// Checks if the DMA transfer has an error.
1915+
pub fn has_error(&self) -> bool {
1916+
self.i2s_tx.tx_channel.has_error()
1917+
}
1918+
1919+
/// Waits for any DMA process to be made.
1920+
pub async fn process(&mut self) -> Result<(), Error> {
1921+
DmaTxDoneChFuture::new(&mut self.i2s_tx.tx_channel).await?;
1922+
Ok(())
1923+
}
1924+
1925+
fn release(mut self) -> (I2sTx<'d, Async>, BUFFER::View) {
1926+
// SAFETY: Since forget is called on self, we know that self.i2s_tx and
1927+
// self.buffer_view won't be touched again.
1928+
let result = unsafe {
1929+
(
1930+
ManuallyDrop::take(&mut self.i2s_tx),
1931+
ManuallyDrop::take(&mut self.buffer_view),
1932+
)
1933+
};
1934+
core::mem::forget(self);
1935+
result
1936+
}
1937+
1938+
fn stop_peripheral(&mut self) {
1939+
self.i2s_tx.i2s.tx_stop();
19151940
}
19161941
}
19171942

0 commit comments

Comments
 (0)