00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 #include <stdlib.h>
00093 #include <string.h>
00094
00095 #include <cfg/arch/avr.h>
00096 #include <dev/hd44780.h>
00097 #include <dev/term.h>
00098 #include <sys/timer.h>
00099
00100 #ifndef LCD_4x20
00101 #ifndef LCD_4x16
00102 #ifndef LCD_2x40
00103 #ifndef LCD_2x20
00104 #ifndef LCD_2x16
00105 #ifndef LCD_2x8
00106 #ifndef LCD_1x20
00107 #ifndef LCD_1x16
00108 #ifndef LCD_1x8
00109 #ifndef KS0073_CONTROLLER
00110 #define LCD_2x16
00111 #endif
00112 #endif
00113 #endif
00114 #endif
00115 #endif
00116 #endif
00117 #endif
00118 #endif
00119 #endif
00120 #endif
00121
00122
00123
00124
00125
00126
00127 #if ( LCD_DATA_AVRPORT == AVRPORTA )
00128 #define LCD_DATA_PORT PORTA
00129 #define LCD_DATA_PIN PINA
00130 #define LCD_DATA_DDR DDRA
00131
00132 #elif ( LCD_DATA_AVRPORT == AVRPORTB )
00133 #define LCD_DATA_PORT PORTB
00134 #define LCD_DATA_PIN PINB
00135 #define LCD_DATA_DDR DDRB
00136
00137 #elif ( LCD_DATA_AVRPORT == AVRPORTC )
00138 #define LCD_DATA_PORT PORTC
00139 #define LCD_DATA_PIN PINC
00140 #define LCD_DATA_DDR DDRC
00141
00142 #elif ( LCD_DATA_AVRPORT == AVRPORTE )
00143 #define LCD_DATA_PORT PORTE
00144 #define LCD_DATA_PIN PINE
00145 #define LCD_DATA_DDR DDRE
00146
00147 #elif ( LCD_DATA_AVRPORT == AVRPORTF )
00148 #define LCD_DATA_PORT PORTF
00149 #define LCD_DATA_PIN PINF
00150 #define LCD_DATA_DDR DDRF
00151
00152 #elif ( LCD_DATA_AVRPORT == AVRPORTG )
00153 #define LCD_DATA_PORT PORTG
00154 #define LCD_DATA_PIN PING
00155 #define LCD_DATA_DDR DDRG
00156
00157 #else
00158 #define LCD_DATA_PORT PORTD
00159 #define LCD_DATA_PIN PIND
00160 #define LCD_DATA_DDR DDRD
00161
00162 #endif
00163
00164 #ifndef LCD_DATA_BITS
00165 #define LCD_DATA_BITS 0xF0
00166 #endif
00167
00168
00169 #if ( LCD_ENABLE_AVRPORT == AVRPORTA )
00170 #define LCD_ENABLE_PORT PORTA
00171 #define LCD_ENABLE_DDR DDRA
00172
00173 #elif ( LCD_ENABLE_AVRPORT == AVRPORTB )
00174 #define LCD_ENABLE_PORT PORTB
00175 #define LCD_ENABLE_DDR DDRB
00176
00177 #elif ( LCD_ENABLE_AVRPORT == AVRPORTC )
00178 #define LCD_ENABLE_PORT PORTC
00179 #define LCD_ENABLE_DDR DDRC
00180
00181 #elif ( LCD_ENABLE_AVRPORT == AVRPORTD )
00182 #define LCD_ENABLE_PORT PORTD
00183 #define LCD_ENABLE_DDR DDRD
00184
00185 #elif ( LCD_ENABLE_AVRPORT == AVRPORTF )
00186 #define LCD_ENABLE_PORT PORTF
00187 #define LCD_ENABLE_DDR DDRF
00188
00189 #elif ( LCD_ENABLE_AVRPORT == AVRPORTG )
00190 #define LCD_ENABLE_PORT PORTG
00191 #define LCD_ENABLE_DDR DDRG
00192
00193 #else
00194 #define LCD_ENABLE_PORT PORTE
00195 #define LCD_ENABLE_DDR DDRE
00196
00197 #endif
00198
00199 #ifndef LCD_ENABLE_BIT
00200 #define LCD_ENABLE_BIT 3
00201 #endif
00202
00203
00204 #if ( LCD_REGSEL_AVRPORT == AVRPORTA )
00205 #define LCD_REGSEL_PORT PORTA
00206 #define LCD_REGSEL_DDR DDRA
00207
00208 #elif ( LCD_REGSEL_AVRPORT == AVRPORTB )
00209 #define LCD_REGSEL_PORT PORTB
00210 #define LCD_REGSEL_DDR DDRB
00211
00212 #elif ( LCD_REGSEL_AVRPORT == AVRPORTC )
00213 #define LCD_REGSEL_PORT PORTC
00214 #define LCD_REGSEL_DDR DDRC
00215
00216 #elif ( LCD_REGSEL_AVRPORT == AVRPORTD )
00217 #define LCD_REGSEL_PORT PORTD
00218 #define LCD_REGSEL_DDR DDRD
00219
00220 #elif ( LCD_REGSEL_AVRPORT == AVRPORTF )
00221 #define LCD_REGSEL_PORT PORTF
00222 #define LCD_REGSEL_DDR DDRF
00223
00224 #elif ( LCD_REGSEL_AVRPORT == AVRPORTG )
00225 #define LCD_REGSEL_PORT PORTG
00226 #define LCD_REGSEL_DDR DDRG
00227
00228 #else
00229 #define LCD_REGSEL_PORT PORTE
00230 #define LCD_REGSEL_DDR DDRE
00231
00232 #endif
00233
00234 #ifndef LCD_REGSEL_BIT
00235 #define LCD_REGSEL_BIT 2
00236 #endif
00237
00238
00239 #if ( LCD_RW_AVRPORT == AVRPORTA )
00240 #define LCD_RW_PORT PORTA
00241 #define LCD_RW_DDR DDRA
00242
00243 #elif ( LCD_RW_AVRPORT == AVRPORTB )
00244 #define LCD_RW_PORT PORTB
00245 #define LCD_RW_DDR DDRB
00246
00247 #elif ( LCD_RW_AVRPORT == AVRPORTC )
00248 #define LCD_RW_PORT PORTC
00249 #define LCD_RW_DDR DDRC
00250
00251 #elif ( LCD_RW_AVRPORT == AVRPORTD )
00252 #define LCD_RW_PORT PORTD
00253 #define LCD_RW_DDR DDRD
00254
00255 #elif ( LCD_RW_AVRPORT == AVRPORTE )
00256 #define LCD_RW_PORT PORTE
00257 #define LCD_RW_DDR DDRE
00258
00259 #elif ( LCD_RW_AVRPORT == AVRPORTF )
00260 #define LCD_RW_PORT PORTF
00261 #define LCD_RW_DDR DDRF
00262
00263 #elif ( LCD_RW_AVRPORT == AVRPORTG )
00264 #define LCD_RW_PORT PORTG
00265 #define LCD_RW_DDR DDRG
00266 #endif
00267
00268
00269
00274
00275 #ifndef LCD_SHORT_DELAY
00276 #define LCD_SHORT_DELAY 1
00277 #endif
00278
00279 #ifndef LCD_LONG_DELAY
00280 #define LCD_LONG_DELAY 2
00281 #endif
00282
00294 static u_char during_init = 1;
00295 #define LCD_DELAY _NOP(); _NOP(); _NOP(); _NOP()
00296
00297 #ifdef LCD_RW_BIT
00298
00299 static INLINE u_char LcdReadNibble(void)
00300 {
00301
00302 u_char ret;
00303 sbi(LCD_RW_PORT, LCD_RW_BIT);
00304 outp(inp(LCD_DATA_DDR) & ~LCD_DATA_BITS, LCD_DATA_DDR);
00305 sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00306 LCD_DELAY;
00307 ret = inp(LCD_DATA_PIN) & LCD_DATA_BITS;
00308 cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00309 LCD_DELAY;
00310 return ret;
00311 }
00312
00313 static INLINE u_char LcdReadByte(void)
00314 {
00315 u_char data;
00316 #if LCD_DATA_BITS == 0x0F
00317 data = LcdReadNibble();
00318 data = data | (LcdReadNibble() << 4);
00319 #elif LCD_DATA_BITS == 0xF0
00320 data = LcdReadNibble() >> 4;
00321 data |= LcdReadNibble();
00322 #elif LCD_DATA_BITS == 0xFF
00323 data = LcdReadNibble();
00324 #else
00325 #error "Bad definition of LCD_DATA_BITS"
00326 #endif
00327 return data;
00328 }
00329
00334 static u_char LcdReadCmd(void)
00335 {
00336 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00337 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00338 return LcdReadByte();
00339 }
00340
00341 #endif
00342
00343
00344 static void LcdDelay(u_char xt)
00345 {
00346 if (during_init) {
00347 NutDelay(xt);
00348 } else {
00349 #if defined(LCD_RW_BIT)
00350 while (LcdReadCmd() & (1 << LCD_BUSY))
00351 LCD_DELAY;
00352 LCD_DELAY;
00353 LCD_DELAY;
00354 LCD_DELAY;
00355 LCD_DELAY;
00356 LCD_DELAY;
00357 LCD_DELAY;
00358 LCD_DELAY;
00359 LCD_DELAY;
00360 LCD_DELAY;
00361 LCD_DELAY;
00362 LCD_DELAY;
00363 #elif defined(NUT_CPU_FREQ)
00364 NutSleep(xt);
00365 #else
00366 NutDelay(xt);
00367 #endif
00368 }
00369 }
00370
00371 static INLINE void LcdSendNibble(u_char nib)
00372 {
00373 #ifdef LCD_RW_BIT
00374 cbi(LCD_RW_PORT, LCD_RW_BIT);
00375 #endif
00376 outp(inp(LCD_DATA_DDR) | LCD_DATA_BITS, LCD_DATA_DDR);
00377 outp((inp(LCD_DATA_PORT) & ~LCD_DATA_BITS) | (nib & LCD_DATA_BITS), LCD_DATA_PORT);
00378 sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00379 LCD_DELAY;
00380 cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00381 LCD_DELAY;
00382 }
00383
00393 static INLINE void LcdSendByte(u_char ch, u_char xt)
00394 {
00395 #if LCD_DATA_BITS == 0x0F
00396 LcdSendNibble(ch >> 4);
00397 if(xt)
00398 LcdDelay(xt);
00399 LcdSendNibble(ch);
00400 #elif LCD_DATA_BITS == 0xF0
00401 LcdSendNibble(ch);
00402 if(xt)
00403 LcdDelay(xt);
00404 LcdSendNibble(ch << 4);
00405 #elif LCD_DATA_BITS == 0xFF
00406 LcdSendNibble(ch);
00407 #else
00408 #error "Bad definition of LCD_DATA_BITS"
00409 #endif
00410 if(xt)
00411 LcdDelay(xt);
00412 }
00413
00414 static void LcdWriteData(u_char ch)
00415 {
00416 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00417 sbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00418 LcdSendByte(ch, LCD_SHORT_DELAY);
00419 }
00420
00424 static void LcdWriteCmd(u_char cmd, u_char xt)
00425 {
00426 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00427 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00428 LcdSendByte(cmd, xt);
00429 }
00430
00431 static void LcdSetCursor(u_char pos)
00432 {
00433 u_char x = 0;
00434 u_char y = 0;
00435
00436 #ifdef KS0073_CONTROLLER
00437 u_char offset[4] = {0x00, 0x20, 0x40, 0x60};
00438 y = pos / 20;
00439 x = pos % 20;
00440 if (y > 3) y = 3;
00441 #endif
00442
00443 #if defined(LCD_2x40)
00444 u_char offset [2] = {0x00, 0x40};
00445 y = pos / 40;
00446 x = pos % 40;
00447 if (y > 1) y = 1;
00448 #endif
00449
00450 #if defined(LCD_4x20) || defined(LCD_2x20)
00451 u_char offset [4] = {0x00, 0x40, 0x14, 0x54};
00452 y = pos / 20;
00453 x = pos % 20;
00454 if (y>3) y=3;
00455 #endif
00456
00457 #if defined(LCD_4x16) || defined(LCD_2x16)
00458 u_char offset [4] = {0x00, 0x40, 0x10, 0x50};
00459 y = pos / 16;
00460 x = pos % 16;
00461 if (y>3) y=3;
00462 #endif
00463
00464 #if defined(LCD_2x8)
00465 u_char offset [2] = {0x00, 0x40};
00466 y = pos / 8;
00467 x = pos % 8;
00468 if (y>1) y=1;
00469 #endif
00470
00471 #if defined(LCD_1x8) || defined(LCD_1x16) || defined(LCD_1x20)
00472 u_char offset [1] = { 0x00 };
00473 y = 0;
00474 x = pos;
00475 #endif
00476
00477 pos = x + offset[y];
00478 LcdWriteCmd(1 << LCD_DDRAM | pos, LCD_SHORT_DELAY);
00479 }
00480
00481 static void LcdCursorHome(void)
00482 {
00483 LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00484 }
00485
00486 static void LcdCursorLeft(void)
00487 {
00488 LcdWriteCmd(1 << LCD_MOVE, LCD_SHORT_DELAY);
00489 }
00490
00491 static void LcdCursorRight(void)
00492 {
00493 LcdWriteCmd(1 << LCD_MOVE | 1 << LCD_MOVE_RIGHT, LCD_SHORT_DELAY);
00494 }
00495
00496 static void LcdClear(void)
00497 {
00498 LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00499 }
00500
00501 static void LcdCursorMode(u_char on)
00502 {
00503 LcdWriteCmd(1 << LCD_ON_CTRL | on ? 1 << LCD_ON_CURSOR : 0x00, LCD_LONG_DELAY);
00504 }
00505
00506 static void LcdInit(NUTDEVICE *dev)
00507 {
00508
00509
00510
00511 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00512 sbi(LCD_ENABLE_DDR, LCD_ENABLE_BIT);
00513 #ifdef LCD_RW_BIT
00514 sbi(LCD_RW_DDR, LCD_RW_BIT);
00515 cbi(LCD_RW_PORT, LCD_RW_BIT);
00516 #endif
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00528
00529 #if (LCD_DATA_BITS == 0xFF) // 8 Bit initialisation
00530 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00531 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00532 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00533 #ifdef KS0073_CONTROLLER
00534 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00535 LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_SHORT_DELAY);
00536 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), LCD_SHORT_DELAY);
00537 #endif
00538 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ?(1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00539
00540
00541 #else // 4 Bit initialisation
00542 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00543 LcdDelay(50);
00544 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00545 LcdDelay(50);
00546 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00547 LcdDelay(50);
00548 LcdSendNibble((1 << LCD_FUNCTION) | ((1 << LCD_FUNCTION) >> 4));
00549 LcdDelay(50);
00550 #ifdef KS0073_CONTROLLER
00551 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00552 LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_LONG_DELAY);
00553 LcdWriteCmd((1 << LCD_FUNCTION), LCD_LONG_DELAY);
00554 #endif
00555 LcdWriteCmd((1 << LCD_FUNCTION) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ? (1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00556 #endif
00557
00558
00559 LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00560
00561 LcdWriteCmd(1 << LCD_ENTRY_MODE | 1 << LCD_ENTRY_INC, LCD_LONG_DELAY);
00562
00563 LcdWriteCmd(1 << LCD_ON_CTRL | 1 << LCD_ON_DISPLAY, LCD_LONG_DELAY);
00564
00565 LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00566
00567 LcdWriteCmd(1 << LCD_DDRAM | 0x00, LCD_LONG_DELAY);
00568 during_init = 0;
00569 }
00570
00574 TERMDCB dcb_term = {
00575 LcdInit,
00576 LcdWriteData,
00577 LcdWriteCmd,
00578 LcdClear,
00579 LcdSetCursor,
00580 LcdCursorHome,
00581 LcdCursorLeft,
00582 LcdCursorRight,
00583 LcdCursorMode,
00584 0,
00585 0,
00586 #ifdef KS0073_CONTROLLER
00587 4,
00588 20,
00589 20,
00590 #endif
00591 #ifdef LCD_4x20
00592 4,
00593 20,
00594 20,
00595 #endif
00596 #ifdef LCD_4x16
00597 4,
00598 16,
00599 16,
00600 #endif
00601 #ifdef LCD_2x40
00602 2,
00603 40,
00604 40,
00605 #endif
00606 #ifdef LCD_2x20
00607 2,
00608 20,
00609 20,
00610 #endif
00611 #ifdef LCD_2x16
00612 2,
00613 16,
00614 16,
00615 #endif
00616 #ifdef LCD_2x8
00617 2,
00618 8,
00619 8,
00620 #endif
00621 #ifdef LCD_1x20
00622 1,
00623 20,
00624 20,
00625 #endif
00626 #ifdef LCD_1x16
00627 1,
00628 16,
00629 16,
00630 #endif
00631 #ifdef LCD_1x8
00632 1,
00633 8,
00634 8,
00635 #endif
00636 0,
00637 0,
00638 0
00639 };
00640
00644 NUTDEVICE devLcd = {
00645 0,
00646 {'l', 'c', 'd', 0, 0, 0, 0, 0, 0},
00647 IFTYP_STREAM,
00648 0,
00649 0,
00650 0,
00651 &dcb_term,
00652 TermInit,
00653 TermIOCtl,
00654 0,
00655 TermWrite,
00656 TermWrite_P,
00657 TermOpen,
00658 TermClose,
00659 0
00660 };
00661