/**
 *   @file  evminit.c
 *
 *   @brief
 *      EVM and EMAC PHY initializations for the EVM.
 *
 *  \par
 *  NOTE:
 *      (C) Copyright 2008, Texas Instruments, Inc.
 *
 *  \par
 */

#include "evminit.h"


/**
 *  @b EMAC_getConfig
 *  @n
 *     This is a callback from the Ethernet driver. This function
 *	   is used by the driver to get its 6 byte MAC address.
 *
 *  @param[in]  pMacAddr
 *      MAC address.
 *
 *  @retval
 *      void
 */
void EMAC_getConfig( UINT8 *pMacAddr)
{
    UINT8 bMacAddr[6];
  	UINT32 addr;

 	 /* Read the e-fuse value as 32 bit values to be endian independent */
  	addr = DEVICE_REG_MAC_ADDR(1);
  	bMacAddr[0] = ((addr & 0x0000ff00) >> 8);   /* MACID[47:40] */
	bMacAddr[1] = (addr & 0x000000ff);          /* MACID[39:32] */
  	addr = DEVICE_REG_MAC_ADDR(0);
  	bMacAddr[2] = ((addr & 0xff000000) >> 24);  /* MACID[31:24] */
	bMacAddr[3] = ((addr & 0x00ff0000) >> 16);  /* MACID[23:16] */
  	bMacAddr[4] = ((addr & 0x0000ff00) >> 8);   /* MACID[15:8] */
	bMacAddr[5] = (addr & 0x000000ff);          /* MACID[7:0] */

    printf("MAC Address read from EFUSE: %02x-%02x-%02x-%02x-%02x-%02x\n",
            bMacAddr[0], bMacAddr[1], bMacAddr[2],
            bMacAddr[3], bMacAddr[4], bMacAddr[5]);

    mmCopy( pMacAddr, bMacAddr, 6 );

    return;
}

/**
 *  @b EMAC_linkStatus
 *  @n
 *      This is a callback from the Ethernet driver. This function
 *      is called whenever there is a change in link state. The
 * 		current PHY and current link state are passed as parameters.
 *
 *  @param[in]  phy
 *      PHY number.
 *  @param[in]  linkStatus
 *      Status of the link.
 *
 *  @retval
 *      void
 */
void EMAC_linkStatus( uint phy, uint linkStatus )
{
    printf("Link Status: %s on PHY %d\n",LinkStr[linkStatus],phy);
}

/**
 *  @b EVM_init
 *  @n
 *      Initialize the board
 *
 *  @param[in]  void
 *
 *  @retval
 *      void
 */
void Init_EVM()
{
    volatile Uint32 test;
    int i32ID;
#if 1
    /* Initialize EVM module.
     * Must always be the first BSL functions called.
     */
    if (EVM_init()!=EVM_INITOK)
    {
        /* Error initializing the EVM */
		printf("EVM Init Failed \n");
        return;
    }
  
    /*  Initialize the GPIO module on this EVM */
    if(EVM_GPIO_init())
    {
		printf("EVM GPIO Init Failed \n");
		return;
    }

    /* Get the DSP ID on which this application is
     * running.
     */
    if(EVM_GPIO_cpuid (&i32ID))                     
    {
        printf("GPIO DSP ID get Failed \n");
        return;
    }    
    else
    {
        if(i32ID == 0)
        {
            i32ID = 1;  /* DSP is DSP2 */
        }
        else if(i32ID == 1)
        {
            i32ID = 0; /* DSP is DSP1 */
        }
        printf("Application is running on DSP%d... \n",i32ID+1);
    }
#endif
	i32ID = 1;
    return;
}

/**
 *  @b EVM_getCPUID
 *  @n
 *      Get the DSP Id using EVM BSL Library.
 *
 *  @retval
 *      Error   -   -1
 *  @retval
 *      Success -   The corresponding DSP ID.
 *      
 */
int EVM_getCPUID(void)
{
    int   i32ID;

    /* Retrieve the DSP ID for this EVM */    
    if(EVM_GPIO_cpuid (&i32ID))                     
    {
        printf("GPIO ID Get Failed \n");
        return -1;      /* return error */
    }    
    else
    {
        if(i32ID == 0)
        {
            i32ID = 1; /* DSP is DSP2 */
        }
        else
        {
            i32ID = 0; /* DSP is DSP1 */
        }
    }

    /* Return the DSP Id (1 based) */
    return (i32ID + 1);
}

/**
 *  @b EVM_getPHYID
 *  @n
 *      Get the PHY ID associated with a given DSP
 *      using EVM BSL Library.
 *
 *  @retval
 *      Error   -   -1
 *  @retval
 *      Success -   The corresponding PHY ID.
 *      
 */
int EVM_getPHYID(int cpuID)
{
    if (cpuID == 1)
    {
        return 0;   /* DSP1 is connected to PHY 0 */
    }
    else if (cpuID == 2)
    {
        return 1;   /* DSP2 is connected to PHY 1 */
    }

    return -1;  /* Incorrect DSP ID. */
}

/**
 *  @b PowerOnEMAC
 *  @n
 *     Called by Ethernet Driver during EMAC bring up to 
 *     wake up the EMAC module from power save sleep.
 *
 *  @retval
 *      void
 */
void EVM_powerOnEMAC()
{
    /* Power up emac    */
    REG_WRITE(PWR_LCK_REG_ADDR, PWR_LCK_REG_VAL);
    REG_WRITE(PWR_MDCTL0_REG_ADDR, PWR_MDCTL0_EMAC_EN_VAL); 
        
    return;
}

/**
 *  @b EVM_wait
 *  @n
 *      Spin in a delay loop for delay iterations
 *
 *  @param[in]  delay
 *      Amount of delay..
 *
 *  @retval
 *      void
 */
void EVM_wait(Uint32 delay)
{
    volatile Uint32 i, n;

    n = 0;
    for (i = 0; i < delay; i++)
    {
        n = n + 1;
    }
}

/**
 *  @b EVM_waitusec
 *  @n
 *      Spin in a delay loop for delay microseconds
 *
 *  @param[in]  delay
 *      Amount of delay.
 *
 *  @retval
 *      void
 */
void EVM_waitusec(Uint32 delay)
{
    EVM_wait(delay * 39);
}
