Hallo liebe Forengemeinde,
für eine Zeitkritische Anwendung versuche ich das DMA Modul meines
Sam3x8e zu verwenden. Da verschiedene Addressen angesprochen werden,
verwende ich Linked Lists.
1 | PMC->PMC_PCER1 = 1 << (ID_DMAC -32);
|
2 | DMAC->DMAC_EBCISR;
|
3 |
|
4 | DMAC->DMAC_CH_NUM[5].DMAC_CFG = DMAC_CFG_SOD_ENABLE|
|
5 | DMAC_CFG_DST_PER(15)|
|
6 | DMAC_CFG_DST_H2SEL_HW|
|
7 | DMAC_CFG_FIFOCFG_ALAP_CFG|
|
8 | DMAC_CFG_AHB_PROT(2)|
|
9 | DMAC_CFG_LOCK_IF;
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_ROUND_ROBIN;
|
15 | DMAC->DMAC_EN = DMAC_EN_ENABLE;
|
16 |
|
17 |
|
18 |
|
19 | IIL[0].ul_ctrlA = DMAC_CTRLA_BTSIZE(2)|
|
20 | DMAC_CTRLA_SRC_WIDTH_WORD|
|
21 | DMAC_CTRLA_DST_WIDTH_WORD;
|
22 |
|
23 | IIL[0].ul_ctrlB = DMAC_CTRLB_FC_MEM2MEM_DMA_FC|
|
24 | DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM|
|
25 | DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM|
|
26 | DMAC_CTRLB_SRC_INCR_INCREMENTING|
|
27 | DMAC_CTRLB_DST_INCR_INCREMENTING;
|
28 | IIL[0].ul_destination_addr = (uint32_t) &(PIOD->PIO_ODSR);
|
29 | IIL[0].ul_source_addr = (uint32_t) array;
|
30 | IIL[0].ul_descriptor_addr = (uint32_t)&IIL[1];
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | IIL[1].ul_ctrlA = DMAC_CTRLA_BTSIZE(2)|
|
36 | DMAC_CTRLA_SRC_WIDTH_WORD|
|
37 | DMAC_CTRLA_DST_WIDTH_WORD|
|
38 | DMAC_CTRLA_SCSIZE_CHK_4;
|
39 | IIL[1].ul_ctrlB = DMAC_CTRLB_FC_MEM2MEM_DMA_FC|
|
40 | DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM|
|
41 | DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM|
|
42 | DMAC_CTRLB_SRC_INCR_INCREMENTING|
|
43 | DMAC_CTRLB_DST_INCR_FIXED;
|
44 | IIL[1].ul_destination_addr = (uint32_t) &(PIOC->PIO_ODSR);
|
45 | IIL[1].ul_source_addr = (uint32_t) array1;
|
46 | IIL[1].ul_descriptor_addr = (uint32_t) 0;
|
47 |
|
48 |
|
49 |
|
50 | DMAC->DMAC_CH_NUM[5].DMAC_DSCR= (uint32_t) &IIL[0];
|
51 | DMAC->DMAC_CHER = DMAC_CHER_ENA5;
|
Wie man sieht verwende ich Mem2Mem Transfer.
Mit einem Oszi an den Beiden Ausgängen die nacheinander geschaltet
werden, wird die Zeit zwischen den beiden LLI transfers gemessen.
Der SAM3x8e ist mit 84 MHz getaktet. Die Zeit zwischen den beiden
Transfers beträgt jedoch fast 500ns (ca. 2Mhz) oder anders gesagt fast
40!!! Clockzyklen.
Ist das ein Programmierfehler meinerseits oder geht es einfach nicht
schneller?
Mit freundlichen Grüßen