Skip to content

Commit 61dcdcb

Browse files
committed
demacrofy DMA
1 parent 821324d commit 61dcdcb

File tree

2 files changed

+66
-73
lines changed

2 files changed

+66
-73
lines changed

src/dma.rs

Lines changed: 55 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Direct Memory Access Engine
22
33
// TODO: add DMA2 for B1, C1
4-
use crate::dmamux::DmaMuxIndex;
5-
use crate::rcc::Rcc;
6-
use crate::stm32::DMAMUX;
4+
use crate::dmamux::{self, DmaMuxExt, DmaMuxIndex};
5+
use crate::rcc::{Enable, Rcc, Reset};
6+
use crate::stm32::{self, DMA1 as DMA, DMAMUX};
77

88
/// Extension trait to split a DMA peripheral into independent channels
99
pub trait DmaExt {
@@ -243,6 +243,57 @@ pub trait Channel: private::Channel {
243243
}
244244
}
245245

246+
/// Singleton that represents a DMA channel
247+
pub struct C<const N: u8> {
248+
mux: dmamux::Channel<N>,
249+
}
250+
251+
impl<const N: u8> private::Channel for C<N> {
252+
fn ch(&self) -> &stm32::dma1::CH {
253+
// NOTE(unsafe) $Ci grants exclusive access to this register
254+
unsafe { &(*DMA::ptr()).ch(N as usize) }
255+
}
256+
}
257+
258+
impl<const N: u8> C<N> {
259+
pub fn mux(&mut self) -> &mut dyn dmamux::DmaMuxChannel {
260+
&mut self.mux
261+
}
262+
}
263+
264+
impl<const N: u8> Channel for C<N> {
265+
fn select_peripheral(&mut self, index: DmaMuxIndex) {
266+
self.mux().select_peripheral(index);
267+
}
268+
269+
fn event_occurred(&self, event: Event) -> bool {
270+
use Event::*;
271+
272+
// NOTE(unsafe) atomic read
273+
let flags = unsafe { (*DMA::ptr()).isr().read() };
274+
match event {
275+
HalfTransfer => flags.htif(N).bit_is_set(),
276+
TransferComplete => flags.tcif(N).bit_is_set(),
277+
TransferError => flags.teif(N).bit_is_set(),
278+
Any => flags.gif(N).bit_is_set(),
279+
}
280+
}
281+
282+
fn clear_event(&mut self, event: Event) {
283+
use Event::*;
284+
285+
// NOTE(unsafe) atomic write to a stateless register
286+
unsafe {
287+
let _ = &(*DMA::ptr()).ifcr().write(|w| match event {
288+
HalfTransfer => w.chtif(N).set_bit(),
289+
TransferComplete => w.ctcif(N).set_bit(),
290+
TransferError => w.cteif(N).set_bit(),
291+
Any => w.cgif(N).set_bit(),
292+
});
293+
}
294+
}
295+
}
296+
246297
macro_rules! dma {
247298
(
248299
channels: {
@@ -251,11 +302,6 @@ macro_rules! dma {
251302
)+
252303
},
253304
) => {
254-
use crate::dmamux;
255-
use crate::rcc::{Enable, Reset};
256-
use crate::stm32::{self, DMA1 as DMA};
257-
use crate::dmamux::DmaMuxExt;
258-
259305
/// DMA channels
260306
pub struct Channels {
261307
$( pub $chi: $Ci, )+
@@ -269,60 +315,8 @@ macro_rules! dma {
269315
}
270316
}
271317

272-
273318
$(
274-
/// Singleton that represents a DMA channel
275-
pub struct $Ci {
276-
mux: dmamux::Channel<$i>,
277-
}
278-
279-
impl private::Channel for $Ci {
280-
fn ch(&self) -> &stm32::dma1::CH {
281-
// NOTE(unsafe) $Ci grants exclusive access to this register
282-
unsafe { &(*DMA::ptr()).ch($i) }
283-
}
284-
}
285-
286-
impl $Ci {
287-
pub fn mux(&mut self) -> &mut dyn dmamux::DmaMuxChannel {
288-
&mut self.mux
289-
}
290-
}
291-
292-
impl Channel for $Ci {
293-
294-
fn select_peripheral(&mut self, index: DmaMuxIndex) {
295-
self.mux().select_peripheral(index);
296-
}
297-
298-
fn event_occurred(&self, event: Event) -> bool {
299-
use Event::*;
300-
301-
// NOTE(unsafe) atomic read
302-
let flags = unsafe { (*DMA::ptr()).isr().read() };
303-
match event {
304-
HalfTransfer => flags.htif($i).bit_is_set(),
305-
TransferComplete => flags.tcif($i).bit_is_set(),
306-
TransferError => flags.teif($i).bit_is_set(),
307-
Any => flags.gif($i).bit_is_set(),
308-
}
309-
}
310-
311-
fn clear_event(&mut self, event: Event) {
312-
use Event::*;
313-
314-
// NOTE(unsafe) atomic write to a stateless register
315-
unsafe {
316-
let _ = &(*DMA::ptr()).ifcr().write(|w| match event {
317-
HalfTransfer => w.chtif($i).set_bit(),
318-
TransferComplete => w.ctcif($i).set_bit(),
319-
TransferError => w.cteif($i).set_bit(),
320-
Any => w.cgif($i).set_bit(),
321-
});
322-
}
323-
}
324-
325-
}
319+
pub type $Ci = C<$i>;
326320
)+
327321
}
328322
}

src/dmamux.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,12 @@ pub trait DmaMuxChannel {
149149
fn select_peripheral(&mut self, index: DmaMuxIndex);
150150
}
151151

152-
pub struct Channel<const N: usize> {
153-
_0: (),
154-
}
152+
#[non_exhaustive]
153+
pub struct Channel<const N: u8>;
155154

156-
impl<const N: usize> DmaMuxChannel for Channel<N> {
155+
impl<const N: u8> DmaMuxChannel for Channel<N> {
157156
fn select_peripheral(&mut self, index: DmaMuxIndex) {
158-
let reg = unsafe { &(*DMAMUX::ptr()).ccr(N) };
157+
let reg = unsafe { &(*DMAMUX::ptr()).ccr(N as usize) };
159158
reg.write(|w| unsafe { w.dmareq_id().bits(index.val()).ege().set_bit() });
160159
}
161160
}
@@ -193,27 +192,27 @@ impl DmaMuxExt for DMAMUX {
193192

194193
fn split(self) -> Self::Channels {
195194
Channels {
196-
ch0: Channel::<0> { _0: () },
197-
ch1: Channel::<1> { _0: () },
198-
ch2: Channel::<2> { _0: () },
199-
ch3: Channel::<3> { _0: () },
200-
ch4: Channel::<4> { _0: () },
195+
ch0: Channel::<0>,
196+
ch1: Channel::<1>,
197+
ch2: Channel::<2>,
198+
ch3: Channel::<3>,
199+
ch4: Channel::<4>,
201200
#[cfg(any(
202201
feature = "stm32g070",
203202
feature = "stm32g071",
204203
feature = "stm32g081",
205204
feature = "stm32g0b1",
206205
feature = "stm32g0c1",
207206
))]
208-
ch5: Channel::<5> { _0: () },
207+
ch5: Channel::<5>,
209208
#[cfg(any(
210209
feature = "stm32g070",
211210
feature = "stm32g071",
212211
feature = "stm32g081",
213212
feature = "stm32g0b1",
214213
feature = "stm32g0c1",
215214
))]
216-
ch6: Channel::<6> { _0: () },
215+
ch6: Channel::<6>,
217216
}
218217
}
219218
}

0 commit comments

Comments
 (0)