/*
 *  Ali Khanalizadeh 20.02,2113
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
 
#include "Config.inc"
#include "header\p18f4550.h" 
//#include "header\typedefs.h"
//#include "header\Def.h"
#include "header\main.h"


//#############	 	Vector  Remapping		#############
//#pragma code _entry_scn=0x000800
//void _entry (void)
//{
//_asm goto main _endasm
//
//}

#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{ 
	_asm
		goto main
	_endasm
}

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
	_asm
		goto High_Priority_IRQ
	_endasm
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
	_asm 
		goto Low_Priority_IRQ 
	_endasm
}

//#pragma code
//========================================================
//============     High Priority interrupt  ==============
//========================================================	
// #pragma interrupt end with retie 
#pragma interrupt  High_Priority_IRQ

void High_Priority_IRQ (void)			//	User_HIGH_IRQ function
{
 	if (PIR2bits.USBIF == 1)	// Check USB Interrupt Flag
	{
		Usb_Irq();				//
	}				
}

//========================================================
//=============     Low Priority interrupt  ==============
//========================================================
#pragma interrupt   Low_Priority_IRQ

void Low_Priority_IRQ (void)						//	User_LOW_IRQ function
{
 	if (INTCONbits.TMR0IF == 1)				 // check ob Timer0 Interrupt accure
	{
		PORTCbits.RC1 = !(PORTCbits.RC1);
//		T0_Flag.T0_OVF = 1;			// Set Overflow Bit T0
		INTCONbits.TMR0IF = 0;		// Timer0 Interrupt zurück setzen
	}

}
#pragma code //user = 0x850			
//========================================================
//============     			main  			==============
//========================================================
void main(void) 
{
	Usb_Init();			
	
	InitDevice();

	T0_Delay = 1;		// Set Timer0 blinkrate ca. 65 mS/130mS = 8 Hz
    Set_T0_Delay();

	while (1)
	{	
		if (Mode_State.b1 == 1)					// Check if User-Data Ready, 1:Data-Ready
		{
			Procces_USB_Data();
			Mode_State.b1 = 0;					// must be clear to recive next data
		}
//		if (T0_Flag.T0_OVF == 1)				// Check TMR0 overflow
//		{
//			PORTCbits.RC1 = !(PORTCbits.RC1);	// ; RC1-Pin togglen			
//			T0_Flag.T0_OVF = 0;					// Clear Overflow flag-Bit		
//		}
	}
}//end main 

//========================================================
//=================     InitDevice   =====================
//========================================================
void InitDevice(void)
{
//------------------		Timer 0 Init		-------------------------------------------
// Timer0 takt is 4MHz-> 250 nS takt -> with 16 bit = 250nS*65535 =0,01638375 S = 16 mS
// z.B. Prescal = 2 -> 250nS*2*65535 = 0,0327675 S = 32 mS
// Prescal =000, 1:2 -> 0,0327675 S = 32   mS
// Prescal =001, 1:4 -> 0,065535  S = 65   mS
// Prescal =010, 1:8 -> 0,13107   S = 131  mS
// Prescal =011 1:16 -> 0,26214   S = 262  mS
// Prescal =100 1:32 -> 0,52428   S = 524  mS
// Prescal =101 1:64 -> 1,04856   S = 1048 mS
// Prescal =110 1:128-> 2,09712   S = 2097 mS
// Prescal =111 1:256-> 4,19424   S = 4194 mS

	T0CONbits.T08BIT = 0;		// T08BIT:[0] -> 16-bit timer/counter
	T0CONbits.T0CS = 0;			// T0CS:[0] -> Timer0 Clock Source is Internal instruction cycle
	T0CONbits.PSA = 0;			// PSA:[0] -> Timer0 prescaler is assigned
								
	T0CONbits.T0PS0 = 1;		// T0PS2:T0PS0: Timer0 Prescaler Select bits		
	T0CONbits.T0PS1 = 0;		
	T0CONbits.T0PS2 = 0;		// 001 = 1:4 Prescale value = 65 mS
									
	INTCON2bits.TMR0IP = 0;		// TMR0IP:[0] -> Low priority Priority Low
	INTCONbits.TMR0IE = 1;		// TMR0IE:[1] ->  Enables TMR0 overflow interrupt
	T0CONbits.TMR0ON = 1;		// TMR0ON:[1] -> 1: Enables Timer0, TMR0ON:[0]: Stops Timer0
// ------------------		Timer 0 Init End		-----------------

//	UCONbits.USBEN = 1;
//	PIE2bits.USBIE = 1;
//	IPR2bits.USBIP = 1;	// 1 = High priority

	RCONbits.IPEN = 1;			// Enable priority levels on interrupts
	INTCONbits.GIEH = 1;		// When IPEN = 1 -> GIEH:[1] -> Enables all high-priority interrupts
	INTCONbits.GIEL = 1;		// When IPEN = 1 -> GIEL:[1] -> Enables all Low-priority peripheral interrupts

// Setting a TRISC bit(0) will make the corresponding PORTC pin an Output
	TRISCbits.TRISC1 = 0;	// ; RC1 as Output, TQFP44 = Pin35, PDIP40 = Pin16, PDIP/SOIC28 = Pin12
	PIR1 = 0;				// clear all peripheral interrupts flag
	PIR2 = 0;					
}

//========================================================
//=================     Set_T0_Delay    ==================
//========================================================
void Set_T0_Delay(void)
{
	INTCONbits.TMR0IE = 0;			// disable TMR0 Interrupt	
	INTCONbits.TMR0IF = 0;			// Clear Interupt Flag	
	T0CONbits.TMR0ON = 0;			// Stop TMR0
	T0CON = T0CON & T0PS_Maske;		// Clear Prescalar bit , lade 0xF8
	T0CON = T0CON | T0_Delay;		// Set Prescalar bit
	TMR0H = 0;						// Clear Timer0
	TMR0L = 0;	
	INTCONbits.TMR0IE = 1;			// Enable TMR0 Interrupt
	T0CONbits.TMR0ON = 1;			// Timer0 Start
}
	
//========================================================
//================= Procces_USB_Data    ==================
//========================================================
void Procces_USB_Data(void)
{	
	Outbuf_ptr = EP1OutBuff;
	CMD = *Outbuf_ptr++;			// read 1.Byte und increment pointer
	if (CMD==1)
	{
		T0_Delay = *Outbuf_ptr;		// Load 2.Byte = Prescaler value
		Set_T0_Delay();
	}
	
}


//#define RM_RESET_VECTOR            0x000800 // define relocated vector addresses
//#define RM_HIGH_INTERRUPT_VECTOR   0x000808
//#define RM_LOW_INTERRUPT_VECTOR    0x000818
//
///** VECTOR MAPPING *******************************************/
//#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
//void _high_ISR (void)
//{
//    _asm goto RM_HIGH_INTERRUPT_VECTOR _endasm
//}
//
//#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
//void _low_ISR (void)
//{
//    _asm goto RM_LOW_INTERRUPT_VECTOR _endasm
//}
//  

/** VECTOR MAPPING *******************************************/
//#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
//void _high_ISR (void)
//{
//    _asm goto RM_HIGH_INTERRUPT_VECTOR _endasm
//}
//
//#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
//void _low_ISR (void)
//{
//    _asm goto RM_LOW_INTERRUPT_VECTOR _endasm
//}

	