#include "lcd.h"
#include "../mcu/pmp.h"
#include "../mcu/delay.h"

#define BUSY		0x80

void LcdCommandW(uint8 x)
{
	PMCONbits.PMPEN = 0;
	TRISE = 0;		// as output
	LCD_RS = 0;
	LCD_E = 1;
	asm volatile(" NOP \n NOP");
	LATE = x;
	asm volatile(" NOP \n NOP");
	LCD_E = 0;
	PMCONbits.PMPEN = 1;
}

void LcdDataW(uint8 x)
{
	PMCONbits.PMPEN = 0;
	TRISE = 0;		// as output
	LCD_RS = 1;
	LCD_E = 1;
	asm volatile(" NOP \n NOP");
	LATE = x;
	asm volatile(" NOP \n NOP");
	LCD_E = 0;
	PMCONbits.PMPEN = 1;
}

char lcd_ready(void)
{
	wait_1us(50);
	return 1;
}

char lcd_ready2(void)
{
	wait_1ms(10);
	return 1;
}

void lcd_clrscr(void)       
{
	lcd_ready2();
	LcdCommandW(0x01);
}

char lcd_init(void)
{
	// Initialize I/O
	TRISBbits.TRISB4 = 0;		// PORTB.4,LCD_RS  as output
	asm volatile("NOP");
	TRISBbits.TRISB5 = 0;		// PORTB.5,LCD_E  as output
	asm volatile("NOP");

	lcd_ready2();
	LcdCommandW(0x38);

	lcd_ready();
	LcdCommandW(0x0C);

	lcd_ready();
	LcdCommandW(0x06);			// increment address

	return 1;
}

void lcd_gotoxy(u_char x, u_char y)
{
    lcd_ready();
    switch(y)
    {
        case 0 : LcdCommandW(0x80 + x); break;
        case 1 : LcdCommandW(0xC0 + x); break;
        case 2 : LcdCommandW(0x94 + x); break;
        case 3 : LcdCommandW(0xD4 + x); break;
    }
}

char * lcd_puts(char* str)
{
	unsigned char i;

	for (i=0; str[i] != '\0'; i++){
		lcd_ready();
		LcdDataW(str[i]);
	}
	return str;
}

void lcd_putch(char ch)
{
	lcd_ready();
	LcdDataW(ch);
}
