/*********************************************

Project : EE476 Final Project--Digital Mirror
Message Machine
Date : 4/11/2001
Author : Brian Ellyson & Dee-Pong Lu
Company : Cornell University 

Comments: Variation of our final code which
displays a 12 hour clock.  Push button 0 on
the development board increases the minute
when held down, and push button 1 increases
the hour.


Chip type : AT90S8515
Clock frequency : 4.000000 MHz
Memory model : Small
Internal SRAM size : 512
External SRAM size : 0
Data Stack size : 128
*********************************************/


#include <90s8515.h>
#include <delay.h>

// Declare your global variables here
unsigned char i, j, temp;
unsigned int count, time;
unsigned int counter;
unsigned int display;
unsigned int initDelay, rastorDelay;
unsigned char setlights, debounce;
unsigned char message[8]={'1', '2', ':', '0', '0', ':', '0', '0'};
unsigned char rastor[259]={
0x83,	0x7D,	0x7D,	0x7D,	0x83,	0xFF,   0xFF,//0
0xFF,	0xBD,	0x01,	0xFD,	0xFF,	0xFF,	0xFF,//1
0xBD,	0x79,	0x75,	0x6D,	0x9D,	0xFF,	0xFF,//2
0x7B,	0x7D,	0x5D,	0x3D,	0x73,	0xFF,	0xFF,//3
0xE7,	0xD7,	0xB7,	0x01,	0xF7,	0xFF,	0xFF,//4
0x1B,	0x5D,	0x5D,	0x5D,	0x63,	0xFF,	0xFF,//5
0xC3,	0xAD,	0x6D,	0x6D,	0xF3,	0xFF,	0xFF,//6
0x7F,	0x71,	0x6F,	0x5F,	0x3F,	0xFF,   0xFF,//7
0x93,	0x6D,	0x6D,	0x6D,	0x93,	0xFF,	0xFF,//8
0x9F,	0x6D,	0x6D,	0x6B,	0x87,	0xFF,   0xFF,//9 
0xFF,	0x93,	0x93,	0xFF,	0xFF,	0xFF,	0xFF,//:
0x81,	0x77,	0x77,	0x77,	0x81,	0xFF,	0xFF,//A
0x01,	0x6D,	0x6D,	0x6D,	0x93,	0xFF,	0xFF,//B
0x83,	0x7D,	0x7D,	0x7D,	0xBB,	0xFF,	0xFF,//C
0x01,	0x7D,	0x7D,	0xBB,	0xC7,	0xFF,	0xFF,//D
0x01,	0x6D,	0x6D,	0x6D,	0x7D,	0xFF,	0xFF,//E
0x01,	0x6F,	0x6F,	0x6F,	0x7F,	0xFF,	0xFF,//F
0x83,	0x7D,	0x6D,	0x6D,	0xA1,	0xFF,	0xFF,//G
0x01,	0xEF,	0xEF,	0xEF,	0x01,	0xFF,	0xFF,//H
0xFF,	0x7D,	0x01,	0x7D,	0xFF,	0xFF,	0xFF,//I
0xFB,	0xFD,	0x7D,	0x03,	0x7F,	0xFF,	0xFF,//J
0x01,	0xEF,	0xD7,	0xBB,	0x7D,	0xFF,	0xFF,//K
0x01,	0xFD,	0xFD,	0xFD,	0xFD,	0xFF,	0xFF,//L
0x01,	0xBF,	0x4F,	0xBF,	0x01,	0xFF,	0xFF,//M
0x01,	0xDF,	0xEF,	0xF7,	0x01,	0xFF,	0xFF,//N
0x83,	0x7D,	0x7D,	0x7D,	0x83,	0xFF,	0xFF,//O
0x01,	0x6F,	0x6F,	0x6F,	0x9F,	0xFF,	0xFF,//P
0x83,	0x7D,	0x75,	0x7B,	0x85,	0xFF,	0xFF, //Q
0x01,	0x6F,	0x67,	0x6B,	0x9D,	0xFF,	0xFF, //R
0x9D,	0x6D,	0x6D,	0x6D,	0x73,	0xFF,	0xFF, //S
0x7F,	0x7F,	0x01,	0x7F,	0x7F,	0xFF,	0xFF, //T
0x03,	0xFD,	0xFD,	0xFD,	0x03,	0xFF,	0xFF, //U
0x07,	0xFB,	0xFD,	0xFB,	0x07,	0xFF,	0xFF, //V
0x03,	0xFD,	0xE3,	0xFD,	0x03,	0xFF,	0xFF, //W
0x39,	0xD7,	0xEF,	0xD7,	0x39,	0xFF,	0xFF, //X
0x1F,	0xEF,	0xF1,	0xEF,	0x1F,	0xFF,	0xFF, //Y
0x79,	0x75,	0x6D,	0x5D,	0x3D,	0xFF,	0xFF //Z
};

void incmin(void);
void inchour(void);
void incsec(void);
void setclock(void);

interrupt [EXT_INT0] void external_interrupt(void)
{ 
  initDelay=(34*(count/10))/64;
  count=0;
  setlights=1;	
}

interrupt [TIM1_COMPA] void cmpA_match(void)
{
 count++;
 counter++;
 time--;
 if (time==0) setclock();
}

void lights(void)
{
 delay_ms(initDelay);
 for (i=0; i<8; i++)
		{
		for (j=0; j<7; j++)
			{
			 PORTA=rastor[message[i]*7+j];
			 delay_us(95);
			}
		}		
PORTA=0xFF;
}

//********************************************************** 
// clock -- Polling the button and setting time
void setclock(void)
{
 time=1000;
 temp=(PIND | 0xfc);
 if ((temp==0xfe)|(temp==0xfd))
 	{debounce++;
     PORTB++;
 	} 
 else
 	debounce=0;
 
 if (debounce==5)
 	{
 	 debounce=0;
 	 if (temp==0xfe)
		incmin();
 	 if (temp==0xfd)
 	  	inchour();
    }
} 
 
//********************************************************** 

void inchour(void)
{
 if ((message[0]==1)&(message[1]==2))
 	{
 	 message[0]=0; message[1]=1;
 	}
 else if ((message[0]==0)&(message[1]==9))
 	{
 	 message[0]=1; message[1]=0;
 	}
 else
 	message[1]++;
}

void incmin(void)
{
 if ((message[3]==5)&(message[4]==9))
 	{
 	 message[3]=0; message[4]=0; inchour();
 	}
 else if ((message[3]!=5)&(message[4]==9))
 	{
 	 message[3]++; message[4]=0;
 	}
 else
 	message[4]++;
}

void incsec(void)
{
 if ((message[6]==5)&(message[7]==9))
 	{
 	 message[6]=0; message[7]=0; incmin();
 	}
 else if ((message[6]!=5)&(message[7]==9))
 	{
 	 message[6]++; message[7]=0;
 	}
 else
 	message[7]++;
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A
DDRA=0xff;
PORTA=0xff;

// Port B
DDRB=0xff;
PORTB=0xff;

// Port C
DDRC=0x00;
PORTC=0x00;

// Port D
DDRD=0x00;
PORTD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Output Compare
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Output Compare
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1A=400;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
GIMSK=0x40;
MCUCR=0x03;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
count=600;
counter=0;
display=0;
time=1000;
#asm
sei
#endasm


for (i=0; i<8; i++)
{
 if (message[i]<59)
 	message[i]=message[i]-48;
 else if (message[i]<91)
 	message[i]=message[i]-54;
}
while (1)
      {
       if (counter>10000)
       	{
       	 counter=0;
       	 incsec();       	
       	}
       if (setlights==1)
       	{
       	 setlights=0;
       	 lights();
       	}
       
  
       
      };      
}
