/*******************************************************************************
 * (c) Copyright 2009 Actel Corporation.  All rights reserved.
 *
 *  TBD
 *
 *
 * Author : Actel's Corporate Application Team
 * Rev    : 1.0.0.0
 *
 *******************************************************************************/

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

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

/**************************************************************************/
/* Firmware Includes */
/**************************************************************************/

#include "hal.h"
#include "core_uart_apb.h"
#include "core_gpio.h"
#include "cortex_nvic.h"
#include "core_i2c.h"
#include "coreai.h"

/**************************************************************************/
/* System Memory Map */
/**************************************************************************/

#include "platform.h"

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

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

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

xSemaphoreHandle stdSemHndl = NULL, htSemHndl = NULL;
xSemaphoreHandle webSemHndl = NULL, ledSemHndl = NULL;
xSemaphoreHandle switchOneSemHndl = NULL;

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

/**************************************************************************/
/*Extern Declarations*/
/**************************************************************************/

extern void led_task(void *para);
extern void ace_task(void *para);
extern void web_task(void *para);
extern void standalone_task(void *para);
extern void hyperterminal_task(void *para);
extern void switch_one_task(void *para);

extern void OLED_init(void );
extern void switch_init(void);
extern void led_initialization(void);
extern void ACE_Initialization(void);
extern void oled_welcome_display(void);

/**************************************************************************/
/*TBD*/
/**************************************************************************/

UART_instance_t g_uart;
gpio_instance_t g_gpio;
i2c_instance_t g_i2c_inst;

#define BAUD_VALUE_57600    42


/**************************************************************************/
/*Functions for Interrupt Handlers */
/**************************************************************************/

/**************************************************************************/
/*Interrupt handler for the functionality of switch 01 */
/*Switch 1 push scroll through menu */
/**************************************************************************/
void IRQ0_IRQHandler( void )
{
    static signed portBASE_TYPE xHigherPriorityTaskWoken;

    xSemaphoreGiveFromISR( stdSemHndl, &xHigherPriorityTaskWoken );

    /*Clearing the IRQ request made by switch01 SW1*/
    GPIO_clear_irq( &g_gpio, GPIO_4 );
    NVIC_clear_interrupt( NVIC_IRQ_0 );
}

/**************************************************************************/
/*Interrupt handler for the functionality of switch 02 */
/*Switch 02 selects the functionality of scrolling menu */
/**************************************************************************/

void IRQ1_IRQHandler( void )
{
    static signed portBASE_TYPE xHigherPriorityTaskWoken;

    xSemaphoreGiveFromISR( switchOneSemHndl, &xHigherPriorityTaskWoken );

    /*Clearing the IRQ request made by switch02 SW2*/
    GPIO_clear_irq( &g_gpio, GPIO_5 );
    NVIC_clear_interrupt( NVIC_IRQ_1 );

}

/**************************************************************************/
/* Function to initialization all necessary hardware components for this*/
/* demo*/
/**************************************************************************/

void init_system()
{
    /* Initialization of NVIC and Enabling NVIC interrupts*/
    NVIC_init();
    NVIC_enable_interrupt( NVIC_IRQ_0 );
    NVIC_enable_interrupt( NVIC_IRQ_1 );
    NVIC_enable_interrupt( NVIC_IRQ_2 );
    NVIC_enable_interrupt( NVIC_IRQ_3 );

	/* Initialize the GPIO */
	GPIO_init( &g_gpio, COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );

	/* Initialize and configure UART0. */
	UART_init( &g_uart, COREUARTAPB_BASE_ADDR, BAUD_VALUE_57600, (DATA_8_BITS | NO_PARITY) );

	/* Initialize the OLED */
    OLED_init();

    /* GPIO inits for the LEDs */
    led_initialization();

    /* ACE Initialization */
    CAI_init( COREAI_BASE_ADDR );

    /* Configuring the GPIOs for the SWITCHES SW1 and SW2 */
    switch_init();

} 

/****************************************************************/
/* Entry to Main form user bootcode                             */
/****************************************************************/

int main()
{
    /* Initialization all necessary hardware components */
    init_system();
    /* Display the welcome string on OLED */
    oled_welcome_display();
    /* Creating the semaphores for the flow control of the demo */
    stdSemHndl       = xSemaphoreCreateCounting( 1, 0);
    webSemHndl       = xSemaphoreCreateCounting( 1, 0);
    ledSemHndl       = xSemaphoreCreateCounting( 1, 0);
    switchOneSemHndl = xSemaphoreCreateCounting( 1, 0);

    /* Creating the tasks for the functional requirement of the demo */
    /* This task is responsible for controlling the demo using the
     * SW1 and SW2 switch inputs from the user */
    xTaskCreate( standalone_task,
                 ( signed portCHAR * ) "standalone_task",
                 configMINIMAL_STACK_SIZE,
                 NULL,
                 tskIDLE_PRIORITY + 1,
                 &stdTaskHndl );
    /* This task is responsible for controlling the demo using the
     * HyperTerminal inputs from the user */
    xTaskCreate( hyperterminal_task,
                 ( signed portCHAR * ) "hyperterminal_task",
                 configMINIMAL_STACK_SIZE,
                 NULL,
                 tskIDLE_PRIORITY +1,
                 &htTaskHndl );
    /* This task is to test the LED functionality */
    xTaskCreate( led_task,
                 ( signed portCHAR * ) "led_task",
                 configMINIMAL_STACK_SIZE,
                 NULL,
                 tskIDLE_PRIORITY +1,
                 &ledTaskHndl );
    /* This task is to test the ACE functionality */
    xTaskCreate( ace_task,
                 ( signed portCHAR * ) "ace_task",
                 configMINIMAL_STACK_SIZE * 2,
                 NULL,
                 tskIDLE_PRIORITY +1,
                 &aceTaskHndl );
    /* 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( switch_one_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 0;

}
