//********************************************
//* (c) 2015 Cristian Copcea                 *
//* Please retain here the credits           *
//* just add yours if you make modifications *
//* to this file                             *
//********************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#define F_CPU 80000000
#include <util/delay.h>


//#include "i2cmaster/i2cmaster.h"
#include "ds1621.h"
#include "rtc.h"


//keys definition
#define KEYSELECT 	3
#define KEYSET 		2
#define KPIN  		PIND


//segment definitions
#define SEG_NULL	0x00
#define SEG_a 		0x01
#define SEG_b 		0x02
#define SEG_c 		0x04
#define SEG_d 		0x08
#define SEG_e 		0x10
#define SEG_f 		0x20
#define SEG_g 		0x40
#define SEG_dot		0x80

//clock working mode definitions
#define	SHOWCLOCK		0x01
#define SHOWTEMP		0x02
#define SHOWDATE		0x03
#define SHOWYEAR		0x04
#define	SETHOURS		0x05
#define SETMINUTES		0x06
#define SETDATE			0x07
#define SETMONTH		0x08
#define SETYEAR			0x09
#define	SETALHOURS		0x0A
#define SETALMINUTES	0x0B
#define SETAL			0x0C
#define	SETSECMODE		0x0D

//seconds display working mode
uint8_t SecMode=1;
uint8_t DefSecMode=0;
uint8_t MinSecMode=1;
uint8_t MaxSecMode=9;

//Alarm related variables
uint8_t ALMinutes=0;
uint8_t ALHours=0;
uint8_t ALSet=0;
uint8_t DefALMinutes=0;
uint8_t DefALHours=0;
uint8_t DefALSet=0;
uint8_t AlarmOn=0;

//variables minimums and maximums definitions
#define MinALMinutes	0
#define MinALHours		0
#define MinALSet		0
#define MaxALMinutes	59
#define MaxALHours		23
#define MaxALSet		1
#define MinYears		10 //(i.e.2010)
#define MinMonth		1
#define MinDate			1
#define MinHours		0
#define MinMinutes		0
#define MaxYears		100
#define MaxMonth		12
#define MaxDate			31
#define MaxHours		23
#define MaxMinutes		59

//EEPROM variables
EEMEM uint8_t ESecMode=6;
EEMEM uint8_t EALMinutes=00;
EEMEM uint8_t EALHours=00;
EEMEM uint8_t EALSet=1;


//global variables 
uint16_t digit, decimal, digit_addressed=0;
uint8_t seconds;
uint8_t d[18];
dateTime dt,dt1;
uint8_t Start=1;
uint8_t temperature;

//clock working mode
uint8_t ClockMode=SHOWCLOCK;

//variables used for various delays
uint16_t t1=0, t2=0, t3=0;

//7-segments character definitions
unsigned char seg[]=
{
	(SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f), 			// 0
	(SEG_b|SEG_c), 									// 1
	(SEG_a|SEG_b|SEG_d|SEG_e|SEG_g), 				// 2
	(SEG_a|SEG_b|SEG_c|SEG_d|SEG_g), 				// 3
	(SEG_b|SEG_c|SEG_c|SEG_f|SEG_g), 				// 4
	(SEG_a|SEG_c|SEG_d|SEG_f|SEG_g), 				// 5
	(SEG_a|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g), 			// 6
	(SEG_a|SEG_b|SEG_c), 							// 7
	(SEG_a|SEG_b|SEG_c|SEG_d|SEG_e|SEG_f|SEG_g), 	// 8
	(SEG_a|SEG_b|SEG_c|SEG_d|SEG_f|SEG_g), 			// 9
	(SEG_dot), 										// NULL DISPLAY (decimal point lit)
	(SEG_a|SEG_b|SEG_f|SEG_g), 						// THE SYMBOL "o" (degrees)
	(SEG_a|SEG_d|SEG_e|SEG_f), 						// THE SYMBOL "C"
	(SEG_c|SEG_e|SEG_g),	 						// THE SYMBOL "n"
	(SEG_a|SEG_e|SEG_f|SEG_g), 						// THE SYMBOL "F"
	(SEG_c|SEG_d|SEG_e|SEG_g), 						// THE SYMBOL "o" (like small o)
	(SEG_NULL), 									// NULL SYMBOL (no decimal point)
	(SEG_a|SEG_b|SEG_c|SEG_e|SEG_f|SEG_g),			// THE SYMBOL "A"
	(SEG_b|SEG_c|SEG_d|SEG_e|SEG_g),				// THE SYMBOL "d"
	(SEG_d|SEG_e|SEG_f|SEG_g),						// THE SYMBOL "t"
	(SEG_d|SEG_e|SEG_f),							// THE SYMBOL "L"
	(SEG_a|SEG_d|SEG_e|SEG_f|SEG_g),				// THE SYMBOL "E"
};


//interrupt routine for character and seconds display into an unending loop.
//it uses the second 16-bit timer, TIMER1
ISR(TIMER1_OVF_vect)
{
	uint8_t PV;
	switch (digit_addressed)
	{
		case 0: 
		PV=PORTD;PV &= ~_BV(4);PV |= _BV(5);PV |= _BV(6);PV |= _BV(7);PORTD=PV;
		PORTA = ~(d[0]);
		PORTC=0xFF;
		break;
		case 1: 
		PV=PORTD;PV |= _BV(4);PV &= ~_BV(5);PV |= _BV(6);PV |= _BV(7);PORTD=PV;
		PORTA = ~(d[1]);
		PORTC=0xFF;
		break;
		case 2: 
		PV=PORTD;PV |= _BV(4);PV |= _BV(5);PV &= ~_BV(6);PV |= _BV(7);PORTD=PV;
		PORTA = ~(d[2]);
		PORTC=0xFF;
		break;
		case 3: 
		PV=PORTD;PV |= _BV(4);PV |= _BV(5);PV |= _BV(6);PV &= ~_BV(7);PORTD=PV;
		PORTA = ~(d[3]);
		PORTC=0xFF;
		break;
		case 4: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (0<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[10]);
		break;
		case 5: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (0<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[11]);
		break;
		case 6: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (0<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[12]);
		break;
		case 7: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (0<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[13]);
		break;
		case 8: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (0<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[14]);
		break;
		case 9: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (0<<DDC5) | (1<<DDC6) | (1<<DDC7);
		PORTA = ~(d[15]);
		break;
		case 10: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (0<<DDC6) | (1<<DDC7);
		PORTA = ~(d[16]);
		break;
		case 11: 
		PORTD= (1<<DDD4) | (1<<DDD5) | (1<<DDD6) | (1<<DDD7);
		PORTC= (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (0<<DDC7);
		PORTA = ~(d[17]);
		break;
	}
	digit_addressed++;
	if(digit_addressed>=12) digit_addressed=0;
}

//tool function to calculate the power of 2
uint8_t p2(uint8_t exponent)
{
	uint8_t a=1,b=1,i;
	for(i=0;i<=exponent-1;i++)
	{
		b*=2;
		a+=b;
	}
	return a;
}

//tool function to convert from decimal to binary display
uint8_t dectobin(uint8_t number)
{
	uint8_t a,i;
	a=1;
	if (number==0) 	a=1;
		else
	{
		for (i=0;i<number;i++) a=a*2;
	}
	return a;
}

//tool function to show if an integer is odd or even
uint8_t odd(uint8_t num)
{
	if (num-num/2*2 !=0)
	return 1;
	else
	return 0;
}

uint8_t bb(uint8_t in11, uint8_t sec1, uint8_t sec2) //function to reduce the code
{
	return dectobin(seconds-in11*8)*((seconds>= sec1) && (seconds<= sec2));
}

void cc(uint8_t d0,uint8_t d1,uint8_t d2,uint8_t d3,uint8_t d4,uint8_t d5,uint8_t d6,uint8_t d7, uint8_t in111)
{

			d[10]=d0 | bb(in111,0,7);
			d[11]=d1 | bb(in111,8,15);
			d[12]=d2 | bb(in111,16,23);
			d[13]=d3 | bb(in111,24,31);
			d[14]=d4 | bb(in111,32,39);
			d[15]=d5 | bb(in111,40,47);
			d[16]=d6 | bb(in111,48,55);
			d[17]=d7 | bb(in111,56,59);
}

//main display function
void display(void)
{
	uint8_t hr, min, month, date, in1,i;
	uint16_t year;
	if (ClockMode==SHOWCLOCK)
	{
		if (t2==0)//show clock
		{
		//computing hours and minutes
		hr=digit/100;
		min=digit-hr*100;
		d[4]= hr/10;
		d[5]= hr-d[4]*10;
		d[6]= min/10;
		d[7]= min-d[6]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		//add dot point on odd seconds
		if (odd(seconds)) d[1]+=SEG_dot;
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
		}
		else
		if (t2<5) //show "date" while setting the clock
		{
		d[0]= seg[18];
		d[1]= seg[17];
		d[2]= seg[19];
		d[3]= seg[21];
		}
		else
		if (t2<=10) //show "S :AL" (Set Alarm) while setting the clock
		{
		d[0]= seg[5];
		d[1]= seg[10];
		d[2]= seg[17];
		d[3]= seg[20];
		}
		else		//show "S :CL" (Set clock) while setting the clock
		{
		d[0]= seg[5];
		d[1]= seg[10];
		d[2]= seg[12];
		d[3]= seg[20];
		}
	}
	else
	if (ClockMode==SHOWDATE)
	{
		//computing hours and minutes
		month=digit/100;
		date=digit-month*100;
		d[4]= month/10;
		d[5]= month-d[4]*10;
		d[6]= date/10;
		d[7]= date-d[6]*10;
		if (d[4]!=0) 	d[0]= seg[d[4]];
		else			d[0]= seg[16];
		//d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		if (d[6]!=0) 	d[2]= seg[d[6]];
		else			d[2]= seg[16];
		//d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	if (ClockMode==SHOWYEAR)
	{
		//computing hours and minutes
		year=digit;
		d[4]= year/1000;
		year-=d[4]*1000;
		d[5]= year/100;
		year-=d[5]*100;
		d[6]= year/10;
		year-=d[6]*10;
		d[7]= year;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	else
	if (ClockMode==SHOWTEMP)
	{
		d[4]= digit/10;
		d[5]= digit-d[4]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		d[2]= seg[11];
		d[3]= seg[12];
	}
	else
	if (ClockMode==SETHOURS)
	{
		d[4]= dt1.hour/10;
		d[5]= dt1.hour-d[4]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]]+SEG_dot;
		d[2]= seg[16];
		d[3]= seg[16];
	}
	else
	if (ClockMode==SETMINUTES)
	{
		d[6]= dt1.minute/10;
		d[7]= dt1.minute-d[6]*10;
		d[0]= seg[16];
		d[1]= seg[16]+SEG_dot;
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	else
	if (ClockMode==SETDATE)
	{
		d[6]= dt1.date/10;
		d[7]= dt1.date-d[6]*10;
		d[0]= seg[16];
		d[1]= seg[16];
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	else
	if (ClockMode==SETMONTH)
	{
		d[4]= dt1.month/10;
		d[5]= dt1.month-d[4]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		d[2]= seg[16];
		d[3]= seg[16];
	}
	else
	if (ClockMode==SETYEAR)
	{
		d[4]= 2;
		d[5]= dt1.year/100;
		d[6]= (dt1.year-d[5]*100)/10;
		d[7]= dt1.year-d[5]*100-d[6]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]];
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	else
	if (ClockMode==SETALHOURS)
	{
		d[4]= ALHours/10;
		d[5]= ALHours-d[4]*10;
		d[0]= seg[d[4]];
		d[1]= seg[d[5]]+SEG_dot;
		d[2]= seg[16];
		d[3]= seg[16];
	}
	else
	if (ClockMode==SETALMINUTES)
	{
		d[6]= ALMinutes/10;
		d[7]= ALMinutes-d[6]*10;
		d[0]= seg[16];
		d[1]= seg[16]+SEG_dot;
		d[2]= seg[d[6]];
		d[3]= seg[d[7]];
	}
	else
	if (ClockMode==SETAL)
	{
		if (ALSet==1) //on
		{
			d[0]= seg[15];
			d[1]= seg[13];
			d[2]= seg[16];
			d[3]= seg[16];
		}
		else
		{
			d[0]= seg[15];
			d[1]= seg[14];
			d[2]= seg[14];
			d[3]= seg[16];
		}
	}
	else
	if (ClockMode==SETSECMODE)
	{
		d[6]= SecMode;
		d[0]= seg[16];
		d[1]= seg[16];
		d[2]= seg[16];
		d[3]= seg[d[6]];
	}

	//computing seconds -> multiple choices available pertaining to the design we wish
	switch(SecMode)
	{
		case 1: //seconds go normally
			in1=seconds/8;
			for (i=0;i<in1;i++)
			{
				d[i+10]=0x00;
			}
			d[in1+10]=dectobin(seconds-in1*8);
				for (i=in1+11;i<18;i++)
			{
				d[i]=0x00;
			}
			break;
		case 2: //seconds are all lit except the current one
				in1=seconds/8;
				for (i=0;i<in1;i++)
				{
					d[i+10]=0xFF;
				}
				d[in1+10]=~dectobin(seconds-in1*8);
				for (i=in1+11;i<18;i++)
				{
					d[i]=0xFF;
				}
			break;
		case 3: //seconds fill progressively
			in1=seconds/8;
			for (i=0;i<in1;i++)
			{
				d[i+10]=0xFF;
			}
			d[in1+10]=p2(seconds-in1*8);
				for (i=in1+11;i<18;i++)
			{
				d[i]=0x00;
			}
			break;
		case 4:	//seconds empty progressively
			in1=seconds/8;
			for (i=0;i<in1;i++)
			{
				d[i+10]=0x00;
			}
			d[in1+10]=~p2(seconds-in1*8);
			for (i=in1+11;i<18;i++)
			{
				d[i]=0xFF;
			}
			break;
		case 5://seconds fill progressively at odd minutes and empty progressively at even minutes
			if (odd(dt.minute))
			{
				in1=seconds/8;
				for (i=0;i<in1;i++)
				{
					d[i+10]=0xFF;
				}
				d[in1+10]=p2(seconds-in1*8);
				for (i=in1+11;i<18;i++)
				{
					d[i]=0x00;
				}
			}
			else
			{
				in1=seconds/8;
				for (i=0;i<in1;i++)
				{
					d[i+10]=0x00;
				}
				d[in1+10]=~p2(seconds-in1*8);
				for (i=in1+11;i<18;i++)
				{
					d[i]=0xFF;
				}
			}
			break;
		case 6: //seconds go normally and red leds lit
			in1=seconds/8;
			cc(0b00100001,0b10000100,0b00010000,0b01000010,0b00001000,0b00100001,0b10000100,0b00010000,in1);
			break;
		case 7:	//seconds go normally and red leds lit. Red leds shift when the current second falls on them
			in1=seconds/8;
			if (seconds-seconds/5*5!=0)
				cc(0b00100001,0b10000100,0b00010000,0b01000010,0b00001000,0b00100001,0b10000100,0b00010000,in1);
			else
			if (odd(seconds/5))
				cc(0b01000010,0b00001000,0b00100001,0b10000100,0b00010000,0b01000010,0b00001000,0b00100001,in1);
			else
				cc(0b00010000,0b01000010,0b00001000,0b00100001,0b10000100,0b00010000,0b01000010,0b00001000,in1);


			break;
		case 8:	//seconds go normally and red leds lit. Red leds go off when the current second falls on them
			in1=seconds/8;
			if (seconds-seconds/5*5!=0)
				cc(0b00100001,0b10000100,0b00010000,0b01000010,0b00001000,0b00100001,0b10000100,0b00010000,in1);
			else
				cc(0,0,0,0,0,0,0,0,in1);


			break;
		case 9:	//try inventing something here: you first to do job
			break;
		default:
			break;
	}
}

//function that beeps
void beep(void)
{
	PORTB &= ~_BV(4);
	_delay_ms(10);
	PORTB |= _BV(4);
}

void init(void)
{
	//Timer 0 stopped
	TCNT0 = 0xFF ;
	TCCR0 = 0x00; 
	//Timer 1 enabled
	TCNT1 = 0xFF ;
	TCCR1A = 0x02; 	//9 bit PWM with external pins disconnected
	TCCR1B = 0x02; 	//prescaler of 8
	TIMSK = 0x82; 	//timer overflow interrupts enabled
	GICR = 0x00; 	//external interrupts disabled: will manage switch pushes in software
	sei();			//enable interrupts

//PORTS
	PORTA=0xFF;		
	DDRA =0xFF;		
	DDRB |=_BV(0) | _BV(4);
	PORTB|=_BV(0) | _BV(1) | _BV(2) | _BV(3)| _BV(4);
	PORTC=0xFF;
	DDRC =0xFF;
	
	PORTD=0xff;
	DDRD =_BV(0) | _BV(1) |_BV(4)|_BV(5)|_BV(6)|_BV(7);

	display();				
	//if SELECT pushed on startup, set the mode seconds are displayed.
	if (bit_is_clear(KPIN, KEYSELECT) || bit_is_clear(KPIN, KEYSET))	ClockMode=SETSECMODE;
	//read EEprom values to current variables
	SecMode= eeprom_read_byte(&ESecMode);
	ALHours= eeprom_read_byte(&EALHours);
	ALMinutes= eeprom_read_byte(&EALMinutes); 
	ALSet= eeprom_read_byte(&EALSet);
}



//function to check if the alarm should start
void CheckAlarm(void)
{
	if (ALSet)
	{
	if ((ALHours==dt.hour) && (ALMinutes==dt.minute) && (dt.second==0))
		{
			AlarmOn=1;
			t3=0;
		}
	}
	if (AlarmOn)
	{
		beep();
		_delay_ms(10);
		t3++;
		if (t3==2900) AlarmOn=0; //2900=10 minutes
	}
}


//function which reads if there is any key pressed
uint8_t readkeys(void)
{
	uint16_t keypressed=0;

	//SELECT and SET keys simultaneously. Not used.
	if (bit_is_clear(KPIN, KEYSELECT) && bit_is_clear(KPIN, KEYSET))
	{
		keypressed=3;
		_delay_ms(20);
	}
	//SELECT key
	else
	if bit_is_clear(KPIN, KEYSELECT) 
	{
		keypressed=1;
		_delay_ms(20);
	}
	//SET key
	else
	if bit_is_clear(KPIN, KEYSET) 
	{
		keypressed=2;
		_delay_ms(20);
	}
	else	keypressed=0;
	return keypressed;

}


//main loop
int main()
 
{
uint8_t key;
	init();
	_delay_ms(10);
	beep();
	while(1)
	{
		//if any key pressed right after reset
		//entering SetSecMode 
		if ((Start==1) && (ClockMode==SETSECMODE))
		{
			key=0;
			t1=6000;
			Start=0;
		}
		else
			key=readkeys();
		//no key pressed
		if (key==0)
		{
			//void all long key presses
			switch (ClockMode)
			{
			case SHOWCLOCK:
				if (t2==0)
				{
					//show clock
					dt=get_date_time();
					digit=dt.hour*100+dt.minute;
					seconds=dt.second;
				}
				else
				if (t2<=5)
				{
					//show the date
					t1=6000;
					t2=0;
					ClockMode=SHOWDATE;
				}
				else
				if (t2<=10)
				{
					//set the alarm
					t1=6000;
					t2=0;
					ClockMode=SETALMINUTES;
				}
				else
				{
					//set the date
					t1=6000;
					t2=0;
					dt1=dt;
					ClockMode=SETYEAR;
				}
				break;	
			case SHOWTEMP:	
				//show temperature until timer expires
				//digit = ds18b20_gettemp();
				digit = get_ds1621_temperature();
  				dt=get_date_time();
				seconds=dt.second;
				_delay_ms(1);
				break;	
			case SHOWDATE:
			//show the date
				dt=get_date_time();
				digit=dt.month*100+dt.date;
				seconds=dt.second;
				break;	
			case SHOWYEAR:
			//show the year
				dt=get_date_time();
				digit=2000+dt.year;
				seconds=dt.second;
				break;	
			case SETHOURS:
				_delay_ms(1);
				break;	
			case SETMINUTES:	
				_delay_ms(1);
				break;	
			case SETDATE:
				_delay_ms(1);
				break;	
			case SETMONTH:
				_delay_ms(1);
				break;	
			case SETYEAR:
				_delay_ms(1);
				break;	
			case SETALHOURS:
				_delay_ms(1);
				break;	
			case SETALMINUTES:
				_delay_ms(1);
				break;	
			case SETAL:
				_delay_ms(1);
				break;	
			case SETSECMODE:
				//read seconds to be displayed
				dt=get_date_time();
				seconds=dt.second;
				_delay_ms(1);
				break;	
			default:
				break;	
			}
		}
		else
		//set key was pressed
		if (key==1)
		{
			if (AlarmOn)
			{
				AlarmOn=0;
			}
			switch (ClockMode)
			{
			case SHOWCLOCK:
				//set to SHOWTEMP and set the timer to ~10 seconds
				t1=900;
				ClockMode=SHOWTEMP;
				break;	
			case SHOWTEMP:	
				//nothing to do	
				break;	
			case SHOWDATE:
				break;	
			case SHOWYEAR:
				break;	
			case SETHOURS:
				t1=900;
				if (++dt1.hour>MaxHours) dt1.hour=MinHours;
				break;	
			case SETMINUTES:	
				t1=900;
				if (++dt1.minute>MaxMinutes) dt1.minute=MinMinutes;
				break;	
			case SETDATE:
				t1=900;
				if (++dt1.date>MaxDate) dt1.date=MinDate;
				break;	
			case SETMONTH:
				t1=900;
				if (++dt1.month>MaxMonth) dt1.month=MinMonth;
				break;	
			case SETYEAR:
				t1=900;
				if (++dt1.year>MaxYears) dt1.year=MinYears;
				break;	
			case SETALHOURS:
				t1=900;
				if (++ALHours>MaxALHours) ALHours=MinALHours;
				break;	
			case SETALMINUTES:
				t1=900;
				if (++ALMinutes>MaxALMinutes) ALMinutes=MinALMinutes; 
				break;	
			case SETAL:
				t1=900;
				if (++ALSet>MaxALSet) ALSet=MinALSet;
				break;	
			case SETSECMODE:
				dt=get_date_time();
				seconds=dt.second;
				t1=900;
				if (++SecMode>MaxSecMode) SecMode=MinSecMode;
				break;	
			default:
				break;	
			}
		}
		else
		//select key pressed
		if (key==2)
		{
			if (AlarmOn)
			{
				AlarmOn=0;
			}
			switch (ClockMode)
			{
			case SHOWCLOCK:
				//short key press 1-5 seconds: show date/time for 10 seconds
				//long key press 6-10 seconds: enter alarm set
				//more than 10 seconds pressed: enter date set
					t2++;
					digit=t2;
			case SHOWTEMP:
				break;	
			case SHOWDATE:
				t1=900;
				ClockMode=SHOWYEAR;
				break;	
			case SHOWYEAR:
				break;	
			case SETHOURS:
				//write the time/date/year into the DS1302
				set_date_time(dt1);
				t1=0;
				beep();
				_delay_ms(200);
				break;	
			case SETMINUTES:	
				ClockMode=SETHOURS;
				break;	
			case SETDATE:
				ClockMode=SETMINUTES;
				break;	
			case SETMONTH:
				ClockMode=SETDATE;
				break;	
			case SETYEAR:
				ClockMode=SETMONTH;
				break;	
			case SETALHOURS:
				ClockMode=SETAL;
				break;	
			case SETALMINUTES:
				ClockMode=SETALHOURS;
				break;	
			case SETAL:
				//write Alarm Values into EEPROM
				eeprom_write_byte(&EALHours,ALHours);
				eeprom_write_byte(&EALMinutes,ALMinutes);
				eeprom_write_byte(&EALSet,ALSet);
				t1=0;
				beep();
				_delay_ms(200);
				break;	
			case SETSECMODE:
				//write SecMode into EEPROM
				eeprom_write_byte(&ESecMode,SecMode);
				t1=0;
				beep();
				_delay_ms(200);
				break;	
			default:
				break;	
			}
		}
		t1--;
		if (t1==0xFFFF) t1=0;
		if (t1==0) ClockMode=SHOWCLOCK;
		display();
		CheckAlarm();
	}

}
 
