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 #include <cfg/arch.h>
00087 #include <cfg/arch/gpio.h>
00088 #include <cfg/lcd.h>
00089
00090 #if 0
00091
00092 #define LCD_DATA_LSB 0
00093 #define LCD_ENABLE_BIT 4
00094 #define LCD_RW_BIT 5
00095 #define LCD_REGSEL_BIT 7
00096
00097 #endif
00098
00099 #include <stdlib.h>
00100 #include <string.h>
00101
00102 #include <sys/nutconfig.h>
00103 #include <dev/hd44780.h>
00104 #include <dev/term.h>
00105 #include <sys/timer.h>
00106
00107 #if !defined(LCD_4x20) && !defined(LCD_4x16)
00108 #if !defined(LCD_2x40) && !defined(LCD_2x20) && !defined(LCD_2x16) && !defined(LCD_2x8)
00109 #if !defined(LCD_1x20) && !defined(LCD_1x16) && !defined(LCD_1x8)
00110 #if !defined(KS0073_CONTROLLER)
00111 #define LCD_2x16
00112 #endif
00113 #endif
00114 #endif
00115 #endif
00116
00117 #ifndef LCD_ROWS
00118 #if defined(LCD_4x20) || defined(LCD_4x16) || defined(KS0073_CONTROLLER)
00119 #define LCD_ROWS 4
00120 #elif defined(LCD_1x20) || defined(LCD_1x16) || defined(LCD_1x8)
00121 #define LCD_ROWS 1
00122 #else
00123 #define LCD_ROWS 2
00124 #endif
00125 #endif
00126
00127 #ifndef LCD_COLS
00128 #if defined(LCD_2x40)
00129 #define LCD_COLS 40
00130 #elif defined(LCD_4x20) || defined(LCD_2x20) || defined(LCD_1x20) || defined(KS0073_CONTROLLER)
00131 #define LCD_COLS 20
00132 #elif defined(LCD_2x8) || defined(LCD_1x8)
00133 #define LCD_COLS 8
00134 #else
00135 #define LCD_COLS 16
00136 #endif
00137 #endif
00138
00142 #if !defined(LCD_PIO_ID)
00143 #if defined(MCU_AT91SAM7X) || defined (MCU_AT91SAM7S256) || defined (MCU_AT91SAM7SE512)
00144 #define LCD_PIO_ID PIOA_ID
00145 #elif defined(MCU_AT91SAM9260) || defined(MCU_AT91SAM9XE512)
00146 #define LCD_PIO_ID PIOB_ID
00147 #else
00148 #define LCD_PIO_ID PIO_ID
00149 #endif
00150 #endif
00151
00155 #if !defined(LCD_PIO_PE_REG)
00156 #if LCD_PIO_ID == PIOA_ID
00157 #define LCD_PIO_PE_REG PIOA_PER
00158 #elif LCD_PIO_ID == PIOB_ID
00159 #define LCD_PIO_PE_REG PIOB_PER
00160 #elif LCD_PIO_ID == PIOC_ID
00161 #define LCD_PIO_PE_REG PIOC_PER
00162 #else
00163 #define LCD_PIO_PE_REG PIO_PER
00164 #endif
00165 #endif
00166
00170 #if !defined(LCD_PIO_OE_REG)
00171 #if LCD_PIO_ID == PIOA_ID
00172 #define LCD_PIO_OE_REG PIOA_OER
00173 #elif LCD_PIO_ID == PIOB_ID
00174 #define LCD_PIO_OE_REG PIOB_OER
00175 #elif LCD_PIO_ID == PIOC_ID
00176 #define LCD_PIO_OE_REG PIOC_OER
00177 #else
00178 #define LCD_PIO_OE_REG PIO_OER
00179 #endif
00180 #endif
00181
00185 #ifdef LCD_RW_BIT
00186 #if !defined(LCD_PIO_OD_REG)
00187 #if LCD_PIO_ID == PIOA_ID
00188 #define LCD_PIO_OD_REG PIOA_ODR
00189 #elif LCD_PIO_ID == PIOB_ID
00190 #define LCD_PIO_OD_REG PIOB_ODR
00191 #elif LCD_PIO_ID == PIOC_ID
00192 #define LCD_PIO_OD_REG PIOC_ODR
00193 #else
00194 #define LCD_PIO_OD_REG PIO_ODR
00195 #endif
00196 #endif
00197 #endif
00198
00202 #if !defined(LCD_PIO_SOD_REG)
00203 #if LCD_PIO_ID == PIOA_ID
00204 #define LCD_PIO_SOD_REG PIOA_SODR
00205 #elif LCD_PIO_ID == PIOB_ID
00206 #define LCD_PIO_SOD_REG PIOB_SODR
00207 #elif LCD_PIO_ID == PIOC_ID
00208 #define LCD_PIO_SOD_REG PIOC_SODR
00209 #else
00210 #define LCD_PIO_SOD_REG PIO_SODR
00211 #endif
00212 #endif
00213
00217 #if !defined(LCD_PIO_COD_REG)
00218 #if LCD_PIO_ID == PIOA_ID
00219 #define LCD_PIO_COD_REG PIOA_CODR
00220 #elif LCD_PIO_ID == PIOB_ID
00221 #define LCD_PIO_COD_REG PIOB_CODR
00222 #elif LCD_PIO_ID == PIOC_ID
00223 #define LCD_PIO_COD_REG PIOC_CODR
00224 #else
00225 #define LCD_PIO_COD_REG PIO_CODR
00226 #endif
00227 #endif
00228
00232 #ifdef LCD_RW_BIT
00233 #if !defined(LCD_PIO_PDS_REG)
00234 #if LCD_PIO_ID == PIOA_ID
00235 #define LCD_PIO_PDS_REG PIOA_PDSR
00236 #elif LCD_PIO_ID == PIOB_ID
00237 #define LCD_PIO_PDS_REG PIOB_PDSR
00238 #elif LCD_PIO_ID == PIOC_ID
00239 #define LCD_PIO_PDS_REG PIOC_PDSR
00240 #else
00241 #define LCD_PIO_PDS_REG PIO_PDSR
00242 #endif
00243 #endif
00244 #endif
00245
00246 #if !defined(LCD_DATA_LSB) && !defined(LCD_DATA_BIT0)
00247 #define LCD_DATA_LSB 0
00248 #endif
00249
00250 #ifdef LCD_DATA_LSB
00251 #define LCD_DATA (0xF << LCD_DATA_LSB)
00252 #else
00253 #define LCD_D0 _BV(LCD_DATA_BIT0)
00254 #define LCD_D1 _BV(LCD_DATA_BIT1)
00255 #define LCD_D2 _BV(LCD_DATA_BIT2)
00256 #define LCD_D3 _BV(LCD_DATA_BIT3)
00257 #define LCD_DATA (LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3)
00258 #endif
00259
00260 #ifndef LCD_ENABLE_BIT
00261 #define LCD_ENABLE_BIT 4
00262 #endif
00263 #define LCD_EN _BV(LCD_ENABLE_BIT)
00264
00265 #ifndef LCD_REGSEL_BIT
00266 #define LCD_REGSEL_BIT 7
00267 #endif
00268 #define LCD_RS _BV(LCD_REGSEL_BIT)
00269
00270 #ifdef LCD_RW_BIT
00271 #define LCD_RW _BV(LCD_RW_BIT)
00272 #endif
00273
00274 #ifndef LCD_SHORT_DELAY
00275 #define LCD_SHORT_DELAY 10
00276 #endif
00277
00278 #ifndef LCD_LONG_DELAY
00279 #define LCD_LONG_DELAY 1000
00280 #endif
00281
00286
00297 static void LcdDelay(unsigned int cycles)
00298 {
00299 while (cycles--) {
00300 _NOP(); _NOP(); _NOP(); _NOP();
00301 _NOP(); _NOP(); _NOP(); _NOP();
00302 _NOP(); _NOP(); _NOP(); _NOP();
00303 _NOP(); _NOP(); _NOP(); _NOP();
00304 _NOP(); _NOP(); _NOP(); _NOP();
00305 _NOP(); _NOP(); _NOP(); _NOP();
00306 _NOP(); _NOP(); _NOP(); _NOP();
00307 _NOP(); _NOP(); _NOP(); _NOP();
00308 _NOP(); _NOP(); _NOP(); _NOP();
00309 _NOP(); _NOP(); _NOP(); _NOP();
00310 _NOP(); _NOP(); _NOP(); _NOP();
00311 _NOP(); _NOP(); _NOP(); _NOP();
00312 }
00313 }
00314
00315 static void INLINE LcdSetBits(unsigned int mask)
00316 {
00317 outr(LCD_PIO_SOD_REG, mask);
00318 outr(LCD_PIO_OE_REG, mask);
00319 }
00320
00321 static void INLINE LcdClrBits(unsigned int mask)
00322 {
00323 outr(LCD_PIO_COD_REG, mask);
00324 outr(LCD_PIO_OE_REG, mask);
00325 }
00326
00327 #ifdef LCD_RW_BIT
00328
00329 static unsigned int LcdReadNibble(void)
00330 {
00331 unsigned int rc;
00332
00333 LcdSetBits(LCD_EN);
00334 LcdDelay(LCD_SHORT_DELAY);
00335 rc = inr(LCD_PIO_PDS_REG) & LCD_DATA;
00336 LcdClrBits(LCD_EN);
00337 LcdDelay(LCD_SHORT_DELAY);
00338
00339 #ifdef LCD_DATA_LSB
00340 rc >>= LCD_DATA_LSB
00341 #else
00342 {
00343 unsigned int val = 0;
00344
00345 if (rc & LCD_D0) {
00346 val |= 0x01;
00347 }
00348 if (rc & LCD_D1) {
00349 val |= 0x02;
00350 }
00351 if (rc & LCD_D2) {
00352 val |= 0x04;
00353 }
00354 if (rc & LCD_D3) {
00355 val |= 0x08;
00356 }
00357 rc = val;
00358 }
00359 #endif
00360 return rc;
00361 }
00362
00366 static unsigned int LcdReadByte(void)
00367 {
00368 outr(LCD_PIO_OD_REG, LCD_DATA);
00369 LcdDelay(LCD_SHORT_DELAY);
00370 LcdSetBits(LCD_RW);
00371 LcdDelay(LCD_SHORT_DELAY);
00372 return (LcdReadNibble() << 4) | LcdReadNibble();
00373 }
00374
00378 static unsigned int LcdReadStatus(void)
00379 {
00380
00381 LcdClrBits(LCD_RS);
00382 return LcdReadByte();
00383 }
00384
00385 #endif
00386
00387 static void LcdWaitReady(unsigned int delay)
00388 {
00389 while (delay--) {
00390 #if defined(LCD_RW_BIT)
00391 if ((LcdReadStatus() & _BV(LCD_BUSY)) == 0) {
00392 break;
00393 }
00394 #endif
00395 _NOP();
00396 }
00397 }
00398
00404 static void LcdWriteNibble(unsigned int nib)
00405 {
00406 #ifdef LCD_DATA_LSB
00407 nib <<= LCD_DATA_LSB;
00408 #else
00409 {
00410 unsigned int val = 0;
00411 if (nib & 0x01) {
00412 val |= LCD_D0;
00413 }
00414 if (nib & 0x02) {
00415 val |= LCD_D1;
00416 }
00417 if (nib & 0x04) {
00418 val |= LCD_D2;
00419 }
00420 if (nib & 0x08) {
00421 val |= LCD_D3;
00422 }
00423 nib = val;
00424 }
00425 #endif
00426 LcdSetBits(nib & LCD_DATA);
00427 LcdClrBits(~nib & LCD_DATA);
00428
00429 LcdDelay(LCD_SHORT_DELAY);
00430 LcdSetBits(LCD_EN);
00431 LcdDelay(LCD_SHORT_DELAY);
00432 LcdClrBits(LCD_EN);
00433 LcdDelay(LCD_SHORT_DELAY);
00434 }
00435
00441 static void LcdWriteByte(unsigned int data)
00442 {
00443 #ifdef LCD_RW_BIT
00444 LcdClrBits(LCD_RW);
00445 #endif
00446 LcdWriteNibble(data >> 4);
00447 LcdWriteNibble(data);
00448 LcdWaitReady(LCD_LONG_DELAY);
00449 }
00450
00456 static void LcdWriteCmd(uint8_t cmd)
00457 {
00458
00459 LcdClrBits(LCD_RS);
00460 LcdWriteByte(cmd);
00461 }
00462
00463 static void LcdWriteInstruction(uint8_t cmd, uint8_t xt)
00464 {
00465 LcdWriteCmd(cmd);
00466 }
00467
00473 static void LcdWriteData(uint8_t data)
00474 {
00475
00476 LcdSetBits(LCD_RS);
00477 LcdWriteByte(data);
00478 }
00479
00480 static void LcdSetCursor(uint8_t pos)
00481 {
00482 uint8_t offset[] = {
00483 #ifdef KS0073_CONTROLLER
00484 0x00, 0x20, 0x40, 0x60
00485 #elif LCD_COLS == 20
00486 0x00, 0x40, 0x14, 0x54
00487 #else
00488 0x00, 0x40, 0x10, 0x50
00489 #endif
00490 };
00491
00492 pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00493 LcdWriteCmd(1 << LCD_DDRAM | pos);
00494 }
00495
00496 static void LcdCursorHome(void)
00497 {
00498 LcdWriteCmd(1 << LCD_HOME);
00499 LcdDelay(10 * LCD_LONG_DELAY);
00500 }
00501
00502 static void LcdCursorLeft(void)
00503 {
00504 LcdWriteCmd(1 << LCD_MOVE);
00505 }
00506
00507 static void LcdCursorRight(void)
00508 {
00509 LcdWriteCmd(1 << LCD_MOVE | 1 << LCD_MOVE_RIGHT);
00510 }
00511
00512 static void LcdClear(void)
00513 {
00514 LcdWriteCmd(_BV(LCD_CLR));
00515 LcdDelay(10 * LCD_LONG_DELAY);
00516 }
00517
00518 static void LcdCursorMode(uint8_t on)
00519 {
00520 LcdWriteCmd(1 << LCD_ON_CTRL | on ? 1 << LCD_ON_CURSOR : 0x00);
00521 LcdDelay(10 * LCD_LONG_DELAY);
00522 }
00523
00524 static int LcdInit(NUTDEVICE * dev)
00525 {
00526 #if defined(PMC_PCER)
00527 outr(PMC_PCER, _BV(LCD_PIO_ID));
00528 #endif
00529
00530
00531 #ifdef LCD_RW_BIT
00532 outr(LCD_PIO_PE_REG, LCD_RW);
00533 LcdClrBits(LCD_RW);
00534 #endif
00535 outr(LCD_PIO_PE_REG, LCD_EN | LCD_RS | LCD_DATA);
00536 LcdClrBits(LCD_DATA | LCD_RS);
00537 LcdDelay(LCD_LONG_DELAY);
00538 LcdClrBits(LCD_EN);
00539 LcdDelay(LCD_LONG_DELAY);
00540
00541
00542 NutSleep(16);
00543
00544
00545
00546 LcdWriteNibble((_BV(LCD_FUNCTION) | _BV(LCD_FUNCTION_8BIT)) >> 4);
00547 NutSleep(5);
00548 LcdWriteNibble((_BV(LCD_FUNCTION) | _BV(LCD_FUNCTION_8BIT)) >> 4);
00549 NutSleep(2);
00550 LcdWriteNibble((_BV(LCD_FUNCTION) | _BV(LCD_FUNCTION_8BIT)) >> 4);
00551 NutSleep(2);
00552 LcdWriteNibble(_BV(LCD_FUNCTION) >> 4);
00553 NutSleep(2);
00554
00555
00556 LcdWriteNibble((_BV(LCD_FUNCTION) | _BV(LCD_FUNCTION_2LINES)) >> 4);
00557 LcdWriteNibble(_BV(LCD_FUNCTION) | _BV(LCD_FUNCTION_2LINES));
00558 NutSleep(2);
00559
00560
00561 LcdWriteNibble(_BV(LCD_ON_CTRL) >> 4);
00562 LcdWriteNibble(_BV(LCD_ON_CTRL));
00563 NutSleep(2);
00564
00565
00566 LcdClear();
00567
00568
00569 LcdWriteCmd(_BV(LCD_ENTRY_MODE) | _BV(LCD_ENTRY_INC));
00570
00571 LcdWriteCmd(_BV(LCD_ON_CTRL) | _BV(LCD_ON_DISPLAY));
00572
00573 LcdCursorHome();
00574
00575 LcdWriteCmd(_BV(LCD_DDRAM));
00576
00577 return 0;
00578 }
00579
00583 TERMDCB dcb_term = {
00584 LcdInit,
00585 LcdWriteData,
00586 LcdWriteInstruction,
00587 LcdClear,
00588 LcdSetCursor,
00589 LcdCursorHome,
00590 LcdCursorLeft,
00591 LcdCursorRight,
00592 LcdCursorMode,
00593 0,
00594 0,
00595 LCD_ROWS,
00596 LCD_COLS,
00597 LCD_COLS,
00598 0,
00599 0,
00600 0
00601 };
00602
00606 NUTDEVICE devLcd = {
00607 0,
00608 {'l', 'c', 'd', 0, 0, 0, 0, 0, 0},
00609 IFTYP_STREAM,
00610 0,
00611 0,
00612 0,
00613 &dcb_term,
00614 TermInit,
00615 TermIOCtl,
00616 0,
00617 TermWrite,
00618 TermOpen,
00619 TermClose,
00620 0
00621 };
00622