码迷,mamicode.com
首页 > 移动开发 > 详细

NIOS2随笔——DMA(1)

时间:2016-08-17 23:26:09      阅读:1495      评论:0      收藏:0      [点我收藏+]

标签:fpga ; nios2

1. NIOS2 DMA控制器结构框图

技术分享


与其它IP外设一样,DMA控制器也是通过AVALON MM总线,实现寄存器配置,数据读写功能。


2. NIOS2 DMA三种传输方式
技术分享


3. NIOS2 DMA API函数

NIOS2 DMA的API函数原型都定义在alt_dma.h头文件中,常用的API函数如下:

alt_dma_txchan alt_dma_txchan_open (const char* name);
static ALT_INLINE int alt_dma_txchan_send (alt_dma_txchan dma, 
             const void* from, 
             alt_u32 length,
             alt_txchan_done* done, 
             void* handle)
{
  return dma ? dma->dma_send (dma, 
        from, 
        length,
        done, 
        handle) : -ENODEV;
}
static ALT_INLINE int alt_dma_txchan_ioctl (alt_dma_txchan dma, 
              int            req, 
              void*          arg)
{
  return dma ? dma->ioctl (dma, req, arg) : -ENODEV;
}
alt_dma_rxchan alt_dma_rxchan_open (const char* dev);
static ALT_INLINE int alt_dma_rxchan_prepare (alt_dma_rxchan   dma, 
                                              void*            data,
                                              alt_u32          len,
                                              alt_rxchan_done* done,  
                                              void*            handle)
{
  return dma ? dma->prepare (dma, data, len, done, handle) : -ENODEV;
}
static ALT_INLINE int alt_dma_rxchan_ioctl (alt_dma_rxchan dma, 
              int            req, 
              void*          arg)
{
  return dma ? dma->ioctl (dma, req, arg) : -ENODEV;
}


4. 参考设计——OnchipMenmory to SDRAM

1) Qsys设置

NIOS2代码运行在SDRAM中,OnchipMemory作为一个片上存储外设。

下面两个图是QSYS中的IP设置,图中可以看出DMA支持BURST读写模式,这样效率会大大提高。

在第二张图片中,博主勾选了show signals选项,可以看到,DMA组件定义的信号接口,有一个AVALON MM SLAVE端口,用于配制寄存器,两个AVALON MM MASTER分别实现读写功能,还有一个IRQ中断输出,向CPU产生中断信号。

技术分享

技术分享

2)软件源码

//file name:	main.c
//date:		2016.8.15
//author:	shugen.yin
//function:	DMA, onchip memory to sdram/ddr2
//log:

#include <stdio.h>
#include <string.h>
#include <sys/alt_irq.h>
#include "system.h"
#include "alt_types.h"
#include "sys/alt_dma.h"

#define DAT_LEN 32

unsigned int buffer0[DAT_LEN/4];
unsigned int *point=ONCHIP_MEMORY1_0_BASE;

static void DMA_Init(void); //初始化DMA
unsigned int dma_end_flag = 0;

alt_dma_txchan tx;
alt_dma_rxchan rx;

void dma_done()
{
	dma_end_flag++;
}

static void DMA_Init(void)
{
	tx = alt_dma_txchan_open("/dev/dma_0");

	if(tx != NULL)
	{
		printf("DMA transition start\n");
	}

	alt_dma_txchan_ioctl(tx,ALT_DMA_SET_MODE_32,NULL);

	//point是源地址、传输数据块长度是DAT_LEN
	alt_dma_txchan_send(tx, point, DAT_LEN, NULL, NULL);

	rx = alt_dma_rxchan_open("/dev/dma_0");

	alt_dma_rxchan_ioctl(rx,ALT_DMA_SET_MODE_32,NULL);

	//buffer0是目标地址、传输数据块长度是DAT_LEN、dma_done()是DMA完成后被调用的回调函数
	alt_dma_rxchan_prepare(rx, buffer0 , DAT_LEN, dma_done, NULL);
}

int main()
{
	int i;

	for(i=0;i<DAT_LEN/4;i++)
		buffer0[i] = 0;

	for(i=0;i<DAT_LEN/4;i++)
		*(point+i) = i+1;

	//初始化DMA
	DMA_Init();
	//等待中断结束,说明传输完成
	while(dma_end_flag == 0)
	{
	}
	//打印接收地址的数据
	for(i=0;i<DAT_LEN/4;i++)
	{
		printf("buffer0[%d]=%d\t",i,buffer0[i]);
	}

	alt_dma_txchan_close(tx);
	alt_dma_rxchan_close(rx);

	return 0;
}





本文出自 “shugenyin的博客” 博客,请务必保留此出处http://shugenyin.blog.51cto.com/4259554/1839585

NIOS2随笔——DMA(1)

标签:fpga ; nios2

原文地址:http://shugenyin.blog.51cto.com/4259554/1839585

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!