/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.6 Professional
Automatic Program Generator
© Copyright 1998-2005 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
e-mail:office@hpinfotech.com

Project : Led+rtc
Version : 
Date    : 14.01.2012
Author  : BenderSS                        
Company : NIIB                            
Comments: 


Chip type           : ATtiny2313
Clock frequency     : 20,000000 MHz
Memory model        : Tiny
External SRAM size  : 0
Data Stack size     : 32
*****************************************************/

#include <tiny2313.h>
#include <delay.h>  

// I2C Bus functions
#asm
   .equ __i2c_port=0x12 ;PORTD
   .equ __sda_bit=5
   .equ __scl_bit=4
#endasm
#include <i2c.h>

// DS1307 Real Time Clock functions
#include <ds1307.h>

unsigned char tmr_cnt, mode;
volatile unsigned char _cmd;
unsigned int ms;    

#define tmr 250     
unsigned char count; //Счетчик 
unsigned char hour,minute,second; //Объявляем переменные для хранения часов, минут, секунд
unsigned char date,month,year; //Объявляем переменные для хранения даты,месяца и года
unsigned int day; //День недели 




flash const unsigned char font[11][8] = {
{0x00, 0x00, 0xFE, 0x81, 0x81, 0xFE, 0x00, 0x00},  // 0
{0x00, 0x00, 0x04, 0x02, 0xFF, 0x00, 0x00, 0x00},  // 1
{0x80, 0x40, 0xA2, 0x11, 0x89, 0x06, 0x80, 0x00},  // 2
{0xC0, 0x00, 0x82, 0x01, 0x89, 0x76, 0x00, 0x00},  // 3
{0x00, 0x10, 0x18, 0x14, 0x12, 0xFF, 0x10, 0x00},  // 4
{0x40, 0x8F, 0x09, 0x89, 0x09, 0x90, 0x60, 0x00},  // 5
{0x00, 0xF0, 0x0C, 0x8A, 0x09, 0x90, 0x60, 0x00},  // 6
{0x00, 0x00, 0x01, 0xF1, 0x09, 0x05, 0x03, 0x00},  // 7
{0x60, 0x96, 0x09, 0x89, 0x09, 0x96, 0x60, 0x00},  // 8
{0x00, 0x00, 0x0E, 0x91, 0x51, 0x3E, 0x00, 0x00},  // 9
{0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00}   // :
};   


//8x5 font for down parth screen
flash const unsigned char d_font[12][5] = {
{0x00, 0x1E, 0x21, 0x21, 0x1E},  // 0
{0x00, 0x00, 0x3F, 0x10, 0x08},  // 1
{0x00, 0x19, 0x25, 0x23, 0x11},  // 2
{0x00, 0x16, 0x29, 0x21, 0x12},  // 3
{0x00, 0x3F, 0x04, 0x04, 0x4C},  // 4
{0x00, 0x26, 0x29, 0x29, 0x39},  // 5
{0x00, 0x06, 0x29, 0x29, 0x1E},  // 6
{0x00, 0x30, 0x28, 0x27, 0x20},  // 7
{0x00, 0x16, 0x29, 0x29, 0x16},  // 8
{0x00, 0x18, 0x26, 0x25, 0x18},  // 9                            
{0x00, 0x03, 0x03, 0x00, 0x00},  //.
{0x00, 0x07, 0x06, 0x00, 0x00}  // ,
};    


//**********************************************************************************
// External Interrupt 0 service routine receive command from IR remote control unit
//**********************************************************************************
interrupt [EXT_INT0] void ext_int0_isr(void)
{unsigned char ppp, pin;
 unsigned int _tmp, tout;
 unsigned char maxday; //Максимальный день в месяце


GIMSK = 0;
  _tmp = 1;  
  
for(ppp = 1; ppp<14; ppp++)
    {delay_us(1200); 
     pin = PIND.2;
     for (tout = 1400; tout > 0; tout--)
        if (pin != PIND.2) break;
     if (tout == 0) {GIMSK = 0x40;
                     EIFR = 0xC0; 
                     return;};
     _tmp = _tmp << 1;
     if (!PIND.2) _tmp++;
     };      
 _cmd = _tmp & 0x003F;    
 
  if ((_cmd & 0x0F) == 1) hour++;
  if (hour >= 24)
   {hour = 0;
   } 
  if ((_cmd & 0x0F) == 2) minute++;
  if (minute >= 60)
   {minute = 0;
   }
  if ((_cmd & 0x0F) == 3) second=0;

  if ((_cmd & 0x0F) == 4) date++;
{
if (date>maxday)
date=1;
}                      
   
  if ((_cmd & 0x0F) == 5) month++;
{
if (month>12)
month=1;
} 
  if ((_cmd & 0x0F) == 6) year++;
  {
  if (year>99)
  year=0;
  }  

  if ((_cmd & 0x0F) == 7) date--;
{
if (date==0)
date=maxday;
}
  if ((_cmd & 0x0F) == 8) month--;
{
if (month==0)
month=12;
}  
  if ((_cmd & 0x0F) == 9) year--;
  {
  if (year==255)
  year=99;
  }
          switch (month) //Определение максимального дня в месяце
                {
                 case 1: maxday=31; break; 
                 case 2: maxday=29; break;
                 case 3: maxday=31; break;
                 case 4: maxday=30; break;
                 case 5: maxday=31; break;
                 case 6: maxday=30; break;
                 case 7: maxday=31; break;
                 case 8: maxday=31; break;
                 case 9: maxday=30; break;
                 case 10: maxday=31; break;
                 case 11: maxday=30; break;
                 case 12: maxday=31; break;
                } 

        
rtc_set_time(hour,minute,second); 
rtc_set_date(date,month,year);   
 _cmd = 0;   
 EIFR  = 0xC0;   
 GIMSK = 0xC0;
} 

        //Функция вычисления дня недели (передаваемые параметры день, месяц, год)
unsigned char day_of_week (unsigned int day_w, unsigned int mon_w, unsigned int year_w)
        {
         unsigned int y;
         y=year_w+2000;
         if (mon_w<=2)
                {
                 y--;
                 day_w=day_w+3;
                }
    return (1+(day_w+y+y/4-y/100+y/400+(31*mon_w+10)/12)%7); //Формула вычисления дня недели
        }     

//********************************************
// External Interrupt 1 service routine 
// Scr for display
//********************************************
interrupt [EXT_INT1] void ext_int1_isr(void)
{
unsigned char i, s, tmp;
char str[10];
tmp = hour/10;
str[0] = tmp;
str[1] = hour-tmp*10;
str[2] = 10;
tmp    = minute/10;
str[3] = tmp;
str[4] = minute-tmp*10;
str[5] = 10;
tmp    = second/10;
str[6] = tmp;
str[7] = second-tmp*10;    
for (s=0; s<8; s++)
    {
    for (i=0; i<7; i++)
        {
        PORTB = font[str[s]][i];
        delay_us(tmr);
        };  
     PORTB = 0;
     delay_us(tmr);   
     };   
 
for (i=0; i<6; i++)
        delay_us(tmr);

//output data
//year
tmp = year/10;
str[0] = year-tmp*10;
str[1] = tmp-tmp/10*10;
str[2] = 0;
str[3] = 2;
str[4] = 10;
//month   
tmp    = month/10;
str[5] = month-tmp*10;
str[6] = tmp;
str[7] = 10;
//day
tmp    = date/10;
str[8] = date-tmp*10;
str[9] = tmp;
for (s=0; s<10; s++)
    {
    for (i=0; i<6; i++)
        {
        PORTB = d_font[str[s]][i];
        delay_us(tmr);
        };  
     PORTB = 0;
     delay_us(tmr);   
     };   
}
      


void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0xFF;
PORTD=0x04;
DDRD=0x00;


TCCR0A=0x00;
TCCR0B=0x04;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
TCCR1A=0x00;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x92;
OCR1AL=0x7C;
OCR1BH=0x00;
OCR1BL=0x00;
GIMSK=0xC0;
MCUCR=0x00;
EIFR=0xC0;
TIMSK=0x40;
USICR=0x00;
ACSR=0x80;
i2c_init();
rtc_init(0,0,0);

 count=0;  
 hour=0;
 minute=0;
 second=0;
 date=1;
 month=1;
 year=2000;
tmr_cnt = 0;
mode = 0;

// Global enable interrupts
#asm("sei")
//Если установлено некорректное время, или дата, то делаем начальные установки
rtc_get_time(&hour,&minute,&second);//Считываем время из микросхемы
if ((hour>24)||(minute>60)||(second>60))            
rtc_set_time(0,0,0);
rtc_get_date(&date,&month,&year);//Считываем дату из микросхемы 
if ((date>31)||(month>12)||(year>99))            
rtc_set_date(0,0,00);            


while (1)
      {
rtc_get_time(&hour,&minute,&second);//Считываем время из микросхемы
rtc_get_date(&date,&month,&year);//Считываем дату из микросхемы

      };
}
