//ICC-AVR application builder : 2007-12-19 ¿ÀÈÄ 1:46:27
// Target : M128
// Crystal: 16.000Mhz
// TEXT LCD : by esan

#include <iom128v.h>
#include <macros.h>
#include <ktmlcd.h>

#define	 C_PORT	   (*(volatile unsigned char *)0x8001)
#define	 D_PORT	   (*(volatile unsigned char *)0x8000)

#define LCD_RS(x)  		(C_PORT = (x ? (CTRL_PORT|=0x01):(CTRL_PORT&=0x0e)))
#define LCD_RW(x)  		(C_PORT = (x ? (CTRL_PORT|=0x02):(CTRL_PORT&=0x0d)))
#define LCD_E(x)		(C_PORT = (x ? (CTRL_PORT|=0x04):(CTRL_PORT&=0x0b)))

#define	 ON            1
#define	 OFF           0
#define	 D_TIME        10

#define	 FST_LIN   	   1
#define	 SND_LIN   	   2

#define	 LCD_SET	   0x38
#define	 SCR_CLR 	   0x0c
#define	 RTN_HOME	   0x06
#define	 CUR_BNK	   0x0F
// Shift Screen to Left
#define	 SCR_L_SHFT	   0x18	  
// Shift Screen to Right
#define	 SCR_R_SHFT	   0x1c

int	   CTRL_PORT, DATA_PORT;

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;		// Control Port
 PORTB = 0x00;
 DDRB  = 0x00;		// Data Port
 PORTC = 0x00;
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
 PORTE = 0x00;
 DDRE  = 0x00;
 PORTF = 0x00;
 DDRF  = 0x00;
 PORTG = 0x00;
 DDRG  = 0x00;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 XDIV  = 0x00; //xtal divider
 XMCRA = 0x00; //external memory
 port_init();

 MCUCR = 0x80;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void delay(int dtimes)
{
    int i,j;
    
    for(i=0 ; i<1000 ; i++){
        for(j=0 ; j<dtimes ; j++) ;
    }
}


void LCD_E_Pulse(void)
{
	 LCD_E(ON);			delay(D_TIME);
	 LCD_E(OFF); 		delay(D_TIME);
}

void Write_LCD(unsigned char val)
{
 	 LCD_E(OFF);		delay(D_TIME);
 	 LCD_RS(OFF);		delay(D_TIME); 	 
	 LCD_RW(OFF);		delay(D_TIME);
	 LCD_E(ON);			delay(D_TIME);
	 D_PORT = val; 		delay(D_TIME); 
	 LCD_E(OFF); 		delay(D_TIME);
//	 LCD_E(ON);			delay(D_TIME); 	 // case in the "SC1602-model"
}

void Write_Char(char Ch)
{
 	 LCD_E(OFF);	 	 delay(D_TIME);
	 LCD_RS(ON);		 delay(D_TIME);
	 LCD_RW(OFF);
	 LCD_E(ON);	 		 delay(D_TIME);
	 D_PORT = Ch;	 	 delay(D_TIME); 
	 LCD_E(OFF); 		 delay(D_TIME);
//	 LCD_E(ON);			 delay(D_TIME);	// case in the "SC1602-model"
}

void Write_Str(char *Str)
{
	 while (*Str) {
	 	Write_Char(*Str++);
	 }
}


int putchar(char c)
{
 	Write_Char(c);
}

void Cur_XY(int Xpos, int Ypos)
{
	 LCD_RS(OFF);
	 LCD_RW(OFF);
     D_PORT = Ypos*20 + Xpos + (Ypos==2 ? 0x80 :0);
	 
	 LCD_E_Pulse();
}

void Printf(int lin, char *Str)
{
	 Write_LCD(LCD_SET);
	 Cur_XY(0, lin);
	 Write_Str(Str);
}

void Scr_R_Shift(int cnt, int dtimes)
{
 	 while (cnt--) {	 
	 	 Write_LCD(SCR_R_SHFT);
		 delay(dtimes);
	 }
}

void Scr_L_Shift(int cnt, int dtimes)
{
 	 while (cnt--) {	 
	 	 Write_LCD(SCR_L_SHFT);
		 delay(dtimes);
	 }
}

void init_LCD(void)
{
 	 Write_LCD(0x38);	 // lcd module setting
 	 Write_LCD(0x0c);	 // clear
 	 Write_LCD(0x06);	 // return home
 	 Write_LCD(CUR_BNK);	 // cursor blank
}



void main(void)
{
 	 int i=0;
	 
 	 init_devices();
	 delay(100);
	 init_LCD(); 
	 delay(100);

 	 Write_Str("LINE 1 ..");
	 delay(100);
 	 Printf(SND_LIN, "LINE 2 ..");
	 delay(100);
	 while (1) {
	     Scr_R_Shift(10, 400);
	     Scr_L_Shift(10, 400);
	 }

}
