/********************************************************************
* FileName:        David Fisher Problem 3.c
* Processor:       PIC18F4520
* Compiler:        MPLAB C18 v.3.06 
*
* This program toggles RB0 when RB4 is pressed 
*  using PORTB interrupt on change interrupts
*                                                                     
*
*       Author               Date              Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// David Fisher

/**  Header Files **************************************************/     
#include <p18f4520.h> 
#include <portb.h>

/** Configuration Bits *********************************************/     
#pragma config OSC = EC  // EC = External 4MHz Crystal for PICDEM board only
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config BOREN = OFF

/** Define Constants Here ******************************************/

/** Local Function Prototypes **************************************/
void low_isr(void);
void high_isr(void);

/** Declare Interrupt Vector Sections ****************************/
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
   _asm goto high_isr _endasm
}

#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
   _asm goto low_isr _endasm
}

/** Global Variables ***********************************************/
	
/*******************************************************************
* Function:        void main(void)
********************************************************************/
#pragma code
void main (void)
{

	RCONbits.IPEN = 1;					// Put the interrupts into Priority Mode
	ADCON1 = 0x0F;
	TRISB = 0xF0;
	PORTB = 0x00;
	
	// Turn on the Change on RB4:RB7 interrupt
	OpenPORTB( PORTB_CHANGE_INT_ON & PORTB_PULLUPS_OFF);
	INTCON2bits.RBIP = 1;				// Make sure it is high priority
	
	INTCONbits.GIEH = 1;				// Turn on High Priority interrupts
	
	
	while (1)
    {
		// This area loops forever
    }
}


/*****************************************************************
* Function:        void high_isr(void)
* Possible sources of interrupt - none
* Overview:
******************************************************************/
#pragma interrupt high_isr
void high_isr(void)
{
	// Add code here for the high priority Interrupt Service Routine (ISR)
	
	
	if(INTCONbits.RBIF)		// Change on RB4:RB7 interrupt
	{
		char currentPORTBvalue;
		// Wierd note: Can only clear this flag AFTER reading PORTB
		currentPORTBvalue = PORTB;
		
		PORTB ^= 0x01;   // Fancy way to toggle bit 0 (ie RB0)
		
		INTCONbits.RBIF = 0;
	}
}

/******************************************************************
* Function:        void low_isr(void)
* Possible sources of interrupt - none
* Overview:
********************************************************************/
#pragma interruptlow low_isr
void low_isr(void)
{
	// Add code here for the low priority Interrupt Service Routine (ISR)
}