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
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 #ifdef __GNUC__
00084
00085 #include <stdlib.h>
00086 #include <string.h>
00087 #include <stdio.h>
00088
00089 #include <sys/nutconfig.h>
00090 #include <dev/hd44780_bus.h>
00091 #include <dev/term.h>
00092 #include <sys/timer.h>
00093
00094 static uint16_t lcd_base = 0x0000;
00095
00096 #ifndef LCD_4x20
00097 #ifndef LCD_4x16
00098 #ifndef LCD_2x40
00099 #ifndef LCD_2x20
00100 #ifndef LCD_2x16
00101 #ifndef LCD_2x8
00102 #ifndef LCD_1x20
00103 #ifndef LCD_1x16
00104 #ifndef LCD_1x8
00105 #ifndef KS0073_CONTROLLER
00106 #define LCD_2x16
00107 #endif
00108 #endif
00109 #endif
00110 #endif
00111 #endif
00112 #endif
00113 #endif
00114 #endif
00115 #endif
00116 #endif
00117
00118 #define LCD_DELAY asm volatile ("nop"); asm volatile ("nop")
00119
00120
00125
00131 static inline void LcdBusyWait(void)
00132 {
00133 #ifndef MMNET02
00134
00135
00136 while (*(volatile uint8_t *) (LCD_CTRL_ADDR + LCD_READ_OFFSET) & 1 << LCD_BUSY)
00137 LCD_DELAY;
00138 LCD_DELAY;
00139 LCD_DELAY;
00140 LCD_DELAY;
00141 LCD_DELAY;
00142 LCD_DELAY;
00143 LCD_DELAY;
00144 LCD_DELAY;
00145 LCD_DELAY;
00146 LCD_DELAY;
00147 LCD_DELAY;
00148 LCD_DELAY;
00149 LCD_DELAY;
00150 #else
00151
00152 NutDelay(5);
00153 #endif
00154 }
00155
00162 static void LcdWriteData(uint8_t data)
00163 {
00164 LcdBusyWait();
00165 *(volatile uint8_t *) (LCD_DATA_ADDR) = data;
00166 }
00167
00171 static void LcdWriteCmd(uint8_t cmd, uint8_t delay)
00172 {
00173 LcdBusyWait();
00174 *(volatile uint8_t *) (LCD_CTRL_ADDR) = cmd;
00175 }
00176
00177 static void LcdSetCursor(uint8_t pos)
00178 {
00179 uint8_t x = 0;
00180 uint8_t y = 0;
00181
00182 #ifdef KS0073_CONTROLLER
00183 uint8_t offset[4] = {0x00, 0x20, 0x40, 0x60};
00184 y = pos / 20;
00185 x = pos % 20;
00186 if (y > 3) y = 3;
00187 #endif
00188
00189 #if defined(LCD_2x40)
00190 uint8_t offset [2] = {0x00, 0x40};
00191 y = pos / 40;
00192 x = pos % 40;
00193 if (y > 1) y = 1;
00194 #endif
00195
00196 #if defined(LCD_4x20) || defined(LCD_2x20)
00197 uint8_t offset [4] = {0x00, 0x40, 0x14, 0x54};
00198 y = pos / 20;
00199 x = pos % 20;
00200 if (y>3) y=3;
00201 #endif
00202
00203 #if defined(LCD_4x16) || defined(LCD_2x16)
00204 uint8_t offset [4] = {0x00, 0x40, 0x10, 0x50};
00205 y = pos / 16;
00206 x = pos % 16;
00207 if (y>3) y=3;
00208 #endif
00209
00210 #if defined(LCD_2x8)
00211 uint8_t offset [2] = {0x00, 0x40};
00212 y = pos / 8;
00213 x = pos % 8;
00214 if (y>1) y=1;
00215 #endif
00216
00217 #if defined(LCD_1x8) || defined(LCD_1x16) || defined(LCD_1x20)
00218 uint8_t offset [1] = { 0x00 };
00219 y = 0;
00220 x = pos;
00221 #endif
00222
00223 pos = x + offset[y];
00224 LcdWriteCmd(1 << LCD_DDRAM | pos, 0);
00225 }
00226
00227 static void LcdCursorHome(void)
00228 {
00229 LcdWriteCmd(1 << LCD_HOME, 0);
00230 }
00231
00232 static void LcdCursorLeft(void)
00233 {
00234 LcdWriteCmd(1 << LCD_MOVE, 0);
00235 }
00236
00237 static void LcdCursorRight(void)
00238 {
00239 LcdWriteCmd(1 << LCD_MOVE | 1 << LCD_MOVE_RIGHT, 0);
00240 }
00241
00242 static void LcdClear(void)
00243 {
00244 LcdWriteCmd(1 << LCD_CLR, 0);
00245 }
00246
00247 static void LcdCursorMode(uint8_t on)
00248 {
00249 LcdWriteCmd(1 << LCD_ON_CTRL | on ? 1 << LCD_ON_CURSOR : 0x00, 0);
00250 }
00251
00256 static void LcdInit(NUTDEVICE * dev)
00257 {
00258 lcd_base = dev->dev_base;
00259 #ifdef KS0073_CONTROLLER
00260
00261 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_RE), 0);
00262 NutDelay(50);
00263 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_RE), 0);
00264 NutDelay(50);
00265 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_RE), 0);
00266 NutDelay(50);
00267
00268 LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), 0);
00269 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT, 0);
00270
00271 #else
00272
00273
00274
00275 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_2LINES), 0);
00276 NutDelay(50);
00277 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_2LINES), 0);
00278 NutDelay(50);
00279 LcdWriteCmd((1 << LCD_FUNCTION) | 1 << LCD_FUNCTION_8BIT | (1 << LCD_FUNCTION_2LINES), 0);
00280 NutDelay(50);
00281 #endif
00282
00283 LcdWriteCmd(1 << LCD_CLR, 0);
00284
00285 LcdWriteCmd(1 << LCD_ENTRY_MODE | 1 << LCD_ENTRY_INC, 0);
00286
00287 LcdWriteCmd(1 << LCD_ON_CTRL | 1 << LCD_ON_DISPLAY, 0);
00288
00289 LcdWriteCmd(1 << LCD_HOME, 0);
00290
00291 LcdWriteCmd(1 << LCD_DDRAM | 0x00, 0);
00292 }
00293
00297 TERMDCB dcb_term = {
00298 LcdInit,
00299 LcdWriteData,
00300 LcdWriteCmd,
00301 LcdClear,
00302 LcdSetCursor,
00303 LcdCursorHome,
00304 LcdCursorLeft,
00305 LcdCursorRight,
00306 LcdCursorMode,
00307 0,
00308 0,
00309 #ifdef KS0073_CONTROLLER
00310 4,
00311 20,
00312 20,
00313 #endif
00314 #ifdef LCD_4x20
00315 4,
00316 20,
00317 20,
00318 #endif
00319 #ifdef LCD_4x16
00320 4,
00321 16,
00322 16,
00323 #endif
00324 #ifdef LCD_2x40
00325 2,
00326 40,
00327 40,
00328 #endif
00329 #ifdef LCD_2x20
00330 2,
00331 20,
00332 20,
00333 #endif
00334 #ifdef LCD_2x16
00335 2,
00336 16,
00337 16,
00338 #endif
00339 #ifdef LCD_2x8
00340 2,
00341 8,
00342 8,
00343 #endif
00344 #ifdef LCD_1x20
00345 1,
00346 20,
00347 20,
00348 #endif
00349 #ifdef LCD_1x16
00350 1,
00351 16,
00352 16,
00353 #endif
00354 #ifdef LCD_1x8
00355 1,
00356 8,
00357 8,
00358 #endif
00359 0,
00360 0,
00361 0
00362 };
00363
00367 NUTDEVICE devLcdBus = {
00368 0,
00369 {'l', 'c', 'd', 'b', 'u', 's', 0, 0, 0},
00370 IFTYP_STREAM,
00371 0,
00372 0,
00373 0,
00374 &dcb_term,
00375 TermInit,
00376 TermIOCtl,
00377 0,
00378 TermWrite,
00379 TermWrite_P,
00380 TermOpen,
00381 TermClose,
00382 0
00383 };
00384
00385
00386 #else
00387 void keep_icc_happy(void)
00388 {
00389 }
00390
00391 #endif
00392