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 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 #else
00076
00077 sbi(MCUCR, SRE);
00078 #endif
00079 }
00080
00081 void lcdBusyWait(void)
00082 {
00083
00084
00085 #ifdef LCD_PORT_INTERFACE
00086 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00087 #ifdef LCD_DATA_4BIT
00088 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00089 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00090 #else
00091 outb(LCD_DATA_DDR, 0x00);
00092 outb(LCD_DATA_POUT, 0xFF);
00093 #endif
00094 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00095 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00096 LCD_DELAY;
00097 while(inb(LCD_DATA_PIN) & 1<<LCD_BUSY)
00098 {
00099 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00100 LCD_DELAY;
00101 LCD_DELAY;
00102 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00103 LCD_DELAY;
00104 LCD_DELAY;
00105 #ifdef LCD_DATA_4BIT // do an extra clock for 4 bit reads
00106 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00107 LCD_DELAY;
00108 LCD_DELAY;
00109 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00110 LCD_DELAY;
00111 LCD_DELAY;
00112 #endif
00113 }
00114 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00115
00116 #else
00117
00118
00119
00120 while( (*((volatile unsigned char *) (LCD_CTRL_ADDR))) & (1<<LCD_BUSY) );
00121
00122 #endif
00123 }
00124
00125 void lcdControlWrite(u08 data)
00126 {
00127
00128 #ifdef LCD_PORT_INTERFACE
00129 lcdBusyWait();
00130 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00131 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00132 #ifdef LCD_DATA_4BIT
00133
00134 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00135 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);
00136 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );
00137 LCD_DELAY;
00138 LCD_DELAY;
00139 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00140 LCD_DELAY;
00141 LCD_DELAY;
00142 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00143 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );
00144 LCD_DELAY;
00145 LCD_DELAY;
00146 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00147 #else
00148
00149 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00150 outb(LCD_DATA_DDR, 0xFF);
00151 outb(LCD_DATA_POUT, data);
00152 LCD_DELAY;
00153 LCD_DELAY;
00154 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00155 #endif
00156
00157 #ifdef LCD_DATA_4BIT
00158 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00159 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00160 #else
00161 outb(LCD_DATA_DDR, 0x00);
00162 outb(LCD_DATA_POUT, 0xFF);
00163 #endif
00164 #else
00165
00166
00167 lcdBusyWait();
00168 *((volatile unsigned char *) (LCD_CTRL_ADDR)) = data;
00169
00170 #endif
00171 }
00172
00173 u08 lcdControlRead(void)
00174 {
00175
00176 register u08 data;
00177 #ifdef LCD_PORT_INTERFACE
00178 lcdBusyWait();
00179 #ifdef LCD_DATA_4BIT
00180 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00181 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00182 #else
00183 outb(LCD_DATA_DDR, 0x00);
00184 outb(LCD_DATA_POUT, 0xFF);
00185 #endif
00186 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00187 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00188 #ifdef LCD_DATA_4BIT
00189
00190 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00191 LCD_DELAY;
00192 LCD_DELAY;
00193 data = inb(LCD_DATA_PIN)&0xF0;
00194 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00195 LCD_DELAY;
00196 LCD_DELAY;
00197 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00198 LCD_DELAY;
00199 LCD_DELAY;
00200 data |= inb(LCD_DATA_PIN)>>4;
00201 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00202 #else
00203
00204 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00205 LCD_DELAY;
00206 LCD_DELAY;
00207 data = inb(LCD_DATA_PIN);
00208 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00209 #endif
00210
00211 #else
00212
00213 lcdBusyWait();
00214 data = *((volatile unsigned char *) (LCD_CTRL_ADDR));
00215
00216 #endif
00217 return data;
00218 }
00219
00220 void lcdDataWrite(u08 data)
00221 {
00222
00223 #ifdef LCD_PORT_INTERFACE
00224 lcdBusyWait();
00225 sbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00226 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00227 #ifdef LCD_DATA_4BIT
00228
00229 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00230 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);
00231 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );
00232 LCD_DELAY;
00233 LCD_DELAY;
00234 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00235 LCD_DELAY;
00236 LCD_DELAY;
00237 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00238 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );
00239 LCD_DELAY;
00240 LCD_DELAY;
00241 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00242 #else
00243
00244 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00245 outb(LCD_DATA_DDR, 0xFF);
00246 outb(LCD_DATA_POUT, data);
00247 LCD_DELAY;
00248 LCD_DELAY;
00249 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00250 #endif
00251
00252 #ifdef LCD_DATA_4BIT
00253 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00254 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00255 #else
00256 outb(LCD_DATA_DDR, 0x00);
00257 outb(LCD_DATA_POUT, 0xFF);
00258 #endif
00259 #else
00260
00261
00262 lcdBusyWait();
00263 *((volatile unsigned char *) (LCD_DATA_ADDR)) = data;
00264
00265 #endif
00266 }
00267
00268 u08 lcdDataRead(void)
00269 {
00270
00271 register u08 data;
00272 #ifdef LCD_PORT_INTERFACE
00273 lcdBusyWait();
00274 #ifdef LCD_DATA_4BIT
00275 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);
00276 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);
00277 #else
00278 outb(LCD_DATA_DDR, 0x00);
00279 outb(LCD_DATA_POUT, 0xFF);
00280 #endif
00281 sbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00282 sbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00283 #ifdef LCD_DATA_4BIT
00284
00285 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00286 LCD_DELAY;
00287 LCD_DELAY;
00288 data = inb(LCD_DATA_PIN)&0xF0;
00289 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00290 LCD_DELAY;
00291 LCD_DELAY;
00292 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00293 LCD_DELAY;
00294 LCD_DELAY;
00295 data |= inb(LCD_DATA_PIN)>>4;
00296 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00297 #else
00298
00299 sbi(LCD_CTRL_PORT, LCD_CTRL_E);
00300 LCD_DELAY;
00301 LCD_DELAY;
00302 data = inb(LCD_DATA_PIN);
00303 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00304 #endif
00305
00306 #else
00307
00308
00309 lcdBusyWait();
00310 data = *((volatile unsigned char *) (LCD_DATA_ADDR));
00311
00312 #endif
00313 return data;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 void lcdInit()
00323 {
00324
00325 lcdInitHW();
00326
00327 lcdControlWrite(LCD_FUNCTION_DEFAULT);
00328
00329 lcdControlWrite(1<<LCD_CLR);
00330 delay(60000);
00331
00332 lcdControlWrite(1<<LCD_ENTRY_MODE | 1<<LCD_ENTRY_INC);
00333
00334
00335 lcdControlWrite(1<<LCD_ON_CTRL | 1<<LCD_ON_DISPLAY );
00336
00337 lcdControlWrite(1<<LCD_HOME);
00338
00339 lcdControlWrite(1<<LCD_DDRAM | 0x00);
00340
00341
00342 lcdLoadCustomChar((u08*)LcdCustomChar,0,0);
00343 lcdLoadCustomChar((u08*)LcdCustomChar,1,1);
00344 lcdLoadCustomChar((u08*)LcdCustomChar,2,2);
00345 lcdLoadCustomChar((u08*)LcdCustomChar,3,3);
00346 lcdLoadCustomChar((u08*)LcdCustomChar,4,4);
00347 lcdLoadCustomChar((u08*)LcdCustomChar,5,5);
00348 lcdLoadCustomChar((u08*)LcdCustomChar,6,6);
00349 lcdLoadCustomChar((u08*)LcdCustomChar,7,7);
00350 }
00351
00352 void lcdHome(void)
00353 {
00354
00355 lcdControlWrite(1<<LCD_HOME);
00356 }
00357
00358 void lcdClear(void)
00359 {
00360
00361 lcdControlWrite(1<<LCD_CLR);
00362 }
00363
00364 void lcdGotoXY(u08 x, u08 y)
00365 {
00366 register u08 DDRAMAddr;
00367
00368
00369 switch(y)
00370 {
00371 case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
00372 case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
00373 case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
00374 case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
00375 default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
00376 }
00377
00378
00379 lcdControlWrite(1<<LCD_DDRAM | DDRAMAddr);
00380 }
00381
00382 void lcdLoadCustomChar(u08* lcdCustomCharArray, u08 romCharNum, u08 lcdCharNum)
00383 {
00384 register u08 i;
00385 u08 saveDDRAMAddr;
00386
00387
00388 saveDDRAMAddr = lcdControlRead() & 0x7F;
00389
00390
00391 lcdCharNum = (lcdCharNum<<3);
00392 romCharNum = (romCharNum<<3);
00393
00394
00395 for(i=0; i<8; i++)
00396 {
00397
00398 lcdControlWrite((1<<LCD_CGRAM) | (lcdCharNum+i));
00399
00400 lcdDataWrite( pgm_read_byte(lcdCustomCharArray+romCharNum+i) );
00401 }
00402
00403
00404 lcdControlWrite(1<<LCD_DDRAM | saveDDRAMAddr);
00405
00406 }
00407
00408 void lcdPrintData(char* data, u08 nBytes)
00409 {
00410 register u08 i;
00411
00412
00413 if (!data) return;
00414
00415
00416 for(i=0; i<nBytes; i++)
00417 {
00418 lcdDataWrite(data[i]);
00419 }
00420 }
00421
00422 void lcdProgressBar(u16 progress, u16 maxprogress, u08 length)
00423 {
00424 u08 i;
00425 u32 pixelprogress;
00426 u08 c;
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 pixelprogress = ((progress*(length*PROGRESSPIXELS_PER_CHAR))/maxprogress);
00437
00438
00439 for(i=0; i<length; i++)
00440 {
00441
00442
00443 if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)+5) > pixelprogress )
00444 {
00445
00446 if( ((i*(u16)PROGRESSPIXELS_PER_CHAR)) > pixelprogress )
00447 {
00448
00449
00450 c = 0;
00451 }
00452 else
00453 {
00454
00455 c = pixelprogress % PROGRESSPIXELS_PER_CHAR;
00456 }
00457 }
00458 else
00459 {
00460
00461 c = 5;
00462 }
00463
00464
00465 lcdDataWrite(c);
00466 }
00467
00468 }
00469