/********************************************************************
 * FileName:		int_single_vector.c
 * Dependencies:	plib.h
 * Processor:		PIC32
 * Hardware:
 * Assembler:
 * Linker:
 * Company:		Microchip Technology Inc.
 *
 * Software License Agreement:
 * The software supplied herewith by Microchip Technology Incorporated
 * (the Company) for its PICmicro Microcontroller is intended and
 * supplied to you, the Companys customer, for use solely and
 * exclusively on Microchip PICmicro Microcontroller products. The
 * software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *********************************************************************
 * File Description:
 *
 * single vector interrupt
 *
 * Change History:
 * Name				Date            Changes
 * Sean Justice		01/02/07		Initial Version
 *
 * $Id: int_single_vector.c 9390 2008-06-16 23:43:04Z rajbhartin $
 ********************************************************************/

#include <plib.h>


// Configuration Bit settings
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 40 MHz
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
// WDT OFF
// Other options are don't care
//
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_2

#define SYS_FREQ (80000000L)

#define CORE_TIMER_PERIOD       SYS_FREQ


/*********************************************************************
 * Function:    int main(void)
 *
 * Overview:
 *  This application demostrates the multi-vectored interrupts using
 *  the core timer and care software interrupts.
 ********************************************************************/
int main(void)
{
	// Configure the device for maximum performance but do not change the PBDIV
	// Given the options, this function will change the flash wait states, RAM
	// wait state and enable prefetch cache but will not change the PBDIV.
	// The PBDIV value is already set via the pragma FPBDIV option above..
	SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

	OpenCoreTimer(CORE_TIMER_PERIOD);              // load with the period
    // set up the core timer interrupt with a prioirty of 2 and zero sub-priority
    mConfigIntCoreTimer((CT_INT_ON | CT_INT_PRIOR_2 | CT_INT_SUB_PRIOR_0));
    // set up the core software interrupt with a prioirty of 3 and zero sub-priority
    mConfigIntCoreSW0((CSW_INT_ON | CSW_INT_PRIOR_3 | CSW_INT_SUB_PRIOR_0));
    // set up the core software interrupt with a prioirty of 3 and zero sub-priority
    mConfigIntCoreSW1((CSW_INT_ON | CSW_INT_PRIOR_7 | CSW_INT_SUB_PRIOR_0));

	// configure outputs
	mPORTASetPinsDigitalOut((BIT_7 | BIT_6 | BIT_2));
	mPORTAClearBits((BIT_7 | BIT_6 | BIT_2));

	INTEnableSystemSingleVectoredInt();		// enable single vector interrupts

    while(1)
    {
        unsigned int i;

        for(i = 0; i < 0xffff; i++)
            ;

        // create a core software 0 interrupt
        SetCoreSW0();

        for(i = 0; i < 0xffff; i++)
            ;

        // create a core software 1 interrupt
        SetCoreSW1();

    }
}

/*********************************************************************
 * Function:        void _SingleVectorHandler(void)
 *
 * PreCondition:    none
 *
 * Input:           none
 *
 * Output:          none
 *
 * Side Effects:    none
 *
 * Overview:        The interrupt handler function for the core timer
 *
 * Note:            The jump to this handler will be placed in the vactor
 *                  location
 ********************************************************************/
void __ISR(_CORE_TIMER_VECTOR, ipl2) _SingleVectorHandler(void)
{
    // if we have a pending priority greater than zero
    while(mINTGetInterruptVectorPriority())
    {
        unsigned int vector;

        vector = mINTGetInterruptVectorNumber();

        switch(vector)
        {
        case _CORE_TIMER_VECTOR:
            mCTClearIntFlag();                      // clear the interrupt flag
            UpdateCoreTimer(CORE_TIMER_PERIOD);     // update the period
            mPORTAToggleBits(BIT_7);
            break;

        case _CORE_SOFTWARE_0_VECTOR:
            mCS0ClearIntFlag();                     // clear the interrupt flag
            ClearCoreSW0();                         // clear the core int flag
            mPORTAToggleBits(BIT_6);
            break;

        case _CORE_SOFTWARE_1_VECTOR:
            mCS1ClearIntFlag();                 // clear the interrupt flag
            ClearCoreSW1();                     // clear the core int flag
            mPORTAToggleBits(BIT_2);
            break;

        // catch errors
        default:
            while(1)
	            mPORTASetBits((BIT_7 | BIT_6 | BIT_2));
            break;
        }
    }
}
