/**************************************************************
***************************************************************
**
** Host Application, Copyright (C) 2002-2004
** Ikanos Communication, Fremont, CA 
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of 
** Ikanos Communication
**
***************************************************************

$Revision: 1.2 $
$Date: 2006/11/07 09:19:08 $
**************************************************************/


/*******  Include Files         ***************************************/
#include <linux/autoconf.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h> /* IXDP425 */
#include <signal.h>
#include "ipos.h"
#include "bsp.h"
#include "oampdb.h"
#include "apposmacro.h"
#include "eventlog.h"
#include "pprofile.h"
#include "apiproto.h"
#include "oamptask.h"
#include "oampdef.h"
#include "appconfig.h"
#ifdef INI_SUPPORT 
#include "HostPtmfApi.h"
#endif //INI_SUPPORT
#include "eocapp.h"
#include "perfhandler.h"
#include "portmap.h"
#ifdef CO_30_DIAGS
#include "diags_mode.h"
#endif

#ifdef	USE_RFM
#include	"rfmapp.h"
#endif
#include "dapi.h"		/* NACK_BUSY, etc. */


/*******  Defines               ***************************************/
#define STATIC	static
#define	BME_RECEIVER_PRIORITY       100
#define	BME_RECEIVER_STACK_SIZE	    8192
#define	UI_TASK_PRIORITY            90
#define	UI_TASK_STACK_SIZE	        8192
#define	ONE_SEC_TASK_PRIORITY       100
#define	ONE_SEC_TASK_STACK_SIZE	    8192
#define	INI_CNTR_HNDLR_PRIORITY     100
#define	INI_CNTR_HNDLR_STACK_SIZE	  8192

unsigned int uliTask,ulBmeRcv;
/*******  Constants             ***************************************/

/*******  Local Data Structures ***************************************/

/*******  External Functions    ***************************************/
#ifndef BUP_DIAGS
extern void taskUi(void);
#endif

// both BUP_DIAGS and CO_30_DIAGS **cannot** be defined together!!!
#if defined(BUP_DIAGS)
extern void bup_taskUi(void);
#elif defined(CO_30_DIAGS)
extern void bup_diags (void);
#endif
extern void UpdatePerfPara(ipos_port_id pid, U8 uid, U32 upar, int status, ipos_port_counters *pREPORT);
extern void taskOneSec(void);
extern void checkFlash (volatile U32 * pChip);
extern void setDefaultPortMapping();
extern void sysBMEInterfaceInit (void);
extern void sysConfigPortPinsForBMEInterface ( void );
extern void hostIntInit();
extern void oampStateResetAll(void);
extern void InitPerfPara(int BmeNum, int PortNum);
extern void eocInit( void );
extern int  coELMAppInit( void );
extern void InitpollMonitorParms();

extern eoamp_port_state oampGetPortState(ipos_port_id pid);
#ifdef INI_SUPPORT 
extern	void	HandleIniInterrupt(void);
extern U32 HostIniFpgaProgm(void);
#endif //INI_SUPPORT 
extern void clearBmeCounters (ipos_port_id pid);

extern int CreateTimer15Mins();
extern int HostReset;
extern int	cpeELMAppInit( void );
extern void HostEpldInterfaceInit (void);
extern void HostAfeAddrSet(char);
void HostResetInit( void );
void RetrievePortConfig(ipos_port_id pid, U8 uid, U32 upar, int status, struct tPortProfile *rxPortProfile,
                                                                        struct tPortProfile *currPortProfile);
void RetrieveSysConfig(ipos_port_id pid, U8 uid, U32 upar, int status, struct tSystemProv *rxProvParms, 
                                                                       struct tSystemProv *currProvParms);
/*******  Global Data           ***************************************/
port_error_counters	portErrorCounters[ IPOS_MAX_PORTS+1 ];

/*******  Local Data            ***************************************/    

/*******  Local Functions Prototypes **********************************/

/************************************************************************/
/* API entry loop for polling	*/
/* invoked after	iposInit called	*/
#ifdef USE_VXWORKS /* IXDP425  for VxWorks*/
STATIC void apiEntryPoll(int arg)
{

	while(1)
	{

		iposTaskDelay (CLOCKS_PER_SEC/40);		/* 40 times a second	*/
                if (!HostReset)
		  iposEntryRcvPoll(500, 0);				

	}
}
#else /* IXDP425 for Linux */
static void timerSigHandler(int j)
{
  printf("\nSignal Handler for sig: %d from thread 1",j);
  iposEntryRcvPoll(500, 0);				
}
#ifdef ALASKA
char vdslLinkStatus;
extern void vdslLED(char flag);
#endif

STATIC void apiEntryPoll(int arg)
{
#ifndef ALASKA
	// remove warning
        // sighandler_t sig;
        int iTimer = 0;


   	struct itimerval itmVal;
   	struct itimerval otmVal;


        // sig = signal(SIGALRM, timerSigHandler);

        signal(SIGALRM, timerSigHandler);
 
        itmVal.it_interval.tv_sec = 0;
        itmVal.it_interval.tv_usec = 20000;//change it to 20000-manju
        itmVal.it_value.tv_sec = 0;
        itmVal.it_value.tv_usec = 20000;//change it to 20000-manju

        iTimer = setitimer(ITIMER_REAL, &itmVal, &otmVal);

	while(1);
	usleep(100);
#else
  static unsigned char vdslLedFlg = 0;
  static int LEDCount = 0;
#ifdef LINUX_2_6
  osSetTaskRealTime(1);
#endif
  while(1)
  {
     if(vdslLinkStatus ==0)
     {
       if ( (LEDCount%0x10)==0)
       {
          vdslLedFlg ^= 1;
          vdslLED(vdslLedFlg);
          LEDCount=0;
       }
     }
     LEDCount++;
     iposEntryRcvPoll(500, 0);				
     usleep(20000);
     // printf("\nSignal Handler for sig: \n");
  }
#endif
}
#endif  /* IXDP425 */

#ifdef INI_SUPPORT
/******************************************************************************
*                                                                             *
* Function.. : ptmfCountHandler                             	                *
*                                                   	                        *
* Purpose... : Task                    	                                      *
*									                                                            *
* Parameters : N/A                                                            *
*                                                                             *
* Returns... : N/A                                                            *
*                                                                             *
******************************************************************************/

STATIC void ptmfCountHandler(void)
{
  ipos_port_id        Pid;
  int  lineNum/*, ptmfPort*/;
  int  IniIndex, IniSlow, IniFast;
#ifdef LINUX_2_6
  osSetTaskRealTime(1);
#endif
  
  while (1)
  {
#ifndef ALASKA
    iposTaskDelay (PTMF_TASK_DELAY);                     // CLOCKS_PER_SEC * 0.2
#else
    usleep(50000);
#endif
    for (Pid.bmeNum = 1;
         Pid.bmeNum <= MAX_NUM_OF_BMES;
         Pid.bmeNum++ )
    {

      for ( Pid.portNum = 1; 
            Pid.portNum <= MAX_PORTS_PER_BME; 
            Pid.portNum ++ )
      {
        if (getLineNum(Pid, &lineNum) == IPOS_SUCCESS)
        {
          if(oampGetPortState(Pid)==uSHOWTIME)
          {
//            getIniPhy (lineNum, &ptmfPort); Modified for dual latency
              getIniMap(Pid, &IniIndex, &IniSlow, &IniFast);
              iposPtmfReadCounters (IniIndex);
			  if (IniSlow != IniFast)
			  {
				  iposPtmfReadCounters (IniIndex + 1);
			  }

//            iposPtmfReadCounters (ptmfPort);
          }
        }
      }
    }
  }
}

#endif //INI_SUPPORT

/*
 *  Demonstration callback in the event of an error report from a port
 *
 *  par is the address of any associated data
 *  len is the length of that data
 *
 */

static void
reportErrorPort( ipos_port_id pid, U8 uid, U32 upar, int errCode, int len, U8 *par )
{
	int	lineNum = 0;

    /*printf( "\nError code %d reported on port b%dp%d\n", errCode, pid.bmeNum, pid.portNum );*/

	if (getLineNum( pid, &lineNum ) != IPOS_SUCCESS)
	{
		printf( "failed to get a line number for port b%dp%d in reportErrorPort\n",
			 pid.bmeNum, pid.portNum );
		return;
	}
	if (errCode == NACK_BUSY)
	{
		portErrorCounters[ lineNum ].countNackBusy++;
	}
	else if (errCode == NACK_ERROR)
	{
		portErrorCounters[ lineNum ].countNackError++;
	}

	portErrorCounters[ lineNum ].totalErrors++;
}

void
reportPortErrorCounts( int portIndex )
{
	int	iter, startingPort, endingPort;
	int	continueOnError;

	if (portIndex == 0)
	{
		startingPort = 1;			/* do not report on index 0 */
		endingPort = IPOS_MAX_PORTS;
		continueOnError = 0;
	}
	else {
		startingPort = portIndex;
		endingPort = portIndex;
		continueOnError = 1;
	}

/* BEWARE:  No semaphore guards the error counters !! */

	for (iter = startingPort; iter <= endingPort; iter++)
	{
		ipos_port_id	pid;
		int		totalErrors = portErrorCounters[ iter ].totalErrors;
		int		countNackBusy = portErrorCounters[ iter ].countNackBusy;
		int		countNackError = portErrorCounters[ iter ].countNackError;
		int		countOtherErrors = totalErrors - (countNackBusy + countNackError);


		if (getBmePortId( iter, &pid) == IPOS_SUCCESS)
		{
			printf(
	    "for port %d (b%dp%d), NACK BUSY: %d, NACK ERROR: %d, other: %d, total: %d\n",
	     iter, pid.bmeNum, pid.portNum,
	     countNackBusy, countNackError, countOtherErrors, totalErrors
			);
		}
		else if (continueOnError)
		{
			printf( "Unable to locate BME for port %d\n", iter );
			printf( "NACK BUSY: %d, NACK ERROR: %d, other: %d, total: %d\n",
				 countNackBusy, countNackError, countOtherErrors, totalErrors
			);
		}
	}
}

void
resetPortErrorCounts( int portIndex )
{
	int	iter, startingPort, endingPort;

	if (portIndex == 0)
	{
		startingPort = 0;		/* reset counters for index 0 */
		endingPort = IPOS_MAX_PORTS;
	}
	else {
		startingPort = portIndex;
		endingPort = portIndex;
	}

/* BEWARE:  No semaphore guards the error counters !! */

	for (iter = startingPort; iter <= endingPort; iter++)
	{
		portErrorCounters[ iter ].totalErrors = 0;
		portErrorCounters[ iter ].countNackBusy = 0;
		portErrorCounters[ iter ].countNackError = 0;
	}
}
extern int bme_device_open();

/*************************************************************************
	Function: start
	
	Description: This function is used to launch all initial tasks and 
				related objects. For now, it is the first function called 
				after VxWorks boots up.
	
	Return: None
************************************************************************/
#ifdef USE_VXWORKS  /* For VxWorks, IXDP425*/
void start(void)
#else                  /* For Linux IXDP425*/
int main(void)
#endif                 /* IXDP425 */
{	
#ifndef BUP_DIAGS
	ipos_port_id	pid;
	int n;
#ifndef USE_VXWORKS /* IXDP425 */
	int iFifo_minPri, iFifo_maxPri;
	int iRr_minPri, iRr_maxPri;

	struct sched_param sNewPri,sOldPri;
	int err;
	int taskList[20];//manju to get the task list running for debugging
#endif 
#endif 
#ifdef CONFIG_KERNELVERSION
/*only for linux-2.6.18 kernel; common for both BUP_DIAGS & non BUP_DIAGS. */ 
    int bme_fd;
    if ((bme_fd = open("/dev/bme", O_RDWR)) < 0)
    {
	FILE *bme_fp;
	int bme_major;
	char bme_dev[80];
	bme_fp=fopen("/sys/class/bme/bme/dev","r");
	if(bme_fp == NULL)
	{
		printf("\nbme driver is not loaded; vdsld exiting\n");
		exit(0);
	}
	fread(bme_dev,sizeof(char),10,bme_fp);
	bme_major=atoi((char *)bme_dev);
	sprintf(bme_dev,"mknod /dev/bme c %d 0\n",bme_major);
	system(bme_dev);
	printf("\ncreated /dev/bme with major number: %d\n",bme_major);
	fclose(bme_fp);
    }
    else
    {
        close(bme_fd);
    }
#endif

#ifndef BUP_DIAGS
#ifndef CPE_ATM
	//checkFlash((U32 *)NVRAM_BLK_START); /* IXDP425 */
#endif /* CPE_ATM*/

//#ifdef INI_SUPPORT
#ifdef P2CO
#ifndef CO_20

	//HostEpldInterfaceInit(); /* IXDP425 */
//	HostAfeAddrSet(0xe4);

#endif

#elif defined(P2CPE) && defined(INI_SUPPORT)

//  HostIniFpgaProgm(); /* commented for IXDP425 */
#endif
#ifndef USE_VXWORKS /* IXDP425 */
  kernelTimeSlice(0); /* IXDP425 */

   iFifo_minPri = sched_get_priority_min( SCHED_FIFO );
   iFifo_maxPri = sched_get_priority_max( SCHED_FIFO );

   iRr_minPri = sched_get_priority_min( SCHED_RR );
   iRr_maxPri = sched_get_priority_max( SCHED_RR );
#ifndef ALASKA
   printf("iFifo_minPri is %d %x\n",iFifo_minPri,iFifo_minPri);
   printf("iFifo_maxPri is %d %x\n",iFifo_maxPri,iFifo_maxPri);
   printf("iRr_minPri is %d %x\n",iRr_minPri,iRr_minPri);
   printf("iRr_maxPri is %d %x\n",iRr_maxPri,iRr_maxPri);    
#endif
   // InitMemoryMapPointer();
#if 1 
   //init_flash(0,NULL);
   sNewPri.__sched_priority = iFifo_maxPri;

   if (0 != (err = sched_setscheduler(0, SCHED_FIFO, &sNewPri))) 
   {
	printf("\n Error in Sched_setscheduler is %d", err);
	return (1);
   }  
//   printf("err when sched_setscheduler called is %d %x\n",err,err);    

   if (0 != (err = sched_getparam(0, &sOldPri)))
   {
	printf("\n Error in sched_getparam %d",err);
	return (1);
   }
   else
   {
   }
 //printf("err when sched_getparam called is %d %x\n",err,err);    
#endif
#endif

	if(iposSysInit() == IPOS_SUCCESS)
  {
	  printf("\nipos system initialized \n");
    bme_device_open();
    
    /* This needs to be done before any other flash updates */
    /* set default port profile parameters */	
    setDefaultPortProfile();
#ifdef VTU_O
    setCoDefaultPortProfile(0);
    setCoDefaultPortProfile(1);
    setCoDefaultPortProfile(2);
#else
    setCpeDefaultPortProfile(0);
    setCpeDefaultPortProfile(1);
    setCpeDefaultPortProfile(2);
#endif

	setDefaultPortMapping();

//    initOamp();
    initOAMPDB();
    sysBMEInterfaceInit();
#ifndef CPE_ATM
    // Initialize BSP related components
    hostIntInit();
#endif /* CPE_ATM*/
    sysConfigPortPinsForBMEInterface();


    InitEventLogs();
    EventLog("Start host processor");
    oampStateResetAll();
#if 1/* manju for debugging only */
  if (iposTaskSpawn("tBmeRcver", BME_RECEIVER_PRIORITY,
                      BME_RECEIVER_STACK_SIZE, (taskFunc)apiEntryPoll,
                      0, 0, 0) == OS_ERROR)
   		printf("Failed to start BME receiver\n");
#endif
// the logic here is like this: For CO3, the diags is always included in the
// production build, with the definition CO_30_DIAGS. There is no separate
// diags build. In the production build, there is an option (set in flash)
// wherein the diags can be skipped. If the diags is run, it can be run either
// in manual mode (menu driven) or in POST (Power On Self Test) mode, wherein
// the tests are run silently automatically and goes to normal operation
// thereafter. If any tests fail in POST, it then goes to manual diags mode.
//
// The BUP_DIAGS define is not used for CO3. It applies to CO2 and earlier diags
// builds.

#ifdef CO_30_DIAGS // always defined for all CO3 builds; see note below

// NOTE: CO_30_DIAGS can be defined in CO_20 normal builds (non-diags) also, to
//       use the new diags on CO_20. (BUP_DIAGS should **NOT** be defined then)

  #define DIAGS_WAIT_TIME (1) // seconds

  if (oampGetDiagsOption != BUP_DIAGS_MANUAL_MODE)
  {
      IK_PRINTF ("\n\nPress ENTER key within %d seconds to enter diags menu...\n",
          DIAGS_WAIT_TIME);

      if (consoleKbHit(DIAGS_WAIT_TIME))
      {
          diagsManualMode = 1;
          getchar(); //flush
      }
  }

  if (diagsManualMode || oampGetDiagsOption != BUP_DIAGS_SKIP_MODE)
  {
	if (iposTaskSpawn("tUiTask", UI_TASK_PRIORITY,
                      UI_TASK_STACK_SIZE, (taskFunc) bup_diags,
                      0, 0, 0) == OS_ERROR)
      	IK_PRINTF("Failed to start UI Task\n");
  }
  else // skip diags
  {
	if (iposTaskSpawn("tUiTask", UI_TASK_PRIORITY,
                      UI_TASK_STACK_SIZE, (taskFunc)taskUi,
                      0, 0, 0) == OS_ERROR)
      	IK_PRINTF("Failed to start UI Task\n");
  }

#elif defined(BUP_DIAGS) // defined for CO_20 diags builds only
	if (iposTaskSpawn("tUiTask", UI_TASK_PRIORITY,
                      UI_TASK_STACK_SIZE, (taskFunc)bup_taskUi,
                      0, 0, 0) == OS_ERROR)
      	IK_PRINTF("Failed to start UI Task\n");

#else // normal CO_20 and other builds
	if (iposTaskSpawn("tUiTask", UI_TASK_PRIORITY,
                      UI_TASK_STACK_SIZE, (taskFunc)taskUi,
                      0, 0, 0) == OS_ERROR)
      	IK_PRINTF("Failed to start UI Task\n");
      //	printf("UI Task is Started\n");		      
#endif


	if (iposTaskSpawn("tOneSecTask", ONE_SEC_TASK_PRIORITY,
                      ONE_SEC_TASK_STACK_SIZE, (taskFunc)taskOneSec,
                      0, 0, 0) == OS_ERROR)
      	printf("Failed to start One Sec Task\n");

#ifdef INI_SUPPORT
  if (iposTaskSpawn("tIniCntrHndlr", INI_CNTR_HNDLR_PRIORITY,
                      INI_CNTR_HNDLR_STACK_SIZE, (taskFunc)ptmfCountHandler,
                      0, 0, 0) == OS_ERROR)
   		printf("Failed to start PTMF counter handler\n");

#endif //INI_SUPPORT

    /* 	initialize two oamp task	*/
    if(appOampTaskInit(MAX_NUM_OF_OAMP_TASKS)!=IPOS_SUCCESS)
    {
      printf("oamp task initialization failed\n ");

    }
    // printf("oamp Task is Started\n");		      
    

	CreateTimer15Mins();



	for (pid.bmeNum=1;pid.bmeNum<=MAX_NUM_OF_BMES;pid.bmeNum++)
		for (pid.portNum=1;pid.portNum<=MAX_PORTS_PER_BME;pid.portNum++)
			InitPerfPara(pid.bmeNum, pid.portNum);

		pid.bmeNum=1;
    for (n = 1; n < MAX_PORTS_PER_BME;n++)
    {
	  pid.portNum=n;
  
    }

    resetPortErrorCounts( 0 );		/* reset them all */

/* Do not use getLineNum or getBmePortId
   These will not work until the port's BME has been provisioned */

    for (pid.bmeNum = 1;
         pid.bmeNum <= MAX_NUM_OF_BMES;
         pid.bmeNum++ )
    {

      for ( pid.portNum = 1;
            pid.portNum <= MAX_PORTS_PER_BME;
            pid.portNum ++ )
      {
            iposSetCbError( pid, 0, reportErrorPort );
			clearBmeCounters(pid);
      }
  
    }
//	setUtopiaAddr();
	eocInit();
	HostResetInit( );


#if defined(VTU_R) && defined(P2CPE) && defined(INI_SUPPORT)
	iposPtmfAddrTabInit(&macFilCfgShadow);
#endif

#if 0  // manju for debugging only
#ifdef	USE_RFM

#ifdef	VTU_O
	coRFMAppInit();
#else
	cpeRFMAppInit();
#endif
#endif
#endif

#ifdef	VTU_O
	coELMAppInit();
#else
	cpeELMAppInit();
#endif

	InitpollMonitorParms();

	} // if(iposSysInit() == IPOS_SUCCESS)
#else // BUP_DIAGS
       bme_device_open();
        if(iposSysInit() == IPOS_SUCCESS)
        {

            printf("iposSysInit(): is done \n");
            if (iposTaskSpawn("tUiTask", UI_TASK_PRIORITY,
                      UI_TASK_STACK_SIZE, (taskFunc)bup_taskUi,
                      0, 0, 0) == OS_ERROR)
            IK_PRINTF("Failed to start UI Task\n");
            IK_PRINTF("Diag Task to start UI Task\n");
        }
#endif // BUP_DIAGS


	while(1) /* IXDP425 */
#if 1 
	{
#ifndef BUP_DIAGS
	//	taskIdListGet(taskList,10);
#endif
		sleep(600);
	}
#endif
}
#if !defined(P2CO) && !defined(BME_CPE_20) && defined(INI_SUPPORT) 
/****************************************************************************/
/*                                                                          */
/* Function.. : handInt	                        			    */
/*                                                   	                    */
/* Purpose... : Handle interrupt from INI				    */
/*									    */
/* Parameters : None							    */
/*                                                                          */
/* Returns... : N/A                                                         */
/*                                                                          */
/****************************************************************************/
void handleIniInt ()
{
//	BYTE data;
//	UINT16 phydata;

/*	iniread (INI_InterruptCsr, (BYTE *) &data);

	EventLog ("*****Interrupt from INI CSR: %x\n",data);
*/
//printf ("\n*****Interrupt from INI CSR: %x\n",data);
	appOampJobAdd(TID_OAMPFUNC, (appOampFunc) HandleIniInterrupt,0,0,NULL);

}

	 
#endif //P2CO

void HostResetInit( void )
{
	 ipos_port_id pid;
   for (pid.bmeNum = 1; pid.bmeNum <= MAX_NUM_OF_BMES; pid.bmeNum++ ) {
			iposSetCbHostRetrieveBme(pid, 0x89, RetrieveSysConfig);
	    for ( pid.portNum = 1; pid.portNum <= MAX_PORTS_PER_BME; pid.portNum ++ ) {
				 iposSetCbHostRetrievePort(pid, 0, RetrievePortConfig);
      }
    }
}
#ifndef BUP_DIAGS
// AFE_IFE SERIAL INTERFACE DEFINE
#ifdef CPE_50
unsigned int rdIfeReg(unsigned int addr, int * data);
unsigned int wtIfeReg(unsigned int addr, unsigned int dt);

#define CPE5_AFE_RDWR_CMD    0xE0018000
#define CPE5_AFE_READ_DATA   0xE0018004
#define CPE5_AFE_WRITE_DATA  0xE0018008
#define CPE5_AFE_RDWR_STAT   0xE001800C

#define AFE_CMD_PASS    (1 << 2)
#define AFE_CMD_FAIL    (1 << 1)
#define AFE_CMD_BUSY    (1 << 0)

#define AFE_REG_RD      (1 << 31)
#define AFE_REG_WR      (1 << 30)
#define AFE_MAX_RW_REPEAT 20
#define AFE_REG_ADDR_MASK 0x1F

#define AFE_HLD_REG_RD_WR_STAT          (0x1A)      // GLOBAL Reg
#define HLD_STAT                    (1 << 31)
#define WR_DATA                     (0x0FFF0000) //27:16
#define RD_DATA                     (0x00000FFF) //11:0

#define AFE_HLD_RDWR_CMD                (0x19)      // GLOBAL Reg
#define HLD_REG_RD                  (1 << 31)
#define HLD_REG_WR                  (1 << 30)



#endif  /* CPE_50 */
#define IFE_VERSION_ADDR 0x00
#define IFE_PGA1_ADDR    0x01
#define IFE_PGA2_ADDR    0x08
int bup_IFEPrgPLL ()
{
    #define CPE5_AFE_BANDGAP_CTRL 0x03

    unsigned int IfeVer;
    int readData;
    int error = 0;
    int itrCount = 10;

    // Read IFE Version
    error = rdIfeReg (IFE_VERSION_ADDR, &IfeVer);
    printf("Hello 2 \n");
    // If read not successful, cannot program the PLL in Band Gap, else, goaheadto program PLL
    if (!error)
    {
        IfeVer = IfeVer & 0x1FFF;

        // If IfeVersion is 0x0E10 then program the Band gap register (PLL bug)
        if (IfeVer == 0x0E10)
        {
            printf ("\t\t\t Read IFE Version is 0x%x\n", IfeVer);
            while (itrCount --)
            {
    printf("wtIfeReg 1 \n");
                error = wtIfeReg (CPE5_AFE_BANDGAP_CTRL, 0);
    printf("wtIfeReg 2 \n");
                if (!error)
                {
                     error = rdIfeReg (CPE5_AFE_BANDGAP_CTRL, &readData);
                     if (!error)
                     {
                         if (readData == 0)
                             break;
                     }
                }
            }
            if (itrCount)
            {
                printf ("Band Gap Register set to 0x%x, ItrCount = %d\n", readData, (10 - itrCount));
            }
            else
            {
                printf ("ERROR!!!: Band Gap Register Not set to 0x%x, ItrCount =%d\n", readData, (10 - itrCount));

            }
        }

    }
    else
    {
        printf ("\t\t\t******** Read IFE Version Failed Cannot program Band GapRegister ********\n");
    }

    return error;
}

#ifdef CPE_50
unsigned int status;
unsigned int rdIfeReg(unsigned int addr, int * data)
{
    unsigned int reg_data;
        unsigned int  stat= 0;
        int i = 0;
        // Read the IFE Status register
        status = testPIORead1 (1,CPE5_AFE_RDWR_STAT );

    // Check for Command Failure condition
    i = 0;
        if ((status & AFE_CMD_FAIL) == AFE_CMD_FAIL)
        {
                printf(" ERROR : Fail bit is set in the AFE_RDWR_STAT Register:status = 0x%x\n",status);
                stat = -1;
                goto error;
        }

    // Check for Busy condition
        while ((status & AFE_CMD_BUSY) == AFE_CMD_BUSY )
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(200);
                if (i > 200 )
                {
                        printf(" ERROR : TimedOUT for ReadDone bit: status = 0x%x\n",status);
                        stat = -1;
                        goto error;
                }
        }

        // Issue the read command
        testPIOWrite(1,CPE5_AFE_RDWR_CMD, (AFE_REG_RD | (addr & AFE_REG_ADDR_MASK)));

        // Check the status of the IFE serial STAT reg
        status = testPIORead1 (1,CPE5_AFE_RDWR_STAT );

    // Check for Command Failure condition
    i = 0;
        if ((status & AFE_CMD_FAIL) == AFE_CMD_FAIL)
        {
                printf(" ERROR : Fail bit is set in the AFE_RDWR_STAT Register:status = 0x%x\n",status);
                stat = -1;
                goto error;
        }

        i = 0;
    //Check for the Busy and Fail condition
        while ((status & AFE_CMD_BUSY) == AFE_CMD_BUSY )
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(20);
                if (i > 200 )
               {
                        printf(" ERROR : AFE BUSY after issuing read command : 0x%x\n",status);
                        stat = -1;
                        goto error;
                }
        }

        // Check for the Done status
    i = 0;
    status = testPIORead1(1, CPE5_AFE_RDWR_STAT);
    while ((status & AFE_CMD_PASS) == 0)
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(4000);
                if (i > 200 )
                {
                        printf(" ERROR : AfE READ DONE timeout Detected after :0x%x\n",status);
                        stat = -1;
                        goto error;
                }

        }

    // Done status detected indicating the command has passed, fetch data from the data register
        reg_data = testPIORead1(1,CPE5_AFE_READ_DATA);

        /* Set AFE_CMD_PASS to clear status */
        testPIOWrite(1,CPE5_AFE_RDWR_STAT, AFE_CMD_PASS);
        *data = reg_data;

error:

if (stat) printf ("rdife %x\n", stat);
        return stat;

}

#endif  /* CPE_50*/
#ifdef CPE_50
unsigned int wtIfeReg(unsigned int addr, unsigned int dt)
{
        unsigned int status, stat= 0;
        int i = 0;

        // Check the status of the IFE serial STAT reg
        status = testPIORead1 (1,CPE5_AFE_RDWR_STAT );

        i = 0;
        if ((status & AFE_CMD_FAIL) == AFE_CMD_FAIL)
        {
                printf(" ERROR : Fail bit is set in the AFE_RDWR_STAT Register:status = 0x%x\n",status);
                stat = -1;
                goto error;
                //break;
        }

    // Check for the busy status
        while ((status & AFE_CMD_BUSY) == AFE_CMD_BUSY )
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(20);
                if (i > 200 )
                {
                        printf(" ERROR : TimedOUT for ReadDone bit: status = 0x%x\n",status);
                        stat = -1;
                        goto error;
                }
        }

        // 0x40000000 is for write bit, send write command & wait for complitionof command
        testPIOWrite(1,CPE5_AFE_WRITE_DATA,dt);
        testPIOWrite(1,CPE5_AFE_RDWR_CMD, (AFE_REG_WR | (addr & AFE_REG_ADDR_MASK)));

    // Check if write was successful
        status = testPIORead1 (1,CPE5_AFE_RDWR_STAT );

        if ((status & AFE_CMD_FAIL) == AFE_CMD_FAIL)
        {
                printf(" ERROR : Fail bit is set in the AFE_RDWR_STAT Register:status = 0x%x\n",status);
                stat = -1;
                goto error;
        }

        i = 0;
        while ((status & AFE_CMD_BUSY) ==AFE_CMD_BUSY )
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(20);
                if (i > 200 )
                {
                        printf(" ERROR : TimedOUT for ReadDone bit: status = 0x%x\n",status);
                        stat = -1;
                        goto error;
                }
        }
        // Check for the Done status
    i = 0;
    status = testPIORead1(1, CPE5_AFE_RDWR_STAT);
    while ((status & AFE_CMD_PASS) == 0)
        {
                status = testPIORead1(1,CPE5_AFE_RDWR_STAT);
                i++;
                // taskDelay(20);
                usleep(20);
                if (i > 200 )
                {
                        printf(" ERROR : AFE READ DONE timeout Detected after :0x%x\n",status);
                        stat = -1;
                        goto error;
                }

        }

    // Clear the done status
        testPIOWrite(1,CPE5_AFE_RDWR_STAT, AFE_CMD_PASS);

error:
if (stat) printf ("wrife %x\n", stat);

        return stat;
}


#endif  /* CPE_50 */
#endif  /* BUP_DIAGS */
