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