//=============================================================================
// Filename: main.c
//=============================================================================
// Autoren:		Christian Blass		Marcus Dettki
// Matr-Nr.:	130623				830621
// Version:		1.00
// Erstellt:	16.06.2005
//=============================================================================
// Compiler:	MPLAB-C18 V2.40
//=============================================================================
// Projekt:		Propeller-Clock
//=============================================================================
// Beschreibung:
// Beschaltung des PortB eines PIC18F4550 zur Ausgabe von Zeichen auf einer
// rotierenden Scheibe. Der Nullpunkt der Umdrehungen wird durch einen Takt
// am Eingang RA4 bestimmt.
//
// Probleme:
// - Bei unguenstiger Drehzahl werden die Werte von Timer 1 falsch ausgelesen
// - Uhrzeit noch nicht implementiert
// - Wenn Zeichen über den Nullpunkt hinaus ausgegeben werden, fällt das
//   Programm in einen nicht definierten Zustand (Zeichen werden viel zu
//   breit ausgegeben und sind nicht mehr lesbar)
//=============================================================================

//----------------------------------------------------------------------------

#include <p18f4550.h>

//----------------------------------------------------------------------------

void main (void);
void InterruptHandlerHigh (void);

//----------------------------------------------------------------------------

unsigned char hour, min, sec;
int col=0;
int sign=0;
int takte=255;
long int takte_pro_umdrehungen=0;
int umdrehungen=0;
int i=0;

/*unsigned int signs[12][5] =	{
								{0x3E,0x45,0x49,0x51,0x3E}, // 0
								{0x00,0x21,0x7F,0x01,0x00}, // 1
								{0x21,0x43,0x45,0x49,0x31}, // 2
								{0x42,0x41,0x51,0x69,0x46}, // 3
								{0x0C,0x14,0x24,0x7F,0x04}, // 4
								{0x72,0x51,0x51,0x51,0x4E}, // 5
								{0x1E,0x29,0x49,0x49,0x06}, // 6
								{0x40,0x47,0x48,0x50,0x60}, // 7
								{0x36,0x49,0x49,0x49,0x36}, // 8
								{0x30,0x49,0x49,0x4A,0x3C}, // 9
								{0x00,0x00,0x36,0x00,0x00}, // :
								{0x00,0x00,0x01,0x00,0x00}  // .
							};*/

unsigned int pdv[12][5] =	{
								{0x7f,0x48,0x48,0x48,0x30}, // P
								{0x7f,0x41,0x41,0x41,0x3e}, // D
								{0x7c,0x02,0x01,0x02,0x7c}, // V
								{0x00,0x00,0x00,0x00,0x00}, // 
								{0x00,0x41,0x7f,0x41,0x00}, // I
								{0x31,0x49,0x49,0x49,0x46}, // S
								{0x40,0x40,0x7f,0x40,0x40}, // T
								{0x00,0x00,0x00,0x00,0x00}, // 
								{0x40,0x40,0x7f,0x40,0x40}, // T
								{0x3e,0x41,0x41,0x41,0x3e}, // O
								{0x7f,0x01,0x01,0x01,0x01}, // L
								{0x7f,0x01,0x01,0x01,0x01}  // L
							};

/*unsigned int pdv[3][5] =	{
								{0x7f,0x48,0x48,0x48,0x30}, // P
								{0x7f,0x41,0x41,0x22,0x1c}, // D
								{0x7c,0x02,0x01,0x02,0x7c}  // V
							};*/

//----------------------------------------------------------------------------

union
{
	struct
	{
		unsigned Timeout:1;		//flag to indicate a TMR0 timeout
		unsigned None:7;
	} Bit;
	unsigned char Byte;
} Flags;


//----------------------------------------------------------------------------
// Main routine


void
main ()
{
	Flags.Byte = 0;
	INTCON = 0x20;				//disable global and enable TMR0 interrupt
	INTCON2 = 0x84;				//TMR0 high priority
	PIR1 = 0x01;				//enable TMR1 interrupt
	PIE1 = 0x01;				//enable TMR1 overflow interrupt
	IPR1 = 0x01;				//TMR1 high priority
	RCONbits.IPEN = 1;			//enable priority levels
	TMR0L = 254;				//clear timer
	TMR1H = 0;					//clear timer
	TMR1L = 0;					//clear timer
	T0CON = 0xe8;				//set up timer0 from T0CKI
	T1CON = 0x01;				//set up timer1 - prescaler 1:1
	INTCONbits.GIEH = 1;		//enable interrupts
	TRISB = 0;

	LATB = 0x0;

	while (1)
	{
		if (Flags.Bit.Timeout == 1)
		{								//timeout?
			Flags.Bit.Timeout = 0;		//clear timeout indicor
			for (sign=0;sign<12;sign++)
			{
				for (col=0;col<5;col++)
				{
					LATB = pdv[sign][col];
					for (i=0;i<takte;i++);
				}
				LATB = 0x00;
				for (i=0;i<takte;i++);
			}
			if (umdrehungen==16)
			{
				takte=((takte_pro_umdrehungen/umdrehungen)/180)/13;
				takte_pro_umdrehungen=0;
				umdrehungen=0;
			}
        }
    }
}


//----------------------------------------------------------------------------
// High priority interrupt vector


#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
	_asm
		goto InterruptHandlerHigh //jump to interrupt routine
	_endasm
}





//----------------------------------------------------------------------------
// High priority interrupt routine

#pragma code
#pragma interrupt InterruptHandlerHigh

void InterruptHandlerHigh ()
{
	if (INTCONbits.TMR0IF)					// pro Umdrehung
	{										//check for TMR0 overflow
		INTCONbits.TMR0IF = 0;				//clear interrupt flag
		takte_pro_umdrehungen+=TMR1H*256;
		takte_pro_umdrehungen+=TMR1L;
		TMR1H=TMR1L=0;
		umdrehungen++;
		TMR0L=255;
		Flags.Bit.Timeout = 1;				//indicate timeout
	}
	else if (PIR1bits.TMR1IF)				// pro Ueberlauf TMR1
	{										//check for TMR1 overflow
		PIR1bits.TMR1IF = 0;				//clear interrupt flag
		takte_pro_umdrehungen+=65536;
	}
}

//----------------------------------------------------------------------------
