// Ray Wagner
// Hantronix LCD display driver code

// Note:  this code has not been fully
// debugged to to both time constraints
// and problems with the EZ-USB development
// board.  As of 4/30/01 the dev board was
// no longer working and further testing
// of code was not possible.  


#include <ezusb.h>
#include <ezregs.h>
#include <intrins.h>

void initialize()
{
	// function which runs initialization routine
	// for LCD display

	PORTBCFG = 0x00;    // Set port B to I/O
	OEB = 0xff;
	
	// Here is an initialization routine which corresponds
	// to Hantronix's guide on how to initialize their LCD
	// displays:

	//EZUSB_Delay(15);	// wait 15ms after VDD reaches 4.5 V
	//OUTB = 0x38;
	//EZUSB_Delay(5); 	// wait 4.1ms
	//OUTB = 0x38;
	//EZUSB_Delay(1);	// wait 100 us
	//OUTB = 0x38;
	//OUTB = 0x28;
	//OUTB = 0x28;
	//OUTB = 0x22;
	//OUTB = 0x20;
	//OUTB = 0x22;
	//OUTB = 0x20;
	//OUTB = 0x30;
	//OUTB = 0x20;
	//OUTB = 0x2c;

	// Here's Hitachi's take on how to initialize the display.
	EZUSB_Delay(15);	// wait 15ms after VDD reaches 4.5 V
	OUTB = 0x08;
	OUTB = 0x08;
	OUTB = 0x00;
	OUTB = 0x00;
	OUTB = 0x0e;
	OUTB = 0x00;
	OUTB = 0x0c;
	OUTB = 0xa4;
	OUTB = 0xa2;


}


void displayTime( int hr, int min, bool pm) 
{
	// This function is the time-displaying workhorse.
	// it takes and integer describing the hour (1-12), an
	// integer describing the minute (00-59), and a boolean
	// signifying AM/PM status (AM=0, PM=1).  The hour digits
	// are displayed in positions 3 and 4 on the display.  
	// The minute digits are in positions 6 and 7.  AM/PM
	// is in positions 9 and 10.

	OUTB = 0x20;	// return cursor to home position
	OUTB = 0x30;	
	writeBlank();	// write a blank in the first space
	writeBlank();	// write a blank in the second space	
	
	int hourUnitDigit;	// temporary variable to hold units digit 

	if (hr >= 10) {		// hour position 1 write
		writeChar(1);
		hourUnitDigit = hr - 10;
	}
	else {
		writeBlank();
		hourUnitDigit = hr;
	}

	writeChar(hourUnitDigit);	// hour position 2 write

	OUTB = b8;	// write colon
	OUTB = aa;


	int minUnitDigit;	// temporary variable to hold minute unit's digit

	if (min >= 50) {	// minute position 1 write
		writeChar(5);
		minUnitDigit = min - 50;
	}
	else {
		if (min >= 40) {
			writeChar(4);
			minUnitDigit = min - 40;
		}
		else { 
			if (min >= 30) {
				writeChar(3);
				minUnitDigit = min - 30;
			}
			else { 
				if (min >= 20) {
					writeChar(2);
					minUnitDigit = min - 20;
				}
				else {
					if (min >= 10) {
						writeChar(1);
						minUnitDigit = min - 10;
					}
					else {
						writeChar(0);
						minUnitDigit = min;
					}
					
				}
			}
		}
	}

	writeChar(minUnitDigit);		// minute position 2 write

	writeBlank();			// write one blank space

	if (pm) {
		OUTB = 0xb4;	// if pm = 1 write a 'P'
		OUTB = 0xa0;
	}
	else {
		OUTB = 0xa4;	// else write an 'A'
		OUTB = 0xb0;
	}

	OUTB = 0xa4;		// write an 'M'
	OUTB = 0xb6;

}



void displayAlarm(bool off, bool type)
{
	// this function displays the alarm icon.
	// if off = 1, nothing is displayed.
	// if off = 0 and type = 0, the buzz icon
	// is displayed.  if off = 0 and type = 1
	// the music icon is displayed.

	
	OUTB = 0x02;		// set DDRAM address to position
	OUTB = 0x16;		// for display character 16/

	if (off)
		writeBlank();	// write a blank if alarm off
	else {
		if (type) {
			OUTB = 0xb2;	// write a music icon
			OUTB = 0xac;	 
		}
		else {
			OUTB = 0xb2;	// write a buzzer icon
			OUTB = 0xa2;
		}
	}
} 
		
	

void writeChar (int char)
{
	// this function used to write a single numeric character
	// in the position specified by the cursor

	OUTB = 0xb8; 	// the first half of the code to write a 0-9 number

	// case-based second half of the 0-9 writing code:

	switch (char)	{
		case 0: OUTB = 0xa0;
		case 1: OUTB = 0xb0;
		case 2: OUTB = 0xa8;
		case 3: OUTB = 0xb8;
		case 4: OUTB = 0xa4;
		case 5: OUTB = 0xb4;
		case 6: OUTB = 0xac;
		case 7: OUTB = 0xbc;
		case 8: OUTB = 0xa2;
		case 9: OUTB = 0x52;
	}
}

	


}

void writeBlank() 
{
	OUTB = 0x30;	
	OUTB = 0xa8;
}	
 

void main()
{
	initialize();

	// test routine to see if I can write time and alarm status:
	
	displayTime(12,23,1);		// display call for 12:20 PM
	displayAlarm(0,1);		// display call for musical alarm

}










