/*
 * Library for LCD display and AVR microcontrollers
 * Author: Peter Fleury (http://homepage.hispeed.ch/peterfleury/)
 * Modified by: Tomas Fryza (fryza@feec.vutbr.cz)
 *              Thomas Breining (breinint@esiee.fr)
 */
#include <avr/io.h>         		// include definition file for Atmel MCU
#define F_CPU 16000000UL			// specify clock frequency (needed for delay library)
#include <util/delay.h>				// include delay library
#include "lcd_h.h"					// include library for LCD display

unsigned char x,y ;					// global variables: current cursor position


void lcd_init( void )				// initialization of LCD display
{
	DDRA = 0xFE ;				
    _delay_ms( 16 ) ;			
	lcd_command( 0b00100000 ) ; 
	lcd_command( 0b00101000 ) ;
	lcd_command( 0b00000100 ) ;
	lcd_command( 0b00001100 ) ;
	lcd_clrscr() ;
}


void lcd_clrscr( void )				// clear LCD screen
{
	lcd_command( 0x00000001 ) ;
	x = 0 ;
	y = 0 ;
	_delay_ms( 16 ) ;
}


void lcd_command( char data )		// send 1-byte instruction to LCD
{
	lcd_write( data, 0 ) ;
}


void lcd_data( char data )			// send 1-byte data to LCD
{
	lcd_write( data, 1 ) ;
}


void lcd_write( char data, char rs )	// send instruction or data to LCD
{										// rs = 0...instruction
	unsigned char temp ;				// rs = 1...data

    if( rs )
		lcd_rs_high() ;					// data
	else
		lcd_rs_low() ;					// instruction

	temp = LCD_PORT & 0x0F ;
    LCD_PORT = temp | ( data & 0xF0 ) ;
    lcd_e_toggle() ;
    LCD_PORT = temp | (( data & 0x0F ) << 4 ) ;
    lcd_e_toggle() ;
    LCD_PORT = temp | 0xF0 ;
    _delay_ms( 2 ) ;
}


void toggle_e( void )				// generate enable pulse
{
    lcd_e_high() ;
    lcd_e_delay() ;
    lcd_e_low() ;
}


void lcd_gotoxy( char x_, char y_ )	// move cursor to new position
{
	if( y_ == 0 ){
		lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE1 + x_ ) ;
		y = 0 ;
	}
    else if( y_ == 1 ){
		lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE2 + x_ ) ;
		y = 1 ;
	}
	else if( y_ == 2 ){
		lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE3 + x_ ) ;
		y = 2 ;
	}
	else if( y_ == 3 ){
		lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE4 + x_ ) ;
		y = 3 ;
	}
	x = x_ ;
}


void lcd_putc( char c )				// put char to LCD
{
    if( c=='\n' )
		lcd_newline() ;
	else{
        if(( x == LCD_DISP_LENGTH ) && ( y == 0 ))
			lcd_secondline() ;
		else if(( x == LCD_DISP_LENGTH ) && ( y == 1 ))
			lcd_thirdline() ;
		else if(( x == LCD_DISP_LENGTH ) && ( y == 2 ))
			lcd_fourthline() ;
		else if(( x == LCD_DISP_LENGTH ) && ( y == 3 ))
			lcd_firstline() ;
	    lcd_data( c ) ;
		x++ ;
	}
}


void lcd_puts( const char *s )		// put string (char succession) to LCD
{
    register char c ;

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


void lcd_newline( void )			// move cursor to next line
{
	if( y == 3 && x == 0 )
		lcd_firstline() ;
	else if( y == 0 && x == 0 )
		lcd_secondline() ;
	else if( y == 1 && x == 0 )
		lcd_thirdline() ;
	else if( y == 2 && x == 0 )
		lcd_fourthline() ;
}


void lcd_firstline( void )			// move cursor to first line
{
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE1 ) ;
	x = 0 ;
	y = 0 ;
	lcd_puts( "                " ) ;
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE1 ) ;
	x = 0 ;
	y = 0 ;
}


void lcd_secondline( void )			// move cursor to second line
{
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE2 ) ;
	x = 0 ;
	y = 1 ;
	lcd_puts( "                " ) ;
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE2 ) ;
	x = 0 ;
	y = 1 ;
}


void lcd_thirdline( void )			// move cursor to third line
{
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE3 ) ;
	x = 0 ;
	y = 2 ;
	lcd_puts( "                " ) ;
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE3 ) ;
	x = 0 ;
	y = 2 ;
}


void lcd_fourthline( void )			// move cursor to fourth line
{
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE4 ) ;
	x = 0 ;
	y = 3 ;
	lcd_puts( "                " ) ;
    lcd_command(( 1<<LCD_DDRAM ) + LCD_START_LINE4 ) ;
	x = 0 ;
	y = 3 ;
}

