/*
 *	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):
 *	
 *	PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
 *	PORTA bit 2 is connected to the LCD RS input (register select)
 *	PORTA bit 3 is connected to the LCD EN bit (enable)
 *	
 *	To use these routines, set up the port I/O (TRISA, TRISB) then
 *	call lcd_init(), then other routines as required.
 *	
 */

#include	<pic.h>
#include	"lcd.h"
#include	"delay.h"
 
#define	LCD_STROBE	((LCD_EN = 1),(LCD_EN=0))


//-----------------------------------------------------------------------------------
//		LCD write routine
//-----------------------------------------------------------------------------------
/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
	PORTB = (PORTB & 0x0F) |  (c & 0xF0);
	LCD_STROBE;
	PORTB = (PORTB & 0x0F) |  (c << 4);
	LCD_STROBE;
	DelayUs(40);
}

void
lcd_writex(unsigned char c)
{
	PORTB = (PORTB & 0x0F) |  (c & 0xF0);
	LCD_STROBE;
}

/*
 * 	Clear and home the LCD
 */

void
lcd_clear(void)
{
	LCD_RS = 0;
	lcd_write(0x1);
	DelayMs(2);
}

/* write one character to the LCD */

void
lcd_putch(char c)
{
	LCD_RS = 1;	// write characters
	lcd_write(c);
}

/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
	LCD_RS = 1;	// write characters
	while(*s)
		lcd_write(*s++);
}


/*
 * Go to the specified position
 */

void
lcd_curs(unsigned char pos)
{
	LCD_RS = 0;
	lcd_write(((pos)&0x7F)|0x80);
}
	
void lcd_prints(unsigned char pos, const char *s)
{
	lcd_curs(pos);
	lcd_puts(s);
}


/* initialise the LCD - put into 4 bit mode */

void
lcd_init(void)
{
	LCD_RW = 0;
	LCD_RS = 0;	// write control bytes
	DelayMs(15);	// power on delay
	lcd_writex(0x30);	// attention!
	DelayMs(5);
	LCD_STROBE;
	DelayUs(100);
	LCD_STROBE;
	DelayMs(5);
	lcd_writex(0x20);	// set 4 bit mode
	DelayUs(40);
	lcd_write(0x28);	// 4 bit mode, 1/16 duty, 5x8 font
	lcd_write(0x08);	// display off
	lcd_write(0x0F);	// display on, blink curson on
	lcd_write(0x06);	// entry mode
}

void
blink_led(unsigned char n)
{
	while (n--) {
	  LED = 1;
	  DelayMs(100);
	  LED = 0;
	  DelayMs(100);
	}
}

char
hexch(unsigned char n)
{
	unsigned char x;

	x = n&0x0f|0x30;
	if (x>'9') x += 7;
	return(x);
}
	
void
lcd_puthex2(unsigned char n)
{
	unsigned char m;

	m = n;
	LCD_RS = 1;	// write characters
	lcd_write(hexch(m>>4));
	lcd_write(hexch(n));
}