/* LCD control for AKI-LAN
2005/03/01
This code was designed and coded by SHIBUYA K.
*/
#include "lcd.h"
#include "3052.h"
#define LCDPORT PB.DR.BYTE
#define LCDPORTDDR PB.DDR
#define WAITSTROBE() {asm("nop");asm("nop");asm("nop");asm("nop");}
typedef unsigned char uchar;
/*--------------------------------------------------------
LCDpin LED H8pin
DB4 LED0 PB0
DB5 LED1 PB1
DB6 LED2 PB2
DB7 LED3 PB3
RS PB4
E PB7
---------------------------------------------------------*/
static void microwait(int n)
{
n *= 3;
while(--n){
WAITSTROBE();
}
}
static void out(uchar data, int cmdflag)
{
uchar udata,ldata,led;
led = LCDPORT&0x0f;
udata = (data>>4);
ldata = (data&0x0f);
if(!cmdflag){
udata |= 0x10;
ldata |= 0x10;
}
LCDPORT = udata;
udata |= 0x80;
LCDPORT = udata;
WAITSTROBE();
udata &= 0x7f;
LCDPORT = udata;
WAITSTROBE();
LCDPORT=ldata;
ldata |= 0x80;
LCDPORT = ldata;
WAITSTROBE();
ldata &= 0x7f;
LCDPORT = ldata;
WAITSTROBE();
LCDPORT = led;
microwait(40);
}
void LCDInit()
{
LCDPORTDDR = 0xff;
microwait(15000); /* Wait more than 15ms after vcc rises to 4.5V */
LCDPORT = 0x83;
WAITSTROBE();
LCDPORT = 0x03;
microwait(4100);
LCDPORT = 0x83;
WAITSTROBE();
LCDPORT = 0x03;
microwait(4100);
LCDPORT = 0x83;
WAITSTROBE();
LCDPORT = 0x03;
microwait(40);
LCDPORT = 0x82;
WAITSTROBE();
LCDPORT = 0x02;
microwait(40);
out(0x28,1); /* Function Set */
out(0x08,1); /* Display OFF */
out(0x01,1); /* Clear Display */
microwait(1600);
out(0x06,1); /* Entry Mode Set */
out(0x0c,1); /* Display ON */
LCDPORT = 0x0f;
}
void LCDClear()
{
out(0x01,1);
microwait(1600);
}
void LCDDisplay(const char *str, int line)
{
unsigned char buf[16];
unsigned int i;
i = 0;
while(*str && (i < sizeof(buf)))
buf[i++] = (unsigned char)(*(str++));
while(i < sizeof(buf))
buf[i++] = ' ';
if(line)
out(0xc0,1);
else
out(0x80,1);
out(0x06,1); /* Entry Mode Set */
for(i = 0; i < sizeof(buf); i++)
out(buf[i],0);
}