summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/dsp/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/dsp/dma.c')
-rw-r--r--firmware/target/arm/tms320dm320/dsp/dma.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/dsp/dma.c b/firmware/target/arm/tms320dm320/dsp/dma.c
new file mode 100644
index 0000000000..fe39dc3b21
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/dsp/dma.c
@@ -0,0 +1,87 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Catalin Patulea
11 * Copyright (C) 2008 by Maurus Cuelenaere
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "registers.h"
22#include "arm.h"
23#include "dma.h"
24
25/* This is placed at the right (aligned) address using linker.cmd. */
26#pragma DATA_SECTION (data, ".dma")
27signed short data[PCM_SIZE / 2];
28
29/* Filled in by loader. */
30unsigned short sdem_addrh;
31unsigned short sdem_addrl;
32
33interrupt void handle_dma0(void) {
34 unsigned long sdem_addr;
35 /* Byte offset to half-buffer locked by DMA0.
36 0 for top, PCM_SIZE/2(0x4000) for bottom */
37 unsigned short dma0_locked;
38 unsigned short dma0_unlocked;
39
40 IFR = 1 << 6;
41
42 /* DMSRC0 is the beginning of the DMA0-locked SARAM half-buffer. */
43 DMSA = 0x00 /* DMSRC0 */;
44 dma0_locked = (DMSDN << 1) & (PCM_SIZE / 2);
45 dma0_unlocked = dma0_locked ^ (PCM_SIZE / 2);
46
47 /* ARM, decode into same half, in SDRAM. */
48 status.msg = MSG_REFILL;
49 status.payload.refill.topbottom = dma0_locked;
50 int_arm();
51
52 /* DMAC, copy opposite halves from SDRAM to SARAM. */
53 sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + dma0_unlocked;
54 SDEM_ADDRL = sdem_addr & 0xffff;
55 SDEM_ADDRH = sdem_addr >> 16;
56 DSP_ADDRL = (unsigned short)data + (dma0_unlocked >> 1);
57 DSP_ADDRH = 0;
58 DMA_SIZE = PCM_SIZE / 2;
59 DMA_CTRL = 0;
60
61 status.payload.refill._DMA_TRG = DMA_TRG;
62 status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
63 status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
64 status.payload.refill._DSP_ADDRH = DSP_ADDRH;
65 status.payload.refill._DSP_ADDRL = DSP_ADDRL;
66
67 DMA_TRG = 1;
68}
69
70interrupt void handle_dmac(void) {
71 IFR = 1 << 11;
72}
73
74void dma_init(void) {
75 /* Configure DMA */
76 DMSFC0 = 2 << 12 | 1 << 11; /* Event XEVT0, 32-bit transfers, 0 frame count */
77 DMMCR0 = 1 << 14 | 1 << 13 | /* Interrupts generated, Half and full buffer */
78 1 << 12 | 1 << 8 | 1 << 6 | 1; /* ABU mode,
79 From data space with postincrement,
80 To data space with no mod */
81 DMSRC0 = (unsigned short)&data;
82 DMDST0 = (unsigned short)&DXR20; /* First of two-word register pair */
83 DMCTR0 = sizeof(data);
84
85 /* Run, Rudolf, run! (with DMA0 interrupts) */
86 DMPREC = 2 << 6 | 1;
87}