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