/***************************************************************************/
/*                                                                         */
/*  LcdTest.c                                                              */
/*             LCD interface implementation                                */
/*                                                                         */
/*   Version : 1.3                                                         */
/*                                                                         */ 
/*                                                                         */ 
/*         By: J. Winpenny                                                 */ 
/*                                                                         */
/*       Date: 19/7/1999                                                   */
/*                                                                         */
/*                                                                         */
/*      Mode : HD44780 type LCD displays                                   */
/*                                                                         */
/* Interface :     SEL = Port A bit 3                                      */
/*                  WR = Port A bit 2                                      */
/*                  RS = Port A bit 0                                      */
/*              Data_7 = Port B bit 7                                      */
/*              Data_6 = Port B bit 6                                      */
/*              Data_5 = Port B bit 5                                      */
/*              Data_4 = Port B bit 4                                      */
/*                                                                         */
/*     Notes : Requires "Delays.c"                                         */
/*                                                                         */
/*             This version is for 4 bit mode                              */
/*                                                                         */
/*                                                                         */
/***************************************************************************/

#define LCD


// Timing settings for delay functions

#pragma CLOCK_FREQ 4000000


/* General definitions */


#include "lcd.h"


char LCD_gp;

/***********************************/
/* Setup the lcd device            */
/***********************************/
void LCD_Setup(void)
{
    /* Reset the LCD */

    /* WARNING, AFFECTS ALL OF PORT A */

    delay_ms(30);                          /* Power up delay */
    LCD_FunctionMode();

    LCD_Write_8_Bit( SYSTEM_SET_4_BIT_C ); /* This sequence resets the LCD */
    delay_ms(5);
    LCD_Write_8_Bit( SYSTEM_SET_4_BIT_C );
    delay_ms(5);
    LCD_Write_8_Bit( SYSTEM_SET_4_BIT_C );
    delay_ms(5);

    LCD_Write_4_Bit( SYSTEM_SET_4_BIT_C );
    delay_ms(2);
    LCD_Write_4_Bit( DISPLAY_OFF_C );
    delay_ms(2);
    LCD_Write_4_Bit( ENTRY_MODE_C );
    delay_ms(2);
    LCD_Write_4_Bit( DISPLAY_ON_C );
    delay_ms(2);
    LCD_Write_4_Bit( SET_DD_RAM_C );
    delay_ms(2);

    LCD_DataMode();
}

/***********************************/
/* Put LCD in Function Mode        */
/***********************************/
void LCD_FunctionMode(void)
{
    output_low_port_a( LCD_RS );
    delay_ms(1);
}

/***********************************/
/* Put LCD in Data Mode            */
/***********************************/

void LCD_DataMode(void)
{
    output_high_port_a( LCD_RS );
    delay_ms(1);
}

/***********************************/
/* Put LCD in Write Mode            */
/***********************************/

void LCD_WriteMode(void)
{
    output_low_port_a( LCD_WR );    /* Write Mode           */
    delay_ms(1);
}

/***********************************/
/* Clock LCD data                  */
/***********************************/

void LCD_ClockData(void)
{
    delay_ms(1);
    output_high_port_a( LCD_SEL ); /* Select LCD    */
    delay_ms(1);
    output_low_port_a( LCD_SEL );  /* De-select LCD */
}

/***********************************/
/* Send command to LCD             */
/***********************************/
void LCD_Command(char d)
{
   LCD_FunctionMode();
   LCD_Write_4_Bit( d );
   LCD_DataMode();
}

/***********************************/
/* Write a single byte to the LCD  */
/* 8 Bit Mode                      */
/***********************************/
void LCD_Write_8_Bit(char d )
{
    LCD_WriteMode();
    output_port_b( d );            /* Setup data    */
    LCD_ClockData();
}


/***********************************/
/* Write a single byte to the LCD  */
/* 4 Bit Mode                      */
/***********************************/
void LCD_Write_4_Bit(char d )
{
    LCD_WriteMode();

    /* Output Higher 4 bits */
    output_port_b( d );
    LCD_ClockData();

    delay_ms(1);

    /* Output Lower 4 bits  */
    d <<= 4;
    output_port_b( d );
    LCD_ClockData();
}

void LCD_WriteInt(int num)
{
 // LCD_Write_4_Bit( '0' + (num / 10000));      // tnes of thousands - max. 99999 dec
 // LCD_Write_4_Bit( '0' + (num / 1000) % 10 ); // thousands         - max. 9999 dec
//  LCD_Write_4_Bit( '0' + (num / 100) % 10);   // hundreds          - max. 999 dec
    LCD_Write_4_Bit( '0' + (num / 10));         // tens              - max. 99 dec
    LCD_Write_4_Bit( '0' + (num % 10));         // ones              - max. 9 dec
}

void LCD_SetPos(char position)
{
    LCD_Command(position);
}

/***********************************/
/* Write Integer in given position */
/***********************************/
void LCD_WriteIntPos( int num, char position )
{
    LCD_Command(position);
    LCD_Write_4_Bit('0' + (num / 10));
    LCD_Write_4_Bit('0' + (num % 10));
}

/***********************************/
/* Clear LCD Screen                */
/***********************************/
void LCD_Clear(void)
{
   LCD_Command( CLEAR_LCD_C );
}


/***********************************/
/* Set Position to line 1          */
/***********************************/
void LCD_GoLine1(void)
{
   LCD_Command( SET_DD_LINE1_C );
}

/***********************************/
/* Set Position to line 2          */
/***********************************/
void LCD_GoLine2(void)
{
   LCD_Command( SET_DD_LINE2_C );
}

/*******************************************/
/* Clear Line 1                            */
/*******************************************/
void LCD_ClearLine1(void)
{
   LCD_GoLine1();
   for( LCD_gp = 0; LCD_gp < 16; LCD_gp++ ){
        LCD_Write_4_Bit(' ');
   }
   LCD_GoLine1();
}

/*******************************************/
/* Clear Line 2                            */
/*******************************************/
void LCD_ClearLine2(void)
{
  LCD_GoLine2();
  for( LCD_gp = 0; LCD_gp < 16; LCD_gp++ ){
       LCD_Write_4_Bit(' ');
  }
  LCD_GoLine2();
}

/*******************************************/
/* printf                                  */
/*******************************************/
void printf( const char *text )
{
    char i;

    LCD_Command( CLEAR_LCD_C );

    for( i=0 ; i < CHAR_COUNT_C ; i++ ){
        if( i == CHARS_IN_LINE_C ){             // Goto line 2
            LCD_Command( SET_DD_LINE2_C );
        }
        if( text[i] == NUL ){                   // exit with NUL
            break;
        }
        LCD_Write_4_Bit( text[i] );
    }
}


syntax highlighted by Code2HTML, v. 0.9.1