/***********************************************************************************************
* Company: Microsemi Corporation
*
* File: main.c
* File history:
*      Revision: 1.0 Date: May 4, 2010 
* 
* Description: 
*
* This code enables the Fabric interrupt. And implements the Interuupt handler functionality for 
* this interrupt.
*
* Author: Pavan Marisetti
*         pavan.marisetti@microsemi.com
*         Corporate Applications Engineering
*
************************************************************************************************/ 

/***********************************************************************************************
 Including Directories
************************************************************************************************/
#include <stdio.h>
#include "../drivers/mss_uart/mss_uart.h"
#include "../drivers/mss_watchdog/mss_watchdog.h"
#define  FABRIC_INT_CTRL_BASE_ADDR 0x40050000
#define  FABRIC_GPIO_BASE_ADDR 0x40050100
#define  FABRIC_INTR_ENBL 0xFFFFFFFF
#define  FABRIC_INTR_CLR 0xFFFFFFFF
#define  FABRIC_INTR_ENBL_OFF_ADDR 0x00000020
#define  FABRIC_INTR_STAT_OFF_ADDR 0x0000002C
#define  FABRIC_INTR_CLR_OFF_ADDR 0x00000080


/************************************************************************************************
 Interrupt Handlers
*************************************************************************************************/

/* Fabric Interrupt Handler */
/* This Interrupt handler executes upon the occurrence of
   Fabric interrupt, which is from the FPGA Fabric.
   This function reads the status register from the FPGA fabric
   and checks for the Interrupt source. It prints source of the
   interrupt to the hyperterminal */
void Fabric_IRQHandler( void )
{
    uint32_t read_data;

    /* reading Interrupt Status register from Interrupt controller in FPGA fabric */
    read_data = (*((uint32_t volatile *)(FABRIC_INT_CTRL_BASE_ADDR + FABRIC_INTR_STAT_OFF_ADDR)));
    /* Identifying the source of the interrupt */
    if(read_data == 1)
    {
        printf("Timer 1 Interrupt Occurred\n\r");
        read_data = 0;
    }
    else if(read_data == 2)
    {
        printf("Timer 2 Interrupt Occurred \n\r");
        read_data = 0;
    }
    else if(read_data == 3)
    {
        printf("Timer 1 and Timer 2 Interrupts Occurred Simultaneously\n\r");
        read_data = 0;
    }
    else if(read_data == 4)
    {
        printf("Switch Interrupt Occurred \n\r");
        read_data = 0;
    }
    else if(read_data == 5)
    {
        printf("Timer 1 and Switch Interrupts Occurred Simultaneously\n\r");
        read_data = 0;
    }
    else if(read_data == 6)
    {
        printf("Timer 2 and Switch Interrupts Occurred Simultaneously\n\r");
        read_data = 0;
    }
    else if(read_data == 7)
    {
        printf("Timer 1, Timer 2 and Switch Interrupts Occurred Simultaneously\n\r");
        read_data = 0;
    }

    /* Clearing the Interrupts in the FPGA */
    (*((uint32_t volatile *)(FABRIC_GPIO_BASE_ADDR + FABRIC_INTR_CLR_OFF_ADDR)) = FABRIC_INTR_CLR);

    NVIC_ClearPendingIRQ( Fabric_IRQn );

  }

/************************************************************************************************
 Function Main
*************************************************************************************************/

int main()
{

	/* Watchdog Disabling function*/
    MSS_WD_disable();
     /* Enabling Fabric Interrupt*/
    NVIC_EnableIRQ(Fabric_IRQn);


    /* Configuring the Interrupt control register in FPGA fabric
     * This will enable the Interrupt in the FPGA*/
    (*((uint32_t volatile *)(FABRIC_INT_CTRL_BASE_ADDR + FABRIC_INTR_ENBL_OFF_ADDR)) = FABRIC_INTR_ENBL);
    for(;;)
    {
    }
    return(0);

}
/************************************************************************************************
 End of function Main
*************************************************************************************************/
