00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <io.h>
00020 #include <progmem.h>
00021
00022 #include "global.h"
00023
00024 #include "lcd.h"
00025
00026
00027 static unsigned char __attribute__ ((progmem)) LcdCustomChar[] =
00028 {
00029 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00,
00030 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00,
00031 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00,
00032 0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00,
00033 0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00,
00034 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00,
00035 0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00,
00036 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00,
00037 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00,
00038 0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00,
00039 0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00,
00040 0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00,
00041 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00042 0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00,
00043 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00,
00044 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00,
00045 0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00,
00046 };
00047
00048
00049
00050
00051
00052 #define LCD_DELAY asm volatile ("nop"); asm volatile ("nop")
00053
00054 void lcdInitHW(void)
00055 {
00056
00057
00058 #ifdef LCD_PORT_INTERFACE
00059
00060 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00061 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00062 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00063
00064 sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
00065 sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
00066 sbi(LCD_CTRL_DDR, LCD_CTRL_E);
00067
00068
00069 #ifdef LCD_DATA_4BIT
00070 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00071 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00072 #else
00073 outb(LCD_DATA_DDR, 0x00);
00074 outb(LCD_DATA_POUT, 0xFF);
00075 #endif
00076 #endif
00077 }
00078
00079 void lcdBusyWait(void)
00080 {
00081
00082
00083 #ifdef LCD_PORT_INTERFACE
00084 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00085 #ifdef LCD_DATA_4BIT
00086 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00087 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00088 #else
00089 outb(LCD_DATA_DDR, 0x00);
00090 outb(LCD_DATA_POUT, 0xFF);
00091 #endif
00092 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00093 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00094 LCD_DELAY;
00095 while(inp(LCD_DATA_PIN) & 1<<LCD_BUSY)
00096 {
00097 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00098 LCD_DELAY;
00099 LCD_DELAY;
00100 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00101 LCD_DELAY;
00102 LCD_DELAY;
00103 #ifdef LCD_DATA_4BIT // do an extra clock for 4 bit reads
00104 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00105 LCD_DELAY;
00106 LCD_DELAY;
00107 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00108 LCD_DELAY;
00109 LCD_DELAY;
00110 #endif
00111 }
00112 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00113
00114 #else
00115
00116
00117
00118 while(*(volatile unsigned char *) (LCD_CTRL_ADDR) & 1<<LCD_BUSY);
00119
00120 #endif
00121 }
00122
00123 void lcdControlWrite(u08 data)
00124 {
00125
00126 #ifdef LCD_PORT_INTERFACE
00127 lcdBusyWait();
00128 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00129 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00130 #ifdef LCD_DATA_4BIT
00131
00132 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00133 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);
00134 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );
00135 LCD_DELAY;
00136 LCD_DELAY;
00137 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00138 LCD_DELAY;
00139 LCD_DELAY;
00140 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00141 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );
00142 LCD_DELAY;
00143 LCD_DELAY;
00144 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00145 #else
00146
00147 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00148 outb(LCD_DATA_DDR, 0xFF);
00149 outb(LCD_DATA_POUT, data);
00150 LCD_DELAY;
00151 LCD_DELAY;
00152 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00153 #endif
00154
00155 #ifdef LCD_DATA_4BIT
00156 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00157 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00158 #else
00159 outb(LCD_DATA_DDR, 0x00);
00160 outb(LCD_DATA_POUT, 0xFF);
00161 #endif
00162 #else
00163
00164 sbi(MCUCR, SRW);
00165 lcdBusyWait();
00166 *(volatile unsigned char *) (LCD_CTRL_ADDR) = data;
00167 cbi(MCUCR, SRW);
00168 #endif
00169 }
00170
00171 u08 lcdControlRead(void)
00172 {
00173
00174 register u08 data;
00175 #ifdef LCD_PORT_INTERFACE
00176 lcdBusyWait();
00177 #ifdef LCD_DATA_4BIT
00178 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00179 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00180 #else
00181 outb(LCD_DATA_DDR, 0x00);
00182 outb(LCD_DATA_POUT, 0xFF);
00183 #endif
00184 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00185 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00186 #ifdef LCD_DATA_4BIT
00187
00188 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00189 LCD_DELAY;
00190 LCD_DELAY;
00191 data = inb(LCD_DATA_PIN)&0xF0;
00192 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00193 LCD_DELAY;
00194 LCD_DELAY;
00195 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00196 LCD_DELAY;
00197 LCD_DELAY;
00198 data |= inb(LCD_DATA_PIN)>>4;
00199 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00200 #else
00201
00202 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00203 LCD_DELAY;
00204 LCD_DELAY;
00205 data = inb(LCD_DATA_PIN);
00206 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00207 #endif
00208
00209 #else
00210 sbi(MCUCR, SRW);
00211 lcdBusyWait();
00212 data = *(volatile unsigned char *) (LCD_CTRL_ADDR);
00213 cbi(MCUCR, SRW);
00214 #endif
00215 return data;
00216 }
00217
00218 void lcdDataWrite(u08 data)
00219 {
00220
00221 #ifdef LCD_PORT_INTERFACE
00222 lcdBusyWait();
00223 sbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00224 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00225 #ifdef LCD_DATA_4BIT
00226
00227 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00228 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);
00229 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );
00230 LCD_DELAY;
00231 LCD_DELAY;
00232 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00233 LCD_DELAY;
00234 LCD_DELAY;
00235 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00236 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );
00237 LCD_DELAY;
00238 LCD_DELAY;
00239 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00240 #else
00241
00242 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00243 outb(LCD_DATA_DDR, 0xFF);
00244 outb(LCD_DATA_POUT, data);
00245 LCD_DELAY;
00246 LCD_DELAY;
00247 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00248 #endif
00249
00250 #ifdef LCD_DATA_4BIT
00251 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00252 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00253 #else
00254 outb(LCD_DATA_DDR, 0x00);
00255 outb(LCD_DATA_POUT, 0xFF);
00256 #endif
00257 #else
00258
00259 sbi(MCUCR, SRW);
00260 lcdBusyWait();
00261 *(volatile unsigned char *) (LCD_DATA_ADDR) = data;
00262 cbi(MCUCR, SRW);
00263 #endif
00264 }
00265
00266 u08 lcdDataRead(void)
00267 {
00268
00269 register u08 data;
00270 #ifdef LCD_PORT_INTERFACE
00271 lcdBusyWait();
00272 #ifdef LCD_DATA_4BIT
00273 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00274 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00275 #else
00276 outb(LCD_DATA_DDR, 0x00);
00277 outb(LCD_DATA_POUT, 0xFF);
00278 #endif
00279 sbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00280 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00281 #ifdef LCD_DATA_4BIT
00282
00283 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00284 LCD_DELAY;
00285 LCD_DELAY;
00286 data = inb(LCD_DATA_PIN)&0xF0;
00287 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00288 LCD_DELAY;
00289 LCD_DELAY;
00290 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00291 LCD_DELAY;
00292 LCD_DELAY;
00293 data |= inb(LCD_DATA_PIN)>>4;
00294 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00295 #else
00296
00297 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00298 LCD_DELAY;
00299 LCD_DELAY;
00300 data = inb(LCD_DATA_PIN);
00301 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00302 #endif
00303
00304 #else
00305
00306 sbi(MCUCR, SRW);
00307 lcdBusyWait();
00308 data = *(volatile unsigned char *) (LCD_DATA_ADDR);
00309 cbi(MCUCR, SRW);
00310 #endif
00311 return data;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 void lcdInit()
00321 {
00322
00323 lcdInitHW();
00324
00325 lcdControlWrite(LCD_FUNCTION_DEFAULT);
00326
00327 lcdControlWrite(1<<LCD_CLR);
00328
00329 lcdControlWrite(1<<LCD_ENTRY_MODE | 1<<LCD_ENTRY_INC);
00330
00331
00332 lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY );
00333
00334 lcdControlWrite(1<<LCD_HOME);
00335
00336 lcdControlWrite(1<<LCD_DDRAM | 0x00);
00337
00338
00339 lcdLoadCustomChar(0,0);
00340 lcdLoadCustomChar(1,1);
00341 lcdLoadCustomChar(2,2);
00342 lcdLoadCustomChar(3,3);
00343 lcdLoadCustomChar(4,4);
00344 lcdLoadCustomChar(5,5);
00345 lcdLoadCustomChar(6,6);
00346 lcdLoadCustomChar(7,7);
00347 }
00348
00349 void lcdHome(void)
00350 {
00351
00352 lcdControlWrite(1<<LCD_HOME);
00353 }
00354
00355 void lcdClear(void)
00356 {
00357
00358 lcdControlWrite(1<<LCD_CLR);
00359 }
00360
00361 void lcdGotoXY(u08 x, u08 y)
00362 {
00363 register u08 DDRAMAddr;
00364
00365
00366 switch(y)
00367 {
00368 case 0: DDRAMAddr = 0x00+x; break;
00369 case 1: DDRAMAddr = 0x40+x; break;
00370 case 2: DDRAMAddr = 20+x; break;
00371
00372 case 3: DDRAMAddr = 84+x; break;
00373 default: DDRAMAddr = 0+x;
00374 }
00375
00376
00377 lcdControlWrite(1<<LCD_DDRAM | DDRAMAddr);
00378 }
00379
00380 void lcdLoadCustomChar(u08 lcdCharNum, u08 romCharNum)
00381 {
00382 register u08 i;
00383 u08 saveDDRAMAddr;
00384
00385
00386 saveDDRAMAddr = lcdControlRead() & 0x7F;
00387
00388 lcdCharNum = (lcdCharNum<<3);
00389 romCharNum = (romCharNum<<3);
00390
00391 for(i=0; i<8; i++)
00392 {
00393
00394 lcdControlWrite((1<<LCD_CGRAM) | (lcdCharNum+i));
00395
00396 lcdDataWrite( PRG_RDB(LcdCustomChar+romCharNum+i) );
00397 }
00398
00399
00400 lcdControlWrite(1<<LCD_DDRAM | saveDDRAMAddr);
00401
00402 }
00403
00404 void lcdPrintData(char* data, u08 nBytes)
00405 {
00406 register u08 i;
00407
00408
00409 if (!data) return;
00410
00411
00412 for(i=0; i<nBytes; i++)
00413 {
00414 lcdDataWrite(data[i]);
00415 }
00416 }
00417
00418 void lcdProgressBar(u16 progress, u16 maxprogress, u08 length)
00419 {
00420 u08 i;
00421 u16 pixelprogress;
00422 u08 c;
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
00433
00434
00435 for(i=0; i<length; i++)
00436 {
00437 if( ((i*PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
00438 {
00439
00440 if( ((i*PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
00441 {
00442
00443
00444 c = 0;
00445 }
00446 else
00447 {
00448
00449 c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
00450 }
00451 }
00452 else
00453 {
00454
00455 c = 5;
00456 }
00457
00458
00459 lcdDataWrite(c);
00460 }
00461
00462 }
00463