⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fast_dma.c

📁 在开发FPGA上比较有用
💻 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 + -