/*
* 声明:本范例源于书籍‘NiosII软件架构解析’
* 作者:蔡伟纲
* 博客地址: http://NiosII.cublog.cn
*
* 一、功能: DMA(Memory to Memory)驱动演示代码.
* 二、运行前提: 本范例需要硬件开发板的支持,
* 要求NiosII系统包含名为”dma”的DMA模块,
* 且DMA的长度寄存器应当大于10位,支持字传输;
*/
#include <stdio.h>
#include <stdlib.h>
#include "sys/alt_dma.h"
#include "altera_avalon_dma_regs.h"
#include "system.h"
#include <sys/alt_cache.h>
//定义DMA传输长度
#define TRANSFER_LENGTH 1024
static volatile int rx_done = 0;
//定义DMA传输结束后的回调函数,它将在DMA传输结束后被系统自动调用;
//通过简单的rx_done++,可告知主程序DMA已经完成传输任务;
static void done(void* handle, void* data)
{
rx_done++;
}
int main(int argc, char* argv[], char* envp[])
{
printf ("DMA Demo(Memory to Memory)!\n");
int return_code;
alt_dma_txchan txchan;
alt_dma_rxchan rxchan;
//开辟源缓冲区,本范例将把源缓冲区的数据传输到目的缓冲区;
//TRANSFER_LENGTH不可过大,否则可能导致堆栈溢出;
char source[TRANSFER_LENGTH];
//开辟目的缓冲区,该缓冲区将接收来自DMA接收通道的数据;
//并通过与源缓冲区数据的对比来确定DMA传输是否正确;
//TRANSFER_LENGTH不可过大,否则可能导致堆栈溢出;
char dest[TRANSFER_LENGTH];
//将源缓冲区的数据全部初始化为0x55;
memset(source, 0x55, TRANSFER_LENGTH);
//清空数据缓存,确保源缓冲区的数据正确初始化;
alt_dcache_flush_all();
//创建DMA发送通道;
if((txchan = alt_dma_txchan_open("/dev/dma")) == NULL)
{
printf ("Failed to open transmit channel\n");
exit(1);
}
else
{
printf ("Create the transmit channel successfully!\n");
}
//创建DMA接收通道;
if((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL)
{
printf ("Failed to open receive channel\n");
exit(1);
}
else
{
printf ("Create the receive channel successfully!\n");
}
//提交DMA发送请求;
if((return_code = alt_dma_txchan_send(txchan,
source,
TRANSFER_LENGTH,
NULL,
NULL)) < 0)
{
printf ("Failed to post transmit request, reason = %i\n", return_code);
exit (1);
}
else
{
printf ("Post the transmit request successfully!\n");
}
//提交DMA接收请求;
if ((return_code = alt_dma_rxchan_prepare(rxchan,
dest,
TRANSFER_LENGTH,
done,
NULL)) < 0)
{
printf ("Failed to post read request, reason = %i\n", return_code);
exit (1);
}
else
{
printf ("Post the receive request successfully!\n");
}
//等待DMA传输结束;
while(rx_done == 0);
int Loop, ErrorCount = 0;
for(Loop = 0; Loop < TRANSFER_LENGTH; Loop++)
{
//对比源缓冲区和目的缓冲区的数据;
if(source[Loop] != dest[Loop])
{
printf("Verify failed at location: 0x%X\n",Loop);
ErrorCount++;
}
}
if(ErrorCount == 0)
{
printf ("Transfer successfully!\n");
}
else
{
printf("Transfer failed!\n");
}
while(1);
}