/*******************************************************************************
 * (c) Copyright 2011 Microsemi Corporation.  All rights reserved.
 *
 *  ACE sampling Application demo for Smartfusion
 *
 *
 * Author : Pavan Marisetti
 *
 *******************************************************************************/

#include "./drivers/mss_ace/mss_ace.h"
#include "./drivers/mss_gpio/mss_gpio.h"

#define  FABRIC_BASE_ADDR 0x40050000


uint8_t                          Seq_interrupt_stat[2] = {0,0};
float                            Simul_VoltageMonitor_0_ADC0;
float                            Simul_VoltageMonitor_1_ADC0;
float                            Simul_VoltageMonitor_4_ADC1;
float                            Simul_VoltageMonitor_5_ADC1;
float                            Seq_VoltageMonitor_2_ADC0;
float                            Seq_VoltageMonitor_3_ADC0;
float                            Seq_VoltageMonitor_8_ADC0;
float                            Seq_VoltageMonitor_6_ADC1;
float                            Seq_VoltageMonitor_7_ADC1;

ace_channel_handle_t first_channel;
ace_channel_handle_t current_channel;
uint16_t adc_result;

/****************************************************************/
/* Analog test */
/* Function to update global variable related ACE values */
/****************************************************************/
void update_TwoADCs_values( ace_channel_handle_t channel_handle,
     uint16_t raw_value )
{
	channel_type_t channel_type;
    channel_type = ACE_get_channel_type( channel_handle );

    switch(channel_handle)
    {
        case VoltageMonitor_0:
           Simul_VoltageMonitor_0_ADC0 =  (float)ACE_convert_to_mV( channel_handle,
                                                         raw_value )/(float)1000;

         break;

        case VoltageMonitor_1:
             Simul_VoltageMonitor_1_ADC0 =  (float)ACE_convert_to_mV( channel_handle,
                                                             raw_value )/(float)1000;


             break;

       case VoltageMonitor_4:
            Simul_VoltageMonitor_4_ADC1 =  (float)ACE_convert_to_mV( channel_handle,
                                                            raw_value )/(float)1000;


            break;

       case VoltageMonitor_5:
            Simul_VoltageMonitor_5_ADC1 =  (float)ACE_convert_to_mV( channel_handle,
                                                            raw_value )/(float)1000;


            break;

        default:
            break;
    }

}

void update_seq_ADC_values( ace_channel_handle_t channel_handle,
     uint16_t raw_value )
{

	channel_type_t channel_type;
	ACE_clear_sse_irq(PC0_FLAG1);
	ACE_clear_sse_irq(PC0_FLAG2);
	channel_type = ACE_get_channel_type( channel_handle );

    switch(channel_handle)
    {
        case VoltageMonitor_2:
        	Seq_VoltageMonitor_2_ADC0 =  (float)ACE_convert_to_mV( channel_handle,
                                                         raw_value )/(float)1000;

        	break;

       case VoltageMonitor_3:
    	   Seq_VoltageMonitor_3_ADC0 =  (float)ACE_convert_to_mV( channel_handle,
                                                            raw_value )/(float)1000;

    	   break;
       case VoltageMonitor_6:
       	Seq_VoltageMonitor_6_ADC1 =  (float)ACE_convert_to_mV( channel_handle,
                                                        raw_value )/(float)1000;

       	break;

      case VoltageMonitor_7:
   	   Seq_VoltageMonitor_7_ADC1 =  (float)ACE_convert_to_mV( channel_handle,
                                                           raw_value )/(float)1000;

   	   break;

      default:
            break;
    }

}

void ACE_PC0_Flag0_IRQHandler(void)
{

	current_channel = ACE_get_first_channel();
    first_channel = current_channel;
    do
    {
        adc_result = ACE_get_ppe_sample( current_channel );
        update_TwoADCs_values( current_channel, adc_result );
        current_channel = ACE_get_next_channel( current_channel );
    } while ( current_channel != first_channel );

	ACE_clear_sse_irq(PC0_FLAG0);
	ACE_load_sse(seq_adc10);
	ACE_start_sse(seq_adc10);
	ACE_load_sse(seq_adc00);
	ACE_start_sse(seq_adc00);

}

void ACE_PC0_Flag1_IRQHandler(void)
{
	Seq_interrupt_stat[0] = 1;
	current_channel = ACE_get_first_channel();
    first_channel = current_channel;
    do
    {
        adc_result = ACE_get_ppe_sample( current_channel );
        update_seq_ADC_values( current_channel, adc_result );
        current_channel = ACE_get_next_channel( current_channel );
    } while ( current_channel != first_channel );
	ACE_clear_sse_irq(PC0_FLAG1);
	if((Seq_interrupt_stat[0] == 1) & (Seq_interrupt_stat[1] == 1))
	{
		(*((uint32_t volatile *)(FABRIC_BASE_ADDR)) = 0xFFFFFFFF);
	   ACE_load_sse(twoAdcs);
	   ACE_start_sse(twoAdcs);
	   Seq_interrupt_stat[0] = 0;
	   Seq_interrupt_stat[1] = 0;
	}
}

void ACE_PC1_Flag0_IRQHandler(void)
{
	Seq_interrupt_stat[1] = 1;
	current_channel = ACE_get_first_channel();
    first_channel = current_channel;
    do
    {
        adc_result = ACE_get_ppe_sample( current_channel );
        update_seq_ADC_values( current_channel, adc_result );
        current_channel = ACE_get_next_channel( current_channel );
    } while ( current_channel != first_channel );
	ACE_clear_sse_irq(PC0_FLAG1);
	if((Seq_interrupt_stat[0] == 1) & (Seq_interrupt_stat[1] == 1))
	{
		(*((uint32_t volatile *)(FABRIC_BASE_ADDR)) = 0xFFFFFFFF);
	   ACE_load_sse(twoAdcs);
	   ACE_start_sse(twoAdcs);
	   Seq_interrupt_stat[0] = 0;
	   Seq_interrupt_stat[1] = 0;
	}
}
int main()
{
	uint8_t gpio1_value = 1;

	/* Disable the Watch Dog Timer */
    MSS_WD_disable( );
    /* ACE Initialization */
    ACE_init();


    ACE_stop_sse(twoAdcs);
	ACE_stop_sse(seq_adc00);
	ACE_stop_sse(seq_adc10);

	ACE_enable_sse_irq(PC0_FLAG0);
    NVIC_EnableIRQ( ACE_PC0_Flag0_IRQn );

    ACE_enable_sse_irq(PC0_FLAG1);
    NVIC_EnableIRQ( ACE_PC0_Flag1_IRQn );

    ACE_enable_sse_irq(PC1_FLAG0);
    NVIC_EnableIRQ( ACE_PC1_Flag0_IRQn );
	ACE_load_sse(twoAdcs);
	ACE_start_sse(twoAdcs);

    MSS_GPIO_config(MSS_GPIO_1 , MSS_GPIO_OUTPUT_MODE );
 	MSS_GPIO_set_output(MSS_GPIO_1,gpio1_value);

	while(1)
     {
    	 ;
     }

	return 0;

}
