/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.0 Professional
Automatic Program Generator
© Copyright 1998-2010 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 30.01.2016
Author  : 
Company : 
Comments: 


Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

#define ADC_VREF_TYPE 0x40

//Объявляем значения АПЦ нажатых кнопок
#define source_but 78
#define ch_up_but 129
#define ch_down_but 195
#define vol_up_but 263
#define vol_down_but 344
#define speech_but 419
#define off_hook_but 500
#define on_hook_but 580

unsigned char b = 0;
unsigned char k = 0;
unsigned char s = 0;
  
// Возврат значения по АЦП
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
  
unsigned char KEYPRESS(void)    //Функция перевода кода по АЦП в функцию нажатия
{ 
unsigned int c;
c = read_adc(0);                //Проводим замер и преобразование АЦП 
if(c < source_but)      return 8;
if(c < ch_up_but)       return 7;
if(c < ch_down_but)     return 6;
if(c < vol_up_but)      return 5;
if(c < vol_down_but)    return 4;
if(c < speech_but)      return 3;
if(c < off_hook_but)    return 2;
if(c < on_hook_but)     return 1;
return 0;
} 

// Функция нажатия с долгим удержанием
unsigned int Pressing_long(void)
{
DDRD &= (~((1<<5)|(1<<6)|(1<<7)));
DDRB &= (~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
switch (k)    
        {
        case (8):                   // source 
                {
                DDRD|=(0x01<<5);
                return 0;
                }
        case (7):                  //folder_up
                {
                DDRB|=(0x01<<1);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (6):                   //folder_down
                {
                DDRB|=(0x01<<2);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (5):                    //vol_up
                {
                DDRB|=(0x01<<3);
                return 0;
                }
        case (4):                    //mute
                {
                DDRD|=(0x01<<7);
                return 0;
                }
        case (3):                    //bt_menu
                {
                DDRD|=(0x01<<5);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (2):                     //answer
                {
                DDRD|=(0x01<<6);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (1):                     //reject call
                {
                DDRB|=(0x01<<0);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (0):
                {
                DDRD &= (~((1<<5)|(1<<6)|(1<<7)));
                DDRB &= (~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
                return 0;
                }

        }
}
// Функция нажатия с коротким удержанием
unsigned char Pressing_short(void)
{
DDRD &= (~((1<<5)|(1<<6)|(1<<7)));
DDRB &= (~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
switch (s)    
        {
        case (8):                   // source 
                {
                DDRD|=(0x01<<5);
                return 0;
                }
        case (7):                  //ch_up
                {
                DDRB|=(0x01<<1);
                return 0;
                }
        case (6):                   //ch_down
                {
                DDRB|=(0x01<<2);
                return 0;
                }
        case (5):                    //vol_up
                {
                DDRB|=(0x01<<3);
                return 0;
                }
        case (4):                    //vol_down
                {
                DDRB|=(0x01<<4);
                return 0;
                }
        case (3):                    //speech
                {
                DDRD|=(0x01<<5);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (2):                     //off_hook
                {
                DDRD|=(0x01<<6);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (1):                     //on_hook
                {
                DDRB|=(0x01<<0);
                DDRB|=(0x01<<5);
                return 0;
                }
        case (0):
                {
                DDRD &= (~((1<<5)|(1<<6)|(1<<7)));
                DDRB &= (~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
                return 0;
                }
        }
}

unsigned char All_to_Z (void)
{
DDRD &= (~((1<<5)|(1<<6)|(1<<7)));
DDRB &= (~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)));
return 0;
}

void main(void)
{
// Declare your local variables here


// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=0 State6=0 State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0xC0;

// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=In 
// State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=P 
PORTC=0x01;
DDRC=0x7E;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=T State6=T State5=T State4=0 State3=0 State2=0 State1=0 State0=0 
PORTD=0x00;
DDRD=0x1F;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x86;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

while (1)
      {
      k = KEYPRESS();
      if (k>0)
                {
                b++;                            //увеличиванием вчетчик 30 мс
                if (b<2)
                        {
                                                //защита от дребезга
                        }
                else 
                        {
                        if (b>=2 && b<20)
                                {
                                s = k;      //флаг, что было короткое нажатие
                                }
                        else
                                {
                                Pressing_long();        //отработка длинного нажатия
                                s = 0;
                                if (b>250) b=35;
                                }
                        }
                }
      else
                {
                if (s!=0)
                        {
                        Pressing_short();       //отработка короткого нажатия
                        delay_ms(100);
                        s = 0;
                        }
                All_to_Z();                     //все ноги в Z
                b=0; //сбрасываем счетчик 50 мс
                k=0;
                }
      delay_ms(30);
      }
}
