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

NIOS2随笔——DMA(1)

时间:2016-08-15 22:40:49      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:fpga ; nios2

1. NIOS2 DMA控制器结构框图


技术分享

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

2. NIOS2 DMA三种传输方式

技术分享

 3. NIOS2 DMA API函数

NIOS2 DAM的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/1838704

NIOS2随笔——DMA(1)

标签:fpga ; nios2

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

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