📄 memdmafunc.asm
字号:
/*****************************************************************************
** **
** Name: MemDMA_descriptor.dpj **
** **
******************************************************************************
(C) Copyright 2003 - Analog Devices, Inc. All rights reserved.
File Name: memDMAfunc.asm
Date Modified: 3/5/03 RG Rev 1.0
Software: VisualDSP++3.1
Hardware: ADSP-BF533 EZ-KIT Board
Special Connections: None
Purpose: To demonstrate various memDMA descriptor examples
including 1D to 1D, 1D to 2D, and 2D to 2D
Program Parameters:
******************************************************************************/
#include "defBF533.h"
/*****************************************************************************
MemDma routines
dmaDescrPtr = memdma_move1Dto2D (srcaddr, xcount, ycount, dstaddr, [priority])
dmaDescrPtr = memdma_move2Dto1D (srcaddr, xcount, ycount, dstaddr, [priority])
dmaDescrPtr = memdma_move1D (srcaddr (32b), count (32b), destaddr (32b), [priority])
memdma_wait (dmaDescrPtr)
******************************************************************************/
#include "memdma.h"
#define NUM_QUEUE_STRUCT_ELEM 2
// All of these are configured as descriptor list (small model) 0x6 in upper byte
// Descriptor size = 8
// all are set to 32-bit transfers
// all are set to DMA enable
#define SRCMEM1DCFG 0x6809 // DMA read
#define SRCMEM2DCFG 0x6819 // 2D bit set, DMA read
#define DSTMEM1DCFG 0x680B // DMA write
#define DSTMEM2DCFG 0x681B // 2D bit set, DMA write
//DMA Descriptor (S&D) - Small Model
//1 32B Word: LS16BW:Src NDPL, MS16BW:Src SAL +0
//2 32B Word: LS16BW:Src SAH, MS16BW:Src DMACFG +4
//3 32B Word: LS16BW:Src XCNT, MS16BW:Src XMOD +8
//4 32B Word: LS16BW:Src YCNT, MS16BW:Src YMOD +12
//6 32B Word: LS16BW:Dst NDPL, MS16BW:Dst SAL +16
//7 32B Word: LS16BW:Dst SAH, MS16BW:Dst DMACFG +20
//8 32B Word: LS16BW:Dst XCNT, MS16BW:Dst XMOD +24
//9 32B Word: LS16BW:Dst YCNT, MS16BW:Dst YMOD +28
.extern MemDMAQueue;
.extern memdma_move1D_buffer; // sets up descriptors for 1D transfer
//.section shell_L1_data;
.section L1_data_a;
.align 4;
//.section shell_L1_data;
.section L1_data_a;
.align 4;
MemDMAQueueStruct:
.byte4 _MemDMAQueueStruct[NUM_QUEUE_STRUCT_ELEM] = MemDMAQueue,
MemDMAQueue;
.section L1_code;
.align 4;
//dummy_start:
.global memdma_move1Dto2D; // sets up 1D to 2D descriptor
memdma_move1Dto2D:
p1.h = MemDMAQueueStruct;
p1.l = MemDMAQueueStruct;
r5 = [p1++]; //tail address
i0 = r5;
r4 = [p1--]; //MemDMAQueue start address
b0 = r4;
l0 = NUM_DESCR_BLOCKS_IN_QUEUE*32 (z);
m0 = 8;
nop;
r4.l = w[i0++]; //S_NDPL -> dummy read
w[i0++] = r0.l; //S_SAL
w[i0++] = r0.h; //S_SAH
r0.l = SRCMEM1DCFG;
w[i0++] = r0.l; //S_CFG
r0 = r1; //S_XMOD = D_XMOD
r0.l = r1.l * r2.l (IU); //S_XCNT = D_XCNT * D_YCNT
[i0++m0] = r0; //S_XCNT/S_XMOD
r4.l = w[i0++]; //D_NDPL -> dummy read
w[i0++] = r3.l; //D_SAL
w[i0++] = r3.h; //D_SAH
r0.l = DSTMEM2DCFG;
w[i0++] = r0.l; //D_CFG
[i0++] = r1; //D_XCNT/D_XMOD
[i0++] = r2; //D_YCNT/D_YMOD
l0 = 0;
r0 = i0;
[p1] = r0; //update tail with NDP value
r0 = r5; // r0 - return parameter
rts;
memdma_move1Dto2D.end:
.global memdma_move2Dto2D; // sets up 2D to 2D descriptor
memdma_move2Dto2D:
p1.h = MemDMAQueueStruct;
p1.l = MemDMAQueueStruct;
r5 = [p1++]; //tail address
i0 = r5;
r4 = [p1--]; //MemDMAQueue start address
b0 = r4;
l0 = NUM_DESCR_BLOCKS_IN_QUEUE*32 (z);
m0 = 8;
nop;
r4.l = w[i0++]; //S_NDPL -> dummy read
w[i0++] = r0.l; //S_SAL
w[i0++] = r0.h; //S_SAH
r0.l = SRCMEM2DCFG;
w[i0++] = r0.l; //D_CFG
[i0++] = r1; //D_XCNT/D_XMOD
[i0++] = r2; //D_YCNT/D_YMOD
#if 0
w[i0++] = r0.l; //S_CFG
r0 = r1; //S_XMOD = D_XMOD
r0.l = r1.l * r2.l (IU); //S_XCNT = D_XCNT * D_YCNT
[i0++m0] = r0; //S_XCNT/S_XMOD
#endif
r4.l = w[i0++]; //D_NDPL -> dummy read
w[i0++] = r3.l; //D_SAL
w[i0++] = r3.h; //D_SAH
r0.l = DSTMEM2DCFG;
w[i0++] = r0.l; //D_CFG
[i0++] = r1; //D_XCNT/D_XMOD
[i0++] = r2; //D_YCNT/D_YMOD
l0 = 0;
r0 = i0;
[p1] = r0; //update tail with NDP value
r0 = r5; // r0 - return parameter
rts;
memdma_move2Dto2D.end:
//r0 -> src address
//r1 -> XCNT/XMOD
//r2 -> YCNT/YMOD
//r3 -> Dst Addr
.global memdma_move1D; // sets up 1D to 1D descriptor
memdma_move1D:
p1.h = MemDMAQueueStruct;
p1.l = MemDMAQueueStruct;
r5 = [p1++]; //tail address
i0 = r5;
r4 = [p1--]; //MemDMAQueue start address
b0 = r4;
l0 = NUM_DESCR_BLOCKS_IN_QUEUE*32 (z);
m0 = 8;
nop;
r4.l = w[i0++]; //dummy read to offset NDPL
w[i0++] = r0.l; //S_SAL
w[i0++] = r0.h; //S_SAH
r0.l = SRCMEM1DCFG;
w[i0++] = r0.l; //S_CFG
[i0++m0] = r1; //S_XCNT/S_XMOD
r4.l = w[i0++]; //dummy read to get over DST NDPL
w[i0++] = r3.l; //D_SAL
w[i0++] = r3.h; //D_SAH
r3.l = DSTMEM1DCFG;
w[i0++] = r3.l; //D_CFG
[i0++m0] = r1; //D_XCNT/D_XMOD
l0 = 0;
r0 = i0;
[p1] = r0; //update tail with NDP value
r0 = r5; // r0 - return parameter
rts;
memdma_move1D.end:
.global activate_dma_engine;
activate_dma_engine: // once descriptor list is set, call this to start DMA
p0.h = HI(MDMA_S0_NEXT_DESC_PTR);
p0.l = LO(MDMA_S0_NEXT_DESC_PTR);
r0.l = MemDMAQueue; //Address of the Source Descriptor
r0.h = MemDMAQueue;
[p0] = r0;
ssync;
p0.l = LO(MDMA_D0_NEXT_DESC_PTR);
r0 +=16; //Address of the Destination Descriptor
[p0] = r0;
ssync;
//Enable MemDMA Source
p0.l = LO(MDMA_S0_CONFIG);
r0.l = SRCMEM1DCFG;
w[p0] = r0.l;
ssync;
//Enable MemDMA Destination
p0.l = LO(MDMA_D0_CONFIG);
r0.l = DSTMEM1DCFG;
w[p0] = r0.l;
ssync;
rts;
activate_dma_engine.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -