/*******************************************************************************
 * (c) Copyright 2008 Actel Corporation.  All rights reserved.
 *
 * Burn-in Design 1.0.101
 * 
 *
 * SVN $Revision:$
 * SVN $Date:$
 */
#include "main.h"
#include "mss_uart.h"
#include "DirectC/dpuser.h"
#include "DirectC/dpalg.h"
#include "mss_watchdog.h"
#include "mss_iap.h"
#ifdef ENABLE_OLED
   #include "./Drivers/i2c_driver/i2c.h"
   #include "./Drivers/oled_driver/oled.h"
#endif

/**************************************************************************/
/* RTOS Includes */
/**************************************************************************/

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

/**************************************************************************/
/* Preprocessor Macros*/
/**************************************************************************/

#define SYS_TICK_CTRL_AND_STATUS_REG      0xE000E010
#define SYS_TICK_CONFIG_REG               0xE0042038
#define SYS_TICK_FCLK_DIV_32_NO_REF_CLK   0x31000000
#define ENABLE_SYS_TICK                   0x7

/**************************************************************************/
/*Declaration of global variables*/
/**************************************************************************/

xSemaphoreHandle webSemHndl       = NULL;
xSemaphoreHandle switchOneSemHndl = NULL;

xTaskHandle stdTaskHndl = NULL, htTaskHndl = NULL, switchOneTaskHndl = NULL;
xTaskHandle webTaskHndl = NULL, aceTaskHndl = NULL, ledTaskHndl = NULL;


/**************************************************************************/
/*Extern Declarations*/
/**************************************************************************/
extern DPULONG SocketConnect;
extern void web_task(void *para);

#ifdef ENABLE_OLED
   /* Configuration for OLED */
   #define OLED_I2C_INSTANCE    &g_mss_i2c0
   struct oled_data                write_data;
   #define FIRST_CHARACTER 0
   /**************************************************************************/
   /* Functions to show the menu on OLED */
   /**************************************************************************/
   void menu_show(char *line1, char *line2)
   {
      write_data.string1        = line1;
      write_data.string2        = line2;
      OLED_write_data(&write_data,BOTH_LINES);
      return;
   }
#endif
unsigned long ulGetRunTimeCounterValue( void )
{
   	return 0UL;
}
void vApplicationMallocFailedHook(void) {
	/* Called if a call to pvPortMalloc() fails because there is insufficient
	 free memory available in the FreeRTOS heap.  pvPortMalloc() is called
	 internally by FreeRTOS API functions that create tasks, queues, software
	 timers, and semaphores.  The size of the FreeRTOS heap is set by the
	 configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
	for (;;)
		;
}
void vApplicationIdleHook( void )
{
	/* This function is called on each cycle of the idle task.  In this case it
	does nothing useful */

}
void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed char *pcTaskName) {
	(void) pcTaskName;
	(void) pxTask;

	/* Run time stack overflow checking is performed if
	 configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
	 function is called if a stack overflow is detected. */
	for (;;)
		;
}
/*-----------------------------------------------------------*/

void vMainConfigureTimerForRunTimeStats(void) {
	/* This function is not used by the Blinky build configuration, but needs
	 to be defined as the Blinky and Full build configurations share a
	 FreeRTOSConfig.h header file. */
}
void action_menu(void)
{
   uint8_t tx_data[24][40] = {
                                {"\r\n\r\n   Action:                    "},
                                {"\r\n01 DEVICE_INFO                    "},
                                {"\r\n02 READ_IDCODE                    "},
                                {"\r\n03 ERASE                          "},
                                {"\r\n04 ERASE_ALL                      "},
                                {"\r\n05 PROGRAM                        "},
                                {"\r\n06 VERIFY                         "},
                                {"\r\n07 ENC_DATA_AUTHENTICATION        "},
                                {"\r\n08 ERASE_ARRAY                    "},
                                {"\r\n09 PROGRAM_ARRAY                  "},
                                {"\r\n10 VERIFY_ARRAY                   "},
                                {"\r\n11 ERASE_FROM                     "},
                                {"\r\n12 PROGRAM_FROM                   "},
                                {"\r\n13 VERIFY_FROM                    "},
                                {"\r\n14 ERASE_SECURITY                 "},
                                {"\r\n15 PROGRAM_SECURITY               "},
                                {"\r\n16 PROGRAM_NVM                    "},
                                {"\r\n17 VERIFY_NVM                     "},
                                {"\r\n18 VERIFY_DEVICE_INFO             "},
                                {"\r\n19 READ_USERCODE                  "},
                                {"\r\n20 PROGRAM_NVM_ACTIVE             "},
                                {"\r\n21 VERIFY_NVM_ACTIVE              "},
                                {"\r\n22 IS_CORE_CONFIGURED             "},
                                {"\r\n Enter 1,2,3,4 .. 22, accordingly "}
                             }; 
   uint8_t rx_data[2];
   uint8_t rx_size =0;
   uint8_t valid_entry = 0;
   MSS_UART_polled_tx (&g_mss_uart0, tx_data[0],sizeof(tx_data));
   while (!valid_entry)
   {
      do 
      {
         rx_size = MSS_UART_get_rx(&g_mss_uart0, &rx_data[1],1);
      }while(rx_size == 0);
      do 
      {
         rx_size = MSS_UART_get_rx(&g_mss_uart0, &rx_data[0],1);
      }while(rx_size == 0);
      Action_code = (rx_data[1] - 48) * 10 + (rx_data[0] - 48);
      if ((Action_code > 0 ) && (Action_code < 23))
      {
         valid_entry = 1;
      }
      else
      {
         dp_display_text("\n\rInvalid entry.  Try again. ");
      }
   }
   return;
}
void iap_task(void *para)
{
   while( 1 )
   {
      action_menu();
      #ifdef ENABLE_OLED
         menu_show("Action code","Received");
      #endif

      #ifdef ENABLE_DEBUG
         dp_display_text("\r\nPerforming IAP actions...");
      #endif
      enable_IAP();
      dp_top();

      #ifdef ENABLE_DEBUG
         dp_display_text("\r\nExit code = ");
         dp_display_value(error_code,DEC);
         dp_display_text("\r\n-------------------------------------------------------------------\r\n\r\n ");
      #endif
      disable_IAP();
   }
}

void main(void)
{
   /*--------------------------------------------------------------------------
   * Disable watchdog.
   */
   MSS_WD_disable();
   MSS_UART_init(&g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
   printf("\n Welcome to SmartFusion: Ethernet Demo \n\r");

   hardware_interface = IAP_SEL;
   /* This task is to test the 10/100 Ethernet MAC
    * functionality using the web server*/
   webSemHndl       = xSemaphoreCreateCounting( 1, 0);
   switchOneSemHndl = xSemaphoreCreateCounting( 1, 0);
   /* This task is to test the 10/100 Ethernet MAC
    * functionality using the web server*/
   xTaskCreate( web_task,
                ( signed portCHAR * ) "web_task",
                configMINIMAL_STACK_SIZE * 2,
                NULL,
                tskIDLE_PRIORITY +1,
                &webTaskHndl );

   /* This task is to test monitor the SW1 input and
   * show the menu to OLED*/
   xTaskCreate( iap_task,
                ( signed portCHAR * ) "Switch_one_task",
                configMINIMAL_STACK_SIZE,
                NULL,
                tskIDLE_PRIORITY +1,
                &switchOneTaskHndl );

   /* Enable the SYS TICK Timer and provide the divider and clock source
    * this is required to enable the RTOS tick */
   *(volatile unsigned long *)SYS_TICK_CTRL_AND_STATUS_REG = ENABLE_SYS_TICK;
   *(volatile unsigned long *)SYS_TICK_CONFIG_REG          = SYS_TICK_FCLK_DIV_32_NO_REF_CLK;

   /* Start the scheduler. */
   vTaskStartScheduler();

   /* Will only get here if there was not enough heap space to create the
   idle task. */
   printf("\n Test Case End: Should never Come here \n\r");
   return;
}

