hd44780.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  *
00032  */
00033 
00034 /*
00035  * $Log: hd44780.c,v $
00036  * Revision 1.6  2008/04/29 16:58:21  thiagocorrea
00037  * Simplified HD44780 code for AVR based on the ARM driver.
00038  *
00039  * Revision 1.5  2006/10/08 16:40:17  haraldkipp
00040  * Many thanks to Thiago Correa for adding LCD port configuration.
00041  *
00042  * Revision 1.4  2006/09/11 09:13:18  olereinhardt
00043  * Another timing patch from Uwe Bonnes
00044  *
00045  * Revision 1.3  2006/09/07 15:53:27  olereinhardt
00046  * Added LCD timing patch from Uwe Bonnes
00047  *
00048  * Revision 1.2  2006/04/07 12:23:18  haraldkipp
00049  * Target specific delay defaults moved from global header to AVR specific
00050  * file.
00051  *
00052  * Revision 1.1  2005/07/26 18:02:27  haraldkipp
00053  * Moved from dev.
00054  *
00055  * Revision 1.6  2005/06/06 10:43:45  haraldkipp
00056  * Fixed to re-enable ICCAVR compilation.
00057  *
00058  * Revision 1.5  2005/05/27 14:02:11  olereinhardt
00059  * Added support for new display sizes configurable by macros
00060  * LCD_4x20, LCD_4x16, LCD_2x40, LCD_2x20, LCD_2x16, LCD_2x8,
00061  * LCD_1x20, LCD_1x16, LCD_1x8, KS0078_CONTROLLER (4x20))
00062  * Also added support for different delay types.
00063  * For not to wait busy too long, I added support for busy bit
00064  * read back and use NutSleep instead NutDelay if NUT_CPU_FREQ
00065  * is defined.
00066  *
00067  * Revision 1.4  2004/05/24 17:11:05  olereinhardt
00068  * dded terminal device driver for hd44780 compatible LCD displays directly
00069  * connected to the memory bus (memory mapped). See hd44780.c for more
00070  * information.Therefore some minor changed in include/dev/term.h and
00071  * dev/term.c are needet to
00072  * pass a base address to the lcd driver.
00073  *
00074  * Revision 1.3  2004/03/16 16:48:27  haraldkipp
00075  * Added Jan Dubiec's H8/300 port.
00076  *
00077  * Revision 1.2  2003/07/17 09:41:35  haraldkipp
00078  * Setting the data direction during init only may fail on some hardware.
00079  * We are now doing this immediately before using the port.
00080  *
00081  * Revision 1.1.1.1  2003/05/09 14:40:37  haraldkipp
00082  * Initial using 3.2.1
00083  *
00084  * Revision 1.3  2003/05/06 18:30:10  harald
00085  * ICCAVR port
00086  *
00087  * Revision 1.2  2003/04/21 16:22:46  harald
00088  * Moved back to outp/inp for portability
00089  *
00090  * Revision 1.1  2003/03/31 14:53:06  harald
00091  * Prepare release 3.1
00092  *
00093  */
00094 
00095 #include <stdlib.h>
00096 #include <string.h>
00097 
00098 #include <cfg/arch/avr.h>
00099 #include <dev/hd44780.h>
00100 #include <dev/term.h>
00101 #include <sys/timer.h>
00102 
00103 /* Backward compatibility with old macros */
00104 #ifndef LCD_ROWS
00105 #if defined(LCD_4x20) || defined(LCD_4x16) || defined(KS0073_CONTROLLER)
00106 #define LCD_ROWS    4
00107 #elif defined(LCD_1x20) || defined(LCD_1x16) || defined(LCD_1x8)
00108 #define LCD_ROWS    1
00109 #else
00110 #define LCD_ROWS    2
00111 #endif
00112 #endif                          /* LCD_ROWS */
00113 
00114 /* Backward compatibility with old macros */
00115 #ifndef LCD_COLS
00116 #if defined(LCD_2x40)
00117 #define LCD_COLS    40
00118 #elif defined(LCD_4x20) || defined(LCD_2x20) || defined(LCD_1x20) || defined(KS0073_CONTROLLER)
00119 #define LCD_COLS    20
00120 #elif defined(LCD_2x8) || defined(LCD_1x8)
00121 #define LCD_COLS    8
00122 #else
00123 #define LCD_COLS    16
00124 #endif
00125 #endif                          /* LCD_COLS */
00126 
00127 /*
00128  * Many thanks to Thiago Correa for adding LCD port configuration.
00129  */
00130 
00131 /* LCD_DATA_PORT and LCD_DATA_DDR switches */
00132 #if ( LCD_DATA_AVRPORT == AVRPORTA )
00133 #define LCD_DATA_PORT PORTA
00134 #define LCD_DATA_PIN PINA
00135 #define LCD_DATA_DDR DDRA
00136 
00137 #elif ( LCD_DATA_AVRPORT == AVRPORTB )
00138 #define LCD_DATA_PORT PORTB
00139 #define LCD_DATA_PIN PINB
00140 #define LCD_DATA_DDR DDRB
00141 
00142 #elif ( LCD_DATA_AVRPORT == AVRPORTC )
00143 #define LCD_DATA_PORT PORTC
00144 #define LCD_DATA_PIN PINC
00145 #define LCD_DATA_DDR DDRC
00146 
00147 #elif ( LCD_DATA_AVRPORT == AVRPORTE )
00148 #define LCD_DATA_PORT PORTE
00149 #define LCD_DATA_PIN PINE
00150 #define LCD_DATA_DDR DDRE
00151 
00152 #elif ( LCD_DATA_AVRPORT == AVRPORTF )
00153 #define LCD_DATA_PORT PORTF
00154 #define LCD_DATA_PIN PINF
00155 #define LCD_DATA_DDR DDRF
00156 
00157 #elif ( LCD_DATA_AVRPORT == AVRPORTG )
00158 #define LCD_DATA_PORT PORTG
00159 #define LCD_DATA_PIN PING
00160 #define LCD_DATA_DDR DDRG
00161 
00162 #else
00163 #define LCD_DATA_PORT PORTD
00164 #define LCD_DATA_PIN PIND
00165 #define LCD_DATA_DDR DDRD
00166 
00167 #endif
00168 
00169 #ifndef LCD_DATA_BITS
00170 #define LCD_DATA_BITS   0xF0
00171 #endif
00172 
00173 /* LCD_ENABLE_PORT switches */
00174 #if ( LCD_ENABLE_AVRPORT == AVRPORTA )
00175 #define LCD_ENABLE_PORT PORTA
00176 #define LCD_ENABLE_DDR DDRA
00177 
00178 #elif ( LCD_ENABLE_AVRPORT == AVRPORTB )
00179 #define LCD_ENABLE_PORT PORTB
00180 #define LCD_ENABLE_DDR DDRB
00181 
00182 #elif ( LCD_ENABLE_AVRPORT == AVRPORTC )
00183 #define LCD_ENABLE_PORT PORTC
00184 #define LCD_ENABLE_DDR DDRC
00185 
00186 #elif ( LCD_ENABLE_AVRPORT == AVRPORTD )
00187 #define LCD_ENABLE_PORT PORTD
00188 #define LCD_ENABLE_DDR DDRD
00189 
00190 #elif ( LCD_ENABLE_AVRPORT == AVRPORTF )
00191 #define LCD_ENABLE_PORT PORTF
00192 #define LCD_ENABLE_DDR DDRF
00193 
00194 #elif ( LCD_ENABLE_AVRPORT == AVRPORTG )
00195 #define LCD_ENABLE_PORT PORTG
00196 #define LCD_ENABLE_DDR DDRG
00197 
00198 #else
00199 #define LCD_ENABLE_PORT PORTE
00200 #define LCD_ENABLE_DDR DDRE
00201 
00202 #endif
00203 
00204 #ifndef LCD_ENABLE_BIT
00205 #define LCD_ENABLE_BIT  3       
00206 #endif
00207 
00208 /* LCD_REGSEL_PORT switches */
00209 #if ( LCD_REGSEL_AVRPORT == AVRPORTA )
00210 #define LCD_REGSEL_PORT PORTA
00211 #define LCD_REGSEL_DDR DDRA
00212 
00213 #elif ( LCD_REGSEL_AVRPORT == AVRPORTB )
00214 #define LCD_REGSEL_PORT PORTB
00215 #define LCD_REGSEL_DDR DDRB
00216 
00217 #elif ( LCD_REGSEL_AVRPORT == AVRPORTC )
00218 #define LCD_REGSEL_PORT PORTC
00219 #define LCD_REGSEL_DDR DDRC
00220 
00221 #elif ( LCD_REGSEL_AVRPORT == AVRPORTD )
00222 #define LCD_REGSEL_PORT PORTD
00223 #define LCD_REGSEL_DDR DDRD
00224 
00225 #elif ( LCD_REGSEL_AVRPORT == AVRPORTF )
00226 #define LCD_REGSEL_PORT PORTF
00227 #define LCD_REGSEL_DDR DDRF
00228 
00229 #elif ( LCD_REGSEL_AVRPORT == AVRPORTG )
00230 #define LCD_REGSEL_PORT PORTG
00231 #define LCD_REGSEL_DDR DDRG
00232 
00233 #else
00234 #define LCD_REGSEL_PORT PORTE
00235 #define LCD_REGSEL_DDR DDRE
00236 
00237 #endif
00238 
00239 #ifndef LCD_REGSEL_BIT
00240 #define LCD_REGSEL_BIT  2       
00241 #endif
00242 
00243 /* LCD_RW_PORT switches */
00244 #if ( LCD_RW_AVRPORT == AVRPORTA )
00245 #define LCD_RW_PORT PORTA
00246 #define LCD_RW_DDR DDRA
00247 
00248 #elif ( LCD_RW_AVRPORT == AVRPORTB )
00249 #define LCD_RW_PORT PORTB
00250 #define LCD_RW_DDR DDRB
00251 
00252 #elif ( LCD_RW_AVRPORT == AVRPORTC )
00253 #define LCD_RW_PORT PORTC
00254 #define LCD_RW_DDR DDRC
00255 
00256 #elif ( LCD_RW_AVRPORT == AVRPORTD )
00257 #define LCD_RW_PORT PORTD
00258 #define LCD_RW_DDR DDRD
00259 
00260 #elif ( LCD_RW_AVRPORT == AVRPORTE )
00261 #define LCD_RW_PORT PORTE
00262 #define LCD_RW_DDR DDRE
00263 
00264 #elif ( LCD_RW_AVRPORT == AVRPORTF )
00265 #define LCD_RW_PORT PORTF
00266 #define LCD_RW_DDR DDRF
00267 
00268 #elif ( LCD_RW_AVRPORT == AVRPORTG )
00269 #define LCD_RW_PORT PORTG
00270 #define LCD_RW_DDR DDRG
00271 #endif
00272 
00273 
00274 
00279 
00280 #ifndef LCD_SHORT_DELAY
00281 #define LCD_SHORT_DELAY 1
00282 #endif
00283 
00284 #ifndef LCD_LONG_DELAY
00285 #define LCD_LONG_DELAY  2
00286 #endif
00287 
00299 static u_char during_init = 1;
00300 #define LCD_DELAY _NOP(); _NOP(); _NOP(); _NOP() /*Three Nops would fit too */
00301 
00302 #ifdef LCD_RW_BIT
00303 
00304 static INLINE u_char LcdReadNibble(void)
00305 {
00306 
00307     u_char ret;
00308     sbi(LCD_RW_PORT, LCD_RW_BIT);
00309     outp(inp(LCD_DATA_DDR) & ~LCD_DATA_BITS, LCD_DATA_DDR);   // enable data input
00310     sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00311     LCD_DELAY;
00312     ret = inp(LCD_DATA_PIN) & LCD_DATA_BITS;
00313     cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00314     LCD_DELAY;
00315     return ret;
00316 }
00317 
00318 static INLINE u_char LcdReadByte(void)
00319 {    
00320     u_char data;
00321 #if LCD_DATA_BITS == 0x0F
00322     data = LcdReadNibble();
00323     data = data | (LcdReadNibble() << 4);
00324 #elif LCD_DATA_BITS == 0xF0
00325     data = LcdReadNibble() >> 4;
00326     data |= LcdReadNibble();
00327 #elif LCD_DATA_BITS == 0xFF
00328     data = LcdReadNibble();
00329 #else
00330 #error "Bad definition of LCD_DATA_BITS"
00331 #endif
00332     return data;
00333 }
00334 
00339 static u_char LcdReadCmd(void)
00340 {
00341     sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00342     cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00343     return LcdReadByte();
00344 }
00345 
00346 #endif
00347 
00348 
00349 static void LcdDelay(u_char xt) 
00350 {
00351     if (during_init) {
00352         NutDelay(xt);
00353     } else {
00354 #if defined(LCD_RW_BIT)
00355     while (LcdReadCmd() & (1 << LCD_BUSY)) 
00356         LCD_DELAY;
00357     LCD_DELAY;
00358     LCD_DELAY;
00359     LCD_DELAY;
00360     LCD_DELAY;
00361     LCD_DELAY;
00362     LCD_DELAY;
00363     LCD_DELAY;
00364     LCD_DELAY;
00365     LCD_DELAY;
00366     LCD_DELAY;
00367     LCD_DELAY;
00368 #elif defined(NUT_CPU_FREQ)    
00369     NutSleep(xt);
00370 #else
00371     NutDelay(xt);
00372 #endif
00373     }
00374 }
00375 
00376 static INLINE void LcdSendNibble(u_char nib)
00377 {
00378 #ifdef LCD_RW_BIT
00379     cbi(LCD_RW_PORT, LCD_RW_BIT);
00380 #endif
00381     outp(inp(LCD_DATA_DDR) | LCD_DATA_BITS, LCD_DATA_DDR);
00382     outp((inp(LCD_DATA_PORT) & ~LCD_DATA_BITS) | (nib & LCD_DATA_BITS), LCD_DATA_PORT);
00383     sbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT);
00384     LCD_DELAY; 
00385     cbi(LCD_ENABLE_PORT, LCD_ENABLE_BIT); 
00386     LCD_DELAY; 
00387 }
00388 
00398 static INLINE void LcdSendByte(u_char ch, u_char xt)
00399 {    
00400 #if LCD_DATA_BITS == 0x0F
00401     LcdSendNibble(ch >> 4);
00402     if(xt)
00403         LcdDelay(xt);
00404     LcdSendNibble(ch);
00405 #elif LCD_DATA_BITS == 0xF0
00406     LcdSendNibble(ch);
00407     if(xt)
00408         LcdDelay(xt);
00409     LcdSendNibble(ch << 4);
00410 #elif LCD_DATA_BITS == 0xFF
00411     LcdSendNibble(ch);
00412 #else
00413 #error "Bad definition of LCD_DATA_BITS"
00414 #endif
00415     if(xt)
00416         LcdDelay(xt);
00417 }
00418 
00419 static void LcdWriteData(u_char ch)
00420 {
00421     sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00422     sbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00423     LcdSendByte(ch, LCD_SHORT_DELAY);
00424 }
00425 
00429 static void LcdWriteCmd(u_char cmd, u_char xt)
00430 {
00431     sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00432     cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00433     LcdSendByte(cmd, xt);
00434 }
00435 
00436 static void LcdSetCursor(u_char pos)
00437 {
00438     u_char offset[] = {
00439 #ifdef KS0073_CONTROLLER
00440         0x00, 0x20, 0x40, 0x60
00441 #elif LCD_COLS == 20
00442         0x00, 0x40, 0x14, 0x54
00443 #else
00444         0x00, 0x40, 0x10, 0x50
00445 #endif
00446     };
00447 
00448     pos = offset[(pos / LCD_COLS) % LCD_ROWS] + pos % LCD_COLS;
00449     LcdWriteCmd(1 << LCD_DDRAM | pos, LCD_SHORT_DELAY);
00450 }
00451 
00452 static void LcdCursorHome(void)
00453 {
00454     LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00455 }
00456 
00457 static void LcdCursorLeft(void)
00458 {
00459     LcdWriteCmd(1 << LCD_MOVE, LCD_SHORT_DELAY);
00460 }
00461 
00462 static void LcdCursorRight(void)
00463 {
00464     LcdWriteCmd(1 << LCD_MOVE | 1 << LCD_MOVE_RIGHT, LCD_SHORT_DELAY);
00465 }
00466 
00467 static void LcdClear(void)
00468 {
00469     LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00470 }
00471 
00472 static void LcdCursorMode(u_char on)
00473 {
00474     LcdWriteCmd(1 << LCD_ON_CTRL | on ? 1 << LCD_ON_CURSOR : 0x00, LCD_LONG_DELAY);
00475 }
00476 
00477 static void LcdInit(NUTDEVICE *dev)
00478 {
00479     /*
00480      * Set LCD register select and enable outputs.
00481      */
00482     sbi(LCD_REGSEL_DDR, LCD_REGSEL_BIT);
00483     sbi(LCD_ENABLE_DDR, LCD_ENABLE_BIT);
00484 #ifdef LCD_RW_BIT
00485     sbi(LCD_RW_DDR, LCD_RW_BIT);
00486     cbi(LCD_RW_PORT, LCD_RW_BIT);
00487 #endif
00488 
00489     
00490     /*
00491      * Send a dummy data byte.
00492      */
00493     //LcdWriteData(0);
00494 
00495     /*
00496      * Initialize for 4-bit operation.
00497      */
00498     cbi(LCD_REGSEL_PORT, LCD_REGSEL_BIT);
00499 
00500 #if (LCD_DATA_BITS == 0xFF)     // 8 Bit initialisation
00501     LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00502     LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00503     LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), 50);
00504     #ifdef  KS0073_CONTROLLER
00505         LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00506         LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_SHORT_DELAY);
00507         LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT), LCD_SHORT_DELAY);
00508     #endif
00509     LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ?(1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00510 
00511 
00512 #else                           // 4 Bit initialisation
00513     LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00514     LcdDelay(50);
00515     LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00516     LcdDelay(50);
00517     LcdSendNibble((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT) | (((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_8BIT)) >> 4));
00518     LcdDelay(50);
00519     LcdSendNibble((1 << LCD_FUNCTION) | ((1 << LCD_FUNCTION) >> 4));    // Enter 4 Bit mode
00520     LcdDelay(50);
00521     #ifdef  KS0073_CONTROLLER
00522         LcdWriteCmd((1 << LCD_FUNCTION) | (1 << LCD_FUNCTION_RE), LCD_SHORT_DELAY);
00523         LcdWriteCmd((1 << LCD_EXT) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 2) ? (1 << LCD_EXT_4LINES) : 0), LCD_LONG_DELAY);
00524         LcdWriteCmd((1 << LCD_FUNCTION), LCD_LONG_DELAY);
00525     #endif
00526     LcdWriteCmd((1 << LCD_FUNCTION) | ((((TERMDCB *) dev->dev_dcb)->dcb_nrows > 1) ? (1 << LCD_FUNCTION_2LINES):0), LCD_SHORT_DELAY);
00527 #endif
00528 
00529     // clear LCD
00530     LcdWriteCmd(1 << LCD_CLR, LCD_LONG_DELAY);
00531     // set entry mode
00532     LcdWriteCmd(1 << LCD_ENTRY_MODE | 1 << LCD_ENTRY_INC, LCD_LONG_DELAY);
00533     // set display to on
00534     LcdWriteCmd(1 << LCD_ON_CTRL | 1 << LCD_ON_DISPLAY, LCD_LONG_DELAY);
00535     // move cursor to home
00536     LcdWriteCmd(1 << LCD_HOME, LCD_LONG_DELAY);
00537     // set data address to 0
00538     LcdWriteCmd(1 << LCD_DDRAM | 0x00, LCD_LONG_DELAY);    
00539     during_init = 0;
00540 }
00541 
00545 TERMDCB dcb_term = {
00546     LcdInit,            
00547     LcdWriteData,       
00548     LcdWriteCmd,        
00549     LcdClear,           
00550     LcdSetCursor,       
00551     LcdCursorHome,      
00552     LcdCursorLeft,      
00553     LcdCursorRight,     
00554     LcdCursorMode,      
00555     0,                  
00556     0,                  
00557     LCD_ROWS,           
00558     LCD_COLS,           
00559     LCD_COLS,           
00560     0,                  
00561     0,                  
00562     0                   
00563 };
00564 
00568 NUTDEVICE devLcd = {
00569     0,              
00570     {'l', 'c', 'd', 0, 0, 0, 0, 0, 0},      
00571     IFTYP_STREAM,   
00572     0,              
00573     0,              
00574     0,              
00575     &dcb_term,      
00576     TermInit,       
00577     TermIOCtl,      
00578     0,
00579     TermWrite,
00580     TermWrite_P,
00581     TermOpen,
00582     TermClose,
00583     0
00584 };
00585 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/