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 #include <cfg/arch.h>
00045 #include <cfg/arch/gpio.h>
00046 #include <cfg/lcd.h>
00047
00048 #include <stdlib.h>
00049 #include <string.h>
00050
00051 #include <sys/nutconfig.h>
00052 #include <dev/st7036.h>
00053 #include <dev/term.h>
00054 #include <sys/timer.h>
00055
00056 #ifndef LCD_ROWS
00057 #define LCD_ROWS 2
00058 #endif
00059
00060 #ifndef LCD_COLS
00061 #define LCD_COLS 16
00062 #endif
00063
00064 #ifndef LCD_SHORT_DELAY
00065 #define LCD_SHORT_DELAY 100
00066 #endif
00067
00068 #ifndef LCD_LONG_DELAY
00069 #define LCD_LONG_DELAY 1000
00070 #endif
00071
00075 #if defined(AT91SAM7X_EK)
00076
00077 #ifndef LCD_CS_PIO_ID
00078 #define LCD_CS_PIO_ID PIOB_ID
00079 #endif
00080 #ifndef LCD_CS_BIT
00081 #define LCD_CS_BIT 24
00082 #endif
00083
00084 #ifndef LCD_RS_PIO_ID
00085 #define LCD_RS_PIO_ID PIOB_ID
00086 #endif
00087 #ifndef LCD_RS_BIT
00088 #define LCD_RS_BIT 23
00089 #endif
00090
00091 #ifndef LCD_CLK_PIO_ID
00092 #define LCD_CLK_PIO_ID PIOA_ID
00093 #endif
00094 #ifndef LCD_CLK_BIT
00095 #define LCD_CLK_BIT 18
00096 #endif
00097
00098 #ifndef LCD_MOSI_PIO_ID
00099 #define LCD_MOSI_PIO_ID PIOA_ID
00100 #endif
00101 #ifndef LCD_MOSI_BIT
00102 #define LCD_MOSI_BIT 17
00103 #endif
00104
00105 #elif defined(AT91SAM7S)
00106
00107 #ifndef LCD_CS_PIO_ID
00108 #define LCD_CS_PIO_ID PIOA_ID
00109 #endif
00110 #ifndef LCD_CS_BIT
00111 #define LCD_CS_BIT 28
00112 #endif
00113
00114 #ifndef LCD_RS_PIO_ID
00115 #define LCD_RS_PIO_ID PIOA_ID
00116 #endif
00117 #ifndef LCD_RS_BIT
00118 #define LCD_RS_BIT 26
00119 #endif
00120
00121 #ifndef LCD_CLK_PIO_ID
00122 #define LCD_CLK_PIO_ID PIOA_ID
00123 #endif
00124 #ifndef LCD_CLK_BIT
00125 #define LCD_CLK_BIT 14
00126 #endif
00127
00128 #ifndef LCD_MOSI_PIO_ID
00129 #define LCD_MOSI_PIO_ID PIOA_ID
00130 #endif
00131 #ifndef LCD_MOSI_BIT
00132 #define LCD_MOSI_BIT 13
00133 #endif
00134
00135 #elif defined(AT91SAM9260_EK)
00136
00137 #ifndef LCD_CS_PIO_ID
00138 #define LCD_CS_PIO_ID PIOB_ID
00139 #endif
00140 #ifndef LCD_CS_BIT
00141 #define LCD_CS_BIT 11
00142 #endif
00143
00144 #ifndef LCD_RS_PIO_ID
00145 #define LCD_RS_PIO_ID PIOB_ID
00146 #endif
00147 #ifndef LCD_RS_BIT
00148 #define LCD_RS_BIT 20
00149 #endif
00150
00151 #ifndef LCD_CLK_PIO_ID
00152 #define LCD_CLK_PIO_ID PIOB_ID
00153 #endif
00154 #ifndef LCD_CLK_BIT
00155 #define LCD_CLK_BIT 2
00156 #endif
00157
00158 #ifndef LCD_MOSI_PIO_ID
00159 #define LCD_MOSI_PIO_ID PIOB_ID
00160 #endif
00161 #ifndef LCD_MOSI_BIT
00162 #define LCD_MOSI_BIT 1
00163 #endif
00164
00165 #else
00166
00167 #ifndef LCD_CS_PIO_ID
00168 #define LCD_CS_PIO_ID PIO_ID
00169 #endif
00170 #ifndef LCD_CS_BIT
00171 #define LCD_CS_BIT 0
00172 #endif
00173
00174 #ifndef LCD_RS_PIO_ID
00175 #define LCD_RS_PIO_ID PIO_ID
00176 #endif
00177 #ifndef LCD_RS_BIT
00178 #define LCD_RS_BIT 3
00179 #endif
00180
00181 #ifndef LCD_CLK_PIO_ID
00182 #define LCD_CLK_PIO_ID PIO_ID
00183 #endif
00184 #ifndef LCD_CLK_BIT
00185 #define LCD_CLK_BIT 1
00186 #endif
00187
00188 #ifndef LCD_MOSI_PIO_ID
00189 #define LCD_MOSI_PIO_ID PIO_ID
00190 #endif
00191 #ifndef LCD_MOSI_BIT
00192 #define LCD_MOSI_BIT 2
00193 #endif
00194
00195 #endif
00196
00197 #define LCD_CS _BV(LCD_CS_BIT)
00198 #define LCD_RS _BV(LCD_RS_BIT)
00199 #define LCD_CLK _BV(LCD_CLK_BIT)
00200 #define LCD_MOSI _BV(LCD_MOSI_BIT)
00201
00202
00203 #if LCD_CS_PIO_ID == PIOA_ID
00204 #define LCD_CS_SET() { outr(PIOA_PER, LCD_CS); outr(PIOA_SODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00205 #define LCD_CS_CLR() { outr(PIOA_PER, LCD_CS); outr(PIOA_CODR, LCD_CS); outr(PIOA_OER, LCD_CS); }
00206 #elif LCD_CS_PIO_ID == PIOB_ID
00207 #define LCD_CS_SET() { outr(PIOB_PER, LCD_CS); outr(PIOB_SODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00208 #define LCD_CS_CLR() { outr(PIOB_PER, LCD_CS); outr(PIOB_CODR, LCD_CS); outr(PIOB_OER, LCD_CS); }
00209 #elif LCD_CS_PIO_ID == PIOC_ID
00210 #define LCD_CS_SET() { outr(PIOC_PER, LCD_CS); outr(PIOC_SODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00211 #define LCD_CS_CLR() { outr(PIOC_PER, LCD_CS); outr(PIOC_CODR, LCD_CS); outr(PIOC_OER, LCD_CS); }
00212 #else
00213 #define LCD_CS_SET() { outr(PIO_PER, LCD_CS); outr(PIO_SODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00214 #define LCD_CS_CLR() { outr(PIO_PER, LCD_CS); outr(PIO_CODR, LCD_CS); outr(PIO_OER, LCD_CS); }
00215 #endif
00216
00217 #if LCD_RS_PIO_ID == PIOA_ID
00218 #define LCD_RS_SET() { outr(PIOA_PER, LCD_RS); outr(PIOA_SODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00219 #define LCD_RS_CLR() { outr(PIOA_PER, LCD_RS); outr(PIOA_CODR, LCD_RS); outr(PIOA_OER, LCD_RS); }
00220 #elif LCD_RS_PIO_ID == PIOB_ID
00221 #define LCD_RS_SET() { outr(PIOB_PER, LCD_RS); outr(PIOB_SODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00222 #define LCD_RS_CLR() { outr(PIOB_PER, LCD_RS); outr(PIOB_CODR, LCD_RS); outr(PIOB_OER, LCD_RS); }
00223 #elif LCD_RS_PIO_ID == PIOC_ID
00224 #define LCD_RS_SET() { outr(PIOC_PER, LCD_RS); outr(PIOC_SODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00225 #define LCD_RS_CLR() { outr(PIOC_PER, LCD_RS); outr(PIOC_CODR, LCD_RS); outr(PIOC_OER, LCD_RS); }
00226 #else
00227 #define LCD_RS_SET() { outr(PIO_PER, LCD_RS); outr(PIO_SODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00228 #define LCD_RS_CLR() { outr(PIO_PER, LCD_RS); outr(PIO_CODR, LCD_RS); outr(PIO_OER, LCD_RS); }
00229 #endif
00230
00231 #if LCD_CLK_PIO_ID == PIOA_ID
00232 #define LCD_CLK_SET() { outr(PIOA_PER, LCD_CLK); outr(PIOA_SODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00233 #define LCD_CLK_CLR() { outr(PIOA_PER, LCD_CLK); outr(PIOA_CODR, LCD_CLK); outr(PIOA_OER, LCD_CLK); }
00234 #elif LCD_CLK_PIO_ID == PIOB_ID
00235 #define LCD_CLK_SET() { outr(PIOB_PER, LCD_CLK); outr(PIOB_SODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00236 #define LCD_CLK_CLR() { outr(PIOB_PER, LCD_CLK); outr(PIOB_CODR, LCD_CLK); outr(PIOB_OER, LCD_CLK); }
00237 #elif LCD_CLK_PIO_ID == PIOC_ID
00238 #define LCD_CLK_SET() { outr(PIOC_PER, LCD_CLK); outr(PIOC_SODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00239 #define LCD_CLK_CLR() { outr(PIOC_PER, LCD_CLK); outr(PIOC_CODR, LCD_CLK); outr(PIOC_OER, LCD_CLK); }
00240 #else
00241 #define LCD_CLK_SET() { outr(PIO_PER, LCD_CLK); outr(PIO_SODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00242 #define LCD_CLK_CLR() { outr(PIO_PER, LCD_CLK); outr(PIO_CODR, LCD_CLK); outr(PIO_OER, LCD_CLK); }
00243 #endif
00244
00245 #if LCD_MOSI_PIO_ID == PIOA_ID
00246 #define LCD_MOSI_SET() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_SODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00247 #define LCD_MOSI_CLR() { outr(PIOA_PER, LCD_MOSI); outr(PIOA_CODR, LCD_MOSI); outr(PIOA_OER, LCD_MOSI); }
00248 #elif LCD_MOSI_PIO_ID == PIOB_ID
00249 #define LCD_MOSI_SET() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_SODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00250 #define LCD_MOSI_CLR() { outr(PIOB_PER, LCD_MOSI); outr(PIOB_CODR, LCD_MOSI); outr(PIOB_OER, LCD_MOSI); }
00251 #elif LCD_MOSI_PIO_ID == PIOC_ID
00252 #define LCD_MOSI_SET() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_SODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00253 #define LCD_MOSI_CLR() { outr(PIOC_PER, LCD_MOSI); outr(PIOC_CODR, LCD_MOSI); outr(PIOC_OER, LCD_MOSI); }
00254 #else
00255 #define LCD_MOSI_SET() { outr(PIO_PER, LCD_MOSI); outr(PIO_SODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00256 #define LCD_MOSI_CLR() { outr(PIO_PER, LCD_MOSI); outr(PIO_CODR, LCD_MOSI); outr(PIO_OER, LCD_MOSI); }
00257 #endif
00258
00263
00274 static void LcdDelay(u_int cycles)
00275 {
00276 while (cycles--) {
00277 _NOP(); _NOP(); _NOP(); _NOP();
00278 _NOP(); _NOP(); _NOP(); _NOP();
00279 _NOP(); _NOP(); _NOP(); _NOP();
00280 _NOP(); _NOP(); _NOP(); _NOP();
00281 _NOP(); _NOP(); _NOP(); _NOP();
00282 _NOP(); _NOP(); _NOP(); _NOP();
00283 _NOP(); _NOP(); _NOP(); _NOP();
00284 _NOP(); _NOP(); _NOP(); _NOP();
00285 _NOP(); _NOP(); _NOP(); _NOP();
00286 _NOP(); _NOP(); _NOP(); _NOP();
00287 _NOP(); _NOP(); _NOP(); _NOP();
00288 _NOP(); _NOP(); _NOP(); _NOP();
00289 }
00290 }
00291
00292 #if 0
00293 static void INLINE LcdSetBits(u_int mask)
00294 {
00295 outr(LCD_PIO_SOD_REG, mask);
00296 outr(LCD_PIO_OE_REG, mask);
00297 }
00298
00299 static void INLINE LcdClrBits(u_int mask)
00300 {
00301 outr(LCD_PIO_COD_REG, mask);
00302 outr(LCD_PIO_OE_REG, mask);
00303 }
00304 #endif
00305
00306 static void LcdWaitReady(u_int delay)
00307 {
00308 while (delay--) {
00309 _NOP();
00310 }
00311 }
00312
00318 static void LcdWriteByte(u_int data)
00319 {
00320 u_char msk = 0x80;
00321
00322 while (msk) {
00323 LCD_CLK_CLR();
00324 if (data & msk) {
00325 LCD_MOSI_SET();
00326 } else {
00327 LCD_MOSI_CLR();
00328 }
00329 LCD_CLK_SET();
00330 msk >>= 1;
00331 LcdDelay(1);
00332 }
00333 LcdWaitReady(LCD_LONG_DELAY);
00334 }
00335
00341 static void LcdWriteCmd(u_char cmd)
00342 {
00343
00344 LCD_CS_CLR();
00345 LcdDelay(LCD_SHORT_DELAY);
00346 LCD_RS_CLR();
00347 LcdDelay(LCD_SHORT_DELAY);
00348 LcdWriteByte(cmd);
00349 LcdDelay(LCD_SHORT_DELAY);
00350 LCD_RS_SET();
00351 LcdDelay(LCD_SHORT_DELAY);
00352 LCD_CS_SET();
00353 LcdDelay(LCD_SHORT_DELAY);
00354 }
00355
00356 static void LcdWriteInstruction(u_char cmd, u_char xt)
00357 {
00358 LcdWriteCmd(cmd);
00359 }
00360
00366 static void LcdWriteData(u_char data)
00367 {
00368
00369 LCD_CS_CLR();
00370 LcdDelay(LCD_SHORT_DELAY);
00371 LCD_RS_SET();
00372 LcdDelay(LCD_SHORT_DELAY);
00373 LcdWriteByte(data);
00374 LcdDelay(LCD_SHORT_DELAY);
00375 LCD_CS_SET();
00376 LcdDelay(LCD_SHORT_DELAY);
00377 }
00378
00379 static void LcdSetCursor(u_char pos)
00380 {
00381 u_char offset[] = {
00382 0x00, 0x40, 0x10, 0x50
00383 };
00384
00385 pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00386 LcdWriteCmd(0x80 | pos);
00387 }
00388
00389 static void LcdCursorHome(void)
00390 {
00391 LcdWriteCmd(0x02);
00392 LcdDelay(10 * LCD_LONG_DELAY);
00393 }
00394
00395 static void LcdCursorLeft(void)
00396 {
00397 LcdWriteCmd(0x10);
00398 }
00399
00400 static void LcdCursorRight(void)
00401 {
00402 LcdWriteCmd(0x14);
00403 }
00404
00405 static void LcdClear(void)
00406 {
00407 LcdWriteCmd(0x01);
00408 LcdDelay(10 * LCD_LONG_DELAY);
00409 }
00410
00411 static void LcdCursorMode(u_char on)
00412 {
00413 if (on) {
00414 LcdWriteCmd(0x0D);
00415 } else {
00416 LcdWriteCmd(0x0C);
00417 }
00418 LcdDelay(10 * LCD_LONG_DELAY);
00419 }
00420
00421 static void LcdInit(NUTDEVICE * dev)
00422 {
00423 #if defined(PMC_PCER)
00424 outr(PMC_PCER, _BV(LCD_CS_PIO_ID) | _BV(LCD_RS_PIO_ID) | _BV(LCD_CLK_PIO_ID) | _BV(LCD_MOSI_PIO_ID));
00425 #endif
00426
00427
00428 LCD_CS_SET();
00429 LCD_RS_SET();
00430 LCD_CLK_SET();
00431 LCD_MOSI_SET();
00432
00433
00434 NutSleep(50);
00435
00436 LCD_RS_CLR();
00437 LCD_CS_CLR();
00438
00439 LcdWriteCmd(0x38);
00440 NutSleep(2);
00441 LcdWriteCmd(0x39);
00442 NutSleep(2);
00443 LcdWriteCmd(0x14);
00444 NutSleep(1);
00445 LcdWriteCmd(0x55);
00446 NutSleep(1);
00447 LcdWriteCmd(0x6D);
00448 NutSleep(1);
00449 LcdWriteCmd(0x78);
00450 NutSleep(1);
00451 LcdWriteCmd(0x0F);
00452 NutSleep(1);
00453 LcdWriteCmd(0x01);
00454 NutSleep(1);
00455 LcdWriteCmd(0x06);
00456 NutSleep(1);
00457
00458 LCD_CS_SET();
00459 LCD_RS_SET();
00460
00461
00462 LcdClear();
00463
00464 LcdCursorHome();
00465 }
00466
00470 static TERMDCB dcb_term = {
00471 LcdInit,
00472 LcdWriteData,
00473 LcdWriteInstruction,
00474 LcdClear,
00475 LcdSetCursor,
00476 LcdCursorHome,
00477 LcdCursorLeft,
00478 LcdCursorRight,
00479 LcdCursorMode,
00480 0,
00481 0,
00482 LCD_ROWS,
00483 LCD_COLS,
00484 LCD_COLS,
00485 0,
00486 0,
00487 0
00488 };
00489
00493 NUTDEVICE devSbiLcd = {
00494 0,
00495 {'s', 'b', 'i', 'l', 'c', 'd', 0, 0, 0},
00496 IFTYP_STREAM,
00497 0,
00498 0,
00499 0,
00500 &dcb_term,
00501 TermInit,
00502 TermIOCtl,
00503 0,
00504 TermWrite,
00505 TermOpen,
00506 TermClose,
00507 0
00508 };
00509