DSP DMA实验

1. DMA简介

DMA(Direct Memory Access),中文意思为直接存储器访问。DMA 可用于实 现外设与存储器之间或者存储器与存储器之间数据传输的高效性。之所以称为高 效,是因为 DMA 传输数据移动过程无需 CPU 直接操作,这样节省的 CPU 资源 就可供其它操作使用。从硬件层面来理解,DMA 就好像是 RAM 与 I/O 设备间数 据传输的通路,外设与存储器之间或者存储器与存储器之间可以直接在这条通路 上进行数据传输。这里说的外设一般指外设的数据寄存器,比如 ADC、SPI、I2C 等外设的数据寄存器,存储器一般是指片内 SRAM、外部存储器、片内 Flash 等。
实现 DMA 传输的关键部件是 DMA 控制器( DMAC)。DMA 系统组成框图如下所 示:

 系统总线分别受到 CPU 和 DMAC 这两个部件的控制,即 CPU 可以向地址总线、 数据总线和控制总线发送信息(非 DMA 方式),DMAC 也可以向地址总线、数据总线和控制总线发送信息(DMA 方式)。但在同一时刻,系统总线只能受一个部 件的控制。究竟是哪个部件来控制系统总线,是由这两个部件之间的“联络信号” 控制实现的。DMA 取得总线控制权前处于受控状态,此时,CPU 可对 DMAC 进行初始化编程,也可以从 DMAC 中读出状态,这时 DMA 处于从态,DMAC 上电或复位时,DMAC 自动处于从态。在 DMAC 获得总线控制权之后,DMAC 取代 CPU 而成为系统总线的主控者,接管和控制系统总线。通过总线向存储器或 IO 设备发出地址、读/ 写信号,以控制在两个实体之前的数据传送。这时候 DMA 处于主动态。

DMA 传送过程大致有以下几个步骤:
①当外设输入数据准备好,外设向 DMA 发出一个选通信号,将数据送到数据 发攻略 端口,向DMA 发出请求。
②DMA 控制器向 CPU 发出总线请求信号(HOLD)高电平。
③CPU 在现行总线周期结束后响应,向 DMA 发出响应信号(HLDA)高电平。
④CPU 待该总线周期结束时,放弃对总线控制,DMA 控制器接管三态总线,接口将数据送上数据总线并撤销 DMA 请求。
⑤内存收到数据以后,给 DMA 一个回答,于是 DMA 修改地址指针,改变传送字节数,检查传送是否结束,没有结束,则下次接口准备好数据,再进行一次新 的传输。
⑥当计数值计为 0,DMA 传输过程便告结束。DMA 控制器撤销总线请求(HOLD 变低),在下一个时钟周期上升沿使总线响应 HLDA 变低,DMA 释放总线,CPU 取得总线控制权。
在高速大数据量场合的情况下,DMA 传输方式显然要比 CPU 中断处理方式更 加优越,效率更加高。但并不是每个控制器都有 DMA 通道,即便 DMA 通道的控制 器,其通道数也是有限的,因为 DMA 通道是有额外硬件开销的。在 DMA 期间由 DMAC(直接存储器存取控制器)控制总线,负责一批数据的传输,数据传送完成 后,再把总线的控制权交给 CPU。由于 DMA 传送期间,CPU 让出总线控制权,这 就可能影响诸如中断请求的及时响应和处理;又因为 DMA 传送方式的高速度是以 增加系统的复杂性和成本为代价的(即用硬件控制代替软件控制)。所以在一些 小系统中,当传送数据量及速度要求不高时,一般不用 DMA 方式。
F28335 的 DMA 的基本特征如下:
①6 个 DMA 通道,6 个通道都具有独立的 PIE 中断。
②外设中断触发源。
DMA 模块是基于事件触发的,因此要求一个外设触发器启动 DMA 数据的传递。比如:它能通过将一个定时器配置成中断触发源,从而鞭策一个周期性的定时驱 动器,中断触发源可以为 6 个DMA 通道分别单独配置。F28335 的外设中断触发 源如下:
--ADC 排序器 1 和排序器 2。
--多路缓冲串行端口 A 和 B(MCBSP-A,MSBSP-B)的发送和接收。
--XINT1~XINT13。
--CPU 定时/计数器。
--ePWM1~6 ADCSOCA 和 ADCSOCB 信号。
--软件
③数据源/目的地。
DMA 传递数据的来源或者传输的目的地,主要如下:
--L4~L7 16K*16 SARAM。
--所有 XINTF 区域(外扩的存储器)。
--ADC 的结果寄存器。
--McBSP-A 和 McBSP-B 发送和接收缓冲器。
--ePWM1~6/HRPWM1~6 外设第 3 帧映射寄存器。
ePWM/HRPWM 寄存器被 DMA 访问之前必须被重新映射到 PF3(通过 MAPCNF 寄
存器的 0 位设置)。
④字长。DMA 传输数据的字长为:
--字的大小:16 位或 32 位(McBSP 只限于 16 位)。
--读写操作:4 周期/字(对于 McBSP 5 周期/字进行读取)
1.2 F28335 DMA 模块介绍
F28335 的 DMA 模块主要结构如下图所示:

 DMA 数据传输是基于事件触发的,这就意味着 DMA 需要外设中断触发来启动DMA 的数据传输。F28335 共有 18 个不同的触发源,上图右边即为触发源,外设触发源有如下所示几种:

 其中有 8 个外部中断触发源,全部来至 GPIO 引脚,这样 DMA 的时间触发是 很灵活的。DMA 不能通过自身数据源定时触发,若要定时触发可以借助外设中断 触发源中的 CPU 定时器来实现。F28335 共有 6 个 DMA 通道,每个通道都可以有 各自的触发源,通过各自独立的 PIE 中断告知 CPU DMA 数据传输的开始和结束,这 6 个通道中,第一通道有着更高的优先级。DMA 模块的核心其实是一个与地址控制逻辑紧密关联的状态机,在数据传输过程中让数据块自动的重新配置,就好像是两个缓冲器之间在打乒乓球一样,因此也把这种机制称为 DMA 的乒乓机制。DMA 总线结构包括一个 22 位地址总线,一个 32 位地址总线,一个 32 位数据读总线和一个 32 位数据写总线,与 DMA 总线相连的资源,好比乒乓球运动员,分别是数据传送的地址源与数据源,地址源与数据源的接口通过总线互相相连,这个接口 DMA 可能会访问,CPU 也会访问。与 DMA 总线相连的资源如上图左边部分(①XINTF 区域 0、6、7、8,L4 SARAM、L5 SARAM、L6 SARAM、L7 SARAM;②ADC 存储器映射结果寄存器;③MCBSP-A 和 MCBSP-B 数据接收寄存器(DDR2/DDR1)和数据发送寄存器(DXR2/DXR1);④映射到外设 3 的 ePWM1-6/HRPWM1-6 寄存器)。

(1)DMA 模块的触发机制
外设中断触发 DMA 数据传送的原理如下:

 (2)DMA 模块的流水线机制

DMA 进行数据传输时采用了 4 级流水线,将数据传输主要分为如下几个工序:产生数据源地址,输出数据源地址,读数据源数据,产生目的源地址,输出目的 源地址,写目的源数据。如下图所示:

 有个例外情况是,当将 MCBSP 作为数据源时,读取 MCBSP DDR 寄存器的值时, 会拖延 DMA 一个时钟周期,如下图所示:

 此外还有一些其他操作也会影响到 DMA 通道的吞吐,如下:

①在每次数据传输之前要增加一个周期的延迟。
②当从 CH1 高优先级中断返回时也会周期延迟。
③32 位传输速度是 16 位传输速度的两倍,传输一个 32 位的字与传输一个16 位的字所花的时间是一样的。
④与 CPU 的冲突可能增加延迟时间。
例如:从 ADC 到 RAM 传递 128 个 16 位的字,通道被配置成 1 波传递 16 个字,每个字要花 4 个时钟周期,8 波能传递完成,总共需要 520 个时钟周期,计算方 法如下:
8 bursts*[(4 cycles/word *16 words/burst)+1]=520 cycles
如果通道被配置成传递 32 位的字,传递过程为 8 bursts*[(4 cycles/word *8 words/burst)+1]=264 cycles,共需要 264 个时钟周期,所花时间差不多减半。 也就是对 DMA 传输而言,采用 32 位数据线传输,若以 16 位为字进行传输,则浪 费了一半吞吐量。
(3)DMA 模块的 CPU 仲裁机制
通常情况下,DMA 的运行是独立于 CPU 运行的。但是有时候 DMA 与 CPU 会同时通过同一个接口访问存储器或外设寄存器,这时候就需要进入 CPU 仲裁程序。 比较特殊的情况是,ADC 寄存器(内存映射 PF0)被 CPU 与 DMA 同时访问的时候 不会有冲突,即使是访问不同的地址。访问任何一个不同的接口或者 CPU 要通过 一个 DMA 正在访问的接口,即访问同一接口的时间是不同时的,都不会产生冲突。 有可能产生冲突的内部接口如下:
①XINTF 存储区域 0、6 和 7
②L4 RAM~L7 RAM
③外设帧 3(MCBSP-A 和 MCBSP-B)
(4)F28335 的 DMA 模块的 ADC 同步特征
当 ADC 转换器工作在连续转换模式且使能覆盖功能时,DMA 可以与 ADC 的序列 1 中断( SEQ1INT)进行硬件同步。在此模式下,ADC 可以连续的转换序列中 的各个通道,并在序列末尾不对序列指针进行复位。DMA 收到触发信号时并不知 道 ADC 的序列指针指向哪个ADCRESULT 寄存器,因此 DMA 与 ADC 之间存在潜在的 不同步问题。当 ADC 配置为上述模式时,每当转换序列指向 RESULT0 寄存器时, 将给 DMA 提供一个同步信号,DMA 用这个同步信号去完成一个返回过程或开始一 次传送。如果 ADC 不这样做,会再度同步。
① 将 返 回 长 度 寄 存 器 WRAP_SIZE 的 值 重 新 装 载 到 返 回 计 数 寄 存 器WRAP_COUNT 中。
②将开始地址指针寄存器 BEG_ADDR 的值装载到 ADDR 当前寄存器中。
③CONTROL 寄存器中的 SYNCERR 位置位。
(5)F28335 的 DMA 溢出检测特征
DMA 有溢出检测逻辑。当 DMA 接收到一次外部中断触发信号时,CONTROL 寄存器中的PERINTFLG 位置位,并将相应的通道在 DMA 状态机中挂起,当该通过的 突发传送开始时,PERINTFLG 被清除。如果 PERINTFLG 置位后在该通过的突发传 送开始前又有型的触发信号到来,则第二个触发信号将被丢失,并且将 CONTROL 寄存器中的错误标志位 OVERFLG 置位,如下图所示,如果溢出中断被使能,则该 通道将向 PIE 模块发出中断请求。

 2 DMA 配置步骤

(1)使能 DMA 外设时钟
要使用 DMA 外设则需开启相应时钟,开启 DMA 外设时钟代码如下:
EALLOW; 
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // DMA Clock 
EDIS;
(2)初始化 DMA
开启了 DMA 时钟后,下面就需要对 DMA 初始化,即复位 DMA 和允许 DMA 在仿真暂停时运行。在 DMA 库文件中,TI 已经提供了此函数,函数如下:
void DMAInitialize(void);
函数内具体代码如下:
void DMAInitialize(void) 
{ 
    EALLOW; 
    // Perform a hard reset on DMA 
    DmaRegs.DMACTRL.bit.HARDRESET = 1; 
    // Allow DMA to run free on emulation suspend 
    DmaRegs.DEBUGCTRL.bit.FREE = 1; 
    EDIS; 
}
(3)DMA 通道相关参数设置,包括指针数据长度、步长、触发源选择、触发 模式等。
要想使用 DMA,除了使能 DMA 时钟和初始化 DMA 外,还需要对其进行通道选择及参数的设置。关于这些相关参数的设置,DMA 库文件内都有相应的函数供我 们调用。例如本章中使用 DMA 通道 1 来进行 ADC 数据传输,设置 ADC 排序器 1、 单次触发模式等。至于 DMA 的其他通道配置都是一样,只不过修改下通道数即可, 具体配置代码如下:
#define ADC_usDELAY  5000L

//---------------------------------------------------------------------------
// InitAdc:
//---------------------------------------------------------------------------
// This function initializes ADC to a known state.
//
void InitAdc(void)
{
    extern void DSP28x_usDelay(Uint32 Count);


    // *IMPORTANT*
	// The ADC_cal function, which  copies the ADC calibration values from TI reserved
	// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
	// Boot ROM. If the boot ROM code is bypassed during the debug process, the
	// following function MUST be called for the ADC to function according
	// to specification. The clocks to the ADC MUST be enabled before calling this
	// function.
	// See the device data manual and/or the ADC Reference
	// Manual for more information.

	    EALLOW;
		SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
		ADC_cal();
		EDIS;




    // To powerup the ADC the ADCENCLK bit should be set first to enable
    // clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
    // Before the first conversion is performed a 5ms delay must be observed
	// after power up to give all analog circuits time to power up and settle

    // Please note that for the delay function below to operate correctly the
	// CPU_CLOCK_SPEED define statement in the DSP2833x_Examples.h file must
	// contain the correct CPU clock period in nanoseconds.

    AdcRegs.ADCTRL3.all = 0x00E0;  // Power up bandgap/reference/ADC circuits/顺序采样
    DELAY_US(ADC_usDELAY);         // Delay before converting ADC channels
}

// This function initializes the DMA to a known state.
//
void DMAInitialize(void)
{
	EALLOW;

	// Perform a hard reset on DMA
	DmaRegs.DMACTRL.bit.HARDRESET = 1;

	// Allow DMA to run free on emulation suspend
	DmaRegs.DEBUGCTRL.bit.FREE = 1;
	
	EDIS;
}

  
void DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	// Set up SOURCE address:
	DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH1.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH1.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH1BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
	EALLOW;
	
	// Set up BURST registers:
	DmaRegs.CH1.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH1.SRC_BURST_STEP = srcbstep;			    // Increment source addr between each word x-ferred
	DmaRegs.CH1.DST_BURST_STEP = desbstep;              // Increment dest addr between each word x-ferred


	EDIS;
}

void DMACH1TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;
	
	// Set up TRANSFER registers:
	DmaRegs.CH1.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH1.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH1.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs

	EDIS;
}

void DMACH1WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;
	
		// Set up WRAP registers:
	DmaRegs.CH1.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH1.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH1.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH1.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH1ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;
	    
	// Set up MODE Register:
	DmaRegs.CH1.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH1.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH1.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH1.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH1.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH1.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH1.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH1.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH1.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH1.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH1.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx1 = 1;              // Enable DMA CH1 interrupt in PIE

	EDIS;
}

// This function starts DMA Channel 1. 
void StartDMACH1(void)
{
	EALLOW;
	DmaRegs.CH1.CONTROL.bit.RUN = 1;
	EDIS;
}

void DMACH2AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	
	// Set up SOURCE address:
	DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH2.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH2.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH2BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
	EALLOW;

	// Set up BURST registers:
	DmaRegs.CH2.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH2.SRC_BURST_STEP = srcbstep;			    // Increment source addr between each word x-ferred
	DmaRegs.CH2.DST_BURST_STEP = desbstep;              // Increment dest addr between each word x-ferred


	EDIS;
}

void DMACH2TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;
	
		// Set up TRANSFER registers:
	DmaRegs.CH2.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH2.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH2.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs

	EDIS;
}

void DMACH2WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;
	
		// Set up WRAP registers:
	DmaRegs.CH2.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH2.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH2.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH2.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH2ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;
	
		// Set up MODE Register:
	DmaRegs.CH2.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH2.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH2.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH2.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH2.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH2.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH2.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH2.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH2.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH2.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH2.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx2 = 1;              // Enable DMA CH2 interrupt in PIE

	EDIS;
}



// This function starts DMA Channel 2. 	
void StartDMACH2(void)
{
	EALLOW;
	DmaRegs.CH2.CONTROL.bit.RUN = 1;
	EDIS;
}



void DMACH3AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	
	// Set up SOURCE address:
	DmaRegs.CH3.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH3.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH3.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH3.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH3BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
	EALLOW;

	// Set up BURST registers:
	DmaRegs.CH3.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH3.SRC_BURST_STEP = srcbstep;			    // Increment source addr between each word x-ferred
	DmaRegs.CH3.DST_BURST_STEP = desbstep;              // Increment dest addr between each word x-ferred


	EDIS;
}

void DMACH3TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;

		// Set up TRANSFER registers:
	DmaRegs.CH3.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH3.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH3.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs
	
	EDIS;
}

void DMACH3WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;
	
			// Set up WRAP registers:
	DmaRegs.CH3.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH3.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH3.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH3.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH3ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;
	
	// Set up MODE Register:
	DmaRegs.CH3.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH3.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH3.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH3.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH3.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH3.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH3.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH3.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH3.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH3.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH3.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH3.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH3.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx3 = 1;              // Enable DMA CH3 interrupt in PIE

	EDIS;
}

// This function starts DMA Channel 3. 	
void StartDMACH3(void)
{
	EALLOW;
	DmaRegs.CH3.CONTROL.bit.RUN = 1;
	EDIS;
}


void DMACH4AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;

	// Set up SOURCE address:
	DmaRegs.CH4.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH4.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH4.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH4.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH4BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
	EALLOW;

	// Set up BURST registers:
	DmaRegs.CH4.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH4.SRC_BURST_STEP = srcbstep;			    // Increment source addr between each word x-ferred
	DmaRegs.CH4.DST_BURST_STEP = desbstep;              // Increment dest addr between each word x-ferred


	EDIS;
}

void DMACH4TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;
	
	// Set up TRANSFER registers:
	DmaRegs.CH4.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH4.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH4.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs
	
	EDIS;
}

void DMACH4WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;
	
		// Set up WRAP registers:
	DmaRegs.CH4.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH4.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH4.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH4.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH4ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;
	
		// Set up MODE Register:
	DmaRegs.CH4.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH4.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH4.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH4.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH4.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH4.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH4.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH4.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH4.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH4.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH4.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH4.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH4.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx4 = 1;              // Enable DMA CH4 interrupt in PIE

	EDIS;
}


// This function starts DMA Channel 4. 	
void StartDMACH4(void)
{
	EALLOW;
	DmaRegs.CH4.CONTROL.bit.RUN = 1;
	EDIS;
}


void DMACH5AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	
	// Set up SOURCE address:
	DmaRegs.CH5.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH5.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH5.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH5.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH5BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
	EALLOW;


	// Set up BURST registers:
	DmaRegs.CH5.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH5.SRC_BURST_STEP = srcbstep;			    // Increment source addr between each word x-ferred
	DmaRegs.CH5.DST_BURST_STEP = desbstep;              // Increment dest addr between each word x-ferred

	EDIS;
}

void DMACH5TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;
	

		// Set up TRANSFER registers:
	DmaRegs.CH5.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH5.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH5.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs
	
	EDIS;
}

void DMACH5WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;
	

		// Set up WRAP registers:
	DmaRegs.CH5.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH5.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH5.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH5.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH5ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;
	
		// Set up MODE Register:
	DmaRegs.CH5.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH5.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH5.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH5.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH5.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH5.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH5.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH5.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH5.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH5.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH5.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH5.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH5.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx5 = 1;              // Enable DMA CH5 interrupt in PIE

	EDIS;
}

// This function starts DMA Channel 5. 	
void StartDMACH5(void)
{
	EALLOW;
	DmaRegs.CH5.CONTROL.bit.RUN = 1;
	EDIS;
}



void DMACH6AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	
	// Set up SOURCE address:
	DmaRegs.CH6.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;	// Point to beginning of source buffer
	DmaRegs.CH6.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

	// Set up DESTINATION address:
	DmaRegs.CH6.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;	    // Point to beginning of destination buffer
	DmaRegs.CH6.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

	
	EDIS;
}

void DMACH6BurstConfig(Uint16 bsize,Uint16 srcbstep, int16 desbstep)
{
	EALLOW;

	// Set up BURST registers:
	DmaRegs.CH6.BURST_SIZE.all = bsize;	                // Number of words(X-1) x-ferred in a burst
	DmaRegs.CH6.SRC_BURST_STEP = srcbstep;				    // Increment source addr between each word x-ferred
	DmaRegs.CH6.DST_BURST_STEP = desbstep;                // Increment dest addr between each word x-ferred


	EDIS;
}

void DMACH6TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
	EALLOW;

	// Set up TRANSFER registers:
	DmaRegs.CH6.TRANSFER_SIZE = tsize;                  // Number of bursts per transfer, DMA interrupt will occur after completed transfer
	DmaRegs.CH6.SRC_TRANSFER_STEP = srctstep;			// TRANSFER_STEP is ignored when WRAP occurs
	DmaRegs.CH6.DST_TRANSFER_STEP = deststep;			// TRANSFER_STEP is ignored when WRAP occurs
	
	EDIS;
}

void DMACH6WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
	EALLOW;

		// Set up WRAP registers:
	DmaRegs.CH6.SRC_WRAP_SIZE = srcwsize;				// Wrap source address after N bursts
    DmaRegs.CH6.SRC_WRAP_STEP = srcwstep;			    // Step for source wrap

	DmaRegs.CH6.DST_WRAP_SIZE = deswsize;				// Wrap destination address after N bursts
	DmaRegs.CH6.DST_WRAP_STEP = deswstep;				// Step for destination wrap
	
	EDIS;
}


void DMACH6ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
{
	EALLOW;

		// Set up MODE Register:
	DmaRegs.CH6.MODE.bit.PERINTSEL = persel;	    // Passed DMA channel as peripheral interrupt source
	DmaRegs.CH6.MODE.bit.PERINTE = perinte;       	// Peripheral interrupt enable
	DmaRegs.CH6.MODE.bit.ONESHOT = oneshot;       	// Oneshot enable
	DmaRegs.CH6.MODE.bit.CONTINUOUS = cont;    		// Continous enable
	DmaRegs.CH6.MODE.bit.SYNCE = synce;         	// Peripheral sync enable/disable
	DmaRegs.CH6.MODE.bit.SYNCSEL = syncsel;       	// Sync effects source or destination
	DmaRegs.CH6.MODE.bit.OVRINTE = ovrinte;         // Enable/disable the overflow interrupt
	DmaRegs.CH6.MODE.bit.DATASIZE = datasize;      	// 16-bit/32-bit data size transfers
	DmaRegs.CH6.MODE.bit.CHINTMODE = chintmode;		// Generate interrupt to CPU at beginning/end of transfer
	DmaRegs.CH6.MODE.bit.CHINTE = chinte;        	// Channel Interrupt to CPU enable

	// Clear any spurious flags:
	DmaRegs.CH6.CONTROL.bit.PERINTCLR = 1;  		// Clear any spurious interrupt flags
	DmaRegs.CH6.CONTROL.bit.SYNCCLR = 1;    		// Clear any spurious sync flags
	DmaRegs.CH6.CONTROL.bit.ERRCLR = 1; 	     	// Clear any spurious sync error flags

	// Initialize PIE vector for CPU interrupt:
	PieCtrlRegs.PIEIER7.bit.INTx6 = 1;              // Enable DMA CH6 interrupt in PIE

	EDIS;
}

// This function starts DMA Channel 6. 	
void StartDMACH6(void)
{
	EALLOW;
	DmaRegs.CH6.CONTROL.bit.RUN = 1;
	EDIS;
}
void DMACH1_ADC_Init(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC
	EDIS;

	// Specific clock setting for this example:
	EALLOW;
	SysCtrlRegs.HISPCP.all = 3;	// HSPCLK = SYSCLKOUT/ADC_MODCLK
	EDIS;

	InitAdc();  // For this example, init the ADC

	// Specific ADC setup for this example:
	AdcRegs.ADCTRL1.bit.ACQ_PS = 0x0f;
	AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x01;
	AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        // 0 Non-Cascaded Mode
	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1;
	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1;
	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;

	AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;   // Set up ADC to perform 4 conversions for every SOC

	// Start SEQ1
	AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0x1;

#ifdef DMA_INT_ENABLE
	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
	EALLOW;	// Allow access to EALLOW protected registers
	PieVectTable.DINTCH1= &local_DINTCH1_ISR;
	EDIS;   // Disable access to EALLOW protected registers

	IER = M_INT7 ;	                             //Enable INT7 (7.1 DMA Ch1)
	EnableInterrupts();

#endif

	EALLOW;
	SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA Clock
	EDIS;
	// Initialize DMA
	DMAInitialize();

	// Configure DMA Channel
	DMACH1AddrConfig(DMA_Dest,DMA_Source);
	DMACH1BurstConfig(15,0,1);         //Will set up to use 32-bit datasize, pointers are based on 16-bit words
	DMACH1TransferConfig(9,0,1);      //so need to increment by 2 to grab the correct location
	DMACH1WrapConfig(40,0,40,0);
	//Use timer0 to start the x-fer.
	//Since this is a static copy use one shot mode, so only one trigger is needed
	//Also using 32-bit mode to decrease x-fer time
	DMACH1ModeConfig(DMA_SEQ1INT,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,SYNC_DISABLE,
						SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);

	StartDMACH1();

}

interrupt void local_DINTCH1_ISR(void)     // DMA Channel 1
{
	// To receive more interrupts from this PIE group, acknowledge this interrupt
	PieCtrlRegs.PIEACK.bit.ACK7 = 1;

//	asm ("      ESTOP0");//ok
//	for(;;);
}
#pragma DATA_SECTION(DMABuf1,"DMARAML4");

#define DMA_BUF_SIZE 40
volatile Uint16 DMABuf1[DMA_BUF_SIZE];

void main()
{
	int i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	// Initialize Tables
	for (i=0; i<DMA_BUF_SIZE; i++)
	{
		DMABuf1[i] = 0;
	}
	DMACH1_ADC_Init(DMABuf1,&AdcMirror.ADCRESULT0);

	while(1)
	{

	}
}

(2)DMA_ram_to_ram

void DMAInitialize(void)
{
	EALLOW;

	// Perform a hard reset on DMA
	DmaRegs.DMACTRL.bit.HARDRESET = 1;

	// Allow DMA to run free on emulation suspend
	DmaRegs.DEBUGCTRL.bit.FREE = 1;
	
	EDIS;
}

void DMACH1_Init(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
	EALLOW;
	SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA Clock
	EDIS;

#ifdef DMA_INT_ENABLE
	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
	EALLOW;	// Allow access to EALLOW protected registers
	PieVectTable.DINTCH1= &local_DINTCH1_ISR;
	EDIS;   // Disable access to EALLOW protected registers

	IER = M_INT7 ;	                             //Enable INT7 (7.1 DMA Ch1)
	EnableInterrupts();

#endif

	// Initialize DMA
	DMAInitialize();
//	init_zone7();

	// Configure DMA Channel
	DMACH1AddrConfig(DMA_Dest,DMA_Source);
	DMACH1BurstConfig(31,2,2);         //Will set up to use 32-bit datasize, pointers are based on 16-bit words
	DMACH1TransferConfig(31,2,2);      //so need to increment by 2 to grab the correct location
	DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
	//Use timer0 to start the x-fer.
	//Since this is a static copy use one shot mode, so only one trigger is needed
	//Also using 32-bit mode to decrease x-fer time
	DMACH1ModeConfig(DMA_TINT0,PERINT_ENABLE,ONESHOT_ENABLE,CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,THIRTYTWO_BIT,CHINT_END,CHINT_ENABLE);

	StartDMACH1();
}


#pragma DATA_SECTION(DMABuf1,"DMARAML4");
#pragma DATA_SECTION(DMABuf2,"DMARAML5");

#define DMA_BUF_SIZE 1024
volatile Uint16 DMABuf1[DMA_BUF_SIZE];
volatile Uint16 DMABuf2[DMA_BUF_SIZE];


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
	int i=0;


	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	// Initialize Tables
	for (i=0; i<DMA_BUF_SIZE; i++)
	{
		DMABuf1[i] = 0;
		DMABuf2[i] = i;
	}

	DMACH1_Init(DMABuf1,DMABuf2);

	while(1)
	{

	}
}

(3)DMA_xintf_to_ram

// Configure the timing paramaters for Zone 7.
// Notes:
//    This function should not be executed from XINTF
//    Adjust the timing based on the data manual and
//    external device requirements.
void init_zone7(void)
{
	EALLOW;
    // Make sure the XINTF clock is enabled
	SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;
	EDIS;
	// Configure the GPIO for XINTF with a 16-bit data bus
	// This function is in DSP2833x_Xintf.c
	InitXintf16Gpio();

    // All Zones---------------------------------
    // Timing for all zones based on XTIMCLK = SYSCLKOUT
	EALLOW;
    XintfRegs.XINTCNF2.bit.XTIMCLK = 0;
    // Buffer up to 3 writes
    XintfRegs.XINTCNF2.bit.WRBUFF = 3;
    // XCLKOUT is enabled
    XintfRegs.XINTCNF2.bit.CLKOFF = 0;
    // XCLKOUT = XTIMCLK
    XintfRegs.XINTCNF2.bit.CLKMODE = 0;

    // Zone 7------------------------------------
    // When using ready, ACTIVE must be 1 or greater
    // Lead must always be 1 or greater
    // Zone write timing
    XintfRegs.XTIMING7.bit.XWRLEAD = 1;
    XintfRegs.XTIMING7.bit.XWRACTIVE = 2;
    XintfRegs.XTIMING7.bit.XWRTRAIL = 1;
    // Zone read timing
    XintfRegs.XTIMING7.bit.XRDLEAD = 1;
    XintfRegs.XTIMING7.bit.XRDACTIVE = 3;
    XintfRegs.XTIMING7.bit.XRDTRAIL = 0;

    // don't double all Zone read/write lead/active/trail timing
    XintfRegs.XTIMING7.bit.X2TIMING = 0;

    // Zone will not sample XREADY signal
    XintfRegs.XTIMING7.bit.USEREADY = 0;
    XintfRegs.XTIMING7.bit.READYMODE = 0;

    // 1,1 = x16 data bus
    // 0,1 = x32 data bus
    // other values are reserved
    XintfRegs.XTIMING7.bit.XSIZE = 3;
    EDIS;
   //Force a pipeline flush to ensure that the write to
   //the last register configured occurs before returning.
   asm(" RPT #7 || NOP");
}

void DMACH1_Init(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{

	EALLOW;
	SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA Clock
	EDIS;

	EALLOW;
	SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
	EDIS;
	CpuTimer0Regs.TCR.bit.TSS  = 1;               //Stop Timer0 for now

#ifdef DMA_INT_ENABLE
	// Interrupts that are used in this example are re-mapped to
	// ISR functions found within this file.
	EALLOW;	// Allow access to EALLOW protected registers
	PieVectTable.DINTCH1= &local_DINTCH1_ISR;
	EDIS;   // Disable access to EALLOW protected registers

	IER = M_INT7 ;	                             //Enable INT7 (7.1 DMA Ch1)
	EnableInterrupts();

#endif

	// Initialize DMA
	DMAInitialize();
	init_zone7();

	// Configure DMA Channel
	DMACH1AddrConfig(DMA_Dest,DMA_Source);
	DMACH1BurstConfig(31,2,2);         //Will set up to use 32-bit datasize, pointers are based on 16-bit words
	DMACH1TransferConfig(31,2,2);      //so need to increment by 2 to grab the correct location
	DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
	//Use timer0 to start the x-fer.
	//Since this is a static copy use one shot mode, so only one trigger is needed
	//Also using 32-bit mode to decrease x-fer time
	DMACH1ModeConfig(DMA_TINT0,PERINT_ENABLE,ONESHOT_ENABLE,CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,THIRTYTWO_BIT,CHINT_END,CHINT_ENABLE);

	StartDMACH1();

	//Init the timer 0
	CpuTimer0Regs.TIM.half.LSW = 512;    //load low value so we can start the DMA quickly
	CpuTimer0Regs.TCR.bit.SOFT = 1;      //Allow to free run even if halted
	CpuTimer0Regs.TCR.bit.FREE = 1;
	CpuTimer0Regs.TCR.bit.TIE  = 1;      //Enable the timer0 interrupt signal
	CpuTimer0Regs.TCR.bit.TSS  = 0;      //restart the timer 0

}
#define DMA_BUF_SIZE 1024
#pragma DATA_SECTION(DMABuf1,"DMARAML4");
#pragma DATA_SECTION(DMABuf2,"ZONE7DATA");

volatile Uint16 DMABuf1[DMA_BUF_SIZE];
volatile Uint16 DMABuf2[DMA_BUF_SIZE];


/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main()
{
	Uint16 i=0;
	Uint16 j=0;

	InitSysCtrl();
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();

	LED_Init();
	TIM0_Init(150,200000);//200ms
	UARTa_Init(4800);

	DMACH1_Init(DMABuf1,DMABuf2);
	// Initialize Tables
	for (i=0; i<DMA_BUF_SIZE; i++)
	{
		DMABuf1[i] = 0;
		DMABuf2[i] = i;
	}
	StartDMACH1();

	while(1)
	{
		j++;
		if(j%200==0)
		{
			LED6_TOGGLE;
		}
		DELAY_US(1000);
	}
}

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值