Skip to content

Commit 90c3fba

Browse files
committed
Extend API of dma::Transfer
Add some crate-public methods that are useful when working with circular DMA transfers.
1 parent c927a05 commit 90c3fba

File tree

1 file changed

+53
-7
lines changed

1 file changed

+53
-7
lines changed

src/dma.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,22 @@ impl<T, C, B> Transfer<T, C, B, Started>
203203

204204
Ok(self.res)
205205
}
206+
207+
/// Returns some transfer state
208+
///
209+
/// The number of items to transfer, the half transfer flag, and the
210+
/// transfer completed flag.
211+
pub(crate) fn state(&self) -> (u16, bool, bool) {
212+
self.res.channel.transfer_state()
213+
}
214+
215+
/// Clears the half transfer and transfer complete flags
216+
///
217+
/// Be careful when calling this, as it can confuse the other methods. This
218+
/// method is designed to manage circular transfers only.
219+
pub(crate) fn clear_flags(&self) {
220+
self.res.channel.clear_flags()
221+
}
206222
}
207223

208224

@@ -280,6 +296,8 @@ pub trait Channel: Sized {
280296
fn is_active(&self) -> bool;
281297
fn clear_complete_flag(&self);
282298
fn error_occured(&self) -> bool;
299+
fn transfer_state(&self) -> (u16, bool, bool);
300+
fn clear_flags(&self);
283301
}
284302

285303
macro_rules! impl_channel {
@@ -289,8 +307,10 @@ macro_rules! impl_channel {
289307
$field:ident,
290308
$chfield:ident,
291309
$cxs:ident,
310+
$htif:ident,
292311
$tcif:ident,
293312
$teif:ident,
313+
$chtif:ident,
294314
$ctcif:ident,
295315
$cteif:ident;
296316
)*
@@ -433,26 +453,52 @@ macro_rules! impl_channel {
433453
false
434454
}
435455
}
456+
457+
fn transfer_state(&self) -> (u16, bool, bool) {
458+
// Safe, as we're only doing atomic reads.
459+
let dma = unsafe { &*pac::DMA1::ptr() };
460+
461+
let isr = dma.isr.read();
462+
463+
let data_remaining = dma.$chfield.ndtr.read().ndt().bits();
464+
465+
let half_transfer = isr.$htif().is_half();
466+
let transfer_complete = isr.$tcif().is_complete();
467+
468+
(data_remaining, half_transfer, transfer_complete)
469+
}
470+
471+
fn clear_flags(&self) {
472+
// Safe, as we're only doing an atomic write to a stateless
473+
// register.
474+
let dma = unsafe { &*pac::DMA1::ptr() };
475+
476+
dma.ifcr.write(|w|
477+
w
478+
.$chtif().clear()
479+
.$ctcif().clear()
480+
);
481+
}
436482
}
437483
)*
438484
}
439485
}
440486

441487
impl_channel!(
442488
Channel1, channel1, ch1,
443-
c1s, tcif1, teif1, ctcif1, cteif1;
489+
c1s, htif1, tcif1, teif1, chtif1, ctcif1, cteif1;
444490
Channel2, channel2, ch2,
445-
c2s, tcif2, teif2, ctcif2, cteif2;
491+
c2s, htif2, tcif2, teif2, chtif2, ctcif2, cteif2;
446492
Channel3, channel3, ch3,
447-
c3s, tcif3, teif3, ctcif3, cteif3;
493+
c3s, htif3, tcif3, teif3, chtif3, ctcif3, cteif3;
448494
Channel4, channel4, ch4,
449-
c4s, tcif4, teif4, ctcif4, cteif4;
495+
c4s, htif4, tcif4, teif4, chtif4, ctcif4, cteif4;
450496
Channel5, channel5, ch5,
451-
c5s, tcif5, teif5, ctcif5, cteif5;
497+
c5s, htif5, tcif5, teif5, chtif5, ctcif5, cteif5;
452498
Channel6, channel6, ch6,
453-
c6s, tcif6, teif6, ctcif6, cteif6;
499+
c6s, htif6, tcif6, teif6, chtif6, ctcif6, cteif6;
454500
Channel7, channel7, ch7,
455-
c7s, tcif7, teif7, ctcif7, cteif7;
501+
c7s, htif7, tcif7, teif7, chtif7, ctcif7, cteif7;
456502
);
457503

458504

0 commit comments

Comments
 (0)