/****************************************************************************
 *
 * Projekt			:	Glacier Batterieboxdeckel Prüfgerät
 * Dateiname		:	DrvTim.c
 * Autor			:	orginal MHoffmann, abgeändert für dieses Projekt Irene Saxer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Initialisierung und Behandlung der Timer des ATmega"
 *
 *
 * Versionsgeschichte
 * 	Revision 1.0	17.04.2019 SAI erste Version
 *
 ****************************************************************************/

/****************************************************************************/
/* COMPILER Direktiven */

/****************************************************************************/
/* INCLUDE Dateien */
#include "DrvTim.h"

/****************************************************************************/
/* KONSTANTEN */

/****************************************************************************/
/* Globale Variablen */
volatile uint16_t gu16_Systicks;
volatile uint16_t gu16_10kHz;

/****************************************************************************/
/* Interrupt service routinen */
ISR(TIMER0_OVF_vect)
{
	//Statusregister sichern
	uint8_t u8_TempStatReg = SREG;

	//den Zaehler inkrementieren
	gu16_Systicks++;

	//Timer 0 - Zaehlregister
	TCNT0 = 0 - TIMER0_BASE;

	//Statusregister zurueckschreiben
	SREG = u8_TempStatReg;
}

ISR(TIMER1_OVF_vect)
{
	//Statusregister sichern
	uint8_t u8_TempStatReg = SREG;

	//den Zaehler inkrementieren
	gu16_10kHz++;

	//Timer 0 - Zaehlregister
	TCNT1 = 0 - TIMER1_BASE;

	//Statusregister zurueckschreiben
	SREG = u8_TempStatReg;
}

void DrvTim_Init()
/*============================================================================
 *
 *  Funktion:		DrvTim_Init
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Initialisierung der Timer (1kHz und ---)
 *  				Timer0: 1kHz-Zaehler
 *  				Timer2: LED-PWM
 *
 *==========================================================================*/
{
	/* Controlregister initialisieren */
	//Timer0 Systicks (1kHz)
	TCCR0A = (0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00); 	//normal Operation (lade OCR1A
	TCCR0B = (0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00);									//Prescaler 256
	TCNT0  = 0x00-TIMER0_BASE;
	TIMSK0 = (0<<OCIE0B) | (0 << OCIE0A) | (1<<TOIE0);											//Interrupt bei Ueberlauf von TCNT0
	TIFR0  = 0xff;																				//alle Interruptflags loeschen

	//Timer1 10kHz-Zaehler fuer genauere Zeitmessung
	TCCR1A = (0<<WGM01) | (0<<WGM00); 															//normal Operation
	TCCR1B = (0<<WGM02) | (0<<CS12) | (0<<CS11) | (1<<CS10);									//Prescaler 1
	TCNT1  = 0x00-TIMER1_BASE;
	TIMSK1 = (0<<OCIE1B) | (0 << OCIE1A) | (1<<TOIE1);											//Interrupt bei Ueberlauf von TCNT0
	TIFR1  = 0xff;																				//alle Interruptflags loeschen

	//Timer2 LEDs
	TCCR2A = (0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (1<<WGM20);;
	TCCR2B = (0<<WGM22) | (1<<CS22) | (1<<CS21) | (0<<CS20);
	TIMSK2 = 0;
	TIFR2 = 0xff;																				//alle INT-Flags loeschen
	OCR2A = 127;
	OCR2B = 127;

	gu16_Systicks = 0;																			//den 16-bit Zaehler zuruecksetzen (1-ms-Zaehler)
}

uint16_t DrvTim_StartTimer(void)
{
	uint16_t u16_Ergebnis = 0;

	TIMSK0 &= ~(1<<TOIE0);			//stoppen des TimerINTs
	u16_Ergebnis = gu16_Systicks;	//aktuellen Wert auslesen
	TIMSK0 |= (1<<TOIE0);			//TimerINT wieder zulassen

	return u16_Ergebnis;
}

uint16_t DrvTim_ReadTimer(uint16_t u16_TimVal)
{
	uint16_t u16_Ergebnis;

	u16_Ergebnis = DrvTim_StartTimer();

	return (u16_Ergebnis-u16_TimVal);
}

void DrvTim_Delay_us(uint8_t u8_us)
{
	uint8_t __ticks;
	uint16_t __tmp = ((F_CPU) / 3e6) * u8_us;
	if (__tmp < 1)
		__ticks = 1;
	else if (__tmp > 255)
		__ticks = 0;	/* i.e. 256 */
	else
		__ticks = (uint8_t)__tmp;
	_delay_loop_1(__ticks);
}

void DrvTim_Delay_ms(uint16_t u16_ms)
{
	uint16_t	u16_Tmp = 0;

	u16_Tmp = DrvTim_StartTimer();

	//ms warten
	for(;DrvTim_ReadTimer(u16_Tmp) < u16_ms;);
}

void DrvTim_DelayClk5(void)	// fuer 20MHz auf 5 erhoeht
{	__asm__ __volatile__ ( \
							"nop\n\t"			   \
							"nop\n\t"			   \
							"nop\n\t"			   \
							"nop\n\t"			   \
							"nop\n\t"			   \
							::);
}

