#include "lcd.h"

//===================================================
// Initialize_LCD()
//===================================================
void LCD_init() {
	unsigned int i; //loop count
	TRISD	= PORTD_DIRECTION;
	TRISE	= PORTE_DIRECTION;
	ADCON1	= 0x02;	// configure all RE pins to be digital pins
	LCD_RW 	= 0;	// write to LCD only
	LCD_E	= 0;	// pull down E line

	TMR2ON	= 1;			// Turn on Timer2

	// initialize LCD
	#ifndef DEBUG
		//24.51 millisecond delay
		for(i=0;i<3500;i++) { 
			wait_15us(); 
		}
	#endif
	write_char_to_LCD(0,0x38);	// write 0x38 to LCD

	#ifndef DEBUG
		//14 millisecond delay
		for(i=0;i<2000;i++) { 
			wait_15us(); 
		}	
	#endif
	write_char_to_LCD(0,0x38);	// write 0x38 to LCD

	#ifndef DEBUG
		//4.9 millisecond delay
		for(i=0;i<700;i++) {
			wait_15us(); 
		}
	#endif

	write_char_to_LCD(0,0x38);	// write 0x38 to LCD
	// send actual commands
	write_char_to_LCD(0,0x38);	// 8-bit data, 2 lines, 5x7 font
	write_char_to_LCD(0,0x01);	// clear display, return cursor to home
	write_char_to_LCD(0,0x0C);	// turn display on, cursor off
	write_char_to_LCD(0,0x06);	// cursor increment
	return;
}

//===================================================
// wait_15us()
//===================================================
// use Timer2 to generate 14.80 microsecond delay each time this routine is called
// at 20 MHz
void wait_15us() {
	#ifndef DEBUG
		TMR2	= 256-53;
		while(TMR2IF==0) {};
	#endif
	return;
}
//===================================================
// write_string_to_LCD(char *)
//===================================================
//#pragma interrupt_level 1
void write_string_to_LCD(const char *str) {
	// always write a character to LCD

	char j = 0;
	while (str[j] != '\0') {
		write_char_to_LCD(1, str[j++]);
	}
		
	return;
} // end write_string_to_LCD()


//===================================================
// write_char_to_LCD(register, data)
//===================================================
//#pragma interrupt_level 1
void write_char_to_LCD(char register_select, char data) {
	char i;
	LCD_DATA = data;
	if (register_select == 0) {
		LCD_RS = 0;
	} else {
		LCD_RS = 1;	// write data
	}
	#ifndef DEBUG
		// 191.65 usecond delay
		for(i=0;i<40;i++) {
			wait_15us(); 
		}
	#endif
	LCD_E = 1;	// pull up E line
	#ifndef DEBUG
		//1.4 millisecond delay
		for(i=0;i<200;i++) { 
			wait_15us(); 
		}
	#endif
	LCD_E	= 0;	// transfer data
	#ifndef DEBUG
		// 43 usecond delay
		for(i=0;i<20;i++) {
			wait_15us(); 
		}
	#endif
	return;
}