Skip to content

Commit 1d03c22

Browse files
authored
Fix incorrect mapping of DMA channel to DMAMUX channel (#80)
* Fix incorrect mapping of DMA channel to DMAMUX channel This is quite an ugly hack but it does try to keep the API as unchanged as possible. This fix only fixes the problem on cat 3 and 4 devices for now. According to RM0440 under "DMAMUX mapping": For category 3 and category 4 devices: * DMAMUX channels 0 to 7 are connected to DMA1 channels 1 to 8 * DMAMUX channels 8 to 15 are connected to DMA2 channels 1 to 8 For category 2 devices: * DMAMUX channels 0 to 5 are connected to DMA1 channels 1 to 6 * DMAMUX channels 6 to 11 are connected to DMA2 channels 1 to 6 * Fix compilation errors on cat 2 devices
1 parent 2162e01 commit 1d03c22

File tree

2 files changed

+90
-13
lines changed

2 files changed

+90
-13
lines changed

src/dma/stream.rs

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub type DMAMUXRegisterBlock = stm32::dmamux::RegisterBlock;
2525

2626
/// Trait that represents an instance of a DMA peripheral
2727
pub trait Instance: Deref<Target = DMARegisterBlock> + Sealed {
28+
const IS_DMA1: bool;
29+
2830
/// Gives a pointer to the RegisterBlock.
2931
fn ptr() -> *const DMARegisterBlock;
3032

@@ -33,6 +35,8 @@ pub trait Instance: Deref<Target = DMARegisterBlock> + Sealed {
3335
}
3436

3537
impl Instance for DMA1 {
38+
const IS_DMA1: bool = true;
39+
3640
#[inline(always)]
3741
fn ptr() -> *const DMARegisterBlock {
3842
DMA1::ptr()
@@ -45,6 +49,8 @@ impl Instance for DMA1 {
4549
}
4650

4751
impl Instance for DMA2 {
52+
const IS_DMA1: bool = false;
53+
4854
#[inline(always)]
4955
fn ptr() -> *const DMARegisterBlock {
5056
DMA2::ptr()
@@ -178,7 +184,7 @@ macro_rules! dma_stream {
178184
($(($name:ident, $number:expr,
179185
regs => $ccr:ident, $cparX:ident, $cmarX:ident, $cndtrX:ident,
180186
fields => $tcif:ident, $htif:ident, $teif:ident, $gif:ident, $tcisr:ident, $htisr:ident, $teisr:ident, $gisr:ident,
181-
dmamux => $cXcr:ident,)
187+
dmamux => $dma1_cXcr:ident, $dma2_cXcr:ident, )
182188
),+$(,)*) => {
183189
$(
184190
impl<I: Instance> Stream for $name<I> {
@@ -294,8 +300,13 @@ macro_rules! dma_stream {
294300
//NOTE(unsafe) We only access the registers that belongs to the StreamX
295301
let dmamux = unsafe { &*I::mux_ptr() };
296302
unsafe {
297-
dmamux.$cXcr
298-
.modify(|_, w| w.dmareq_id().bits(request_line));
303+
if I::IS_DMA1 {
304+
dmamux.$dma1_cXcr
305+
.modify(|_, w| w.dmareq_id().bits(request_line));
306+
} else {
307+
dmamux.$dma2_cXcr
308+
.modify(|_, w| w.dmareq_id().bits(request_line));
309+
};
299310
}
300311
}
301312

@@ -504,55 +515,108 @@ macro_rules! dma_stream {
504515
};
505516
}
506517

518+
// Cat 3 and 4 devices
519+
#[cfg(any(
520+
feature = "stm32g471",
521+
feature = "stm32g473",
522+
feature = "stm32g474",
523+
feature = "stm32g483",
524+
feature = "stm32g484",
525+
feature = "stm32g491",
526+
feature = "stm32g49a",
527+
))]
507528
dma_stream!(
508529
// Note: the field names start from one, unlike the RM where they start from
509530
// zero. May need updating if it gets fixed upstream.
510531
(
511532
Stream0, 0,
512533
regs => ccr1, cpar1, cmar1, cndtr1,
513534
fields => tcif1, htif1, teif1, gif1, tcif1, htif1, teif1, gif1,
514-
dmamux => c0cr,
535+
dmamux => c0cr, c8cr,
515536
),
516537
(
517538
Stream1, 1,
518539
regs => ccr2, cpar2, cmar2, cndtr2,
519540
fields => tcif2, htif2, teif2, gif2, tcif2, htif2, teif2, gif2,
520-
dmamux => c1cr,
541+
dmamux => c1cr, c9cr,
521542
),
522543
(
523544
Stream2, 2,
524545
regs => ccr3, cpar3, cmar3, cndtr3,
525546
fields => tcif3, htif3, teif3, gif3, tcif3, htif3, teif3, gif3,
526-
dmamux => c2cr,
547+
dmamux => c2cr, c10cr,
527548
),
528549
(
529550
Stream3, 3,
530551
regs => ccr4, cpar4, cmar4, cndtr4,
531552
fields => tcif4, htif4, teif4, gif4, tcif4, htif4, teif4, gif4,
532-
dmamux => c3cr,
553+
dmamux => c3cr, c11cr,
533554
),
534555
(
535556
Stream4, 4,
536557
regs => ccr5, cpar5, cmar5, cndtr5,
537558
fields => tcif5, htif5, teif5, gif5, tcif5, htif5, teif5, gif5,
538-
dmamux => c4cr,
559+
dmamux => c4cr, c12cr,
539560
),
540561
(
541562
Stream5, 5,
542563
regs => ccr6, cpar6, cmar6, cndtr6,
543564
fields => tcif6, htif6, teif6, gif6, tcif6, htif6, teif6, gif6,
544-
dmamux => c5cr,
565+
dmamux => c5cr, c13cr,
545566
),
546567
(
547568
Stream6, 6,
548569
regs => ccr7, cpar7, cmar7, cndtr7,
549570
fields => tcif7, htif7, teif7, gif7, tcif7, htif7, teif7, gif7,
550-
dmamux => c6cr,
571+
dmamux => c6cr, c14cr,
551572
),
552573
(
553574
Stream7, 7,
554575
regs => ccr8, cpar8, cmar8, cndtr8,
555576
fields => tcif8, htif8, teif8, gif8, tcif8, htif8, teif8, gif8,
556-
dmamux => c7cr,
577+
dmamux => c7cr, c15cr,
578+
),
579+
);
580+
581+
// Cat 2 devices
582+
#[cfg(any(feature = "stm32g431", feature = "stm32g441",))]
583+
dma_stream!(
584+
// Note: the field names start from one, unlike the RM where they start from
585+
// zero. May need updating if it gets fixed upstream.
586+
(
587+
Stream0, 0,
588+
regs => ccr1, cpar1, cmar1, cndtr1,
589+
fields => tcif1, htif1, teif1, gif1, tcif1, htif1, teif1, gif1,
590+
dmamux => c0cr, c6cr,
591+
),
592+
(
593+
Stream1, 1,
594+
regs => ccr2, cpar2, cmar2, cndtr2,
595+
fields => tcif2, htif2, teif2, gif2, tcif2, htif2, teif2, gif2,
596+
dmamux => c1cr, c7cr,
597+
),
598+
(
599+
Stream2, 2,
600+
regs => ccr3, cpar3, cmar3, cndtr3,
601+
fields => tcif3, htif3, teif3, gif3, tcif3, htif3, teif3, gif3,
602+
dmamux => c2cr, c8cr,
603+
),
604+
(
605+
Stream3, 3,
606+
regs => ccr4, cpar4, cmar4, cndtr4,
607+
fields => tcif4, htif4, teif4, gif4, tcif4, htif4, teif4, gif4,
608+
dmamux => c3cr, c9cr,
609+
),
610+
(
611+
Stream4, 4,
612+
regs => ccr5, cpar5, cmar5, cndtr5,
613+
fields => tcif5, htif5, teif5, gif5, tcif5, htif5, teif5, gif5,
614+
dmamux => c4cr, c10cr,
615+
),
616+
(
617+
Stream5, 5,
618+
regs => ccr6, cpar6, cmar6, cndtr6,
619+
fields => tcif6, htif6, teif6, gif6, tcif6, htif6, teif6, gif6,
620+
dmamux => c5cr, c11cr,
557621
),
558622
);

src/dma/transfer.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,14 +691,27 @@ transfer_constructor!(
691691
(DMA1, Stream3),
692692
(DMA1, Stream4),
693693
(DMA1, Stream5),
694-
(DMA1, Stream6),
695-
(DMA1, Stream7),
696694
(DMA2, Stream0),
697695
(DMA2, Stream1),
698696
(DMA2, Stream2),
699697
(DMA2, Stream3),
700698
(DMA2, Stream4),
701699
(DMA2, Stream5),
700+
);
701+
702+
// Cat 3 and 4 devices
703+
#[cfg(any(
704+
feature = "stm32g471",
705+
feature = "stm32g473",
706+
feature = "stm32g474",
707+
feature = "stm32g483",
708+
feature = "stm32g484",
709+
feature = "stm32g491",
710+
feature = "stm32g49a",
711+
))]
712+
transfer_constructor!(
713+
(DMA1, Stream6),
714+
(DMA1, Stream7),
702715
(DMA2, Stream6),
703716
(DMA2, Stream7),
704717
);

0 commit comments

Comments
 (0)