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