/*functions about LCD
 *author
 *
 *
 *
 *
 *
 */

#include"lonly.h"

#define LCD_E  RB4
#define LCD_RS RB5
#define PORT_B PORTB


// ====================== send 4bit-data to LCD module ======================
static void LCD_send4(unsigned char cmd1) {

        LCD_RS = 0;

PORT_B = (PORT_B & 0xF0) | cmd1;
LCD_E = 1;
LCD_E = 0;
NOP();
        NOP();


return;
}

// ==================== Send 1byte-command to LCD module =================
static void LCD_cmd(unsigned char cmd1)
{
        // write upper 4bits
        LCD_RS = 0;
        unsigned char cmd2 = cmd1;
        cmd2 &= 0xF0;
        cmd2 >>= 4;
PORT_B = (PORT_B & 0xF0) | cmd2;
cmd2 = PORT_B;
LCD_E = 1;	 // write upper 4bits
        NOP();
        NOP();
        LCD_E = 0;
        NOP();
        NOP();
        cmd2 = cmd1 & 0x0F;
PORT_B = (PORT_B & 0xF0) | cmd2;
cmd2 = PORT_B;
LCD_E = 1;        // write lower 4bits
        NOP();
        NOP();
        LCD_E = 0;
        __delay_ms(7);

return;
}

// ==================== Send 1byte-data to LCD =================
static void LCD_data(unsigned char cmd1)
{
LCD_RS = 1;
        unsigned char cmd2 = cmd1;
        cmd2 &= 0xF0;
        cmd2 >>= 4;
PORT_B = (PORT_B & 0xF0) | cmd2;
cmd2 = PORT_B;
LCD_E = 1;	 // write upper 4bits
        NOP();
        NOP();

        LCD_E = 0;
        NOP();
        NOP();
        cmd2 = cmd1 & 0x0F;
PORT_B = (PORT_B & 0xF0) | cmd2;
cmd2 = PORT_B;
LCD_E = 1;        // write lower 4bits
        NOP();
        NOP();
        LCD_E = 0;
        __delay_ms(4);


return;
}

// ==================== LCD initialization ===========================
/*
 *      LCD
 *	RB0:LCD_DB4
 *	RB1:LCD_DB5
 *	RB2:LCD_DB6
 *	RB3:LCD_DB7
 *	RB5:LCD_RS
 *	RB4:LCD_E
 *	LCD_R/W  : GND
*/

void LCD_init()
{
LCD_RS = 0;
LCD_E = 0;
        __delay_ms(70);

LCD_send4(0x03);	// Send 3 to DB4-7
        __delay_ms(30);
LCD_send4(0x03);	// Send 3 to DB4-7
        __delay_ms(13);
LCD_send4(0x03);	// Send 3 to DB4-7
        __delay_ms(3);
LCD_send4(0x02);	// Send 2 to DB4-7
        __delay_ms(2);

        // 4bit mode
LCD_cmd(0x28);	// DL=0:4bit ,N=1:2lines ,F=0:5*7dot
        __delay_ms(3);
        LCD_cmd(0x08);	// Display off
        LCD_cmd(0x01);	// Display on ,cursor on ,no blink
        LCD_cmd(0x0C);	// Display on ,cursor on ,no blink
        LCD_cmd(0x06);	// Entry mode (Inc ,No Shift)
//      LCD_cmd(0x07);	// Entry mode (Inc ,With Shift)
        LCD_cmd(0x01);	// Clear Display
        __delay_ms(200);

return;
}

// ================== location function ===========
void LCD_locate(unsigned char x, unsigned char y)
{
unsigned char cmd1;

cmd1 = 3-x;	//
cmd1 *= 0x40;	//
cmd1 += y;	//
cmd1--;	//
        cmd1 |= 0x80;	 //
        LCD_cmd(cmd1);
}

// ================== word outputs ===========
void LCD_print( const char *c )
{
while(*c!=0x00 ) //'\0'
        {
            LCD_data( *c );
                c++;
}
}
// ================ LCD clear =================

void LCD_clr()
{
        LCD_cmd(1);
        __delay_ms(1000);
}

static void ByteToStr(int value, char string[])
 {
        char digit;

        *string++ = '0';
        *string++ = '0';
        *string++ = '0';
        *string++ = '0';
        *string = '\0';

        do
        {
                digit = value;
                value /= 10;
                digit -= (char) value * 10;
                *--string = digit + '0';
        }
        while(value);
        return;
 }

void rgb_disp(int b, int g, int r)
{
    static char buf[10];

    ByteToStr(b, buf);
    LCD_locate(2,1);
    LCD_print(buf);

    ByteToStr(g, buf);
    LCD_locate(2,6);
    LCD_print(buf);

    ByteToStr(r, buf);
    LCD_locate(2,12);
    LCD_print(buf);
}
