#include "Lcd.h"

#define  testbit(var, bit)   ((var) & (1 <<(bit)))
#define  setbit(var, bit)    ((var) |= (1 << (bit)))
#define  clrbit(var, bit)    ((var) &= ~(1 << (bit)))

unsigned char ucDDRAMaddr;
unsigned int uiDDRAMsymb;

void LCD_delay(unsigned short usDelay)
{
    unsigned short usCount;
    char chO = 0;
    for (usCount = 0; usCount < usDelay; usCount++)
        chO = 0;
}

//+++ b15 b14 b13 bb12 b11 b10 b9 B8 B7 bb6 B5 B4 B3 B2 B1 B0
void LCD_init(void)
{
    ucDDRAMaddr = 0;
    uiDDRAMsymb = 0x0020;
    LCD_command(0x0038);    //+++ 
    LCD_command(0x0080);    //+++ 
    LCD_command(0x000E);    //+++ 
    LCD_command(0x0001);    //+++ 
}

void LCD_command(unsigned int var)
{
    var = Map(var);
    LCD_rs = 0;
    LCD_rw = 0;
    LCD_data = var;    
    LCD_en = 1;
    LCD_delay(3000);
    LCD_en = 0;
}

void LCD_senddata(unsigned int var)
{
    var = Map(var);
    LCD_rs = 1;
    LCD_rw = 0;
    LCD_data = var;    
    LCD_en = 1;
    LCD_delay(300);
    LCD_en = 0;
}

unsigned int Map(unsigned int var)
{
    int ooo = testbit(var, 7);
    if (ooo)
    {
        clrbit(var, 7);
        setbit(var, 8);
    }
    
    ooo = testbit(var, 6);
    if (ooo)
    {
        clrbit(var, 6);
        setbit(var, 7);
    }
    
    return var;
}

/*************************************************************************
Display character
Input:    character to be displayed
Returns:  none
*************************************************************************/
void lcd_putc(char c)
{
    if (ucDDRAMaddr == 0x10)
        ucDDRAMaddr = 0x40;
    if (ucDDRAMaddr == 0x50)
        ucDDRAMaddr = 0x00;
    LCD_command(0x0080 + ucDDRAMaddr++);    //+++ 
    LCD_senddata(c);
}


/*************************************************************************
Display string
Input:    string to be displayed
Returns:  none
*************************************************************************/
void lcd_puts(const char *s)
{
    register char c;

    while ((c = *s++)) 
      lcd_putc(c);
}