/*
 *	LCD interface example
 *	Uses routines from delay.c
 *	This code will interface to a standard LCD controller
 *	like the Hitachi HD44780. It uses it in 4 bit mode, with
 *	the hardware connected as follows (the standard 14 pin 
 *	LCD connector is used):
 *	
 *	LCD_D bits 4-7 are connected to the LCD data bits 4-7 (high nibble)
 *	LCD_RS bit 2 is connected to the LCD RS input (register select)
 *	LCD_E bit is connected to the LCD E bit (enable)
 *	
 *	To use these routines, set up the port I/O (TRISA, TRISB) then
 *	call lcd_init(), then other routines as required.
 *	
 */

#include <xc.h>
#include "main.h"


#define	LCD_STROBE	((LCD_E = 1),(LCD_E=0))

/* 
 * write a byte to the LCD in 4 bit mode
 */
void lcd_write(unsigned char c)
{
    //PORTD = (PORTD & 0x0F) |  (c & 0xF0);
    if(c & 0x80) LCD_D7=1; else LCD_D7=0;
    if(c & 0x40) LCD_D6=1; else LCD_D6=0;
    if(c & 0x20) LCD_D5=1; else LCD_D5=0;
    if(c & 0x10) LCD_D4=1; else LCD_D4=0;
    LCD_STROBE;
    //PORTD = (PORTD & 0x0F) |  (c >> 4);
    if(c & 0x08) LCD_D7=1; else LCD_D7=0;
    if(c & 0x04) LCD_D6=1; else LCD_D6=0;
    if(c & 0x02) LCD_D5=1; else LCD_D5=0;
    if(c & 0x01) LCD_D4=1; else LCD_D4=0;
    LCD_STROBE;
    __delay_us(40);
}

/*
 * 	Clear and home the LCD
 */
void lcd_clear(void)
{
	LCD_RS = 0;
	lcd_write(0x1);
	__delay_ms(2);
}

/* 
 * write a string of chars to the LCD
 */
void lcd_puts(const char * s)
{
	LCD_RS = 1;	// write characters
	while(*s)
		lcd_write(*s++);
}

/*
 * write one character to the LCD
 */
void lcd_putc(char c)
{
	LCD_RS = 1;	// write characters
        lcd_write(c);
}


/*
 * Go to the specified position
 */
void lcd_goto(unsigned char pos)
{
	LCD_RS = 0;
	lcd_write(0x80+pos);
}
	
/* initialise the LCD - put into 4 bit mode */

void
lcd_init(void)
{
	LCD_RS = 0;	// write control bytes
	__delay_ms(15);	// power on delay
	//PORTD = (PORTD & 0x0F) | 0x30;	// attention!
        LCD_D7 = 0;
        LCD_D6 = 0;
        LCD_D5 = 1;
        LCD_D4 = 1;
	LCD_STROBE;
	__delay_ms(5);
	LCD_STROBE;
	__delay_us(100);
	LCD_STROBE;
	__delay_ms(5);
	//PORTD = (PORTD & 0x0F) | 0x20;	// set 4 bit mode
        LCD_D7 = 0;
        LCD_D6 = 0;
        LCD_D5 = 1;
        LCD_D4 = 0;
	LCD_STROBE;
	__delay_us(40);
	lcd_write(0x28);	// 4 bit mode, 1/16 duty, 5x8 font
	lcd_write(0x08);	// display off
	lcd_write(0x0C);	// display on, blink curson off
	lcd_write(0x06);	// entry mode
}
