/*******************************************************************************
 *  emeter-main.c -
 *
 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 
 *  ALL RIGHTS RESERVED
 * 
*/

/*! \file emeter-structs.h */

#include <inttypes.h>
#include <stdlib.h>
#include <stdbool.h>
#if !defined(__MSP430__)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#if !defined(__TI_COMPILER_VERSION__)  &&  defined(__GNUC__)
#include <signal.h>
#endif
#include <math.h>
#if defined(__MSP430__)
#include <msp430.h>
#endif
#define __MAIN_PROGRAM__

#include "emeter-template.h"

#include <emeter-toolkit.h>
#include <emeter-metrology.h>

#if defined(IEC62056_SUPPORT)
#include <uart_comms.h>
#include <iec62056_46_user.h>
#include "emeter-iec62056.h"
#endif
#if defined(DLT645_SUPPORT)
#include "emeter-dlt645.h"
#endif

#if defined(TRNG_PURITY_TESTS)
#include "fips_tests.h"
#endif

#include "emeter-main.h"
#include "emeter-app.h"
#include "emeter-rtc.h"
#include "emeter-lcd.h"
#include "emeter-communication.h"
#include "emeter-dlt645.h"
#include "emeter-basic-display.h"
#include "emeter-keypad.h"
#include "emeter-autocal.h"


extern __interrupt void Dummy_Isr (void);
extern __interrupt void P1_Isr(void);
extern __interrupt void P2_Isr(void);
extern __interrupt void Timer1_A1_Isr(void);
extern __interrupt void Timer1_A0_Isr(void);
extern __interrupt void Timer0_A1_Isr(void);
extern __interrupt void Timer0_A0_Isr(void);
extern __interrupt void USCI_B0_Isr(void);
extern __interrupt void WDT_Isr(void);
extern __interrupt void VMON_Isr(void);



extern __interrupt void TI_MSPBoot_Comm_Isr(void);

#if defined(TEMPERATURE_SUPPORT)  &&  defined(TRNG_SUPPORT)  &&  defined(IEC62056_SUPPORT)
/* 16 byte salt for DLMS authentication exchanges */
uint8_t salt[16];
int salt_counter = 0;
#endif

#if defined(LCD_BARGRAPH_SUPPORT)
uint8_t bar_strength = 0;
#endif

#if !defined(NO_ENERGY_ACCUMULATION)
/* These are all the possible types of consumed energies */
#if NUM_PHASES == 1
energy_t energy_consumed[1][APP_TOTAL_ENERGY_BINS] = {0};
#else
energy_t energy_consumed[NUM_PHASES + 1][APP_TOTAL_ENERGY_BINS] = {0};
#endif
#endif

#if defined(SAG_SWELL_SUPPORT)
uint8_t sag_events[NUM_PHASES];
uint32_t sag_duration[NUM_PHASES]; 
uint8_t swell_events[NUM_PHASES];
uint32_t swell_duration[NUM_PHASES];
uint8_t phase_reverse;
#endif

static __inline__ int32_t abs32(int32_t x)
{
    return (x < 0)  ?  -x  :  x;
}

#if defined(BATTERY_MONITOR_SUPPORT)
void test_battery(void)
{
    P3DIR |= (BIT1);
    P3OUT &= ~(BIT1);
    battery_countdown = 1000;
    
    // Toggle LED1 in P1.0
    P2DIR |= BIT0;
}
#endif

#if defined(__IAR_SYSTEMS_ICC__)  ||  defined(__TI_COMPILER_VERSION__)
void main(void)
#else
int main(int argc, char *argv[])
#endif
{
#if NUM_PHASES == 1
#define ph 0
#else
    int ph;
#endif
#if defined(TRNG_SUPPORT)
    uint16_t randy;
#endif
#if defined(TRNG_PURITY_TESTS)
    int fips_result;
#endif
    static int32_t x;
    int phase_state;
#if (defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(ON_REVERSED_SELECT_POSITIVE_READING))  ||  defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
    int metrology_state;
#endif

#if !defined(__MSP430__)
    if (start_host_environment(argc, argv) < 0)
        exit(2);
#endif
    system_setup();
#if defined(TRNG_PURITY_TESTS)
    fips_init();
    fips_result = -1;
#endif

#if defined(IEC62056_SUPPORT)
    serial_timer_init();
    iec62056_init();
#endif

    metrology_init();

#if defined(ESP_SUPPORT)
    esp_start_measurement();
#endif

#if defined(MULTI_RATE_SUPPORT)
    tariff_initialise();
#endif
      // Toggle LED1 in P1.0
    P2DIR |= BIT0;
    for (;;)
    {

//    P2OUT |= BIT0;
//    P2OUT &= ~BIT0;   
    
//    __delay_cycles(500000);
//    P2OUT &= ~BIT0;
//    __delay_cycles(500000);
    P2OUT |= BIT0;
//    __delay_cycles(500000);
//    P2OUT &= ~BIT0;
    
        kick_watchdog();

#if defined(IEC62056_SUPPORT)
        iec62056_service();
#endif
#if defined(DLT645_SUPPORT)
        dlt645_service();
#endif

#if defined(TRNG_SUPPORT)
    #if defined(TRNG_PURITY_TESTS)
        /* Perform FIPS testing of the true random number generator */
        if (trng(&randy) == 0)
        {
            if ((fips_result = fips_test(randy)) != -1)
            {
                for (;;)
                  /* Stick here */;
            }
        }
    #elif defined(IEC62056_SUPPORT)
        if (trng(&randy) == 0)
        {
            /* Roll around the 16 byte salt buffer, updating it little by little */
            salt[salt_counter++] = randy >> 8;
            salt[salt_counter++] = randy;
            if (salt_counter >= 16)
                salt_counter = 0;
        }
    #endif
#endif
#if !defined(__MSP430__)
        /* In the host environment we need to simulate interrupts here */
        adc_interrupt();
#endif
#if NUM_PHASES > 1
        for (ph = 0;  ph < NUM_PHASES;  ph++)
#endif
        {
            /* Unless we are in normal operating mode, we should wait to be
               woken by a significant event from the interrupt routines. */
#if defined(__MSP430__)
            if (operating_mode != OPERATING_MODE_NORMAL)
                _BIS_SR(LPM0_bits);
#endif
#if defined(POWER_DOWN_SUPPORT)
            if (operating_mode == OPERATING_MODE_POWERFAIL)
                switch_to_powerfail_mode();
#endif
#if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
            if (!meter_calibrated())
                enable_ir_receiver();
#endif
            phase_state = phase_status(ph);
#if (defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(ON_REVERSED_SELECT_POSITIVE_READING))  ||  defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
            metrology_state = metrology_status();
#endif
            if ((phase_state & PHASE_STATUS_NEW_LOG))
            {
                /* The background activity has informed us that it is time to
                   perform a block processing operation. */
                /* We can only do real power assessment in full operating mode */
                calculate_phase_readings(ph);
                x = active_power(ph);
                if (abs32(x) < RESIDUAL_POWER_CUTOFF  ||  (phase_state & PHASE_STATUS_V_OVERRANGE))
                {
                    x = 0;
                    /* Turn off the LEDs, regardless of the internal state of the
                       reverse and imbalance assessments. */
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                    metrology_state &= ~METROLOGY_STATUS_REVERSED;
                    clr_reverse_current_indicator();
#endif
#if defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
                    metrology_state &= ~METROLOGY_STATUS_EARTHED;
                    clr_earthed_indicator();
#endif
                }
                else
                {
                    if (operating_mode == OPERATING_MODE_NORMAL)
                    {
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)  &&  defined(ON_REVERSED_SELECT_POSITIVE_READING)
                        if ((phase_state & PHASE_STATUS_REVERSED))
                        {
                            metrology_state |= METROLOGY_STATUS_REVERSED;
                            set_reverse_current_indicator();
                            phase_reverse = true;
                        }
                        else
                        {
                            metrology_state &= ~METROLOGY_STATUS_REVERSED;
                            clr_reverse_current_indicator();
                            phase_reverse = false;
                        }
#endif
#if defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
                        if ((phase_state & PHASE_STATUS_UNBALANCED))
                        {
                            metrology_state |= METROLOGY_STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            metrology_state &= ~METROLOGY_STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
#endif
                    }
#if defined(LIMP_MODE_SUPPORT)
                    else
                    {
    #if defined(PHASE_REVERSED_DETECTION_SUPPORT)
                        /* We cannot tell forward from reverse current in limp mode,
                           so just say it is not reversed. */
                        metrology_state &= ~METROLOGY_STATUS_REVERSED;
                        clr_reverse_current_indicator();
    #endif
    #if defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
                        /* We are definitely in the unbalanced state, but only set
                           the indicator if we have persistence checked, and the current
                           is sufficient to sustain operation. */
                        if ((phase_state & PHASE_STATUS_UNBALANCED)  &&  rms_current(ph) >= LIMP_MODE_MINIMUM_CURRENT)
                        {
                            metrology_state |= METROLOGY_STATUS_EARTHED;
                            set_earthed_indicator();
                        }
                        else
                        {
                            metrology_state &= ~METROLOGY_STATUS_EARTHED;
                            clr_earthed_indicator();
                        }
    #endif
    #if defined(LIMP_MODE_SUPPORT)  &&  defined(IEC1107_SUPPORT)
                        /* Only run the IR interface if we are sure there is enough power from the
                           supply to support the additional current drain. If we have not yet been
                           calibrated we had better keep the IR port running so we can complete the
                           calibration. */
                        if (rms_current(ch) >= LIMP_MODE_MINIMUM_CURRENT_FOR_IR
                            ||
                            !meter_calibrated())
                        {
                            enable_ir_receiver();
                        }
                        else
                        {
                            disable_ir_receiver();
                        }
    #endif
                    }
#endif
                }
#if defined(SUPPORT_ONE_POINT_AUTOCALIBRATION)
                if (ph == 0)
                    autocalibrate();
#endif
            }
#if defined(LIMP_MODE_SUPPORT)
            metrology_limp_normal_detection();
#endif
        }
#if NUM_PHASES > 1  &&  defined(NEUTRAL_MONITOR_SUPPORT)  &&  defined(IRMS_SUPPORT)
        if ((phase_status(FAKE_PHASE_NEUTRAL) & PHASE_STATUS_NEW_LOG))
        {
            /* The background activity has informed us that it is time to
               perform a block processing operation. */
            calculate_neutral_readings();
        }
#endif

#if defined(MULTI_RATE_SUPPORT)
        tariff_management();
#endif

#if defined(RTC_SUPPORT)
        /* Do display and other housekeeping here */
        if ((rtc_status & RTC_STATUS_TICKER))
        {
            /* Two seconds have passed */
            /* We have a 2 second tick */
            rtc_status &= ~RTC_STATUS_TICKER;
    #if defined(LCD_BARGRAPH_SUPPORT)
            bar_graph(bar_strength);
            if (++bar_strength > 6)
                bar_strength = 1;
    #endif
    #if defined(LCD_DISPLAY_SUPPORT)
            /* Update the display, cycling through the phases */
            update_display();
    #endif
    #if !defined(__MSP430_HAS_RTC_C__)  &&  defined(RTC_SUPPORT)  &&  defined(CORRECTED_RTC_SUPPORT)
            correct_rtc();
    #endif
        }
#endif
    }
#if !defined(__IAR_SYSTEMS_ICC__)  &&  !defined(__TI_COMPILER_VERSION__)
    return  0;
#endif
}

#if defined(LIMP_MODE_SUPPORT)
void switch_to_limp_mode(void)
{
    clr_normal_indicator();
    #if defined(PHASE_REVERSED_DETECTION_SUPPORT)
    clr_reverse_current_indicator();
    #endif
    #if defined(IEC62056_21_SUPPORT)
    disable_ir_receiver();
    #endif
}
#endif

void switch_to_normal_mode(void)
{
#if defined(LIMP_MODE_SUPPORT)
    set_normal_indicator();
#endif
    /* The LCD might need to be revived */
#if defined(LCD_DISPLAY_SUPPORT)
    lcd_awaken();
#else
    /* Tell the world we are ready to start */
#endif
#if defined(IEC62056_21_SUPPORT)
    enable_ir_receiver();
#endif
}

void switch_to_powerfail_mode(void)
{
#if defined(LIMP_MODE_SUPPORT)
    clr_normal_indicator();
#endif
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
    clr_reverse_current_indicator();
#endif
#if defined(PHASE_UNBALANCED_DETECTION_SUPPORT)
    clr_earthed_indicator();
#endif
#if defined(IEC62056_21_SUPPORT)
    disable_ir_receiver();
#endif
}

#if defined(TOTAL_ACTIVE_ENERGY_PULSES_PER_KW_HOUR)  ||  defined(ACTIVE_ENERGY_PULSES_PER_KW_HOUR)
    #if NUM_PHASES == 1
void active_energy_pulse_start(void)
{
    //custom_active_energy_pulse_start();
}
    #else
void active_energy_pulse_start(int ph)
{
    //custom_active_energy_pulse_start(ph);
}
    #endif

    #if NUM_PHASES == 1
void active_energy_pulse_end(void)
{
    custom_active_energy_pulse_end();
}
    #else
void active_energy_pulse_end(int ph)
{
    custom_active_energy_pulse_end(ph);
}
    #endif
#endif

#if defined(TOTAL_REACTIVE_ENERGY_PULSES_PER_KVAR_HOUR)  ||  defined(REACTIVE_ENERGY_PULSES_PER_KVAR_HOUR)
    #if NUM_PHASES == 1
void reactive_energy_pulse_start(void)
{
    custom_reactive_energy_pulse_start();
}
    #else
void reactive_energy_pulse_start(int ph)
{
    custom_reactive_energy_pulse_start(ph);
}
    #endif

    #if NUM_PHASES == 1
void reactive_energy_pulse_end(void)
{
    custom_reactive_energy_pulse_end();
}
    #else
void reactive_energy_pulse_end(int ph)
{
    custom_reactive_energy_pulse_end(ph);
}
    #endif
#endif

void energy_update(int phx, int type, energy_t amount)
{
#if !defined(NO_ENERGY_ACCUMULATION)
    static const int map[16] =
    {
#if defined(ACTIVE_ENERGY_SUPPORT)  ||  defined(TOTAL_ACTIVE_ENERGY_SUPPORT)
        APP_ACTIVE_ENERGY_IMPORTED,
        APP_ACTIVE_ENERGY_EXPORTED,
#else
        -1,
        -1,
#endif
#if defined(FUNDAMENTAL_ACTIVE_ENERGY_SUPPORT)  ||  defined(TOTAL_FUNDAMENTAL_ACTIVE_ENERGY_SUPPORT)
        APP_FUNDAMENTAL_ACTIVE_ENERGY_IMPORTED,
        APP_FUNDAMENTAL_ACTIVE_ENERGY_EXPORTED,
#else
        -1,
        -1,
#endif
#if defined(REACTIVE_ENERGY_SUPPORT)  ||  defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
        APP_REACTIVE_ENERGY_QUADRANT_I,
        APP_REACTIVE_ENERGY_QUADRANT_II,
        APP_REACTIVE_ENERGY_QUADRANT_III,
        APP_REACTIVE_ENERGY_QUADRANT_IV,
#else
        -1,
        -1,
        -1,
        -1,
#endif
#if defined(FUNDAMENTAL_REACTIVE_ENERGY_SUPPORT)  ||  defined(TOTAL_FUNDAMENTAL_REACTIVE_ENERGY_SUPPORT)
        APP_FUNDAMENTAL_REACTIVE_ENERGY_QUADRANT_I,
        APP_FUNDAMENTAL_REACTIVE_ENERGY_QUADRANT_II,
        APP_FUNDAMENTAL_REACTIVE_ENERGY_QUADRANT_III,
        APP_FUNDAMENTAL_REACTIVE_ENERGY_QUADRANT_IV,
#else
        -1,
        -1,
        -1,
        -1,
#endif
#if defined(APPARENT_ENERGY_SUPPORT)  ||  defined(TOTAL_APPARENT_ENERGY_SUPPORT)
        APP_APPARENT_ENERGY_IMPORTED,
        APP_APPARENT_ENERGY_EXPORTED,
#else
        -1,
        -1,
#endif
#if defined(INTEGRATED_V2_SUPPORT)  ||  defined(TOTAL_INTEGRATED_V2_SUPPORT)
        APP_INTEGRATED_V2,
#else
        -1,
#endif
#if defined(INTEGRATED_I2_SUPPORT)  ||  defined(TOTAL_INTEGRATED_I2_SUPPORT)
        APP_INTEGRATED_I2,
#else
        -1,
#endif
    };

    /* Adjust a stored energy level */
    if (type < 16  &&  map[type] >= 0)
        energy_consumed[phx][map[type]] += amount;
#endif
}

#if defined(SAG_SWELL_SUPPORT)
void sag_swell_event(int phx, int event)
{
    /* Processing in this routine MUST be very quick, as it is called from the
       metrology interrupt. It is OK to set flags, or perform other functions taking
       just a few instructions. Do not do anything slow. */
    switch (event)
    {
    //case SAG_SWELL_VOLTAGE_POWER_DOWN_OK:
        /* The power is OK */
        //break;
    case SAG_SWELL_VOLTAGE_POWER_DOWN_SAG:
        /* The power is failing, and important information should be saved before the power
           supply starts to drop. */
        asm("NOP");
        break;
    case SAG_SWELL_VOLTAGE_SAG_ONSET:
        sag_events[phx] = 1;
        sag_duration[phx]++;
        break;
    case SAG_SWELL_VOLTAGE_SAG_CONTINUING:
        sag_duration[phx]++;
        break;
    case SAG_SWELL_VOLTAGE_NORMAL:
        sag_events[phx] = 0;
        sag_duration[phx] = 0;
        swell_events[phx] = 0;
        swell_duration[phx] = 0;
        /* The voltage has returned to its normal range */
        break;
    case SAG_SWELL_VOLTAGE_SWELL_ONSET:
        swell_events[phx] = 1;
        swell_duration[phx]++;
        break;
    case SAG_SWELL_VOLTAGE_SWELL_CONTINUING:
        swell_duration[phx]++;
        break;
    }
}
#endif

#if defined(x__MSP430__)
void power_sense(void)
{
    #if defined(POWER_DOWN_SUPPORT)  &&  defined(POWER_UP_BY_SUPPLY_SENSING)
    /* Select the lower threshold to watch for the power supply dying. */
    CACTL1 = CAREF_1 | CAON;
    #endif
    #if defined(BASIC_KEYPAD_SUPPORT)  ||  defined(CUSTOM_KEYPAD_SUPPORT)
    if (keypad_debounce())
        _BIC_SR_IRQ(LPM0_bits);
    #endif

    #if defined(POWER_DOWN_SUPPORT)  &&  defined(POWER_UP_BY_SUPPLY_SENSING)
        #if defined(__MSP430_HAS_COMPA__)
    if ((CACTL2 & CAOUT))
        #else
    /* Use an I/O pin to sense the power falling */
    POWER_GOOD_THRESHOLD_LOW;
    if (!POWER_GOOD_SENSE)
        #endif
    {
        /* The comparator output can oscillate a little around the
           switching point, so we need to do some debouncing. */
        if (power_down_debounce < POWER_FAIL_DEBOUNCE + 1)
        {
            if (++power_down_debounce == POWER_FAIL_DEBOUNCE)
            {
                power_down_debounce = 0;
                /* The power is falling. We need to get to a low power
                   consumption state now! The battery will be supplying the
                   meter soon. */
                operating_mode = OPERATING_MODE_POWERFAIL;
        #if defined(__MSP430__)
                /* Get the foreground to respond quickly. It might be conserving
                   power (e.g. in limp mode). */
                _BIC_SR_IRQ(LPM0_bits);
        #endif
            }
        }
    }
    else
    {
        power_down_debounce = 0;
    }
        #if defined(__MSP430_HAS_COMPA__)
    CACTL1 &= ~(CAON);
        #endif
    #endif
}
#endif

int is_calibration_enabled(void)
{
    /* This custom function must check the conditions, such as passswords and shorting link tests,
       appropriate to the meter's "enable calibration" condition. */
    return custom_is_calibration_enabled();
}

#if defined(__IAR_SYSTEMS_ICC__)  ||  defined(__TI_COMPILER_VERSION__)

#if defined(__MSP430AFE252__)  ||  defined(__MSP430AFE253__)
#pragma vector = PORT2_VECTOR, \
		 	 	 PORT1_VECTOR, \
		 	 	 TIMERA1_VECTOR, \
		 	 	 TIMERA0_VECTOR, \
	 	 	     /* USART0TX_VECTOR, */ \
 	 	 	 	 /* USART0RX_VECTOR, */ \
 	 	 	 	 /* WDT_VECTOR, */ \
 	 	 	 	 /* SD24_VECTOR, */ \
 	 	         NMI_VECTOR
#elif defined(__MSP430F427__)  ||  defined(__MSP430F427A__)
#pragma vector = /* BASICTIMER_VECTOR, */ \
		 	 	 PORT2_VECTOR, \
		 	 	 PORT1_VECTOR, \
		 	 	 TIMERA1_VECTOR, \
		 	 	 /* TIMERA0_VECTOR, */ \
	 	 	     /* USART0TX_VECTOR, */ \
 	 	 	 	 /* USART0RX_VECTOR, */ \
 	 	 	 	 WDT_VECTOR, \
 	 	 	 	 /* SD16_VECTOR, */ \
 	 	         NMI_VECTOR
#elif defined(__MSP430FE427__)  ||  defined(__MSP430FE427A__)  ||  defined(__MSP430FE4272__)
#pragma vector = /* BASICTIMER_VECTOR, */ \
		 	 	 PORT2_VECTOR, \
		 	 	 PORT1_VECTOR, \
		 	 	 TIMERA1_VECTOR, \
		 	 	 /* TIMERA0_VECTOR, */ \
	 	 	     /* USART0TX_VECTOR, */ \
 	 	 	 	 /* USART0RX_VECTOR, */ \
 	 	 	 	 WDT_VECTOR, \
 	 	 	 	 /* SD16_VECTOR, */ \
                 /* ESP430_VECTOR, */ \
 	 	         NMI_VECTOR
#elif defined(__MSP430F4794__)
#pragma vector = /* BASICTIMER_VECTOR, */ \
				 PORT2_VECTOR, \
				 USCIAB1TX_VECTOR, \
				 USCIAB1RX_VECTOR, \
				 PORT1_VECTOR, \
				 TIMERA1_VECTOR, \
				 TIMERA0_VECTOR, \
				 /* SD16A_VECTOR, */ \
				 /* USCIAB0TX_VECTOR, */ \
				 /* USCIAB0RX_VECTOR, */ \
				 WDT_VECTOR, \
				 COMPARATORA_VECTOR, \
				 TIMERB1_VECTOR, \
				 TIMERB0_VECTOR, \
				 NMI_VECTOR
#elif defined(__MSP430F47197__)  ||  defined(__MSP430F47187__)
#pragma vector = /* DMA_VECTOR, */ \
                 /* BASICTIMER_VECTOR, */ \
				 PORT2_VECTOR, \
				 /* USCIAB1TX_VECTOR, */ \
				 /* USCIAB1RX_VECTOR, */ \
				 PORT1_VECTOR, \
				 TIMERA1_VECTOR, \
				 TIMERA0_VECTOR, \
				 /* SD16A_VECTOR, */ \
				 /* USCIAB0TX_VECTOR, */ \
				 /* USCIAB0RX_VECTOR, */ \
				 WDT_VECTOR, \
				 COMPARATORA_VECTOR, \
				 TIMERB1_VECTOR, \
				 TIMERB0_VECTOR, \
				 NMI_VECTOR
#elif defined(__MSP430F6736__)
#pragma vector = /* RTC_VECTOR, */ \
	             LCD_C_VECTOR, \
                 TIMER3_A1_VECTOR, \
                 TIMER3_A0_VECTOR, \
                 PORT2_VECTOR, \
                 TIMER2_A1_VECTOR, \
                 TIMER2_A0_VECTOR, \
                 PORT1_VECTOR, \
                 TIMER1_A1_VECTOR, \
                 /* TIMER1_A0_VECTOR, */ \
                 DMA_VECTOR, \
                 USCI_A2_VECTOR, \
                 /* USCI_A1_VECTOR, */ \
                 TIMER0_A1_VECTOR, \
                 /* TIMER0_A0_VECTOR, */ \
                 /* SD24B_VECTOR, */ \
                 /* ADC10_VECTOR, */ \
                 USCI_B0_VECTOR, \
                 /* USCI_A0_VECTOR, */ \
                 /* WDT_VECTOR, */ \
                 UNMI_VECTOR, \
                 SYSNMI_VECTOR
#elif defined(__MSP430F6749__)  ||  defined(__MSP430F6779__)
#pragma vector = AES_VECTOR, \
                 COMP_B_VECTOR, \
                 /* RTC_VECTOR, */ \
	             LCD_C_VECTOR, \
                 TIMER3_A1_VECTOR, \
                 TIMER3_A0_VECTOR, \
                 PORT2_VECTOR, \
                 TIMER2_A1_VECTOR, \
                 TIMER2_A0_VECTOR, \
                 PORT1_VECTOR, \
                 USCI_B1_VECTOR, \
                 USCI_A3_VECTOR, \
                 TIMER1_A1_VECTOR, \
                 TIMER1_A0_VECTOR, \
                 DMA_VECTOR, \
                 /* USCI_A2_VECTOR, */ \
                 /* USCI_A1_VECTOR, */ \
                 TIMER0_A1_VECTOR, \
                 TIMER0_A0_VECTOR, \
                 /* SD24B_VECTOR, */ \
                 /* ADC10_VECTOR, */ \
                 USCI_B0_VECTOR, \
                 /* USCI_A0_VECTOR, */ \
                 /* WDT_VECTOR, */ \
                 UNMI_VECTOR, \
                 SYSNMI_VECTOR
#elif defined(__MSP430F67491__)  ||  defined(__MSP430F67791__)
#pragma vector = COMP_B_VECTOR, \
                 /* RTC_VECTOR, */ \
	             LCD_C_VECTOR, \
                 TIMER3_A1_VECTOR, \
                 TIMER3_A0_VECTOR, \
                 PORT2_VECTOR, \
                 TIMER2_A1_VECTOR, \
                 TIMER2_A0_VECTOR, \
                 PORT1_VECTOR, \
                 USCI_B1_VECTOR, \
                 /* USCI_A3_VECTOR, */ \
                 TIMER1_A1_VECTOR, \
                 /* TIMER1_A0_VECTOR, */ \
                 DMA_VECTOR, \
                 /* USCI_A2_VECTOR, */ \
                 /* USCI_A1_VECTOR, */ \
                 TIMER0_A1_VECTOR, \
                 TIMER0_A0_VECTOR, \
                 /* SD24B_VECTOR, */ \
                 /* ADC10_VECTOR, */ \
                 USCI_B0_VECTOR, \
                 /* USCI_A0_VECTOR, */ \
                 /* WDT_VECTOR, */ \
                 UNMI_VECTOR, \
                 SYSNMI_VECTOR
#elif defined(__MSP430I4020__)
#pragma vector = PORT1_VECTOR, \
		         TIMER0_A1_VECTOR, \
		         TIMER0_A0_VECTOR, \
                 USCI_B0_VECTOR, \
                 /* USCI_A0_VECTOR, */ \
                 /* WDT_VECTOR, */ \
                 VMON_VECTOR, \
                 /* SD24_VECTOR, */ \
                 NMI_VECTOR
#elif defined(__MSP430i2040__)  ||  defined(__MSP430i2041__)  ||  defined(__MSP430I2040__)  ||  defined(__MSP430I2041__)  || defined(__MSP430i2020__)  ||  defined(__MSP430i2021__)  ||  defined(__MSP430I2020__)  ||  defined(__MSP430I2021__)
#pragma vector = PORT1_VECTOR, \
                 PORT2_VECTOR, \
                 TIMER0_A1_VECTOR, \
                 TIMER0_A0_VECTOR, \
                 TIMER1_A1_VECTOR, \
                 TIMER1_A0_VECTOR, \
                 USCI_B0_VECTOR, \
                 /* USCI_A0_VECTOR, */ \
                 WDT_VECTOR, \
                 VMON_VECTOR, \
                 /* SD24_VECTOR, */ \
                 NMI_VECTOR
                   
                   
#pragma DATA_SECTION(ProxyVectorTable, ".APP_PROXY_VECTORS")
#pragma RETAIN(ProxyVectorTable)
const uint16_t ProxyVectorTable[] =
{
    0x4030, (uint16_t) PORT1_VECTOR,                               // APP_PROXY_VECTOR(0)  
    0x4030, (uint16_t) PORT2_VECTOR,                               // APP_PROXY_VECTOR(1)  
    0x4030, (uint16_t) TIMER0_A1_VECTOR,                               // APP_PROXY_VECTOR(2)  
    0x4030, (uint16_t) TIMER0_A0_VECTOR,         //ISR(TIMER0_A0, TIMER0_A0_isr),           // APP_PROXY_VECTOR(3)  
    0x4030, (uint16_t) Dummy_Isr,                               // APP_PROXY_VECTOR(4)  
    0x4030, (uint16_t) USCI_B0_VECTOR,                               // APP_PROXY_VECTOR(5)  
    0x4030, (uint16_t) Dummy_Isr,                               // APP_PROXY_VECTOR(6)  
    0x4030, (uint16_t) WDT_VECTOR,                               // APP_PROXY_VECTOR(7)  
    0x4030, (uint16_t) VMON_VECTOR,                               // APP_PROXY_VECTOR(8)  
    0x4030, (uint16_t) TIMER1_A1_VECTOR,                               // APP_PROXY_VECTOR(9) 
    0x4030, (uint16_t) TIMER1_A0_VECTOR,         //ISR(TIMER1_A0, TIMER1_A0_isr),           // APP_PROXY_VECTOR(10)  
    0x4030, (uint16_t) NMI_VECTOR,                               // APP_PROXY_VECTOR(11) 
   
      
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(10)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(11)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(12)
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(13)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(14)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(15)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(16)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(17)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(18)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(19)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(20)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(21)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(22)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(23)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(24)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(25)
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(26)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(27)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(28)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(29)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(30)  
//    0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(31)
};
#else
#error Device not recognised
#endif
                   
                  
#endif
                  
                   
/******************************************************************************
 *.
 * @brief   Dummy Interrupt service routine
 *  This ISR will be executed if an undeclared interrupt is called
 *
 * @return  none
 *****************************************************************************/
//#pragma vector = unused_interrupts
__interrupt void Dummy_Isr(void)
{
    while(1)
        ;
}

/******************************************************************************
 *
 * @brief   P1 Interrupt service routine
 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void P1_Isr(void)
{

}

/******************************************************************************
 *
 * @brief   P2 Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void P2_Isr(void)
{

}

/******************************************************************************
 *
 * @brief   Timer0_A1 Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void Timer0_A1_Isr(void)
{

}




/******************************************************************************
 *
 * @brief   Timer1_A1 Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void Timer1_A1_Isr(void)
{

}


/******************************************************************************
 *
 * @brief   Timer1_A0 Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void Timer1_A0_Isr(void)
{
//
}


/******************************************************************************
 *
 * @brief   USCI_B0 Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void USCI_B0_Isr(void)
{

}


/******************************************************************************
 *
 * @brief   WDT Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void WDT_Isr(void)
{

}


/******************************************************************************
 *
 * @brief   VMON Interrupt service routine

 *   Note that this function prototype should be accessible by TI_MSPBoot_Mgr_Vectors.c
 *   and it should be declared in ProxyVectorTable
 *
 * @return  none
 *****************************************************************************/
__interrupt void VMON_Isr(void)
{

}