// ****************
//
//	LCD Functions
//	Donald Burnette
//	2-4-2007
//
// ****************


void initLCD(void);						// Code initiallizes LCD and display's Welcome
void LCDChar(char);						// Writes a single character to the LCD Screen
void LCDCommand(char);					// Sends a command to the LCD

void LCDLine(char[], int, int, int);	// writes message to LCD ("message", speed, x, y) where (x(1-4),y(0-19)) is the location on the screen
										// for no location change, use (-1,-1).

void LCDClear(void);					// Clear LCD Display
void LCDNumber(int, int, int, int);		// Write a number to the LCD (Number, , speed, x, y) where (x(1-4),y(0-19)) is the location on the screen
void LCDjump(int, int);					// Jumps to (x,y) on LCD where y is the row and x is the character in that row.
void createIRGui(void);					// Creates a GUI for reading IR Data



//Writes a single character to the LCD Screen			
void LCDChar(char character)
{

	char tempChar;

	//First nibble
	tempChar = character & 0xF0;
	tempChar |= 0x0A;
	PORTC  = tempChar;		
	_delay_us(1);
	tempChar &= 0b11110111;
	PORTC  = tempChar;		
	_delay_us(1);

	//Second nibble
	tempChar = character & 0x0F;
	tempChar *=	16;
	tempChar |= 0x0A;
	PORTC  = tempChar;		
	_delay_us(1);
	tempChar &= 0b11110111;
	PORTC  = tempChar;	
	_delay_us(1);
	
}

//Writes a single character to the LCD Screen			
void LCDCommand(char character)
{

	char tempChar;

	//First nibble
	tempChar = character & 0xF0;
	tempChar |= 0x08;
	PORTC  = tempChar;		
	_delay_us(2);
	tempChar &= 0b11110111;
	PORTC  = tempChar;	
	_delay_us(2);

	//Second nibble
	tempChar = character & 0x0F;
	tempChar *=	16;
	tempChar |= 0x08;
	PORTC  = tempChar;		
	_delay_us(2);
	tempChar &= 0b11110111;
	PORTC  = tempChar;	
	_delay_us(2);
	
}

//Clears screen and writes message to LCD
void LCDLine(char characters[], int delay, int x, int y)
{
	//Clear Display
	LCDjump(x, y);
	int i=0;
	int j=0;

	while (characters[i] != '\0' && i < 50)
	{
		LCDChar(characters[i]);	
		for(j=0; j< delay; j++)
		{
			_delay_ms(1);
		}
		i++;
	}

}

//Writes an integer value to the screen
void LCDNumber(int number, int delay, int x, int y)
{
	char charNumber[5];

	if (number < 0)
	{
		number = -1*number;
		charNumber[0] = '-';
	}
	else
	{
		charNumber[0] = ' ';
	}
	charNumber[1] = 0x30+(number/100)%10;
	charNumber[2] = 0x30+(number/10)%10;
	charNumber[3] = 0x30+(number)%10;
	charNumber[4] = '\0';

	LCDLine(charNumber, delay, x, y);

}

// Code initiallizes LCD and display's Welcome
void initLCD()
{
			PORTC = 0;
			DDRC  = 0xFF;

	LCDCommand(0b00110011);		// Set 4 bit mode
	_delay_ms(1);
	LCDCommand(0b00110010);		// Set 4 bit mode
	_delay_ms(1);
	LCDCommand(0b00101000);		// Function Set N=1. F=0
	_delay_ms(1);
	LCDCommand(0b00000001);		// Clear Display
	_delay_ms(1);
	LCDCommand(0b00000110);		// Entry Mode Set ID=1, S = 0
	_delay_ms(1);
	LCDCommand(0b00001100);		// Display On: Cursor=0, Blink=0
	_delay_ms(1);

}	

//Clears LCD Display
void LCDClear()
{
	LCDCommand(0b00000001);		// Clear Display
	_delay_ms(5);
}

// Moves the cursor to any position on the LCD screen anywhere from (1,0) to (4,19)
void LCDjump(int x, int y)
{
	char address = 0x80;

	if (-1 > y || y < 20)
	{
		switch (x)
		{
			case 1:
				address |= (char)(y);
				LCDCommand(address);
				break;

			case 2:
				address |= (char)(64+y);
				LCDCommand(address);
			break;

			case 3:
				address |= (char)(20+y);
				LCDCommand(address);
			break;

			case 4:
				address |= (char)(84+y);
				LCDCommand(address);
			break;

			default:
			break;
		}
	}
}

void createIRGui()
{
	LCDLine("IR1 D:", 0, 1, 0);
	LCDLine("IR1 V:", 0, 2, 0);
	LCDLine("IR1 A:", 0, 3, 0);
}
