/*****************************************************
Chip type           : ATtiny2313
Clock frequency     : 8,000000 MHz
Data Stack size     : 64
*****************************************************/

#include <tiny2313.h>
#include <delay.h>

#define digit0 PORTD.5      //питание дисплея
#define digit1 PORTD.6      //питание дисплея

flash char digits[] = 
   {
  0xC0,// 0    
  0xF9,// 1
  0xA4,// 2
  0xB0,// 3
  0x99,// 4
  0x92,// 5
  0x82,// 6
  0xF8,// 7
  0x80,// 8
  0x90,// 9
  };  

char digit_out[2], cur_dig ; 
 


//Временные пределы
#define Tmin 40 //длинный промежуток
#define Tmax 68
#define TminK 22 //короткий промежуток
#define TmaxK 34

unsigned char sct_bit = 0;      //Счетчик битов RC5
unsigned char RC5_buffer [14];  //Буффер RC5
bit centre =  0;                //Флаг центра 
bit not_korr = 0;               //Флаг попадания в промежутки
unsigned char Timer = 0;        //число в счетчике таймера
unsigned char trigger = 0;      //переменная тригера
unsigned int device = 0;        //переменная адреса ПДУ
unsigned char command = 0;      //переменная для команды

void rc5_cl_buf(void){            //очищаем буффер
  char i = 0;      
  for (i=0; i<14; i++){ RC5_buffer [i] = 0;  }
}   

void rc5_ti_stop(void){           //остановка таймера
   GIMSK|=0x00;
   TCCR0B = 0x00;
   TCNT0 = 0;
   sct_bit = 0;
} 

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
Timer = TCNT0; //запоминаем значение счетчика   
TCNT0 = 0;     //обнуляем счетчик
not_korr = 1;                         
if(sct_bit==0){                                    
       

                  

                  TCCR0B = 0x04; //запускаем таймер  (31.250 KHz)
                  RC5_buffer [sct_bit] = !PIND.2;//записываем в эл.массива
                  sct_bit++;            //+1 к счётчику принятых битов
                  centre = 1;           
        }else{
        
        
                  if ((Timer>TminK)&&(Timer<TmaxK)){   // проверка короткого промежутка
                                                  if (centre) {
                                                              centre = 0;
                                                              not_korr = 0; 
                                                  }else{
                                                              centre = 1;
                                                              RC5_buffer [sct_bit] = !PIND.2;
                                                              sct_bit++;
                                                              not_korr=0;
                                                  };
                  };
                                        
                     PORTD.1=1;
                     
                  if ((Timer>Tmin)&&(Timer<Tmax)){ // проверка длинного промежутка
                                                  RC5_buffer [sct_bit] = !PIND.2;
                                                  sct_bit++;
                                                  not_korr = 0;
                  }; 
                                                
                  if (not_korr == 1) {             // если не попали ни в один из промежутков то  
                                       rc5_ti_stop();   //останавливаем таймер
                                       rc5_cl_buf();    //очищаем буффер
                  };
                  
                  if (sct_bit == 14){        // если бит последний то 
                  
                  
                    rc5_ti_stop();   //останавливаем таймер
                     
                    trigger = RC5_buffer [2];  //формируем переменную тригера 
                   
                    device = (RC5_buffer [3] << 4)|(RC5_buffer [4] << 3)|(RC5_buffer [5] << 2)|(RC5_buffer [6] << 1)|RC5_buffer [7];                                    //формируем адрес ПДУ                
                    command = (RC5_buffer [8] << 5)|(RC5_buffer [9] << 4)|(RC5_buffer [10] << 3 )|(RC5_buffer [11] << 2)|(RC5_buffer [12] << 1)|RC5_buffer [13];        //формируем команду

                     
                    //выводим данные на дисплей   
                    digit_out[0]=command%10;   //перевод для 1 цифры
                    command=command/10;                //подготовка 
                    digit_out[1]=command%10;   //перевод для 2 цифры 
       
                    EIFR=0x40;   // сбрасываем флаг прерывания по входу INT0
                       };                                                                         
        };    
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{   
rc5_ti_stop();        //останавливаем таймер
rc5_cl_buf();        //очищаем буффер
GIMSK|=0x40; //разрешаем прерывания по входу
EIFR=0x40;  //сбрасываем флаг прерывания (если произошло)
} 

//динамическая индикация
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
 {
 PORTB=0x00;                   //чтобы небыло тени
 switch (cur_dig)                             //---
  {   
  case 0:{digit1=1;digit0=0;break;};  //подаём питание на 1
  case 1:{digit0=1;digit1=0;break;};  //подаём питание на 2
  }                          
  PORTB=digits[digit_out[cur_dig]]; 
 cur_dig++;                        
 if (cur_dig==2) cur_dig=0;
 }

void main(void)
{
// Port A initialization
PORTA=0x00;
DDRA=0x00;
// Port B initialization
PORTB=0x00;
DDRB=0xFF;
// Port D initialization
PORTD=0x00;
DDRD=0x7A;

// Timer/Counter 0 initialization
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x40;
MCUCR=0x01;
EIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;

// Global enable interrupts
#asm("sei")

 while (1)
      {

      };
}
