Skip to content

Commit 25ee0f3

Browse files
authored
Merge pull request #173 from quartiq/feature/number-of-transfers
[DMA] Next transfer returns number of remaining data
2 parents 0bfeeca + 8483294 commit 25ee0f3

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/dma/mod.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,11 @@ where
467467

468468
/// Changes the buffer and restarts or continues a double buffer
469469
/// transfer. This must be called immediately after a transfer complete
470-
/// event. Returns the old buffer together with its `CurrentBuffer`. If an
471-
/// error occurs, this method will return the new buffer with the error.
470+
/// event. Returns (old_buffer, `CurrentBuffer`, remaining), where
471+
/// `old_buffer` is the old buffer, `CurrentBuffer` indicates which buffer
472+
/// the data represents, and `remaining` indicates the number of remaining
473+
/// data in the transfer. If an error occurs, this method will return the
474+
/// new buffer with the error.
472475
///
473476
/// This method will clear the transfer complete flag on entry, it will also
474477
/// clear it again if an overrun occurs during its execution. Moreover, if
@@ -481,7 +484,7 @@ where
481484
pub fn next_transfer(
482485
&mut self,
483486
mut new_buf: BUF,
484-
) -> Result<(BUF, CurrentBuffer), DMAError<BUF>> {
487+
) -> Result<(BUF, CurrentBuffer, usize), DMAError<BUF>> {
485488
if self.double_buf.is_some()
486489
&& DIR::direction() != DmaDirection::MemoryToMemory
487490
{
@@ -513,10 +516,10 @@ where
513516
// preceding reads"
514517
compiler_fence(Ordering::Acquire);
515518

516-
let old_buf = self.buf.replace(new_buf);
517-
518519
// We always have a buffer, so unwrap can't fail
519-
return Ok((old_buf.unwrap(), CurrentBuffer::FirstBuffer));
520+
let old_buf = self.buf.replace(new_buf).unwrap();
521+
522+
return Ok((old_buf, CurrentBuffer::FirstBuffer, 0));
520523
} else {
521524
unsafe {
522525
self.stream
@@ -535,10 +538,10 @@ where
535538
// preceding reads"
536539
compiler_fence(Ordering::Acquire);
537540

538-
let old_buf = self.double_buf.replace(new_buf);
539-
540541
// double buffering, unwrap can never fail
541-
return Ok((old_buf.unwrap(), CurrentBuffer::DoubleBuffer));
542+
let old_buf = self.double_buf.replace(new_buf).unwrap();
543+
544+
return Ok((old_buf, CurrentBuffer::DoubleBuffer, 0));
542545
}
543546
}
544547
self.stream.disable();
@@ -547,6 +550,9 @@ where
547550
// "No re-ordering of reads and writes across this point is allowed"
548551
compiler_fence(Ordering::SeqCst);
549552

553+
// Check how many data in the transfer are remaining.
554+
let remaining_data = STREAM::get_number_of_transfers();
555+
550556
// NOTE(unsafe) We now own this buffer and we won't call any &mut
551557
// methods on it until the end of the DMA transfer
552558
let buf_len = unsafe {
@@ -556,7 +562,9 @@ where
556562
buf_len
557563
};
558564
self.stream.set_number_of_transfers(buf_len as u16);
559-
let old_buf = self.buf.replace(new_buf);
565+
566+
// We own the buffer now, so unwrap is always safe.
567+
let old_buf = self.buf.replace(new_buf).unwrap();
560568

561569
// Ensure that all transfers to normal memory complete before
562570
// subsequent memory transfers.
@@ -573,7 +581,7 @@ where
573581
self.stream.enable();
574582
}
575583

576-
Ok((old_buf.unwrap(), CurrentBuffer::FirstBuffer))
584+
Ok((old_buf, CurrentBuffer::FirstBuffer, remaining_data as usize))
577585
}
578586

579587
/// Stops the stream and returns the underlying resources.
@@ -651,6 +659,10 @@ where
651659
/// error will be returned if this method is called before the end of a
652660
/// transfer while double buffering and the closure won't be executed.
653661
///
662+
/// The closure accepts the current buffer, the `CurrentBuffer` indicating
663+
/// which buffer is provided, and a `remaining` parameter indicating the
664+
/// number of transfers not completed in the DMA transfer.
665+
///
654666
/// # Panics
655667
///
656668
/// This method will panic when double buffering and one or both of the
@@ -672,7 +684,7 @@ where
672684
f: F,
673685
) -> Result<T, DMAError<()>>
674686
where
675-
F: FnOnce(BUF, CurrentBuffer) -> (BUF, T),
687+
F: FnOnce(BUF, CurrentBuffer, usize) -> (BUF, T),
676688
{
677689
if self.double_buf.is_some()
678690
&& DIR::direction() != DmaDirection::MemoryToMemory
@@ -689,7 +701,7 @@ where
689701
} else {
690702
self.double_buf.take().unwrap()
691703
};
692-
let r = f(db, !current_buffer);
704+
let r = f(db, !current_buffer, 0);
693705
let mut new_buf = r.0;
694706
let (new_buf_ptr, new_buf_len) = new_buf.write_buffer();
695707

@@ -749,9 +761,11 @@ where
749761
// "No re-ordering of reads and writes across this point is allowed"
750762
compiler_fence(Ordering::SeqCst);
751763

764+
let remaining_data = STREAM::get_number_of_transfers();
765+
752766
// Can never fail, we never let the Transfer without a buffer
753767
let old_buf = self.buf.take().unwrap();
754-
let r = f(old_buf, CurrentBuffer::FirstBuffer);
768+
let r = f(old_buf, CurrentBuffer::FirstBuffer, remaining_data as usize);
755769
let mut new_buf = r.0;
756770

757771
let (buf_ptr, buf_len) = new_buf.write_buffer();

0 commit comments

Comments
 (0)