/*******************************************************************************
 * (c) Copyright 2010 Microsemi Corporation.  All rights reserved.
 *
 *  Modbus Server TCP on lwIP TCP/IP stack with freeRTOS Application demo
 *  for SmartFusion
 *
 *
 * Author : Corporate Application Team
 * Rev    : 1.0
 *
 *******************************************************************************/

/**************************************************************************/
/* Standard Includes */
/**************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/**************************************************************************/
/* RTOS Includes */
/**************************************************************************/
#include "FreeRTOS.h"
#include "task.h"



/* ------------------------ FreeModbus includes ------------------------- */
#include "mb.h"

/**************************************************************************/
/* lwIP TCP/IP Stack Includes */
/**************************************************************************/
#include "cpu_types.h"
#include "conf_eth.h"
#include "ppp/ppp.h"
#include "lwip/api.h"

/**************************************************************************/
/* Firmware Includes */
/**************************************************************************/
#include "mss_ethernet_mac.h"
#include "./drivers/mss_watchdog/mss_watchdog.h"

#define PPP_AUTH_ENABLED        0
#define PPP_USER                "freemodbus"
#define PPP_PASS                "insecure"

/* ----------------------- Type definitions ---------------------------------*/

#define PHY_ADDRESS			       1
/* Demo file headers. */
extern unsigned char               my_ip[4];
uint32_t mac_cfg;
extern unsigned int                num_pkt_rx;
extern unsigned char               ip_known;
extern unsigned char               dhcp_ip_found;

/* Priority definitions for most of the tasks in the demo application. */
#define USER_RX_BUFF_SIZE	       1600
#define OPEN_IP 1
#define PROG                    "FreeModbus"


extern void prvlwIPInit( void );
void show_ip()
{
    printf( "Successfully requested IP addr \n\r" );

    if( (my_ip[0] == 192) && (my_ip[1]==168)&& (my_ip[2]==0) && (my_ip[3]==14))
    {
        printf( "Static IP address: " );
    }
    else
    {
        printf( "Dynamic/Open IP address: " ); 
    }
    printf( "%d.%d.%d.%d \n\r", my_ip[0], my_ip[1], my_ip[2], my_ip[3] );
}

void init_mac()
{
	uint32_t time_out = 0;
	int32_t i;
	int32_t rx_size;
    uint8_t rx_buffer[USER_RX_BUFF_SIZE];
    
	portCHAR MacAddress[6];

	   /* Default MAC addr. */
    MacAddress[0] = ETHERNET_CONF_ETHADDR0;
    MacAddress[1] = ETHERNET_CONF_ETHADDR1;
	MacAddress[2] = ETHERNET_CONF_ETHADDR2;
	MacAddress[3] = ETHERNET_CONF_ETHADDR3;
	MacAddress[4] = ETHERNET_CONF_ETHADDR4;
	MacAddress[5] = ETHERNET_CONF_ETHADDR5;
   

    MSS_MAC_init(PHY_ADDRESS );
	/*
	 * Configure the MAC.
	 */
	mac_cfg = MSS_MAC_get_configuration();

	mac_cfg &= ~(MSS_MAC_CFG_STORE_AND_FORWARD | MSS_MAC_CFG_PASS_BAD_FRAMES );

	mac_cfg |=
          MSS_MAC_CFG_RECEIVE_ALL |
          MSS_MAC_CFG_PROMISCUOUS_MODE |
          MSS_MAC_CFG_FULL_DUPLEX_MODE |
          MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE |
          MSS_MAC_CFG_THRESHOLD_CONTROL_00;

	MSS_MAC_configure(mac_cfg );

	MSS_MAC_set_mac_address((uint8_t *)MacAddress);

	ip_known = 0;
	num_pkt_rx = 0;
	time_out = 0;
	for (i = 0; i < 1600; i++)
	{
		rx_buffer[i] = 0;
	}
	
#ifdef OPEN_IP
	do{

    	send_bootp_packet(0);
    	do {		    		
			rx_size = MSS_MAC_rx_pckt_size();
			time_out++;
			if(dhcp_ip_found)
			   break;//goto here;
    	}while ( rx_size == 0 && (time_out < 3000000));
		MSS_MAC_rx_packet( rx_buffer, USER_RX_BUFF_SIZE, MSS_MAC_BLOCKING );
		num_pkt_rx++;		
		process_packet( rx_buffer );
    }while((!dhcp_ip_found) && (time_out < 7000000));
#endif
    show_ip();
} // End of ethernet


void vMBServerTask( void *arg )
{
    eMBErrorCode    xStatus;

    for( ;; )
    {
        if( eMBTCPInit( MB_TCP_PORT_USE_DEFAULT ) != MB_ENOERR )
        {
            printf("can't initialize modbus stack!\r\n");
        }
        else if( eMBEnable(  ) != MB_ENOERR )
        {
            printf("can't enable modbus stack!\r\n");
        }
        else
        {
            do
            {
                xStatus = eMBPoll(  );
            }
            while( xStatus == MB_ENOERR );
        }
        printf("Disabling modbus stack!\r\n");
        /* An error occured. Maybe we can restart. */
        ( void )eMBDisable(  );
        printf("Closing modbus stack!\r\n");
        ( void )eMBClose(  );

    }
}

int main( void )
{
	MSS_WD_disable();
    printf("SmartFusion Modbus Demo\n\r");
    printf("Initializing the MAC and getting IP Address\n\r");

    ACE_init();

    init_mac();

	/* Setup lwIP. & Starts the vMBServerTask after TCP Task is created */
	prvlwIPInit();

	/* Enabling the M3 SysTick TImer in SF */ 
	*(volatile unsigned long *)0xE000E010 = 0x7;    
    *(volatile unsigned long *)0xE0042038 = 0x31000000;    
    /* Starts the FreeRTOS Scheduler */
	vTaskStartScheduler();
    printf("Should Never Come here\n\r");
	return 0;
}

