Skip to content

Commit bac4ab0

Browse files
authored
Merge pull request #263 from Sh3Rm4n/dma-interrupt
Dma interrupt
2 parents 3d0f18e + 1a3d030 commit bac4ab0

File tree

2 files changed

+49
-26
lines changed

2 files changed

+49
-26
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
9595
- Becuase EXTI interrupt confiugration could cancel out, make it more obvious
9696
in that SysCfg manages the interrupts, not the pin itself.
9797
Change `make_interrupt_source()` to `SysCfg::select_exti_interrupt_source()`.
98+
- Change dma interrupt API to be more in line with the new serial interrupt
99+
API. ([#263])
98100

99101
## [v0.7.0] - 2021-06-18
100102

@@ -420,6 +422,7 @@ let clocks = rcc
420422
[defmt]: https://github.com/knurling-rs/defmt
421423
[filter]: https://defmt.ferrous-systems.com/filtering.html
422424

425+
[#263]: https://github.com/stm32-rs/stm32f3xx-hal/pull/263
423426
[#262]: https://github.com/stm32-rs/stm32f3xx-hal/pull/262
424427
[#260]: https://github.com/stm32-rs/stm32f3xx-hal/pull/260
425428
[#259]: https://github.com/stm32-rs/stm32f3xx-hal/pull/259

src/dma.rs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ use core::{
2424
sync::atomic::{self, Ordering},
2525
};
2626

27+
#[cfg(feature = "enumset")]
28+
use enumset::EnumSetType;
29+
2730
/// Extension trait to split a DMA peripheral into independent channels
2831
pub trait DmaExt {
2932
/// The type to split the DMA into
@@ -42,6 +45,8 @@ pub trait Target {
4245
}
4346

4447
/// An in-progress one-shot DMA transfer
48+
#[derive(Debug)]
49+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
4550
pub struct Transfer<B, C: Channel, T: Target> {
4651
// This is always a `Some` outside of `drop`.
4752
inner: Option<TransferInner<B, C, T>>,
@@ -131,7 +136,7 @@ impl<B, C: Channel, T: Target> Transfer<B, C, T> {
131136
/// Is this transfer complete?
132137
pub fn is_complete(&self) -> bool {
133138
let inner = crate::unwrap!(self.inner.as_ref());
134-
inner.channel.event_occurred(Event::TransferComplete)
139+
inner.channel.is_event_triggered(Event::TransferComplete)
135140
}
136141

137142
/// Stop this transfer and return ownership over its parts
@@ -159,6 +164,8 @@ impl<B, C: Channel, T: Target> Drop for Transfer<B, C, T> {
159164
}
160165

161166
/// This only exists so we can implement `Drop` for `Transfer`.
167+
#[derive(Debug)]
168+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
162169
struct TransferInner<B, C, T> {
163170
buffer: B,
164171
channel: C,
@@ -176,6 +183,8 @@ impl<B, C: Channel, T: Target> TransferInner<B, C, T> {
176183
}
177184

178185
/// DMA address increment mode
186+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
187+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
179188
pub enum Increment {
180189
/// Enable increment
181190
Enable,
@@ -193,6 +202,8 @@ impl From<Increment> for cr::PINC_A {
193202
}
194203

195204
/// Channel priority level
205+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
206+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
196207
pub enum Priority {
197208
/// Low
198209
Low,
@@ -216,6 +227,8 @@ impl From<Priority> for cr::PL_A {
216227
}
217228

218229
/// DMA transfer direction
230+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
231+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
219232
pub enum Direction {
220233
/// From memory to peripheral
221234
FromMemory,
@@ -233,6 +246,10 @@ impl From<Direction> for cr::DIR_A {
233246
}
234247

235248
/// DMA events
249+
#[derive(Debug)]
250+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
251+
#[cfg_attr(feature = "enumset", derive(EnumSetType))]
252+
#[cfg_attr(not(feature = "enumset"), derive(Copy, Clone, PartialEq, Eq))]
236253
pub enum Event {
237254
/// First half of a transfer is done
238255
HalfTransfer,
@@ -247,7 +264,7 @@ pub enum Event {
247264
/// Trait implemented by all DMA channels
248265
pub trait Channel: private::Channel {
249266
/// Is the interrupt flag for the given event set?
250-
fn event_occurred(&self, event: Event) -> bool;
267+
fn is_event_triggered(&self, event: Event) -> bool;
251268

252269
/// Clear the interrupt flag for the given event.
253270
///
@@ -258,6 +275,11 @@ pub trait Channel: private::Channel {
258275
/// call this method with `Event::Any`.
259276
fn clear_event(&mut self, event: Event);
260277

278+
/// Clear **all** interrupt event flags
279+
fn clear_events(&mut self) {
280+
self.clear_event(Event::Any);
281+
}
282+
261283
/// Reset the control registers of this channel.
262284
/// This stops any ongoing transfers.
263285
fn reset(&mut self) {
@@ -357,34 +379,28 @@ pub trait Channel: private::Channel {
357379
self.ch().cr.modify(|_, w| w.dir().variant(dir));
358380
}
359381

360-
/// Enable the interrupt for the given event
361-
fn listen(&mut self, event: Event) {
362-
use Event::*;
382+
/// Enable or disable the interrupt for the specified [`Event`].
383+
fn configure_intterupt(&mut self, event: Event, enable: bool) {
363384
match event {
364-
HalfTransfer => self.ch().cr.modify(|_, w| w.htie().enabled()),
365-
TransferComplete => self.ch().cr.modify(|_, w| w.tcie().enabled()),
366-
TransferError => self.ch().cr.modify(|_, w| w.teie().enabled()),
367-
Any => self.ch().cr.modify(|_, w| {
368-
w.htie().enabled();
369-
w.tcie().enabled();
370-
w.teie().enabled()
385+
Event::HalfTransfer => self.ch().cr.modify(|_, w| w.htie().bit(enable)),
386+
Event::TransferComplete => self.ch().cr.modify(|_, w| w.tcie().bit(enable)),
387+
Event::TransferError => self.ch().cr.modify(|_, w| w.teie().bit(enable)),
388+
Event::Any => self.ch().cr.modify(|_, w| {
389+
w.htie().bit(enable);
390+
w.tcie().bit(enable);
391+
w.teie().bit(enable)
371392
}),
372393
}
373394
}
374395

375-
/// Disable the interrupt for the given event
376-
fn unlisten(&mut self, event: Event) {
377-
use Event::*;
378-
match event {
379-
HalfTransfer => self.ch().cr.modify(|_, w| w.htie().disabled()),
380-
TransferComplete => self.ch().cr.modify(|_, w| w.tcie().disabled()),
381-
TransferError => self.ch().cr.modify(|_, w| w.teie().disabled()),
382-
Any => self.ch().cr.modify(|_, w| {
383-
w.htie().disabled();
384-
w.tcie().disabled();
385-
w.teie().disabled()
386-
}),
387-
}
396+
/// Enable the interrupt for the given [`Event`].
397+
fn enable_interrupt(&mut self, event: Event) {
398+
self.configure_intterupt(event, true);
399+
}
400+
401+
/// Disable the interrupt for the given [`Event`].
402+
fn disable_interrupt(&mut self, event: Event) {
403+
self.configure_intterupt(event, false);
388404
}
389405

390406
/// Start a transfer
@@ -447,6 +463,8 @@ macro_rules! dma {
447463
}
448464

449465
/// DMA channels
466+
#[derive(Debug)]
467+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
450468
pub struct Channels {
451469
$(
452470
/// Channel
@@ -464,6 +482,8 @@ macro_rules! dma {
464482

465483
$(
466484
/// Singleton that represents a DMA channel
485+
#[derive(Debug)]
486+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
467487
pub struct $Ci {
468488
_0: (),
469489
}
@@ -476,7 +496,7 @@ macro_rules! dma {
476496
}
477497

478498
impl Channel for $Ci {
479-
fn event_occurred(&self, event: Event) -> bool {
499+
fn is_event_triggered(&self, event: Event) -> bool {
480500
use Event::*;
481501

482502
// NOTE(unsafe) atomic read

0 commit comments

Comments
 (0)