/*******************************************************************************
版权所有 (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.*/
f
评论0