Skip to content

Commit 32e6a4f

Browse files
committed
fix: read transfer not starting properly
1 parent 2207a6a commit 32e6a4f

File tree

3 files changed

+16
-150
lines changed

3 files changed

+16
-150
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ impl DmaTxStreamBufView {
15351535
}
15361536

15371537
fn truncate_by(n: usize, by: usize) -> usize {
1538-
(n >= by).then_some(n - by).unwrap_or(n)
1538+
(n >= by).then(|| n - by).unwrap_or(n)
15391539
}
15401540

15411541
let n_chunks = self.buf.descriptors.len();

esp-hal/src/dma/mod.rs

Lines changed: 0 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,60 +2530,6 @@ pub(crate) mod dma_private {
25302530
}
25312531
}
25322532

2533-
/// DMA transaction for TX only transfers
2534-
///
2535-
/// # Safety
2536-
///
2537-
/// Never use [core::mem::forget] on an in-progress transfer
2538-
#[non_exhaustive]
2539-
#[must_use]
2540-
pub struct DmaTransferTx<'a, I>
2541-
where
2542-
I: dma_private::DmaSupportTx,
2543-
{
2544-
instance: &'a mut I,
2545-
}
2546-
2547-
impl<'a, I> DmaTransferTx<'a, I>
2548-
where
2549-
I: dma_private::DmaSupportTx,
2550-
{
2551-
#[cfg_attr(esp32c2, allow(dead_code))]
2552-
pub(crate) fn new(instance: &'a mut I) -> Self {
2553-
Self { instance }
2554-
}
2555-
2556-
/// Wait for the transfer to finish.
2557-
pub fn wait(self) -> Result<(), DmaError> {
2558-
self.instance.peripheral_wait_dma(false, true);
2559-
2560-
if self
2561-
.instance
2562-
.tx()
2563-
.pending_out_interrupts()
2564-
.contains(DmaTxInterrupt::DescriptorError)
2565-
{
2566-
Err(DmaError::DescriptorError)
2567-
} else {
2568-
Ok(())
2569-
}
2570-
}
2571-
2572-
/// Check if the transfer is finished.
2573-
pub fn is_done(&mut self) -> bool {
2574-
self.instance.tx().is_done()
2575-
}
2576-
}
2577-
2578-
impl<I> Drop for DmaTransferTx<'_, I>
2579-
where
2580-
I: dma_private::DmaSupportTx,
2581-
{
2582-
fn drop(&mut self) {
2583-
self.instance.peripheral_wait_dma(true, false);
2584-
}
2585-
}
2586-
25872533
/// DMA transaction for RX only transfers
25882534
///
25892535
/// # Safety
@@ -2598,37 +2544,6 @@ where
25982544
instance: &'a mut I,
25992545
}
26002546

2601-
impl<'a, I> DmaTransferRx<'a, I>
2602-
where
2603-
I: dma_private::DmaSupportRx,
2604-
{
2605-
#[cfg_attr(esp32c2, allow(dead_code))]
2606-
pub(crate) fn new(instance: &'a mut I) -> Self {
2607-
Self { instance }
2608-
}
2609-
2610-
/// Wait for the transfer to finish.
2611-
pub fn wait(self) -> Result<(), DmaError> {
2612-
self.instance.peripheral_wait_dma(true, false);
2613-
2614-
if self
2615-
.instance
2616-
.rx()
2617-
.pending_in_interrupts()
2618-
.contains(DmaRxInterrupt::DescriptorError)
2619-
{
2620-
Err(DmaError::DescriptorError)
2621-
} else {
2622-
Ok(())
2623-
}
2624-
}
2625-
2626-
/// Check if the transfer is finished.
2627-
pub fn is_done(&mut self) -> bool {
2628-
self.instance.rx().is_done()
2629-
}
2630-
}
2631-
26322547
impl<I> Drop for DmaTransferRx<'_, I>
26332548
where
26342549
I: dma_private::DmaSupportRx,
@@ -2832,63 +2747,6 @@ pub(crate) mod asynch {
28322747

28332748
use super::*;
28342749

2835-
#[must_use = "futures do nothing unless you `.await` or poll them"]
2836-
pub struct DmaTxFuture<'a, CH>
2837-
where
2838-
CH: DmaTxChannel,
2839-
{
2840-
pub(crate) tx: &'a mut ChannelTx<Async, CH>,
2841-
}
2842-
2843-
impl<'a, CH> DmaTxFuture<'a, CH>
2844-
where
2845-
CH: DmaTxChannel,
2846-
{
2847-
#[cfg_attr(esp32c2, allow(dead_code))]
2848-
pub fn new(tx: &'a mut ChannelTx<Async, CH>) -> Self {
2849-
Self { tx }
2850-
}
2851-
}
2852-
2853-
impl<CH> core::future::Future for DmaTxFuture<'_, CH>
2854-
where
2855-
CH: DmaTxChannel,
2856-
{
2857-
type Output = Result<(), DmaError>;
2858-
2859-
fn poll(
2860-
self: core::pin::Pin<&mut Self>,
2861-
cx: &mut core::task::Context<'_>,
2862-
) -> Poll<Self::Output> {
2863-
if self.tx.is_done() {
2864-
self.tx.clear_interrupts();
2865-
Poll::Ready(Ok(()))
2866-
} else if self
2867-
.tx
2868-
.pending_out_interrupts()
2869-
.contains(DmaTxInterrupt::DescriptorError)
2870-
{
2871-
self.tx.clear_interrupts();
2872-
Poll::Ready(Err(DmaError::DescriptorError))
2873-
} else {
2874-
self.tx.waker().register(cx.waker());
2875-
self.tx
2876-
.listen_out(DmaTxInterrupt::TotalEof | DmaTxInterrupt::DescriptorError);
2877-
Poll::Pending
2878-
}
2879-
}
2880-
}
2881-
2882-
impl<CH> Drop for DmaTxFuture<'_, CH>
2883-
where
2884-
CH: DmaTxChannel,
2885-
{
2886-
fn drop(&mut self) {
2887-
self.tx
2888-
.unlisten_out(DmaTxInterrupt::TotalEof | DmaTxInterrupt::DescriptorError);
2889-
}
2890-
}
2891-
28922750
#[must_use = "futures do nothing unless you `.await` or poll them"]
28932751
pub struct DmaRxFuture<'a, CH>
28942752
where

esp-hal/src/i2s/master.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ where
428428
self.i2s.reset_tx();
429429

430430
// Enable corresponding interrupts if needed
431+
self.i2s.listen(I2sInterrupt::TxDone);
431432

432433
// configure DMA outlink
433434
unsafe {
@@ -476,6 +477,7 @@ where
476477
pub fn read<'t, RXBUF>(
477478
mut self,
478479
mut buf: RXBUF,
480+
chunk_size: usize,
479481
) -> Result<I2sReadDmaTransfer<'d, Dm, RXBUF>, Error>
480482
where
481483
RXBUF: DmaRxBuffer,
@@ -488,6 +490,7 @@ where
488490
self.i2s.reset_rx();
489491

490492
// Enable corresponding interrupts if needed
493+
self.i2s.listen(I2sInterrupt::RxDone);
491494

492495
// configure DMA inlink
493496
unsafe {
@@ -498,10 +501,11 @@ where
498501
self.rx_channel.start_transfer()?;
499502

500503
// start: set I2S_RX_START
501-
self.i2s.rx_start();
504+
self.i2s.rx_start(chunk_size);
502505
Ok(I2sReadDmaTransfer {
503506
i2s_rx: ManuallyDrop::new(self),
504507
buffer_view: ManuallyDrop::new(buf.into_view()),
508+
chunk_size,
505509
})
506510
}
507511
}
@@ -548,7 +552,7 @@ impl<'d, Dm: DriverMode, BUFFER: DmaTxBuffer> I2sWriteDmaTransfer<'d, Dm, BUFFER
548552

549553
/// Checks if the DMA transfer is done.
550554
pub fn is_done(&self) -> bool {
551-
self.i2s_tx.tx_channel.is_done()
555+
self.i2s_tx.i2s.interrupts().contains(I2sInterrupt::TxDone)
552556
}
553557

554558
/// Stops and restarts the DMA transfer.
@@ -583,6 +587,7 @@ impl<'d, Dm: DriverMode, BUFFER: DmaTxBuffer> I2sWriteDmaTransfer<'d, Dm, BUFFER
583587
/// An in-progress async circular DMA read transfer.
584588
pub struct I2sReadDmaTransfer<'d, Dm: DriverMode, BUFFER: DmaRxBuffer> {
585589
i2s_rx: ManuallyDrop<I2sRx<'d, Dm>>,
590+
chunk_size: usize,
586591
buffer_view: ManuallyDrop<BUFFER::View>,
587592
}
588593

@@ -622,13 +627,14 @@ impl<'d, Dm: DriverMode, BUFFER: DmaRxBuffer> I2sReadDmaTransfer<'d, Dm, BUFFER>
622627

623628
/// Returns true if the transfer is done.
624629
pub fn is_done(&self) -> bool {
625-
self.i2s_rx.rx_channel.is_done()
630+
self.i2s_rx.i2s.interrupts().contains(I2sInterrupt::RxDone)
626631
}
627632

628633
/// Stops and restarts the DMA transfer.
629634
pub fn restart(self) -> Result<Self, Error> {
635+
let chunk_size = self.chunk_size;
630636
let (i2s, buf) = self.stop();
631-
i2s.read(buf)
637+
i2s.read(buf, chunk_size)
632638
}
633639

634640
/// Checks if the transfer has an error.
@@ -1466,7 +1472,11 @@ mod private {
14661472
});
14671473
}
14681474

1469-
fn rx_start(&self) {
1475+
fn rx_start(&self, len: usize) {
1476+
let len = len - 1;
1477+
self.regs()
1478+
.rxeof_num()
1479+
.write(|w| unsafe { w.rx_eof_num().bits(len as u16) });
14701480
self.regs().rx_conf().modify(|_, w| w.rx_start().set_bit());
14711481
}
14721482

@@ -1816,8 +1826,6 @@ pub mod asynch {
18161826
impl<BUFFER: DmaRxBuffer> I2sReadDmaTransfer<'_, Async, BUFFER> {
18171827
/// Waits for DMA process to be made and additional room to be
18181828
/// available.
1819-
///
1820-
/// Returns [crate::dma::DmaError::Late] if DMA is already completed.
18211829
pub async fn wait_for_available(&mut self) -> Result<(), Error> {
18221830
DmaRxDoneChFuture::new(&mut self.i2s_rx.rx_channel).await?;
18231831
Ok(())

0 commit comments

Comments
 (0)