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

📄 fpgaload.c

📁 这是一个用C语言写的SPI读写FPGA的典型代码
💻 C
字号:
/*******************************************************************************
   版权所有 (C), 2005, 上海中兴通讯技术有限责任公司

********************************************************************************
  文件名          : fpgaLoad.c
  版本号          : 1.0
  作者            : 王晔
  生成日期        : 2005-7-4
  最近修改        : 
  功能描述        : 
  函数列表        : 
  修改历史        : 
    日期          : 2005-7-4
    作者          : 王晔
    修改内容      : 生成
*******************************************************************************/
/**
 * 版权所有 (C), 2005, 上海中兴通讯技术有限责任公司
   实现CPU对FPGA的配置下载
 * @file fpgaLoad.c
 * @version 1.0
 * @author 肖长春
 * @date 2005-7-12
 */
#include "vxWorks.h"
#include "fpgadata.h" 
#include "fpgaLoad.h"
#include "drv/sio/ppc860Sio.h"

#define FPGA_DEBUG
/*----------------------------------------------------------------------------*
 * 模块级变量                                                                 *
 *----------------------------------------------------------------------------*/
/*内部存储区地址*/

/*----------------------------------------------------------------------------*
 * 外部函数原型说明                                                           *
 *----------------------------------------------------------------------------*/
extern UINT32 vxImmrIsbGet();
 /*----------------------------------------------------------------------------*
 * 内部函数原型说明                                                           *
 *----------------------------------------------------------------------------*/
void readportc();

	

#define	FPGA_PROG	(1<<(15-11))	/*PC11*/
#define FPGA_INIT	(1<<(15-12))	/*PC12*/
#define	FPGA_CLK	(1<<(15-13))	/*PC13*/
#define FPGA_DIN	(1<<(15-14)) 	/*PC14*/
#define FPGA_DONE	(1<<(15-15))	/*PC15*/

/************************************************/
/*Set function:									*/
/*Set or Reset FPGA_INIT, FPGA_PROG, FPGA_CLK   */
/************************************************/
/*fpga_clk set function*/

/**
 * set fpga clk low
 * @fn set_fpga_clk_low
 * @arginput UINT32 ImmerBase
 * @return void
*/

static void set_fpga_clk_low(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) &= ~FPGA_CLK; 
}
/**
 * set fpga clk high
 * @fn set_fpga_clk_high
 * @arginput UINT32 ImmerBase
 * @return void
*/
   
static void set_fpga_clk_high(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) |= FPGA_CLK; 
}
  
/*fpga_din set function*/   
/**
 * set fpga din low
 * @fn set_fpga_din_low
 * @arginput UINT32 ImmerBase
 * @return void
*/   

static void set_fpga_din_low(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) &= ~FPGA_DIN; 
}
/**
 * set fpga din high
 * @fn set_fpga_din_high
 * @arginput UINT32 ImmerBase
 * @return void
*/   

   
static void set_fpga_din_high(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) |= FPGA_DIN; 
}   

/*fpga_prog set function*/
/**
 * set fpga prog low
 * @fn set_fpga_prog_low
 * @arginput UINT32 ImmerBase
 * @return void
*/   
static void set_fpga_prog_low(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) &= ~FPGA_PROG; 
}
/**
 * set fpga prog high
 * @fn set_fpga_prog_high
 * @arginput UINT32 ImmerBase
 * @return void
*/   

static void set_fpga_prog_high(UINT32 ImmerBase)
{
    	
    	*MPC860_PCDAT(ImmerBase) |= FPGA_PROG; 
}   

/*************************************************/
/*Get status function:							 */
/*Get fpga_init ,fpga_done status                */
/*************************************************/

/**
 * get the fpga_init status
 * @fn get_fpga_init
 * @arginput UINT32 ImmerBase
 * @return BOOL
*/   
BOOL	get_fpga_init(UINT32 ImmerBase)
{
	return ((*MPC860_PCDAT(ImmerBase) & FPGA_INIT) != 0 )? TRUE: FALSE;
}

/**
 * get the fpga_done status
 * @fn get_fpga_done
 * @arginput UINT32 ImmerBase
 * @return BOOL
*/   
BOOL	get_fpga_done(UINT32 ImmerBase)
{
	return ((*MPC860_PCDAT(ImmerBase) & FPGA_DONE) != 0 )? TRUE: FALSE;
}

 
/**
 * waiting for fpga_init high
 * @fn waiting_fpga_init_high
 * @arginput UINT32 ImmerBase
 * @return BOOL
*/     
static BOOL waiting_fpga_init_high(UINT32 ImmerBase)
{
   	UINT32 k;

	for(k = 0; k < 5000000; k++)
	{
    	if(get_fpga_init(ImmerBase))
    	{
       		return TRUE;
    	}
	}
	return FALSE;
}
/**
 * waiting for fpga_done high
 * @fn waiting_fpga_done_high
 * @arginput UINT32 ImmerBase
 * @return BOOL
*/   

static BOOL waiting_fpga_done_high(UINT32 ImmerBase)
{
	/*继续送出CLK信号,并且等待DONE信号变高*/
   		UINT32 k;
 
    	for(k = 0; k < 200000; k++)
    	{
        	/*CCLK = 0*/ 
        	set_fpga_clk_low(ImmerBase);
        	        
        	if((*MPC860_PCDAT(ImmerBase) & FPGA_DONE) != 0)	/*test if fpga_done high*/
        	{
            		return TRUE;
        	}
        
        	/*CCLK = 1*/  
        	set_fpga_clk_high(ImmerBase);
        	
    	}
	return FALSE;
}
/**
 * start fpga config
 * @fn start_fpga_config
 * @arginput UINT32 ImmerBase
 * @return void
*/   

static void start_fpga_config(UINT32 ImmerBase)
{
	
	set_fpga_prog_high(ImmerBase);
	/*Program(PC11) from hign to low,*/
	set_fpga_prog_low(ImmerBase);
	
	taskDelay(1);
	
	set_fpga_prog_high(ImmerBase);
}

/**
 * initialize IO port
 * @fn InitIOPort
 * @return void
*/   

static void InitIOPort(void)
{
	UINT32 i32 = 1<<31;
	UINT32 m_lImmrBase = vxImmrIsbGet();

	/* PC11, PC12, PC13, PC14, PC15 general I/O port*/
	*MPC860_PCPAR(m_lImmrBase) &= ~(FPGA_DIN | FPGA_INIT | FPGA_DONE | FPGA_CLK | FPGA_PROG);
#ifdef	FPGA_DEBUG
	printf("PCPAR = 0x%x\n", *MPC860_PCPAR(m_lImmrBase));
#endif	/*FPGA_DEBUG*/
	/*PC15 DONE, PC12 INIT_N - input*/
	*MPC860_PCDIR(m_lImmrBase) &= ~(FPGA_INIT | FPGA_DONE);
	
	/*PC13 CCLK, PC14 DIN, PC11 PROGRAM -  output*/  
	*MPC860_PCDIR(m_lImmrBase) |= (FPGA_CLK | FPGA_DIN | FPGA_PROG);  
#ifdef	FPGA_DEBUG
	printf("PCDIR = 0x%x\n", *MPC860_PCDIR(m_lImmrBase));
#endif	/*FPGA_DEBUG*/
	
	
	*MPC860_PCSO(m_lImmrBase) &= ~(FPGA_DIN | FPGA_INIT | FPGA_DONE | FPGA_CLK | FPGA_PROG);
#ifdef	FPGA_DEBUG
	printf("PCSO = 0x%x\n", *MPC860_PCSO(m_lImmrBase));
#endif	/*FPGA_DEBUG*/
	
	set_fpga_prog_high(m_lImmrBase);
	   	
}

/**
 * send the bytes
 * @fn bytesend
 * @arginput UINT8 data
 * @arginput UINT32 ImmerBase
 * @return int
*/   



static int bytesend(UINT8 data, UINT32 ImmerBase)
{
	UINT16 i;

	for(i = 0; i < 8; i++)
	{ 
		/*Set fpga_clk high.*/
		set_fpga_clk_high(ImmerBase);	
		
		/*set fpga_din*/
		if(((data<<i)&0x80))
			set_fpga_din_high(ImmerBase);
		else
			set_fpga_din_low(ImmerBase);
				
		/*set fpga_clk low*/
		set_fpga_clk_low(ImmerBase);	
		
	}

	return get_fpga_init(ImmerBase);	/*return state of fpga_init*/
}
/**
 * download fpga
 * @fn fpga_download
 * @arginput int nBytes
 * @arginput UINT8* sourcedata
 * @return BOOL
*/   

BOOL fpga_download(unsigned long nBytes, unsigned char *sourcedata)
{
	UINT32 m_lImmrBase;
	unsigned long k;
	UINT8* 	pAddr;
	pAddr = sourcedata;
	
	/*Test pointer sourcedata.*/
	if( NULL == sourcedata )
	{
		return FALSE;
	}
	m_lImmrBase = vxImmrIsbGet();
	
	/*配置I/O口初始化*/
	InitIOPort();
	
	
	/*
	FPGA_CLK	-------
	FPGA_Din	_______
	FPGA_Prog	--\_/--
	*/
	set_fpga_clk_high(m_lImmrBase);
	set_fpga_din_low(m_lImmrBase);
	start_fpga_config(m_lImmrBase);
	
	
	
#ifdef FPGA_DEBUG	
	printf("Init port\n");
	readportc();
#endif /*FPGA_DEBUG*/
	
	/*等待INIT信号变高,若在一段时间内未变高,返回配置不成功值0(等待的时间大于4us即可)*/
	if(waiting_fpga_init_high(m_lImmrBase)==FALSE)
	{
#ifdef FPGA_DEBUG
    	printf(" b wait init signal high error\n");
#endif /*FPGA_DEBUG*/
    	return FALSE;
    }
#ifdef FPGA_DEBUG    
	printf("config data\n");
#endif /*FPGA_DEBUG*/
	/*Download bit data.*/ 
	for(k = 0; k < nBytes; k++)
	{
    	if(bytesend(*(pAddr+k), m_lImmrBase) == 0)
    	{
#ifdef FPGA_DEBUG
    		printf("send data byte error\n");
#endif
    		return FALSE;
    	}
	}
    	
   	/*return the result of waiting for fpga_done*/
   	return waiting_fpga_done_high(m_lImmrBase);
}



void testdown()
{
	printf("Test down fpga data...\n");
	if(fpga_download(lenfpga,fpgadata))
		printf("Fpga down data finished!\n ");
	else
		printf("Fpga down data failed!\n");	
}


void readportc()
{
	UINT32 m_lImmrBase = vxImmrIsbGet();
	UINT16 PortCDat	= *MPC860_PCDAT(m_lImmrBase);
	
	printf("FPGA_PROG = 0x%4x\n", PortCDat&FPGA_PROG);
	printf("FPGA_INIT = 0x%4x\n", PortCDat&FPGA_INIT);
	printf("FPGA_CLK  = 0x%4x\n", PortCDat&FPGA_CLK);
	printf("FPGA_DIN  = 0x%4x\n", PortCDat&FPGA_DIN);
	printf("FPGA_DONE = 0x%4x\n", PortCDat&FPGA_DONE);
	
	return;
}

⌨️ 快捷键说明

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