#define F_CPU 11059200UL  // 11,0592mhz

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>

#define STOP_TIMER    TCCR0 &= 0b11111000
#define START_TIMER   TCCR0 |= 0b00000011 // prescaler = c/64


typedef volatile unsigned char BYTE;
typedef volatile unsigned int WORD;



BYTE minutes=0;
BYTE seconds=0;
BYTE hours=0;
WORD Interrupts=0;

bool s=false;
bool h=false;
bool m=false;


unsigned char segs[]=
{
0b00111111,
0b00000110,
0b01011011,
0b01001111,
0b01100110,
0b01101101,
0b01111101,
0b00000111,
0b01111111,
0b01101111
};


ISR(TIMER0_OVF_vect)
{

 
Interrupts++;

// at 11,0592mhz with a 'Clock/64' prescaler, 675 interrupts = 1 sec!
if (Interrupts == 675)
		{
		if(++seconds>=60)
				{
				seconds=0;
				if(++minutes>=60)
						{
						minutes=0;
						if(++hours>=24)
								{
								hours=0;
								}
						}
				}
		Interrupts = 0;
		}

}






void ConfigureDevice(void)
{
cli(); // mask interruptions


_SFR_BYTE(DDRD)=0b11111111;
_SFR_BYTE(DDRC)=0b00001111;
_SFR_BYTE(DDRB)=0b00000000;

TCNT0 = 0x00;
START_TIMER;
TIMSK  |= _BV(TOIE0);






sei(); // unmask interruptions
}

int main(void)
{
// format:   8 8 : 8 8
// segment:  8 4   2 1
// segment is used to select each 7segments display one after the other (with pov there's no need to have 4 seven bits ports)
// 8=0b00001000;4=0b00000100;2=0b00000010;1=0b00000001
// btw, it's possible to use only one pin from c port with the 8th from b port (2 bits = 4 combinations) but then we'll need some extra elecronic demux part

unsigned char segment=1;
unsigned char portval=0;
unsigned char temp=0;
ConfigureDevice();

hours=0;
minutes=0;
seconds=0;

while(1)
		{

		m=(PINB&0b00000100)==0?0:m;
		h=(PINB&0b00000010)==0?0:h;

		if((PINB&0b00000001)!=0 && (PINB&0b00000010)!=0 &&  !h)
		{
		h=true;
		seconds=0;
		Interrupts=0;
		if(++hours>=24)
				{
				hours=0;
				}
		}
		

		temp=PINB&0b00000100;
		if((PINB&0b00000001)!=0 && (PINB&0b00000100)!=0 &&  !m)
		{
		m=true;
		seconds=0;
		Interrupts=0;
		if(++minutes>=60)
				{
				minutes=0;
				}
		}
		


		switch(segment)
				{
				//segs is inverted to use with common anode 7 segments displays (up to 300mA sinking current)
				case 1:/*xx:xV*/ portval=~segs[minutes%10];break;
				case 2:/*xx:Vx*/ portval=~segs[minutes/10];break;
				case 4:/*xV:xx*/ portval=~segs[hours%10];break;
				case 8:/*Vx:xx*/ portval=~segs[hours/10];break;
				}
		_SFR_BYTE(PORTC)=0;
		_SFR_BYTE(PORTD)=portval;
		_SFR_BYTE(PORTC)=segment;
		segment=(segment<<1)>8?1:segment<<1;
		}

}

