Skip to content

Commit e6738af

Browse files
committed
fix: read transfer not starting properly
1 parent f61ba39 commit e6738af

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
@@ -2528,60 +2528,6 @@ pub(crate) mod dma_private {
25282528
}
25292529
}
25302530

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

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

28312746
use super::*;
28322747

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

esp-hal/src/i2s/master.rs

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

437437
// Enable corresponding interrupts if needed
438+
self.i2s.listen(I2sInterrupt::TxDone);
438439

439440
// configure DMA outlink
440441
unsafe {
@@ -483,6 +484,7 @@ where
483484
pub fn read<'t, RXBUF>(
484485
mut self,
485486
mut buf: RXBUF,
487+
chunk_size: usize,
486488
) -> Result<I2sReadDmaTransfer<'d, Dm, RXBUF>, Error>
487489
where
488490
RXBUF: DmaRxBuffer,
@@ -495,6 +497,7 @@ where
495497
self.i2s.reset_rx();
496498

497499
// Enable corresponding interrupts if needed
500+
self.i2s.listen(I2sInterrupt::RxDone);
498501

499502
// configure DMA inlink
500503
unsafe {
@@ -505,10 +508,11 @@ where
505508
self.rx_channel.start_transfer()?;
506509

507510
// start: set I2S_RX_START
508-
self.i2s.rx_start();
511+
self.i2s.rx_start(chunk_size);
509512
Ok(I2sReadDmaTransfer {
510513
i2s_rx: ManuallyDrop::new(self),
511514
buffer_view: ManuallyDrop::new(buf.into_view()),
515+
chunk_size,
512516
})
513517
}
514518
}
@@ -555,7 +559,7 @@ impl<'d, Dm: DriverMode, BUFFER: DmaTxBuffer> I2sWriteDmaTransfer<'d, Dm, BUFFER
555559

556560
/// Checks if the DMA transfer is done.
557561
pub fn is_done(&self) -> bool {
558-
self.i2s_tx.tx_channel.is_done()
562+
self.i2s_tx.i2s.interrupts().contains(I2sInterrupt::TxDone)
559563
}
560564

561565
/// Stops and restarts the DMA transfer.
@@ -590,6 +594,7 @@ impl<'d, Dm: DriverMode, BUFFER: DmaTxBuffer> I2sWriteDmaTransfer<'d, Dm, BUFFER
590594
/// An in-progress async circular DMA read transfer.
591595
pub struct I2sReadDmaTransfer<'d, Dm: DriverMode, BUFFER: DmaRxBuffer> {
592596
i2s_rx: ManuallyDrop<I2sRx<'d, Dm>>,
597+
chunk_size: usize,
593598
buffer_view: ManuallyDrop<BUFFER::View>,
594599
}
595600

@@ -629,13 +634,14 @@ impl<'d, Dm: DriverMode, BUFFER: DmaRxBuffer> I2sReadDmaTransfer<'d, Dm, BUFFER>
629634

630635
/// Returns true if the transfer is done.
631636
pub fn is_done(&self) -> bool {
632-
self.i2s_rx.rx_channel.is_done()
637+
self.i2s_rx.i2s.interrupts().contains(I2sInterrupt::RxDone)
633638
}
634639

635640
/// Stops and restarts the DMA transfer.
636641
pub fn restart(self) -> Result<Self, Error> {
642+
let chunk_size = self.chunk_size;
637643
let (i2s, buf) = self.stop();
638-
i2s.read(buf)
644+
i2s.read(buf, chunk_size)
639645
}
640646

641647
/// Checks if the transfer has an error.
@@ -1470,7 +1476,11 @@ mod private {
14701476
});
14711477
}
14721478

1473-
fn rx_start(&self) {
1479+
fn rx_start(&self, len: usize) {
1480+
let len = len - 1;
1481+
self.regs()
1482+
.rxeof_num()
1483+
.write(|w| unsafe { w.rx_eof_num().bits(len as u16) });
14741484
self.regs().rx_conf().modify(|_, w| w.rx_start().set_bit());
14751485
}
14761486

@@ -1812,8 +1822,6 @@ pub mod asynch {
18121822
impl<BUFFER: DmaRxBuffer> I2sReadDmaTransfer<'_, Async, BUFFER> {
18131823
/// Waits for DMA process to be made and additional room to be
18141824
/// available.
1815-
///
1816-
/// Returns [crate::dma::DmaError::Late] if DMA is already completed.
18171825
pub async fn wait_for_available(&mut self) -> Result<(), Error> {
18181826
DmaRxDoneChFuture::new(&mut self.i2s_rx.rx_channel).await?;
18191827
Ok(())

0 commit comments

Comments
 (0)