/** \file ******************************************************************
* \brief Button Interface
* 
* \author Dominic Rathje (dominic.rathje@uni-ulm.de)
* \version 1.0
* \note
* - Compiler          : WinAVR 20100110
* - Supported devices : ATMega8
*
*****************************************************************************/

#define _BUTTON_C_ 1

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "button.h"
#include "uart.h"


void button_init(void) {
	
	//Set Button-Pins as Output
	DDRC |= (1<<PC4) | (1<<PC5);
	DDRD |= (1<<PD5) | (1<< PD6) | (1<<PD7);
	DDRB |= (1<<PB0);
	
	//Set Button-Pins High to charge debounce capacitors
	PORTC |= (1<<PC4) | (1<<PC5);
	PORTD |= (1<<PD5) | (1<< PD6) | (1<<PD7);
	PORTB |= (1<<PB0);
	_delay_ms(1);
	
	//Set Button-Pins as Input
	//as PORTxn is still High, the Pull-Up Resistors are enabled
	DDRC &= ~((1<<PC4) | (1<<PC5));
	DDRD &= ~((1<<PD5) | (1<< PD6) | (1<<PD7));
	DDRB &= ~((1<<PB0));
	
}

uint8_t button_read(void) {
	uint8_t tmp;
	
	tmp=0;
	tmp |= ( PINC & (1<<PC5) ) >> 5;
	tmp |= ( PINC & (1<<PC4) ) >> 3;
	tmp |= ( PINB & (1<<PB0) ) << 2;
	tmp |= ( PIND & (1<<PD7) ) >> 4; 
	tmp |= ( PIND & (1<<PD6) ) >> 2;
	tmp |= ( PIND & (1<<PD5) );
	
	
	return ~tmp;
	
}

void button_process(void) {
	static uint8_t read=0;
	uint8_t old;
	uint8_t mask;
	uint8_t diff;
	uint8_t sample0;
	static uint8_t sample1=0;
	uint8_t tmp;
	uint8_t i;
	
	
	//simple debouncing:
	//PIN must be same level vor 2 samples.
	//read contains current (debounced) state.
	//old contains previous state for edge detection
	sample0 = sample1;
	sample1 = button_read();
	mask = (sample0 ^ sample1);
	old = read;
	read = ( (old & mask) | (sample1 & (~mask)) ); 
	
	
	diff = (old ^ read);
	
	//rising edge
	tmp = (read & diff);
	for(i=0; i<6; i++) {
		if(tmp & (1<<i)) {
			uart_sendbyte('a'+i);
		}
	}
	
	//falling edge
	tmp = ( (~read) & diff);
	for(i=0; i<6; i++) {
		if(tmp & (1<<i)) {
			uart_sendbyte('A'+i);
		}
	}
	
}
