
// 
// This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package.
//
//*****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
#include "driverlib/flash.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "driverlib/rom_map.h"
#include "utils/locator.h"
#include "utils/lwiplib.h"
#include "utils/uartstdio.h"
#include "utils/ustdlib.h"
#include "httpserver_raw/httpd.h"
#include "drivers/pinout.h"
#include "io.h"
#include "cgifuncs.h"
#include "lwip/inet.h"

//*****************************************************************************


//*****************************************************************************
//
// Defines for setting up the system clock.
//
//*****************************************************************************
#define SYSTICKHZ               100
#define SYSTICKMS               (1000 / SYSTICKHZ)

//*****************************************************************************
//
// Interrupt priority definitions.  The top 3 bits of these values are
// significant with lower values indicating higher priority interrupts.
//
//*****************************************************************************
#define SYSTICK_INT_PRIORITY    0x80
#define ETHERNET_INT_PRIORITY   0xC0

//struct ip_addr *udpDestIpAddr;
 uint32_t sourceaddr, netmask,gateway;
 struct ip_addr udpDestIpAddr;

//*****************************************************************************
//
// A set of flags.  The flag bits are defined as follows:
//
//     0 -> An indicator that the animation timer interrupt has occurred.
//
//*****************************************************************************
#define FLAG_TICK            0
static volatile unsigned long g_ulFlags;

//*****************************************************************************
//
// External Application references.
//
//*****************************************************************************

extern void udp_init(void);



//*****************************************************************************
//
// The current IP address.
//
//*****************************************************************************
uint32_t g_ui32IPAddress;

//*****************************************************************************
//
// The system clock frequency.  Used by the SD card driver.
//
//*****************************************************************************
uint32_t g_ui32SysClock;



struct udp_pcb *my_pcb;
struct pbuf* pbuf1;
char buf [120];

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif



//*****************************************************************************
//
// The interrupt handler for the SysTick interrupt.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{
    //
    // Call the lwIP timer handler.
    //
    lwIPTimer(SYSTICKMS);
}


//*****************************************************************************
//
// 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);
}

//*****************************************************************************
//
// Required by lwIP library to support any host-related timer functions.
//
//*****************************************************************************
void
lwIPHostTimerHandler(void)
{
    uint32_t ui32Idx, ui32NewIPAddress;

    //
    // Get the current IP address.
    //
    ui32NewIPAddress = lwIPLocalIPAddrGet();

    //
    // See if the IP address has changed.
    //
    if(ui32NewIPAddress != g_ui32IPAddress)
    {
        //
        // See if there is an IP address assigned.
        //
        if(ui32NewIPAddress == 0xffffffff)
        {
            //
            // Indicate that there is no link.
            //
            UARTprintf("Waiting for link.\n");
        }
        else if(ui32NewIPAddress == 0)
        {
            //
            // There is no IP address, so indicate that the DHCP process is
            // running.
            //
            UARTprintf("Waiting for IP address.\n");
        }
        else
        {
            //
            // Display the new IP address.
            //
            UARTprintf("IP Address: ");
            DisplayIPAddress(ui32NewIPAddress);
            UARTprintf("\n");
            UARTprintf("Open a browser and enter the IP address.\n");

        }

        //
        // Save the new IP address.
        //
        g_ui32IPAddress = ui32NewIPAddress;
    }

    //
    // If there is not an IP address.
    //
    if((ui32NewIPAddress == 0) || (ui32NewIPAddress == 0xffffffff))
    {
        //
        // Loop through the LED animation.
        //

        for(ui32Idx = 1; ui32Idx < 100; ui32Idx++) //was < 17
        {

            //
            // Toggle the GPIO
            //
            MAP_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1,
                    (MAP_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1) ^
                     GPIO_PIN_1));

            SysCtlDelay(g_ui32SysClock/(ui32Idx << 1));

        }
    }
}

//*****************************************************************************
//
// This example demonstrates the use of the Ethernet Controller and lwIP
// TCP/IP stack to control various peripherals on the board via a web
// browser.
//
//*****************************************************************************
	int	main(void)
	{

	    uint8_t pui8MACArray[8];
	    //struct udp_pcb *socketfd = NULL;

	    //
	    // Make sure the main oscillator is enabled because this is required by
	    // the PHY.  The system must have a 25MHz crystal attached to the OSC
	    // pins.  The SYSCTL_MOSC_HIGHFREQ parameter is used when the crystal
	    // frequency is 10MHz or higher.
	    //
	    SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ);

	    //
	    // Run from the PLL at 120 MHz.
	    //
	    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
	                                             SYSCTL_OSC_MAIN |
	                                             SYSCTL_USE_PLL |
	                                             SYSCTL_CFG_VCO_480), 120000000);

	    //
	    // Configure the device pins.
	    //
	    PinoutSet(true, false);

	    //
	    // Configure debug port for internal use.
	    //
	    UARTStdioConfig(0, 115200, g_ui32SysClock);

	    //
	    // Clear the terminal and print a banner.
	    //
	    UARTprintf("\033[2J\033[H");
	    UARTprintf("Ethernet IO Example\n\n");


	   	    //
	    // Configure SysTick for a periodic interrupt.
	    //
	    MAP_SysTickPeriodSet(g_ui32SysClock / SYSTICKHZ);
	    MAP_SysTickEnable();
	    MAP_SysTickIntEnable();

	    pui8MACArray[0] = 0x01;
	    pui8MACArray[1] = 0x02;
	    pui8MACArray[2] = 0x03;
	    pui8MACArray[3] = 0x01;
	    pui8MACArray[4] = 0x02;
	    pui8MACArray[5] = 0x03;

    //
    // Initialze the lwIP library, using DHCP.
	    sourceaddr=inet_addr("28.1.17.172");
	                netmask=inet_addr("0.0.255.255");
	          gateway=inet_addr("3.0.17.172");

	          lwIPInit(g_ui32SysClock,pui8MACArray,sourceaddr,netmask,gateway,IPADDR_USE_STATIC);

    //LocatorInit();
    //LocatorMACAddrSet(pui8MACArray);


  udp_init();

    struct udp_pcb * mypcb;
    mypcb = udp_new();
    if (mypcb == NULL)
    {
        UARTprintf("udp failed.\n");
    }
    else
    {
        UARTprintf("udp up.\n");
    }

    if (udp_bind(mypcb, IP_ADDR_ANY, 8760) != ERR_OK)
    {
        UARTprintf("udp bind failed.\n");
    }
    pbuf1 = pbuf_alloc(PBUF_TRANSPORT, 1024, PBUF_RAM);
    //
    // Set the interrupt priorities.  We set the SysTick interrupt to a higher
    // priority than the Ethernet interrupt to ensure that the file system
    // tick is processed if SysTick occurs while the Ethernet handler is being
    // processed.  This is very likely since all the TCP/IP and HTTP work is
    // done in the context of the Ethernet interrupt.
    //
    MAP_IntPrioritySet(INT_EMAC0, ETHERNET_INT_PRIORITY);
    MAP_IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY);

    //
    // Pass our tag information to the HTTP server.
    //

    //
    while(1)
    {

        // Transmit to UDP
        //
        static int n = 0;
        pbuf1->payload = (void*)buf;
        pbuf1->tot_len = 1024;
        pbuf1->len = 1024;
        buf[0] = 0x10;
        buf[1] = 0;
        usprintf(&buf[4], "************CORNET**************", n++);
        IP4_ADDR(&udpDestIpAddr,172,17,2,30);
        udp_sendto(mypcb, pbuf1,&udpDestIpAddr,1001);

        //udp_sendto(mypcb, pbuf1,IP_ADDR_BROADCAST,1001);

    }
    pbuf_free(pbuf1);
}
