/* tastenzustand_02.c ATmega88 @ 1MHz */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

#define button_down !(PIND & (1<<PD2))	// Button = Low
#define button_up (PIND & (1<<PD2))		// Button = High
#define debounce_time 2					// Entprellzeit = 32ms x 2
#define short_keypress_timeout 15		// 15 x 32ms = 0,48s
#define long_keypress_time 25			// 25 x 32ms = 0,8s

enum press_type {short_keypress, long_keypress, running};
	
int main(void)
{
	WDTCSR = (1<<WDIE) | (1<<WDP0);		// watchdog @32ms + interrupt enabled
	DDRB |= (1 << PB0) + (1 << PB1);	// PB0 und PB1 = Ausgang
	DDRD &= ~(1<<PD2);					// PD2 = Eingang
	
	sei();								// Interrupts aktivieren
	
	while(1)
	{
		asm ("NOP");					// Nichts tun
	}
}

ISR (WDT_vect)							// ISR Watchdogtimer Overflow Interrupt
{
	static unsigned int button_timer;	// timer to determine button state
	static enum press_type typ;
	
	typ = running;						// vorherigen Tasterzustand verlassen
	
	if (button_down)					// button wurde gedrückt (LOW)
	{
		if (button_timer < long_keypress_time)
		button_timer ++;
	}
	
	else								// button wurde losgelassen (HIGH)
	{
		if (button_timer == long_keypress_time)
		{
			typ = long_keypress;		// Tastendruck = langer Tastendruck
		}
		
		else if ((button_timer > debounce_time) && (button_timer < short_keypress_timeout))
		{
			typ = short_keypress;		// Tastendruck = kurzer Tastendruck
		}
		
		if (button_timer)				// Button Timer nach Tastendruck zurücksetzen
		{
			button_timer = 0;
		}
	}
	
	if (typ == long_keypress)			// Langer Tastendruck
	{
		PORTB ^= (1<<PB0);				// Portpin PB0 toggeln
	}
	
	else if (typ == short_keypress)		// Kurzer Tastendruck
	{
		PORTB ^= (1<<PB1);				// Portpin PB1 toggeln
	}
	WDTCSR = (1<<WDIE);					// Watchdog Interrupt aktivieren
}