📄 fast_dma.c
字号:
/**************************************************************
程序说明 :FAST DMA
类 型 :Nios II
作 者 :柳军胜
公 司 :杭州自由电子科技
:http://www.freefpga.com
电 话 :0571-85084089
修 改 :
日期时间 :20060529
说 明 :
Nios II HAL中有一套DMA操作函数,使用中不直观,针对DMA外设
寄存器映射,直接操作效率更高,控制更直观,本模块重新整理了早期的
SDK。同时也把使用HAL库的整合函数放置在本模块中。
**************************************************************/
#include <alt_types.h>
#include <sys/alt_irq.h>
#include <io.h>
#include <sys/alt_dma.h>
#include <system.h>
#include "fast_dma.h"
#include <altera_avalon_dma_regs.h>
/************************************
功 能:模块本地数据区
说 明:
0、DMA设备地址
1、DMA通道句柄
2、DMA缓冲区
3、DMA传输完成标志
*************************************/
void *dma_base;
int gControl_bits=0;
int gDmaLen;
static unsigned int dma_buff[512];
static volatile int rx_done_flag=0,tx_done_flag=0;
static alt_dma_txchan txchan;
static alt_dma_rxchan rxchan;
/*********************************************
函数名:fast_dma_init
功 能:FAST DMA初始化函数
输 入: dma base address
返 回: 0 success,-1 error
备 注:
FAST DMA 初始化:
1、保存DMA设备地址
2、清除DMA设备状态
3、设置接收和发送地址
4、设置传输长度
4、设置传输BIT宽度
5、设置结束传输条件为传输长度控制
6、接收和发送地址增量控制由参数mode中设置
7、默认设置为非中断方式,中断方式需要在MODE参数中增加IEN位
不启动GO
**********************************************/
int fast_dma_init(void *baseaddr,
int bytes_per_transfer,
void *source_address,
void *destination_address,
int transfer_count,
int mode)
{
int len;
dma_base=(np_dma *)baseaddr;
gControl_bits = 0;
// 清除所有控制位设置
IOWR_ALTERA_AVALON_DMA_CONTROL(dma_base,0);
// 清除状态位
IOWR_ALTERA_AVALON_DMA_STATUS(dma_base, 0);
// 源地址
IOWR_ALTERA_AVALON_DMA_RADDRESS(dma_base, source_address);
// 目标地址
IOWR_ALTERA_AVALON_DMA_WADDRESS(dma_base, destination_address);
// 字节传输长度
gDmaLen=transfer_count * bytes_per_transfer;
IOWR_ALTERA_AVALON_DMA_LENGTH(dma_base,gDmaLen);
// 控制位设定
gControl_bits =
mode // wcon, rcon bits
| (bytes_per_transfer & 7) // low three bits of control reg
| ((bytes_per_transfer & 8) ? ALTERA_AVALON_DMA_CONTROL_DWORD_MSK : 0)
| ((bytes_per_transfer & 16) ? ALTERA_AVALON_DMA_CONTROL_QWORD_MSK : 0)
| ALTERA_AVALON_DMA_CONTROL_LEEN_MSK;
IOWR_ALTERA_AVALON_DMA_CONTROL(dma_base, gControl_bits);
return 0;
}
/*********************************************
函数名:fast_dma_irq
功 能:fast_dma中断处理函数
输 入:context:相关内容指针,中断号
返 回:
备 注:
该函数目前只是重新启动一次DMA传输
**********************************************/
void fast_dma_irq(void *context,alt_u32 interrupt)
{
int iRet;
IOWR_ALTERA_AVALON_DMA_LENGTH(dma_base,gDmaLen);
IOWR_ALTERA_AVALON_DMA_CONTROL(dma_base, gControl_bits|ALTERA_AVALON_DMA_CONTROL_GO_MSK);
}
/*********************************************
函数名:rx_done
功 能:DMA接收完成回调函数
输 入:
返 回:
备 注:
**********************************************/
static void rx_done (void* handle, void* data)
{
rx_done_flag++;
}
/*********************************************
函数名:tx_done
功 能:DMA发送完成回调函数
输 入:
返 回:
备 注:
**********************************************/
static void tx_done (void* handle, void* data)
{
tx_done_flag++;
}
/**************************************************
函数名:init_dma_channel
功 能:初始化DMA通道
输 入: 0 成功, -1 打开发送通道错误,-2 打开接收通道错误
返 回:
备 注:使用HAL的扩展函数
**************************************************/
int init_dma_channel()
{
int iRet;
if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == 0)
{
printf ("Failed to open transmit channel\n");
return -1;
}
alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_32,0);
alt_dma_txchan_ioctl(txchan,
ALT_DMA_TX_ONLY_ON,
__IO_CALC_ADDRESS_NATIVE (FREEDEV_AIC23_0_BASE, 0x07));
if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == 0)
{
printf ("Failed to open receive channel\n");
alt_dma_txchan_close(txchan);
return -2;;
}
alt_dma_rxchan_ioctl(rxchan,ALT_DMA_SET_MODE_32,0);
alt_dma_rxchan_ioctl(rxchan,
ALT_DMA_RX_ONLY_ON,
__IO_CALC_ADDRESS_NATIVE (FREEDEV_AIC23_0_BASE, 0x07));
return 0;
}
/**************************************************
函数名:close_dma_channel
功 能:初始化DMA通道
输 入: 0 成功, -1 打开发送通道错误,-2 打开接收通道错误
返 回:
备 注:使用HAL的扩展函数
**************************************************/
int close_dma_channel()
{
alt_dma_txchan_close(txchan);
alt_dma_rxchan_close(rxchan);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -