
/********************************************************************
// keypad_xhruby00.c
//-------------------------------------------------------------------
// 
// Komunikace s klavesnici 3x4
//
// Michal Hrubý 2011
// VUTBR
// xhruby00
//
//
// Skenuje jestli neni zmacknute tlacitko
// Pokud je stisknute - vrati poradove cislo tlacitka
// Pokud neni stisknute - vrati cislo 0

// Rozlozeni registru 
// PD7  PD6  PD5  PD4  PD3  PD2  PD1  PD0
// NA   R4   R3   R2   R1   S3   S2   S1  
// NA 	Row4 Row3 Row2 Row1 Col3 Col2 Col1

//
// PIN pro tlacitko 5 = R2 a S2 =  00010010
//
********************************************************************/


#define F_CPU 8000000UL		// frekvence hodinového signálu (nutné pro delay.h)
#include <avr/io.h>			// hlavičkový soubor pro mikrokontrolér ATmega16
#include <util/delay.h>     // hlavičkový soubor pro zpoždění
#include <avr/pgmspace.h>   // hlavičkový soubor pro zapis FLASH

#include "keypad_xhruby00.h" 		// headerfile KEYPAD


//-------------------------------------------------------------------
// FUNKCE
//-------------------------------------------------------------------



char keypad_read(void){
	/***************************************************************
	Cteni stiknuteho tlacitka vcetne osetreni zakmitu

	Navratova hodnota:
	char :  0 - 12 
			0 = nic nestisknuto
			1 az 9 = 1-9
			10 = *
			11 = nula
			12 = #

	****************************************************************/

	char row; 				// cislo radek
	char state1,state2;		// cteni 2 stavu - osetreni zakmitu	
	char button=0;			// 0 = nebyla stiknuta klavesa

	char dir[4]=			//DDR portu 0=input
    {	0b00001000,		
     	0b00010000,
     	0b00100000,
     	0b01000000	};

  for(row=0;row<4;row++)    	// prochazime po radcich
  {
    KEY_DDR=dir[row];
    KEY_PORT=~dir[row];			//~ = bitová negace

    do{							// cteni stavu s 2ms rozdilem
      state1=KEY_PIN;
      _delay_ms(2);
      state2=KEY_PIN;
    }
    while(state1!=state2);		// pokud se stavy shoduji

    state1=(~state1)&0b00000111;	// ve spodnich 3 bytech se nachazi sloupce
    
	if (state1!=0)					// state1=0  nebylo stisnuto tlacitko
	{
		switch (state1) 			// prirazeni stavoveho cisla
		{
			case 1:			// stisknuto tlacitko ve sloupci 1 (0b001)
				button=1+3*row;
			break;

			case 2:			// stisknuto tlacitko ve sloupci 2 (0b010)
				button=2+3*row;			
			break;
	
			case 4:			// stisknuto tlacitko ve sloupci 3 (0b100)
				button=3+3*row;			
			break;

		}								
	}									
  }									
  return button;
}



char keypad_decode (char button){
	/***************************************************************
	Prevede stavovy kod stiknuteho tlacitka na ASCII

	Navratova hodnota:
	char :  ASCII hodnota stiksnuteho tlacitka (1 -> '1')

	****************************************************************/
	unsigned char key_convert[] = { 'X',		// pole s ASCII
		'1','2','3',
		'4','5','6',
		'7','8','9',
		'*','0','#',
		};	 

	if (button<=12){
		return key_convert[button];				// prirazeni
	}else {
		return button;
	}

}
