/******************************************************************************
*
*  Module:         timers.c
*  Description:    
*
******************************************************************************/
 
#include "includes.h"


extern tsEDK EDK;

		
/**********************************************************************************
Function Name :  Init_Timer_Variables
Description   :  inicializace promenych
***********************************************************************************/
void Init_Timer_Variables(void)
{
  appCB.timer5ms.divider = TIMER_5MS_DIVIDER_PRESET;		// inicializace citacu
  appCB.timer10ms.divider = TIMER_10MS_DIVIDER_PRESET;
  appCB.timer100ms.divider = TIMER_100MS_DIVIDER_PRESET;
  appCB.timer200ms.divider = TIMER_200MS_DIVIDER_PRESET;				
  appCB.timer250ms.divider = TIMER_250MS_DIVIDER_PRESET;				
  appCB.timer1sec.divider = TIMER_1000MS_DIVIDER_PRESET;  
  
  EDK.counter.sync_out = SYNC_OUT_DIVIDER_PRESET;			// inicializace SYNC OUT
  EDK.counter.optocoupler = EDK_PRESET_OPTOCOUPLER_TIME;	// filtrace OPTOCOUPLER

  EDK.counter.input1 = EDK_PRESET_INPUT1_TIME;		// filtrace vstupu
  EDK.counter.input2 = EDK_PRESET_INPUT2_TIME;	
	
}



/**********************************************************************************
Function Name :  Init_TimerA
Description   :  Configures the timer A.
***********************************************************************************/
void Init_TimerA(void)
{
	tck0_tramr = 0;			// clock source f1
	tck1_tramr = 0;
	tck2_tramr = 0;

	tmod0_tramr=0;
	tmod1_tramr=0;
	tmod2_tramr=0;			//Timer mode selected(tramr bit 0, 1 and 2)


// Setting main cycle timer
// TIME/128/(1/FCLK)=DILKY
// 1/(FCLK)MHz * DIV * DILKY = TIME(us)	
    trapre.byte = 128;        		// Set Prescaler X register
	tra.byte = TIMER_PRESET_1MS;
    traic.byte = INT_LEVEL_TIMER_A;	// Interrupt priority level = 5
    ir_traic = 0;               	// Interrupt request flag clear

	Start_TimerA();    		     	// and start it
}




/**********************************************************************************
Function Name :  Init_TimerB
Description   :  Configures the timer B, overflow 1ms
***********************************************************************************/
/*
void Init_TimerB(void)
{
    tUChar a,b;
	
	tstart_trbcr = 0;				// Stop Timer RB operation 
	while(tcstf_trbcr != 0);

	trbic.byte = INT_DISABLED;		// Disable Timer RB Interrupt 
	tstop_trbcr = 1;				// The TRBPRE and TRBPR registers are initialized 
									// The TSTART and TCSTF bits in the TRBCR register are initialized too. 

	trbmr.byte = 0x00;				// Selected division = X:1/1    

	// Period between underflows : 1ms 
    trbpre.byte = TIMER_B_PRE_1MS;  // Set Prescaler X register
	trbpr.byte  = TIMER_B_PRI_1MS; 	// Set timer B primary register 
	
	topl_trbioc = 0;				// Set to "0" in timer mode 
	tocnt_trbioc = 0;				// Set to "0" in timer mode 
	inostg_trbioc = 0;				// Set to "0" in timer mode 
	inoseg_trbioc = 0;				// Set to "0" in timer mode 

	tmod0_trbmr = 0;				// Set to "00" in timer mode 
	tmod1_trbmr = 0;
	twrc_trbmr = 0;					// Write to reload register and counter 

	tck0_trbmr = 1;             	// Select "f2" in Count Source 
	tck1_trbmr = 1;

	tckcut_trbmr = 0;				// Provides count source 

    trbic.byte = INT_LEVEL_TIMER_B;	// Interrupt priority level = 4
    ir_trbic = 0;               	// Interrupt request flag clear
}
*/

/**********************************************************************************
Function Name :  Init_TimerC
Description   :  Configures the timer C - jen volnobezny citac pro kratke casy
***********************************************************************************/
void Init_TimerC(void)
{
	msttrc = 0;					// timer c power on
	
	trcmr.byte = 0;     		// timer stopped
	trcic.byte = INT_DISABLED;	// Timer RC interrupt disabled
	
	tck0_trccr1 = 0;			// clock source f32
	tck1_trccr1 = 0;
	tck2_trccr1 = 1;
	
	trc.word = 0;

	tstart_trcmr = 1;			// TRCCNT  start 		
} 


/**********************************************************************************
Function Name :  Init_TimerE
Description   :  Configures the timer E, overflow 14ms, pouzit pro externi WDT 
***********************************************************************************/
void Init_TimerE(void)
{
	tstart_trecr1 = 0;			// Stop Timer RE operation 

	while (tcstf_trecr1 != 0);	// Check for this bit is cleared 
		
	treic.byte = INT_DISABLED;	// Disable Timer RE Interrupt 

	trerst_trecr1 = 1;	// reset TIMER E
	trerst_trecr1 = 0;

	toena_traioc = 0;	// disable TEO output
	toena_trecr1 = 0;	

	int_trecr1 = 0;	
	pm_trecr1 = 0;	

	
	rcs0_trecsr = 0;	// divider f/32
	rcs1_trecsr = 1;

	rcs2_trecsr	= 1;	// 4-Bit Counter is on = divider 16
	rcs3_trecsr	= 0;	// output compare mode


// Setting main cycle timer to (1/(18.432/4))*32*(tremin+1)) = Xms
	// Setting the period of TREO output 
	tremin.byte = 0xff;  // interval casovace
	
	comie_trecr2 = 1; 	 // Enable Compare match interupt 

	// Enable RE interrupt, increasing it's priority 
	treic.byte = INT_LEVEL_TIMER_E;


	tstart_trecr1 = 1;			// Start Timer RE operation 
	while (!tcstf_trecr1);  	// Check for this bit is set 

}


// ****************************************************************************
// Timer A count start flag = start
// ****************************************************************************
void Start_TimerA(void)
{
	tstart_tracr = 1;				
}

// ****************************************************************************
// Timer A count start flag = stop
// ****************************************************************************
void Stop_TimerA(void)
{
	tstop_tracr = 1;				
}

// ****************************************************************************
// Timer B count start flag = start
// ****************************************************************************
void Start_TimerB(void)
{
	/* Period between underflows : 1ms */
    trbpre.byte = TIMER_B_PRE_1MS;  // Set Prescaler X register
	trbpr.byte  = TIMER_B_PRI_1MS; 	// Set timer B primary register 
	tstart_trbcr = 1;					/* Start Timer RB operation */
}


// ****************************************************************************
// Timer B count start flag = stop
// ****************************************************************************
/*
void Stop_TimerB(void)
{
	tstart_trbcr = 0;					// Stop Timer RB operation 
}
*/


// ****************************************************************************
// The interrupt handler of the timer ra  (na R8C/1B je to TIMER X)
// _timer_ra			(software int 22)
// ****************************************************************************
void _timer_ra(void) __attribute__ ((interrupt));
void _timer_ra(void)
{
	ir_traic = 0;
    
	
// virtualni timer 20ms
// obsluha virtualniho casovace pro parsovani dat
// max. delka paketu=32Bajtu -> 32*520.8us/bajt=17ms + mezera mezi bajty = cca 20ms interval parsovani
    if (!appCB.timer20ms.divider--)
	 {
		appCB.timer20ms.divider = TIMER_20MS_DIVIDER_PRESET;
	    appCB.timer20ms.overflow = 1;
     }  

// virtualni citac 100ms 
    if (!appCB.timer100ms.divider--)
	 {
		appCB.timer100ms.divider = TIMER_100MS_DIVIDER_PRESET;
		appCB.timer100ms.overflow = 1;
	 }

// virtualni timer 1s
    if (!appCB.timer1sec.divider--)
	 {
		appCB.timer1sec.divider = TIMER_1000MS_DIVIDER_PRESET;
	    appCB.timer1sec.overflow = 1;
     }  

// virtualni timer 5ms
    if (!appCB.timer5ms.divider--)
	 {
		appCB.timer5ms.divider = TIMER_5MS_DIVIDER_PRESET;
		appCB.timer5ms.overflow = 1;
     }  

// virtualni timer 10ms
    if (!appCB.timer10ms.divider--)
	 {
		appCB.timer10ms.divider = TIMER_10MS_DIVIDER_PRESET;
		appCB.timer10ms.overflow = 1;

		#if defined INTERFACE_RD3
  		  if (EDK.input.state & EDK_IN_WAIT_RXD_BUSY)
   		  {
	 		EdkBusTimer();
   		  }
 		#endif
     }  


// virtualni timer 200ms pro generovani synchronizacniho signalu do svorky IN1
    if (!appCB.timer200ms.divider--)
	 {
		appCB.timer200ms.divider = TIMER_200MS_DIVIDER_PRESET;
		appCB.timer200ms.overflow = 1;
     }  

  
// virtualni citac 250ms pro interval cteni karty
// v rezimu EDK je cteni karty spousteno ridicim terminal na pinu D0-IN1 
    if (!appCB.timer250ms.divider--)
	 {
        appCB.timer250ms.divider = TIMER_250MS_DIVIDER_PRESET;				
		appCB.timer250ms.overflow = 1;
	 }

// je nutne obnovovat nastaveni Timeru A - jinak to dela bordel, a timer se zastavuje
    trapre.byte = 128;        			// Set Prescaler X register
	tra.byte = TIMER_PRESET_1MS;


	// smazat interrupt flag az pred opustenim funkce
	//ir_traic = 0;		 


// hlidani timeoutu na lince	
	EdkBusTimer();

}


// ****************************************************************************
// The interrupt handler of the timer rb (na R8C/1B je to TIMER Z)
// _timer_rb 		(software int 24)
// TIMEOUT TIMER - overflow 1ms 
// ****************************************************************************
void _timer_rb(void) __attribute__ ((interrupt));
void _timer_rb(void)
{
 /*   ALL_InterruptDisable;				// nutne zakazat I flag pri zmene ir_xxic registru

	ir_trbic = 0;

    ALL_InterruptEnable;
	
	
    if(appCB.timerB.counter)    
         appCB.timerB.counter--;    // Decrease timeout counter   

    if(!appCB.timerB.counter)    
    {   
	 Stop_TimerB();
     appCB.timerB.timeout = 1;  	// Set timeout flag
    }   
*/
	ir_trbic = 0;
}


// ****************************************************************************
// The interrupt handler of the timer rc
// ****************************************************************************
void _timer_rc(void)
{
	ir_trcic = 0;			// Clear the interrupt flags 

}


// ****************************************************************************
// The interrupt handler of the timer re
// overflow 1ms 
// slouzi jako citac delky pulsu do pinu DATA1
// ****************************************************************************
void _timer_re(void) __attribute__ ((interrupt));
void _timer_re(void)
{
  ir_treic = 0;			// Clear the interrupt flags 

  #ifdef INTERFACE_EDK									
	// citac delky pulsu do pinu DATA1
  	if (EDK.counter.d1pulse_time >1)		// rozliseni delky pulsu x5ms
   	 {
       EDK.counter.d1pulse_time--;			// dekrementovat citac
     }
    else if (EDK.counter.d1pulse_time==1)	// posledni cyklus
	 {
	   EDK.counter.d1pulse_time--;			// a dekrementovat do 0
       DATA1_IDLE;	
	 }
  #endif

}


/******************************************************************************/ 
void wait_ms(tUInt _ms)
{
  WaitTimeout(_ms);
}


/******************************************************************************/ 
/*void SetTimeoutTimerB(unsigned int _time)
{
    Stop_TimerB();
	while (tstop_trbcr!=0);

	appCB.timerB.counter = _time;	
    appCB.timerB.timeout = 0;
	
	Start_TimerB();			// start timer up mode 
}
*/

/******************************************************************************/ 
void WaitTimeout(unsigned int _time)
{
  while(_time--)
   { 
	 ClearWDT();
	 wait_us_range(DELAY_1000us);
   }
}




/******************************************************************************/ 
// kratke casy v ramci us jsou reseny pres TIMER_C
// vypocet je 1/(f/32)
// Fclk = 13.56Mhz pro MIFARE a 18.432 pro EMMARIN
// TIME/32/(1/FCLK)=DILKY
void wait_us_range(tUInt delay)
{
  #if !defined INTERFACE_RD3
    do { ClearWDT();} while (!(BusControl.BusState & BUS_FREE));
  #endif


 ALL_InterruptDisable; 
	
 tstart_trcmr = 0;				// TRCCNT  stop 		
 trcsr.byte = 0;				// clear TRCSR
   
 trc.word = 0xffff - delay;		// citac se inkrementuje
 tstart_trcmr = 1;				// TRCCNT  start 		
 ovf_trcsr = 0;					// clear overflow flag
 

 ALL_InterruptEnable;
 do { ClearWDT();} while (!ovf_trcsr);
}