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

📄 rio.c

📁 dsp program
💻 C
字号:
/********************************************************************************/
/* 本程序用来测试Xilinx Virtex II Pro系列FPGA MGT通信的性能					    */
/* 本程序在c6416的环境下运行通过,CCS版本2.20.03                                */
/* 版权所有(c)2004 北京邮电大学 电信工程学院   马健 045498				        */
/********************************************************************************/
#include <std.h>
#include <csl_irq.h>
#include <stdio.h>
#include <csl_irq.h>  
#include "reg1.h"


#define INTERVAL	0x7fffff		/*  FPGA两次发送数据的时间间隔              */
#define	TOTAL_TIME	0x10000000		/*  */
#define TX_RAM		0x80000000      /*  发送RAM的首地址(位于DSP EMIFA的ce0空间) */
#define TX_Ctrl_Reg	0x80040000      /*  FPGA的发送控制寄存器(位于EMIFA的ce0空间)*/
#define	RX_RAM		0x60000000      /*  接收RAM的首地址(位于DSP EMIFB的ce0空间) */
#define RX_Ctrl_Reg 0x60040000      /*  FPGA的接收控制寄存器(位于EMIFB的ce0空间)*/
#define	BUF_SZ		0x100           /*  进行数据校验的长度                      */
#define true		1
#define	false		0
#define	Inc			1
#define	Dec			0

/********************************************************************************/
/*  子函数,中断函数声明                                                         */
/********************************************************************************/
void MGT_Reset();                   /*  MGT复位子函数                           */
void MGT_Start();                   /*  MGT开始自程序                           */
void FillData();                    /*  向缓冲区写入校验图样数据子函数          */
void CompareData();                 /*  校验数据子函数                          */
void PrintResult();                 /*  打印结果子函数                          */
void timer0_start();                /*  定时器开启子函数                        */
interrupt void EX5_ISR();           /*  外部中断5服务子程序                     */
interrupt void Timer0_ISR();        /*  定时器中断服务子程序                    */

/********************************************************************************/
/*  全局变量定义                                                                */
/********************************************************************************/
int Err_Flag = false, PingPong = Inc, Finish_Flag = true, Start_Flag = true;
int Total_times = 0, Err_times = 0, Errors = 0, int_times = 0;
short Pre_Data[256], Current_Data[256];


void main(void)
{

	int  i;                 /*  main函数局部变量定义                            */

	IER |= 0x4023;      	/*  中断使能寄存器配置,打开EXT_INT5以及定时器中断  */                            
	CSR |= 0x1;	            /*  打开全局中断使能                                */

	
	T0CTL = 0x200;
	T0PRD = 0x0FFF;
	
		
	for (i = 0; i <= 0x10000000; i++){  /*  对FPGA的MGT通信进行i次的校验        */
		
		Total_times++;                  /*  总的校验次数,用来计算错误概率      */
		
		timer0_start();                 /*  插入一段等待时间,使MGT更好同步     */

		while(true){                    /*  阻塞,等待MGT通信开始               */		
			if (Start_Flag == false)
				break;		
		}
		
		Start_Flag = true;              /*  建立MGT通信开始阻塞标志             */
		
		MGT_Reset();                    /*  MGT复位                             */

		FillData();                     /*  填充新的数据                        */
		
		MGT_Start();                    /*  开启MGT的通信传输                   */
		
		while(true){                    /*  阻塞,等待MGT通信以及数据校验完成   */
			if (Finish_Flag == false)
				break;		
		}
		
		Finish_Flag = true;             /*  建立MGT通信完成阻塞标志             */		
		
		if( Err_Flag ){                 /*  接收到的数据是否存在错误            */
			Err_Flag = false;
			Err_times++;                /*  记录总的错误次数                    */
			PrintResult();              /*  打印错误情况,以帮助判断FPGA问题    */		
		}							
	}		
}

/********************************************************************************/
/*  FPGA的MGT 复位子函数                                                        */
/*  通过DSP的EMIFA/B分别控制FPGA MGT的收发状态                                  */
/********************************************************************************/
void MGT_Reset()
{
	//reset MGT_tx
	*(unsigned volatile int *)TX_Ctrl_Reg = 0;
	*(unsigned volatile int *)TX_Ctrl_Reg = 1;
	*(unsigned volatile int *)TX_Ctrl_Reg = 0;
	//reset MGT_rx
	*(unsigned volatile int *)RX_Ctrl_Reg = 0;
	*(unsigned volatile int *)RX_Ctrl_Reg = 1;
	*(unsigned volatile int *)RX_Ctrl_Reg = 0;
}

/********************************************************************************/
/*  填充发送数据子函数                                                          */
/*  通过DSP的EMIFA给FPGA的发送缓冲区交替写入正序和倒序的数据                    */
/*  这样可以更方便的鉴别是否MGT通信是否存在边界问题                             */
/********************************************************************************/
void FillData()
{
	int i, j;
	
	if ( PingPong ){	                    /*  给发送缓充区填入正序的数据      */
		
		i = 0;                              
		
		for (j = 0; j < BUF_SZ; j++){
		    *((unsigned volatile short *)TX_RAM + j) = i++; 
		}
		
		PingPong = Dec;                     /*  修改乒乓开关,下次写入倒序数据  */
	}
	else{	
		
		i = 0xff;                           /*  给发送缓充区填入倒序的数据      */
		
		
		for (j = 0; j < BUF_SZ; j++){
		    *((unsigned volatile short *)TX_RAM + j) = i--;		    	
		}
		
		PingPong = Inc;                     /*  修改乒乓开关,下次写入正序数据  */
	}
}

/********************************************************************************/
/*  MGT发送子函数                                                               */
/*  通过FPGA的MGT控制寄存器开启,MGT的发送                                      */
/********************************************************************************/
void MGT_Start()
{
	//start MGT TX
	*(unsigned volatile int *)TX_Ctrl_Reg = 0x0;
	*(unsigned volatile int *)TX_Ctrl_Reg = 0x2;
	*(unsigned volatile int *)TX_Ctrl_Reg = 0x0;
}

/********************************************************************************/
/*  进行数据比较的子函数                                                        */
/*  可以得出发送错误数据的位置以及错误图样                                      */
/********************************************************************************/
void CompareData()
{
	int j;
	short Data_Receive;
	
	Errors = 0;                             /*  子函数局部错误个数变量清零      */
	
	if (PingPong == Dec ){                  /*  比较倒序数据                    */
		
		for ( j = 0; j < BUF_SZ; j++){
			Data_Receive = *((unsigned volatile short *)RX_RAM + j);

			if ( Data_Receive != j ){       /*  发现错误                        */
				Current_Data[Errors] = Data_Receive;
				Pre_Data[Errors] = j;       /*  记录错误的数据,即发生错误的位置 */

				Err_Flag = true;            /*  建立错误标志,后面打印错误结果   */
				Errors++;                   /*  记录本次错误个数                */

			}	
		}
	}
	else{                                   /*  比较正序数据                    */
	
		for ( j = 0; j < BUF_SZ; j++){
			Data_Receive = *((unsigned volatile short *)RX_RAM + j);
			
			if ( Data_Receive != (0xff - j) ){
				Current_Data[Errors] = Data_Receive;
				Pre_Data[Errors] = 0xff - j;/*  发现错误                        */

				Err_Flag = true;            /*  建立错误标志,后面打印错误结果   */
				Errors++;                   /*  记录本次错误个数                */
			}			
		}
	}
}	

/********************************************************************************/
/*  外部中断EXT_INT5的中断服务子程序                                            */
/*  根据需要打印出需要的数据,以判断MGT通信的性能                                */
/********************************************************************************/
void PrintResult()
{
	int i, Errors_local;
	printf("Error!!  Total_times = %d        Err_Times = %d \n", Total_times, Err_times);			
			
	Errors_local = Errors;
	
	if ( Errors_local > 10 )
	{
		Errors_local = 10;
	}
	if ( PingPong == Dec )
	{
		printf("Increase:  \n");
		
		for( i = 0; i < Errors_local; i++)
		{
			printf("0x%x:      0x%x  --->  0x%x \n", Pre_Data[i]*2, Pre_Data[i], Current_Data[i]);
		}
		printf("\n");	
	}
	else
	{
		printf("Decrease \n");

		for( i = 0; i < Errors_local; i++)
		{
			printf("0x%x:      0x%x  --->  0x%x \n", (0xff-Pre_Data[i])*2, Pre_Data[i], Current_Data[i]);
		}		
		printf("\n");
	}
	


}	

/********************************************************************************/
/*  定时器timer0的开启子函数                                                    */
/********************************************************************************/
void timer0_start()
{
	T0CTL=0x00000200;
	T0CTL=0x000002c0;
}		

/********************************************************************************/
/*  外部中断EXT_INT5的中断服务子程序                                            */
/*  MGT传输已经完成,可以开始进行数据的比较校验                                 */
/********************************************************************************/
interrupt void EX5_ISR()
{
	Finish_Flag = 0;                        /*  清除MGT通信结束阻塞标志         */
	CompareData();                          /*  比较数据                        */
}

/********************************************************************************/
/*  定时器中断服务子程序                                                        */
/********************************************************************************/
interrupt void Timer0_ISR()
{
	Start_Flag = 0;                         /*  清除MGT通信开始阻塞标志         */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -