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
00093
00094
00095 #include <stdlib.h>
00096 #include <string.h>
00097
00098 #include <cfg/arch/avr.h>
00099 #include <dev/hd44780.h>
00100 #include <dev/term.h>
00101 #include <sys/timer.h>
00102
00103
00104 #ifndef LCD_ROWS
00105 #if defined(LCD_4x20) || defined(LCD_4x16) || defined(KS0073_CONTROLLER)
00106 #define LCD_ROWS 4
00107 #elif defined(LCD_1x20) || defined(LCD_1x16) || defined(LCD_1x8)
00108 #define LCD_ROWS 1
00109 #else
00110 #define LCD_ROWS 2
00111 #endif
00112 #endif
00113
00114
00115 #ifndef LCD_COLS
00116 #if defined(LCD_2x40)
00117 #define LCD_COLS 40
00118 #elif defined(LCD_4x20) || defined(LCD_2x20) || defined(LCD_1x20) || defined(KS0073_CONTROLLER)
00119 #define LCD_COLS 20
00120 #elif defined(LCD_2x8) || defined(LCD_1x8)
00121 #define LCD_COLS 8
00122 #else
00123 #define LCD_COLS 16
00124 #endif
00125 #endif
00126
00127
00128
00129
00130
00131
00132 #if ( LCD_DATA_AVRPORT == AVRPORTA )
00133 #define LCD_DATA_PORT PORTA
00134 #define LCD_DATA_PIN PINA
00135 #define LCD_DATA_DDR DDRA
00136
00137 #elif ( LCD_DATA_AVRPORT == AVRPORTB )
00138 #define LCD_DATA_PORT PORTB
00139 #define LCD_DATA_PIN PINB
00140 #define LCD_DATA_DDR DDRB
00141
00142 #elif ( LCD_DATA_AVRPORT == AVRPORTC )
00143 #define LCD_DATA_PORT PORTC
00144 #define LCD_DATA_PIN PINC
00145 #define LCD_DATA_DDR DDRC
00146
00147 #elif ( LCD_DATA_AVRPORT == AVRPORTE )
00148 #define LCD_DATA_PORT PORTE
00149 #define LCD_DATA_PIN PINE
00150 #define LCD_DATA_DDR DDRE
00151
00152 #elif ( LCD_DATA_AVRPORT == AVRPORTF )
00153 #define LCD_DATA_PORT PORTF
00154 #define LCD_DATA_PIN PINF
00155 #define LCD_DATA_DDR DDRF
00156
00157 #elif ( LCD_DATA_AVRPORT == AVRPORTG )
00158 #define LCD_DATA_PORT PORTG
00159 #define LCD_DATA_PIN PING
00160 #define LCD_DATA_DDR DDRG
00161
00162 #else
00163 #define LCD_DATA_PORT PORTD
00164 #define LCD_DATA_PIN PIND
00165 #define LCD_DATA_DDR DDRD
00166
00167 #endif
00168
00169 #ifndef LCD_DATA_BITS
00170 #define LCD_DATA_BITS 0xF0
00171 #endif
00172
00173
00174 #if ( LCD_ENABLE_AVRPORT == AVRPORTA )
00175 #define LCD_ENABLE_PORT PORTA
00176 #define LCD_ENABLE_DDR DDRA
00177
00178 #elif ( LCD_ENABLE_AVRPORT == AVRPORTB )
00179 #define LCD_ENABLE_PORT PORTB
00180 #define LCD_ENABLE_DDR DDRB
00181
00182 #elif ( LCD_ENABLE_AVRPORT == AVRPORTC )
00183 #define LCD_ENABLE_PORT PORTC
00184 #define LCD_ENABLE_DDR DDRC
00185
00186 #elif ( LCD_ENABLE_AVRPORT == AVRPORTD )
00187 #define LCD_ENABLE_PORT PORTD
00188 #define LCD_ENABLE_DDR DDRD
00189
00190 #elif ( LCD_ENABLE_AVRPORT == AVRPORTF )
00191 #define LCD_ENABLE_PORT PORTF
00192 #define LCD_ENABLE_DDR DDRF
00193
00194 #elif ( LCD_ENABLE_AVRPORT == AVRPORTG )
00195 #define LCD_ENABLE_PORT PORTG
00196 #define LCD_ENABLE_DDR DDRG
00197
00198 #else
00199 #define LCD_ENABLE_PORT PORTE
00200 #define LCD_ENABLE_DDR DDRE
00201
00202 #endif
00203
00204 #ifndef LCD_ENABLE_BIT
00205 #define LCD_ENABLE_BIT 3
00206 #endif
00207
00208
00209 #if ( LCD_REGSEL_AVRPORT == AVRPORTA )
00210 #define LCD_REGSEL_PORT PORTA
00211 #define LCD_REGSEL_DDR DDRA
00212
00213 #elif ( LCD_REGSEL_AVRPORT == AVRPORTB )
00214 #define LCD_REGSEL_PORT PORTB
00215 #define LCD_REGSEL_DDR DDRB
00216
00217 #elif ( LCD_REGSEL_AVRPORT == AVRPORTC )
00218 #define LCD_REGSEL_PORT PORTC
00219 #define LCD_REGSEL_DDR DDRC
00220
00221 #elif ( LCD_REGSEL_AVRPORT == AVRPORTD )
00222 #define LCD_REGSEL_PORT PORTD
00223 #define LCD_REGSEL_DDR DDRD
00224
00225 #elif ( LCD_REGSEL_AVRPORT == AVRPORTF )
00226 #define LCD_REGSEL_PORT PORTF
00227 #define LCD_REGSEL_DDR DDRF
00228
00229 #elif ( LCD_REGSEL_AVRPORT == AVRPORTG )
00230 #define LCD_REGSEL_PORT PORTG
00231 #define LCD_REGSEL_DDR DDRG
00232
00233 #else
00234 #define LCD_REGSEL_PORT PORTE
00235 #define LCD_REGSEL_DDR DDRE
00236
00237 #endif
00238
00239 #ifndef LCD_REGSEL_BIT
00240 #define LCD_REGSEL_BIT 2
00241 #endif
00242
00243
00244 #if ( LCD_RW_AVRPORT == AVRPORTA )
00245 #define LCD_RW_PORT PORTA
00246 #define LCD_RW_DDR DDRA
00247
00248 #elif ( LCD_RW_AVRPORT == AVRPORTB )
00249 #define LCD_RW_PORT PORTB
00250 #define LCD_RW_DDR DDRB
00251
00252 #elif ( LCD_RW_AVRPORT == AVRPORTC )
00253 #define LCD_RW_PORT PORTC
00254 #define LCD_RW_DDR DDRC
00255
00256 #elif ( LCD_RW_AVRPORT == AVRPORTD )
00257 #define LCD_RW_PORT PORTD
00258 #define LCD_RW_DDR DDRD
00259
00260 #elif ( LCD_RW_AVRPORT == AVRPORTE )
00261 #define LCD_RW_PORT PORTE
00262 #define LCD_RW_DDR DDRE
00263
00264 #elif ( LCD_RW_AVRPORT == AVRPORTF )
00265 #define LCD_RW_PORT PORTF
00266 #define LCD_RW_DDR DDRF
00267
00268 #elif ( LCD_RW_AVRPORT == AVRPORTG )
00269 #define LCD_RW_PORT PORTG
00270 #define LCD_RW_DDR DDRG
00271 #endif
00272
00273
00274
00279
00280 #ifndef LCD_SHORT_DELAY
00281 #define LCD_SHORT_DELAY 1
00282 #endif
00283
00284 #ifndef LCD_LONG_DELAY
00285 #define LCD_LONG_DELAY 2
00286 #endif
00287
00299 static u_char during_init = 1;
00300 #define LCD_DELAY _NOP(); _NOP(); _NOP(); _NOP()
00301
00302 #ifdef LCD_RW_BIT
00303
00304 static INLINE u_char LcdReadNibble(void)
00305 {
00306
00307 u_char ret;
00308 sbi(LCD_RW_PORT, LCD_RW_BIT);
00309 outp(inp(LCD_DATA_DDR) & ~LCD_DATA_BITS, LCD_DATA_DDR);
00310 sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00311 LCD_DELAY;
00312 ret = inp(LCD_DATA_PIN) & LCD_DATA_BITS;
00313 cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00314 LCD_DELAY;
00315 return ret;
00316 }
00317
00318 static INLINE u_char LcdReadByte(void)
00319 {
00320 u_char data;
00321 #if LCD_DATA_BITS == 0x0F
00322 data = LcdReadNibble();
00323 data = data | (LcdReadNibble() << 4);
00324 #elif LCD_DATA_BITS == 0xF0
00325 data = LcdReadNibble() >> 4;
00326 data |= LcdReadNibble();
00327 #elif LCD_DATA_BITS == 0xFF
00328 data = LcdReadNibble();
00329 #else
00330 #error "Bad definition of LCD_DATA_BITS"
00331 #endif
00332 return data;
00333 }
00334
00339 static u_char LcdReadCmd(void)
00340 {
00341 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00342 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00343 return LcdReadByte();
00344 }
00345
00346 #endif
00347
00348
00349 static void LcdDelay(u_char xt)
00350 {
00351 if (during_init) {
00352 NutDelay(xt);
00353 } else {
00354 #if defined(LCD_RW_BIT)
00355 while (LcdReadCmd() & (1 << LCD_BUSY))
00356 LCD_DELAY;
00357 LCD_DELAY;
00358 LCD_DELAY;
00359 LCD_DELAY;
00360 LCD_DELAY;
00361 LCD_DELAY;
00362 LCD_DELAY;
00363 LCD_DELAY;
00364 LCD_DELAY;
00365 LCD_DELAY;
00366 LCD_DELAY;
00367 LCD_DELAY;
00368 #elif defined(NUT_CPU_FREQ)
00369 NutSleep(xt);
00370 #else
00371 NutDelay(xt);
00372 #endif
00373 }
00374 }
00375
00376 static INLINE void LcdSendNibble(u_char nib)
00377 {
00378 #ifdef LCD_RW_BIT
00379 cbi(LCD_RW_PORT, LCD_RW_BIT);
00380 #endif
00381 outp(inp(LCD_DATA_DDR) | LCD_DATA_BITS, LCD_DATA_DDR);
00382 outp((inp(LCD_DATA_PORT) & ~LCD_DATA_BITS) | (nib & LCD_DATA_BITS), LCD_DATA_PORT);
00383 sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00384 LCD_DELAY;
00385 cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00386 LCD_DELAY;
00387 }
00388
00398 static INLINE void LcdSendByte(u_char ch, u_char xt)
00399 {
00400 #if LCD_DATA_BITS == 0x0F
00401 LcdSendNibble(ch >> 4);
00402 if(xt)
00403 LcdDelay(xt);
00404 LcdSendNibble(ch);
00405 #elif LCD_DATA_BITS == 0xF0
00406 LcdSendNibble(ch);
00407 if(xt)
00408 LcdDelay(xt);
00409 LcdSendNibble(ch << 4);
00410 #elif LCD_DATA_BITS == 0xFF
00411 LcdSendNibble(ch);
00412 #else
00413 #error "Bad definition of LCD_DATA_BITS"
00414 #endif
00415 if(xt)
00416 LcdDelay(xt);
00417 }
00418
00419 static void LcdWriteData(u_char ch)
00420 {
00421 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00422 sbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00423 LcdSendByte(ch, LCD_SHORT_DELAY);
00424 }
00425
00429 static void LcdWriteCmd(u_char cmd, u_char xt)
00430 {
00431 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00432 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00433 LcdSendByte(cmd, xt);
00434 }
00435
00436 static void LcdSetCursor(u_char pos)
00437 {
00438 u_char offset[] = {
00439 #ifdef KS0073_CONTROLLER
00440 0x00, 0x20, 0x40, 0x60
00441 #elif LCD_COLS == 20
00442 0x00, 0x40, 0x14, 0x54
00443 #else
00444 0x00, 0x40, 0x10, 0x50
00445 #endif
00446 };
00447
00448 pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00449 LcdWriteCmd(1 << LCD_DDRAM | pos, LCD_SHORT_DELAY);
00450 }
00451
00452 static void LcdCursorHome(void)
00453 {
00454 LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00455 }
00456
00457 static void LcdCursorLeft(void)
00458 {
00459 LcdWriteCmd(1 << LCD_MOVE, LCD_SHORT_DELAY);
00460 }
00461
00462 static void LcdCursorRight(void)
00463 {
00464 LcdWriteCmd(1 << LCD_MOVE | 1 << LCD_MOVE_RIGHT, LCD_SHORT_DELAY);
00465 }
00466
00467 static void LcdClear(void)
00468 {
00469 LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00470 }
00471
00472 static void LcdCursorMode(u_char on)
00473 {
00474 LcdWriteCmd(1 << LCD_ON_CTRL | on ? 1 << LCD_ON_CURSOR : 0x00, LCD_LONG_DELAY);
00475 }
00476
00477 static void LcdInit(NUTDEVICE *dev)
00478 {
00479
00480
00481
00482 sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00483 sbi(LCD_ENABLE_DDR, LCD_ENABLE_BIT);
00484 #ifdef LCD_RW_BIT
00485 sbi(LCD_RW_DDR, LCD_RW_BIT);
00486 cbi(LCD_RW_PORT, LCD_RW_BIT);
00487 #endif
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00499
00500 #if (LCD_DATA_BITS == 0xFF) // 8 Bit initialisation
00501 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00502 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00503 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00504 #ifdef KS0073_CONTROLLER
00505 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00506 LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_SHORT_DELAY);
00507 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), LCD_SHORT_DELAY);
00508 #endif
00509 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ?(1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00510
00511
00512 #else // 4 Bit initialisation
00513 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00514 LcdDelay(50);
00515 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00516 LcdDelay(50);
00517 LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00518 LcdDelay(50);
00519 LcdSendNibble((1 << LCD_FUNCTION) | ((1 << LCD_FUNCTION) >> 4));
00520 LcdDelay(50);
00521 #ifdef KS0073_CONTROLLER
00522 LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00523 LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_LONG_DELAY);
00524 LcdWriteCmd((1 << LCD_FUNCTION), LCD_LONG_DELAY);
00525 #endif
00526 LcdWriteCmd((1 << LCD_FUNCTION) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ? (1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00527 #endif
00528
00529
00530 LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00531
00532 LcdWriteCmd(1 << LCD_ENTRY_MODE | 1 << LCD_ENTRY_INC, LCD_LONG_DELAY);
00533
00534 LcdWriteCmd(1 << LCD_ON_CTRL | 1 << LCD_ON_DISPLAY, LCD_LONG_DELAY);
00535
00536 LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00537
00538 LcdWriteCmd(1 << LCD_DDRAM | 0x00, LCD_LONG_DELAY);
00539 during_init = 0;
00540 }
00541
00545 TERMDCB dcb_term = {
00546 LcdInit,
00547 LcdWriteData,
00548 LcdWriteCmd,
00549 LcdClear,
00550 LcdSetCursor,
00551 LcdCursorHome,
00552 LcdCursorLeft,
00553 LcdCursorRight,
00554 LcdCursorMode,
00555 0,
00556 0,
00557 LCD_ROWS,
00558 LCD_COLS,
00559 LCD_COLS,
00560 0,
00561 0,
00562 0
00563 };
00564
00568 NUTDEVICE devLcd = {
00569 0,
00570 {'l', 'c', 'd', 0, 0, 0, 0, 0, 0},
00571 IFTYP_STREAM,
00572 0,
00573 0,
00574 0,
00575 &dcb_term,
00576 TermInit,
00577 TermIOCtl,
00578 0,
00579 TermWrite,
00580 TermWrite_P,
00581 TermOpen,
00582 TermClose,
00583 0
00584 };
00585