/********************************************************************
* FileName:        Problem 2 David Fisher.c
* Processor:       PIC18F4520
* Compiler:        MPLAB C18 v.3.06 
*
* This file makes buzzer noises using RB0 interrupts
*                                                                     
*
*       Author               Date              Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// (Your name here) 

/**  Header Files **************************************************/     
#include <p18f4520.h> 
#include <timers.h>
#include <pwm.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 ******************************************/
#define SAMPLE 100
#define D_MID_294_HZ 211
#define VOLUME 100
#define NO_VOLUME 0

/** Local Function Prototypes **************************************/
void low_isr(void);
void high_isr(void);
void sampleFunction(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 ***********************************************/
int sampleVariable = 0;
	
/*******************************************************************
* Function:        void main(void)
********************************************************************/
#pragma code
void main (void)
{
	ADCON1 = 0x0F;
	INTCONbits.INT0IF = 0;	// Optional, sometimes wise to clear the flag to avoid initially calling isr at startup
	OpenRB0INT( PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_OFF);
	// The OpenRB0INT takes care of the TRISB setting
	// Instead of the OpenRB0INT function the SFRs could be set directly
		
	// This area happens once
	// Good for initializing and things that need to happen once
	OpenTimer2(TIMER_INT_OFF & T2_PS_1_16);
	OpenPWM1(D_MID_294_HZ);		// Use the middle A #define to set the frequency
	SetDCPWM1(NO_VOLUME);		// Stop the buzzer
	
	INTCONbits.GIE = 1;					// Turn on Global interrupts (core interrupts only) (Compatibility mode)
		
	while (1)
    {
		// This area loops forever
    }
}

/*****************************************************************
* Additional Helper Functions
******************************************************************/

/*****************************************************************
* Function:			void sample(void)
* Input Variables:	none
* Output Return:	none
* Overview:			Use a comment block like this before functions
******************************************************************/
void sampleFunction()
{
	// Some function that does a specific task
}	

/*****************************************************************
* 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.INT0IF)	// Interrupt 0, RB0
	{
		INTCONbits.INT0IF = 0;		
		if (INTCON2bits.INTEDG0 == 0)
		{
			SetDCPWM1(VOLUME);  		// set the duty cycle (provides volume)
			INTCON2bits.INTEDG0 = 1;
		}
		else
		{
			SetDCPWM1(NO_VOLUME);  		// set the duty cycle (provides volume)
			INTCON2bits.INTEDG0 = 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)
}