/** @file sys_main.c 
*   @brief Application main file
*
*   This file contains an empty main function,
*   which can be used for the application.
*/

/* (c) Texas Instruments 2009-2014, All rights reserved. */

/* USER CODE BEGIN (0) */
/* USER CODE END */

/* Include Files */

#include "sys_common.h"

/* USER CODE BEGIN (1) */
#include "system.h"
#include "bl_emac.h"
#include "bl_mdio.h"
#include "ports/hdk/include/netif/phy_dp83640.h"
#include "hw_sci.h"
#include "lwipopts.h"
#include "lwiplib.h"
#include "httpserver_raw_io/httpd.h"
#include "lwip/inet.h"
#include "locator.h"
#include "string.h"
#include "bl_tftp.h"
#include "bl_config.h"
#include "ustdlib.h"
#include "uartstdio.h"
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
#define ENABLE_UPDATE_CHECK
#define FORCED_UPDATE_PIN		7

//*****************************************************************************
//
// This holds the current address that is being written to during a download
// command.
//
//*****************************************************************************
uint32_t g_ulTransferAddress;

void 	IntMasterIRQEnable	(void);
void 	sciDisplayText(sciBASE_t *sci, uint8_t *text,uint32_t length);
uint32_t CheckGPIOForceUpdate(void);

/* USER CODE END */

uint8_t		emacAddress[6] 	= 	{0x7C, 0xE6, 0xD3, 0x69, 0x8E, 0xD7};

//*****************************************************************************
//
// Display an lwIP type IP Address.
//
//*****************************************************************************
void
DisplayIPAddress(uint32_t ui32Addr)
{
    char pcBuf[16];

    //
    // Convert the IP Address into a string.
    //
    usprintf(pcBuf, "%d.%d.%d.%d", ui32Addr & 0xff, (ui32Addr >> 8) & 0xff,
            (ui32Addr >> 16) & 0xff, (ui32Addr >> 24) & 0xff);

    //
    // Display the string.
    //
    UARTprintf(pcBuf);
}

void main(void)
{
	/* USER CODE BEGIN (3) */
	sciInit();
//	sciSetBaudrate(sciREG, 115200);   //scilinREG

	/* Enable the interrupt generation in CPSR register */
	IntMasterIRQEnable();

    UARTprintf("Ethernet lwIP Bootloader \n\r");

    // Check if update needed
    if(0 == CheckGPIOForceUpdate() && (*(uint8_t *)APP_START_ADDRESS) != 0xFF)
    {
    	g_ulTransferAddress = (uint32_t)APP_START_ADDRESS;
    	((void (*)(void))g_ulTransferAddress)();
    }

    lwIPInit(0, emacAddress,  htonl(inet_addr("10.219.61.175")) , htonl(inet_addr("255.255.254.0")), htonl(inet_addr("10.219.60.1")), IPADDR_USE_STATIC );  //3232235778 是192.168.1.2 static IP Address
//    lwIPInit(0, emacAddress,  inet_addr("10.219.61.175") , inet_addr("255.255.254.0"), inet_addr("10.219.60.1"), IPADDR_USE_STATIC );  //3232235778 是192.168.1.2 static IP Address

    TFTPQSInit();

    g_ulTransferAddress = (uint32_t)APP_START_ADDRESS;
    ((void (*)(void))g_ulTransferAddress)();

    /* USER CODE END */
}

void sciDisplayText(sciBASE_t *sci, uint8_t *text,uint32_t length)
{
    while(length--)
    {
        while ((sciREG->FLR & 0x4) == 4); /* wait until busy */
        sciSendByte(sciREG,*text++);      /* send out text   */
    };
}

void IntMasterIRQEnable(void)
{
	_enable_IRQ();
	return;
}

void IntMasterIRQDisable(void)
{
	_disable_IRQ();
	return;
}

unsigned int IntMasterStatusGet(void)
{
    return (0xC0 & _get_CPSR());
}

/*
** Interrupt Handler for Core 0 Receive interrupt
*/
volatile int countEMACCore0RxIsr = 0;
#pragma INTERRUPT(EMACCore0RxIsr, IRQ)
void EMACCore0RxIsr(void)
{
	countEMACCore0RxIsr++;
	lwIPRxIntHandler(0);
}

/*
** Interrupt Handler for Core 0 Transmit interrupt
*/
volatile int countEMACCore0TxIsr = 0;
#pragma INTERRUPT(EMACCore0TxIsr, IRQ)
void EMACCore0TxIsr(void)
{
	countEMACCore0TxIsr++;
    lwIPTxIntHandler(0);
}

//*****************************************************************************
//
// Checks a GPIO for a forced update.
//
// This function checks the state of a GPIO to determine if a update is being
// requested.
//
// \return Returns a non-zero value if an update is being requested and zero
// otherwise.
//
//*****************************************************************************
#ifdef ENABLE_UPDATE_CHECK
uint32_t
CheckGPIOForceUpdate(void)
{
    /** bring GIO module out of reset */
    gioREG->GCR0      = 1;
    gioREG->ENACLR 	  = 0xFF;
    gioREG->LVLCLR    = 0xFF;

    // Set the pin as input
    gioPORTA->DIR &= ~(1 << FORCED_UPDATE_PIN);

    // Enable the pull up/down.
    gioPORTA->PULDIS &= ~(1 << FORCED_UPDATE_PIN);

    // Enable the weak pull up.
    gioPORTA->PSL |= 1 << FORCED_UPDATE_PIN;

    // Check the pin to see if an update is being requested.

    if ((gioPORTA->DIN & (0x1 << FORCED_UPDATE_PIN) ) == 0)
    {
        // Remember that this was a forced update.
//        g_ulForced = 1;
        return(1);
    }

    // No update is being requested so return 0.
    return(0);
}
#endif

/* USER CODE END */
