//******************************************************************************
//* Ping test application.                                                     *
//******************************************************************************
#include <xparameters.h>
#include <mb_interface.h>
#include <xintc_l.h>
#include <xil_cache.h>
#include "enc424j600/logsys_ethernet.h"
#include "udp/netif.h"
#include "udp/udp.h"
#include "udp/timer.h"

//Network interface structures.
netif_data netif1;


void ApplicationInit();


//******************************************************************************
//* Ethernet driver functions.                                                 *
//******************************************************************************
unsigned long ethernet_init(pnetif_data netif)
{
    //Initialize the ENC424J600.
    netif->nextRxPacketPtr = 0;
    EncInitialize(netif->baseaddr);
    //Set the size of the RX buffer in the ENC424J600.
    EncSetRxBufferSize(netif->baseaddr, 6 * 1024, &(netif->nextRxPacketPtr));
    //Read the MAC address.
    EncReadMacAddress(netif->baseaddr, netif->macaddr);
    //Initialize the Ethernet MAC.
    EncInitializeMac(netif->baseaddr, 0, 1518);

    return 0;
}

unsigned long ethernet_rx(pnetif_data netif)
{
	unsigned short len;

	//Receive a packet and store its length.
	EncReceivePacket(netif->baseaddr, netif->packet, &len, &(netif->nextRxPacketPtr));
	netif->rxbytes = len;

	return 0;
}

unsigned long ethernet_tx(pnetif_data netif)
{
	//Wait for the previous transfer to complete.
	EncWaitForTxComplete(netif->baseaddr);
	//Set the start address of the TX buffer.
	EncWriteReg16(netif->baseaddr, EGPWRPT, 0x0000);
	//Copy the data to the TX buffer.
	EncCopyToSram(netif->baseaddr, SRAM_GP_BUFFER, netif->packet, netif->txbytes);
	//Send the packet.
	EncTransmitPacket(netif->baseaddr, 0x0000, (unsigned short)netif->txbytes);

	return 0;
}


//******************************************************************************
//* Main program.                                                              *
//******************************************************************************
int main()
{
    unsigned char ipaddr[4];

    //Initialization.
    Xil_ICacheEnable();
    Xil_DCacheEnable();
    microblaze_enable_interrupts();
    XIntc_MasterEnable(XPAR_XPS_INTC_0_BASEADDR);
    timer_init(XPAR_PROC_BUS_0_FREQ_HZ);
    ApplicationInit();
    netif_init();

    //Register the network interfaces.
    ipaddr[0] = 192;
    ipaddr[1] = 168;
    ipaddr[2] = 2;
    ipaddr[3] = 50;
    netif_add(&netif1, XPAR_LOGSYS_PLB_ETH_IF_0_BASEADDR, 0, ipaddr, 0, ethernet_init, ethernet_rx, ethernet_tx);

    //Initialize the network interfaces.
    netif_start();

    //Handle the packet reception and transmission.
    while (1)
    {
    	netif_process_all();
    }

    return 0;
}
