#include <avr/io.h>
#include <avr/interrupt.h>
#include "uart.h"
#include "bt_ports.h"
#include "LMX_commands.h"
#include "message.h"
#include "spp_profil.h"
#include <stdlib.h>

#define F_CPU 8000000
#include <util/delay.h>

#define KEY_DDR         DDRA
#define KEY_PORT        PORTA
#define KEY_PIN         PINA
#define KEY0            0
#define KEY1            1
#define KEY2            2
#define KEY3            3
#define KEY4            4
#define KEY5            5
#define KEY6            6
#define KEY7            7
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2 )
 
#define REPEAT_MASK     (1<<KEY0 | 1<<KEY1 | 1<<KEY2 )       // repeat: key1, key2
#define REPEAT_START    50                        // after 500ms
#define REPEAT_NEXT     25                        // every 200ms
#define REPEAT_START_2    50                        // after 500ms
#define REPEAT_NEXT_2     20                        // every 200ms

volatile uint8_t key_state;                                // debounced and INVERTED key state:
                                                  		   // bit = 1: key pressed 
volatile uint8_t key_press;                                // key press detect
 
volatile uint8_t key_rpt;                                  // key long press and repeat

volatile uint8_t key_rpt_2;                                  // für mehrere Tasten

volatile uint8_t key_release;                                // key release detect


uint8_t get_key_press( uint8_t);
uint8_t get_key_rpt( uint8_t);
uint8_t get_key_short( uint8_t);
uint8_t get_key_long( uint8_t);
uint8_t get_key_release( uint8_t);
uint8_t get_key_long_2( uint8_t);
uint8_t get_key_rpt_2( uint8_t);


uint8_t tr_on = 0;
uint8_t once = 1;
uint8_t eingabe;
uint8_t help;


void init(void)
{

	DDRA	= 0x00;    //Datadirection 0-input
	DDRC 	= 0xFF;	   //Datadirection 1-output
	DDRD  	= 0xF9; //11111001
	PORTA   = 0xFF;	


	PORTC |= (1<<BT_RESET);
	PORTC |= (1<<OP3);   //Baudrate 9600
	PORTC &= ~(1<<OP4);
	PORTC |= (1<<OP5);
	
	
	PORTD 	= 0x80; //LED aus
//	PORTD |= (1<<PD1);


}

void main_function (uint8_t data)
{
 if (data == 0x87)
 {
 	
// 	PORTD &= ~(1<<PD7);
	

	tr_on = 1;
									// Slave
 }
}


int main (void)
{
	
	init();
	USARTs_Init();
	
	KEY_DDR &= ~ALL_KEYS;                // konfigure key port for input
  	KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
 
  	TCCR0A = (1<<CS02)|(1<<CS00);			// divide by 1024
	TIMSK0 = 1<<TOIE0;				// enable timer interrupt

	sei();
	
	



	while (1)
	{	
		
		
//		if (tr_on) 
		if (transparent_on())
		{	
			eingabe = KEY_PIN;
			/*if (eingabe != 127)
			{
			_delay_ms(200);
			eingabe = PINA;
			}
			
			if (eingabe != 127)
			{
				switch (eingabe)				   // Jumper in Taste 8 deshalb erste Stelle gleich NULL
				{
				case 126:                          // Taste 1: 01111110
				print1 (" Taste 1 gedrückt ");
				break;

				case 125:                          // Taste 2: 01111101
				print1 (" Taste 2 gedrückt ");
				break;

				case 123:                          // Taste 3: 01111011
				print1 (" Taste 3 gedrückt ");
				break;

				case 121:                          // Taste 3: 01111001
				print1 (" Taste 3 und Taste 2 gedrückt ");
				break;
				}
			}*/
			
//			uint8_t last=0;

	/*	help = get_key_rpt( eingabe );

			if (help != 0)
			USART1_Transmit (help + 0x30);
			switch (help)				   
				{
				case 1:
				{
				print1 (" Taste 1 kurz gedrückt ");
			//	USART1_Transmit (help + 0x30);
				}
				break;

				case 2:
				{
				print1 (" Taste 2 kurz gedrückt ");
			//	USART1_Transmit (help + 0x30);
				}
				break;

				case 4:
				{
				print1 (" Taste 3 kurz gedrückt ");
			//	USART1_Transmit (help + 0x30);
				}
				break;

				case 3:                    
				{
				print1 (" Taste 1 und Taste 2 kurz gedrückt ");
			//	USART1_Transmit (help + 0x30);
				}
				break;
				}

			help = get_key_press( eingabe );
		//	USART1_Transmit (0x20);
		//	USART1_Transmit (help + 0x30);
			
			switch (help)				   
				{
				case 1:                    
				print1 (" Taste 1 lang gedrückt ");
				break;

				case 2:                    
				print1 (" Taste 2 lang gedrückt ");
				break;

				case 4:                    
				{
				print1 (" Taste 3 lang gedrückt ");
			//	SPP_PORT_BREAK_REQ_T* SPP_Request;
			//	SPP_Request = (SPP_PORT_BREAK_REQ_T*)malloc(sizeof(SPP_PORT_BREAK_REQ_T));
			//	SPP_Request->LocalPort = 0x01;
			//	SPP_Request->Break_Length_LSB = 0x20;
			//	SPP_Request->Break_Length_MSB = 0x20;

			//	SPP_PORT_BREAK_Req(SPP_Request);
				}
				break;
				
				case 3:                    
				print1 (" Taste 1 und Taste 2 lang gedrückt ");
				break;
				}*/

			
			if(( get_key_rpt_2( (1<<KEY0) )  ^ get_key_rpt_2( (1<<KEY1) )) == 3)
			{
				print1 (" Taste 1 und 2 kurz gedrückt ");
			}
			
			if(( get_key_rpt_2( (1<<KEY0) ) ^ get_key_rpt_2( (1<<KEY2) )) == 5)
			{
				print1 (" Taste 1 und 3 gedrückt ");
			}

			if( (get_key_press( 1<<KEY0 )) )
			{
				print1 (" Taste 1 kurz gedrückt ");  //durch ausgabe fkt ersetzen
            }                                     // release after short press: task 1
                                                  // long press: task 2
			if( (get_key_rpt( 1<<KEY0)) && (( get_key_rpt_2( (1<<KEY0) ) ^ get_key_rpt_2( (1<<KEY1) )) != 3) )
			{
      			print1 (" Taste 1 lang gedrückt ");
			}

    		if( (get_key_press(1<<KEY1)) )
			{
      			print1 (" Taste 2 kurz gedrückt ");
			}
 
    		if( (get_key_rpt(1<<KEY1)) && (( get_key_rpt_2( (1<<KEY0) ) ^ get_key_rpt_2( (1<<KEY1) )) != 3))
			{
      			print1 (" Taste 2 lang gedrückt ");
			}
			
			if( (get_key_press( 1<<KEY2)) )
			{
				print1 (" Taste 3 kurz gedrückt ");
			}
							
			if( (get_key_rpt(1<<KEY2)) && (( get_key_rpt_2( (1<<KEY0) ) | get_key_rpt_2( (1<<KEY2) )) != 5))
			{
      			print1 (" Taste 3 lang gedrückt ");
			}
			
	
			if (once)
		 	{
				//USART1_Transmit (0x87);
				//bin_to_ascii (0x87);
				print1 (" Verbindung aufgebaut ");   //Ausgabe über Bluetooth-Modul
													 // für Ausgabe an PC print0
				once = 0;
			}
			
		}
		
	if (tr_on)    				// Slave
		led();	

	}
	
}


ISR( TIMER0_OVF_vect )                            // every 10ms
{
  static uint8_t ct0, ct1, rpt, rpt2;
  uint8_t i;
 
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 25e-3 + 0.5);  // preload for 10ms TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0,5); 
 
  i = key_state ^ (~KEY_PIN &(1<<KEY0 | 1<<KEY1 | 1<<KEY2 | 1<<KEY3| 1<<KEY4| 1<<KEY5));                       // key changed ?
  ct0 = ~( ct0 & i );                             // reset or count ct0
  ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
  i &= ct0 & ct1;                                 // count until roll over ?
  key_state ^= i;                                 // then toggle debounced state
  key_press |= key_state & i;                     // 0->1: key press detect

  key_release |= ~key_state & i;					  // 1->0: key release detect
 
  if( (key_state & REPEAT_MASK) == 0 )
  {            // check repeat function
     rpt = REPEAT_START;
	 rpt2 = REPEAT_START_2;
  }                          // start delay
  if( --rpt == 0 )
  {
    rpt = REPEAT_NEXT;                            // repeat delay
    key_rpt |= key_state & REPEAT_MASK;
  }

  if( --rpt2 == 0 )
  {
  	rpt2 = REPEAT_NEXT_2;
	key_rpt_2 |= key_state & REPEAT_MASK;
  }
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t get_key_press( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_press;                          // read key(s)
  key_press ^= key_mask;                          // clear key(s)
  sei();
  return key_mask;
}
 
///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported beeing pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
//
uint8_t get_key_rpt( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_rpt;                            // read key(s)
  key_rpt ^= key_mask;                            // clear key(s)
  sei();
  return key_mask;
}
 
///////////////////////////////////////////////////////////////////
//
uint8_t get_key_rpt_2( uint8_t key_mask )
{
  cli();                                          // read and clear atomic !
  key_mask &= key_rpt_2;                            // read key(s)
  key_rpt_2 ^= key_mask;                            // clear key(s)
  sei();
  return key_mask;
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_short( uint8_t key_mask )
{
  cli();                                          // read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );  // ~key_state & 
}
 
///////////////////////////////////////////////////////////////////
//
uint8_t get_key_long( uint8_t key_mask )
{
  return get_key_press( get_key_rpt( key_mask ));
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_long_2( uint8_t key_mask )
{
  return get_key_press( get_key_rpt_2( key_mask ));
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_release( uint8_t key_mask )
{
  cli();
  key_mask &= key_release;
  key_release ^= key_mask;
  sei();
  return key_mask;
}
