新手上路
- 积分
- 29
- 金钱
- 29
- 注册时间
- 2018-6-21
- 在线时间
- 8 小时
|

楼主 |
发表于 2025-4-9 11:05:21
|
显示全部楼层
#include "stdio.h"
#include "xaxidma.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xscugic.h"
#include "AXI4_Lite.h"
#include "sleep.h"
/************************** Constant Definitions *****************************/
#define DMA_DEV_ID XPAR_AXIDMA_0_DEVICE_ID
#define RX_INTR_ID XPAR_FABRIC_AXIDMA_0_VEC_ID
//#define TX_INTR_ID XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define DDR_BASE_ADDR XPAR_PS7_DDR_0_S_AXI_BASEADDR //0x00100000
#define MEM_BASE_ADDR (DDR_BASE_ADDR + 0x1000000) //0x01100000
//#define TX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000) //0x01200000
#define RX_BUFFER_BASE (MEM_BASE_ADDR + 0x00100000) //0x01400000
#define AXI4_lite_IP_BASEADDR XPAR_AXI4_LITE_0_S0_AXI_BASEADDR //AXI4_lite IP 基地址
#define AXI4_lite_IP_REG0 AXI4_LITE_S0_AXI_SLV_REG0_OFFSET //AXI4_lite IP 寄存器地址 0
#define AXI4_lite_IP_REG1 AXI4_LITE_S0_AXI_SLV_REG1_OFFSET //AXI4_lite IP 寄存器地址 1
#define RESET_TIMEOUT_COUNTER 10000 //复位时间
#define TEST_START_VALUE 0x0 //测试起始值
#define MAX_PKT_LEN 4096 //发送包长度
/************************** Function Prototypes ******************************/
//static void tx_intr_handler(void *callback);
static void rx_intr_handler(void *callback);
static void Devicd_intr_handler();
static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr, u16 rx_intr_id, u16 intr_id1);
static void disable_intr_system(XScuGic * int_ins_ptr, u16 rx_intr_id, u16 intr_id1);
/************************** Variable Definitions *****************************/
static XAxiDma axidma; //XAxiDma 实例
static XScuGic intc; //中断控制器的实例
volatile int rx_done; //接收完成标志
volatile int error; //传输出错标志
volatile int Index;
/************************** Function Definitions *****************************/
int main(void)
{
int status;
u8 *rx_buffer_ptr;
XAxiDma_Config *config;
//rx_buffer_ptr = (u8 *)RX_BUFFER_BASE;
Index = 0;
rx_done = 0;
xil_printf("\r\n---Entering main()---\r\r");
config = XAxiDma_LookupConfig(DMA_DEV_ID);//查找DMA控制器的配置信息
if(!config)
{
xil_printf("No config found for %d\r\n",DMA_DEV_ID);
return XST_FAILURE;
}
//初始化DMA引擎
status = XAxiDma_CfgInitialize(&axidma,config);
if(status != XST_SUCCESS)
{
xil_printf("Initialization failed %d\r\n", status);
return XST_FAILURE;
}
if(XAxiDma_HasSg(&axidma))
{
xil_printf("Device configured as SG mode \r\n");
return XST_FAILURE;
}
//建立中断系统
status = setup_intr_system(&intc, &axidma, RX_INTR_ID, XPS_FPGA0_INT_ID);
if(status != XST_SUCCESS)
{
xil_printf("Failed intr setup\r\n");
return XST_FAILURE;
}
AXI4_LITE_mWriteReg(AXI4_lite_IP_BASEADDR,AXI4_lite_IP_REG1,100);
AXI4_LITE_mWriteReg(AXI4_lite_IP_BASEADDR,AXI4_lite_IP_REG0,100);
//usleep(50);
// while(1)
// ;
// AXI4_LITE_mWriteReg(AXI4_lite_IP_BASEADDR,AXI4_lite_IP_REG0,100);
while(Index == 0)
;
rx_buffer_ptr = (u8 *)RX_BUFFER_BASE;
status = XAxiDma_SimpleTransfer(&axidma,(UINTPTR)rx_buffer_ptr, MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
if(status != XST_SUCCESS)
{
return XST_FAILURE;
}
while(rx_done == 0)
;
xil_printf("Successfully ran AXI DMA Loop\r\n");
disable_intr_system(&intc, RX_INTR_ID, XPS_FPGA0_INT_ID);
xil_printf("---Exiting main()---\r\n");
return XST_SUCCESS;
}
//DMA RX 中断处理函数
static void rx_intr_handler(void *callback)
{
u32 irq_status;
int timeout;
XAxiDma *axidma_inst = (XAxiDma *) callback;
irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DEVICE_TO_DMA);
//Rx出错
if((irq_status &XAXIDMA_IRQ_ERROR_MASK))
{
error = 1;
XAxiDma_Reset(axidma_inst);
timeout = RESET_TIMEOUT_COUNTER;
while(timeout)
{
if(XAxiDma_ResetIsDone(axidma_inst))
break;
timeout -= 1;
}
return;
}
//Rx完成
if((irq_status &XAXIDMA_IRQ_IOC_MASK))
rx_done = 1;
}
static void Devicd_intr_handler()
{
AXI4_LITE_mWriteReg(AXI4_lite_IP_BASEADDR,AXI4_lite_IP_REG0,100);
Index = 1;
}
//建立 DMA 中断系统
// @param int_ins_ptr 是指向 XScuGic 实例的指针
// @param AxiDmaPtr 是指向 DMA 引擎实例的指针
// @param tx_intr_id 是 TX 通道中断 ID
// @param rx_intr_id 是 RX 通道中断 ID
// @return:成功返回 XST_SUCCESS,否则返回 XST_FAILURE
static int setup_intr_system(XScuGic * int_ins_ptr,XAxiDma * axidma_ptr, u16 rx_intr_id, u16 intr_id1)
{
int status;
XScuGic_Config *intc_config;
//初始化中断控制器驱动
intc_config = XScuGic_LookupConfig(INTC_DEVICE_ID);
if(NULL == intc_config)
{
return XST_FAILURE;
}
status = XScuGic_CfgInitialize(int_ins_ptr, intc_config, intc_config->CpuBaseAddress);
if (status != XST_SUCCESS)
{
return XST_FAILURE;
}
//设置优先级和触发类型
XScuGic_SetPriorityTriggerType(int_ins_ptr, rx_intr_id, 0xA0, 0x3);
XScuGic_SetPriorityTriggerType(int_ins_ptr, intr_id1, 0xA0, 0x3);
//为中断设置中断处理函数
status = XScuGic_Connect(int_ins_ptr, rx_intr_id, (Xil_InterruptHandler)rx_intr_handler,axidma_ptr);
if(status != XST_SUCCESS)
{
return status;
}
status = XScuGic_Connect(int_ins_ptr, intr_id1, (Xil_InterruptHandler)Devicd_intr_handler,(void *)1);
if(status != XST_SUCCESS)
{
return status;
}
XScuGic_Enable(int_ins_ptr, rx_intr_id);
XScuGic_Enable(int_ins_ptr, intr_id1);
//启用来自硬件的中断
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, (void *)int_ins_ptr);
Xil_ExceptionEnable();
//使能DMA中断
XAxiDma_IntrEnable(&axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);
return XST_SUCCESS;
}
//此函数禁用 DMA 引擎的中断
static void disable_intr_system(XScuGic * int_ins_ptr, u16 rx_intr_id, u16 intr_id1)
{
XScuGic_Disconnect(int_ins_ptr, rx_intr_id);
XScuGic_Disconnect(int_ins_ptr, intr_id1);
}
|
|