硬件准备
ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器
软件准备
Visual DSP++软件
硬件链接
接口功能介绍
MDMA 全称是 memoryDMA ,是内存到内存搬运数据的 DMA。在 DSP 做算法时,经常会遇到数据重组或者搬移,如果用 core 搬运这些数据,是对 DSP 资源的一种浪费,此时就可以用到 MDMA 进行数据搬移。
接口寄存器说明
核心代码分析
*pMDMA_S0_START_ADDR = pSrc; //设置源地址
*pMDMA_S0_X_COUNT = 8; //传输次数 8 次
*pMDMA_S0_X_MODIFY = 2; //地址修改增量 2,16bit 模式一次读 2 个 byte
*pMDMA_D0_START_ADDR = pDest;
*pMDMA_D0_X_COUNT = 8;
*pMDMA_D0_X_MODIFY = 2;
*pMDMA_S0_PERIPHERAL_MAP = 0x0040; //配置使用的 DMA 通道
*pMDMA_D0_PERIPHERAL_MAP = 0x0040;
*pMDMA_S0_CONFIG = 0x0024; //配置源 DMA 工作模式
*pMDMA_D0_CONFIG = 0x00a6; //配置目的 DMA 工作模式
*pSIC_IAR5 = 0xfffff6ff; //设置中断等级
register_handler(ik_ivg13, MDMA_ISR); //注册中断
*pSIC_IMASK1 = 0x00000400; //打开中断屏蔽
代码实现功能
代码实现了将源地址 buffer 中的 8 个数据搬到目的地址中,完成搬运后会进入中断程序,然后在中断中再次使能 MDMA,重复搬运数据。
在中断函数中打个断点,运行代码后,Src_Buf 中的数据会被搬运到 Dest_Buf 中去,完成搬运后会进入中断函数,通过 Visual DSP 下的 memory 窗口,可以查看 Dest_Buf 中的数据。
完整代码
- CPU.C
#include <cdefBF533.h>
void Set_PLL(int pmsel,int pssel)
{
int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}
void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}
void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
}
- MDMA.c
#include <cdefBF533.h>
#include <ccblkfn.h>
#include <sys/exception.h>
#include “cpu.h”
//*pSrc :源地址
//*pDest :目的地址
void Init_MDMA(unsigned short *pSrc,unsigned short *pDest)
{
*pMDMA_S0_START_ADDR = pSrc; //设置源地址
*pMDMA_S0_X_COUNT = 8; //传输次数 8次
*pMDMA_S0_X_MODIFY = 2; //地址修改增量2,16bit模式一次读2个byte
*pMDMA_D0_START_ADDR = pDest;
*pMDMA_D0_X_COUNT = 8;
*pMDMA_D0_X_MODIFY = 2;
*pMDMA_S0_PERIPHERAL_MAP = 0x0040; //配置使用的DMA通道
*pMDMA_D0_PERIPHERAL_MAP = 0x0040;
*pMDMA_S0_CONFIG = 0x0024; //配置源DMA工作模式
*pMDMA_D0_CONFIG = 0x00a6; //配置目的DMA工作模式
}
void MDMA_Enable(void) //使能MDMA
{
*pMDMA_S0_CONFIG |= 0x0001;
*pMDMA_D0_CONFIG |= 0x0001;
}
EX_INTERRUPT_HANDLER(MDMA_ISR) //中断函数
{
*pMDMA_D0_IRQ_STATUS=0x1; //清楚中断标志位
MDMA_Enable(); //使能MDMA继续传输
}
void Init_MDMA_Interrupt(void) //初始化中断
{
*pSIC_IAR2 = 0xff6fffff; //设置中断等级
register_handler(ik_ivg13, MDMA_ISR); //注册中断
*pSIC_IMASK = 0x00200000; //打开中断屏蔽
}
- Main.c
#include <cdefBF533.h>
#include “cpu.h”
unsigned short Src_Buf[8]={1,2,3,4,5,6,7,8};
unsigned short Dest_Buf[8]; //目的buffer
void main(void)
{
Set_PLL(16,4); //配置内核时钟400MHz,系统时钟100MHz,25M*16/4
Init_EBIU(); //初始化EBIU
Init_SDRAM(); //初始化SDRAM
Init_MDMA_Interrupt(); //初始化MDMA中断
Init_MDMA(Src_Buf,Dest_Buf); //初始化MDMA
MDMA_Enable(); //使能MDMA
while(1);
}