user config

Dependents:   StormXalike

Fork of TextLCD by Wim Huiskamp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TextLCD.cpp Source File

TextLCD.cpp

00001 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780
00002  * Copyright (c) 2007-2010, sford, http://mbed.org
00003  *               2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs 
00004  *               2013, v02: WH, Added I2C and SPI bus interfaces  
00005  *               2013, v03: WH, Added support for LCD40x4 which uses 2 controllers 
00006  *               2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess
00007  *               2013, v05: WH, Added support for 8x2B, added some UDCs   
00008  *               2013, v06: WH, Added support for devices that use internal DC/DC converters 
00009  *               2013, v07: WH, Added support for backlight and include portdefinitions for LCD2004 Module from DFROBOT 
00010  *               2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined pins 
00011  *               2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032 
00012  *               2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module  
00013  *               2014, v11: WH, Added support for native I2C controllers such as PCF21XX, Improved the _initCtrl() method to deal with differences between all supported controllers  
00014  *               2014, v12: WH, Added support for native I2C controller PCF2119 and native I2C/SPI controllers SSD1803, ST7036, added setContrast method (by JH1PJL) for supported devices (eg ST7032i) 
00015  *               2014, v13: WH, Added support for controllers US2066/SSD1311 (OLED), added setUDCBlink() method for supported devices (eg SSD1803), fixed issue in setPower() 
00016  *               2014, v14: WH, Added support for PT6314 (VFD), added setOrient() method for supported devices (eg SSD1803, US2066), added Double Height lines for supported devices, 
00017  *                              added 16 UDCs for supported devices (eg PCF2103), moved UDC defines to TextLCD_UDC file, added TextLCD_Config.h for feature and footprint settings.
00018  *               2014, v15: WH, Added AC780 support, added I2C expander modules, fixed setBacklight() for inverted logic modules. Fixed bug in LCD_SPI_N define 
00019  *               2014, v16: WH, Added ST7070 and KS0073 support, added setIcon(), clrIcon() and setInvert() method for supported devices 
00020  *
00021  * Permission is hereby granted, free of charge, to any person obtaining a copy
00022  * of this software and associated documentation files (the "Software"), to deal
00023  * in the Software without restriction, including without limitation the rights
00024  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00025  * copies of the Software, and to permit persons to whom the Software is
00026  * furnished to do so, subject to the following conditions:
00027  *
00028  * The above copyright notice and this permission notice shall be included in
00029  * all copies or substantial portions of the Software.
00030  *
00031  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00032  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00033  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00034  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00035  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00036  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00037  * THE SOFTWARE.
00038  */
00039 #include "mbed.h"
00040 #include "TextLCD.h"
00041 #include "TextLCD_UDC.inc"
00042    
00043 /** Create a TextLCD_Base interface
00044   *
00045   * @param type  Sets the panel size/addressing mode (default = LCD16x2)
00046   * @param ctrl  LCD controller (default = HD44780)           
00047   */
00048 TextLCD_Base::TextLCD_Base(LCDType type, LCDCtrl ctrl) : _type(type), _ctrl(ctrl) {
00049     
00050   // Extract LCDType data  
00051 
00052   // Columns encoded in b7..b0
00053   _nr_cols = (_type & 0xFF);          
00054 
00055   // Rows encoded in b15..b8  
00056   _nr_rows = ((_type >> 8) & 0xFF);  
00057 
00058   // Addressing mode encoded in b19..b16  
00059   _addr_mode = _type & LCD_T_ADR_MSK;
00060 }
00061 
00062 /**  Init the LCD Controller(s)
00063   *  Clear display 
00064   *  @param _LCDDatalength dl sets the datalength of data/commands
00065   *  @return none 
00066   */
00067 void TextLCD_Base::_init(_LCDDatalength dl) {
00068   
00069   // Select and configure second LCD controller when needed
00070   if(_type==LCD40x4) {
00071     _ctrl_idx=_LCDCtrl_1;        // Select 2nd controller   
00072     _initCtrl(dl);               // Init 2nd controller   
00073   }
00074     
00075   // Select and configure primary LCD controller
00076   _ctrl_idx=_LCDCtrl_0;          // Select primary controller  
00077   _initCtrl(dl);                 // Init primary controller
00078 
00079   // Clear whole display and Reset Cursor location
00080   // Note: This will make sure that some 3-line displays that skip topline of a 4-line configuration 
00081   //       are cleared and init cursor correctly.
00082   cls();   
00083 } 
00084 
00085 /**  Init the LCD controller
00086   *   Set number of lines, fonttype, no cursor etc
00087   *   The controller is accessed in 4-bit parallel mode either directly via mbed pins or through I2C or SPI expander.
00088   *   Some controllers also support native I2C or SPI interfaces. 
00089   *
00090   *  @param _LCDDatalength dl sets the 4 or 8 bit datalength of data/commands. Required for some native serial modes.
00091   *  @return none  
00092   *
00093   *  Note: some configurations are commented out because they have not yet been tested due to lack of hardware
00094   */
00095 void TextLCD_Base::_initCtrl(_LCDDatalength dl) {
00096   int _bias_lines=0; // Set Bias and lines (Instr Set 1), temporary variable.
00097   int _lines=0;      // Set lines (Ext Instr Set), temporary variable.
00098 
00099     this->_setRS(false); // command mode
00100     
00101     wait_ms(20);         // Wait 20ms to ensure powered up
00102 
00103     // The Controller could be in 8 bit mode (power-on reset) or in 4 bit mode (warm reboot) at this point.
00104     // Follow this procedure to make sure the Controller enters the correct state. The hardware interface
00105     // between the uP and the LCD can only write the 4 most significant bits (Most Significant Nibble, MSN).
00106     // In 4 bit mode the LCD expects the MSN first, followed by the LSN.
00107     //
00108     //    Current state:               8 bit mode                |  4 bit mode, MSN is next      | 4 bit mode, LSN is next          
00109                          //-------------------------------------------------------------------------------------------------                          
00110     _writeNibble(0x3);   //  set 8 bit mode (MSN) and dummy LSN, |   set 8 bit mode (MSN),       |    set dummy LSN, 
00111                          //  remains in 8 bit mode               |    change to 8 bit mode       |  remains in 4 bit mode
00112     wait_ms(15);         //                           
00113     
00114     _writeNibble(0x3);   //  set 8 bit mode and dummy LSN,       | set 8 bit mode and dummy LSN, |    set 8bit mode (MSN), 
00115                          //  remains in 8 bit mode               |   remains in 8 bit mode       |  remains in 4 bit mode
00116     wait_ms(15);         // 
00117     
00118     _writeNibble(0x3);   //  set 8 bit mode and dummy LSN,       | set 8 bit mode and dummy LSN, |    set dummy LSN, 
00119                          //  remains in 8 bit mode               |   remains in 8 bit mode       |  change to 8 bit mode
00120     wait_ms(15);         // 
00121 
00122     // Controller is now in 8 bit mode
00123 
00124     _writeNibble(0x2);   // Change to 4-bit mode (MSN), the LSN is undefined dummy
00125     wait_us(40);         // most instructions take 40us
00126 
00127     // Display is now in 4-bit mode
00128     // Note: 4/8 bit mode is ignored for most native SPI and I2C devices. They dont use the parallel bus.
00129     //       However, _writeNibble() method is void anyway for native SPI and I2C devices.
00130    
00131     // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc
00132     switch (_ctrl) {
00133 
00134       case KS0073:
00135           // Initialise Display configuration
00136           switch (_type) {
00137             case LCD8x1:         //8x1 is a regular 1 line display
00138             case LCD12x1:                                
00139             case LCD16x1:                                            
00140             case LCD20x1:
00141             case LCD24x1:
00142 //            case LCD32x1:        // EXT pin is High, extension driver needed
00143 //            case LCD40x1:        // EXT pin is High, extension driver needed                        
00144               _function  = 0x02;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00145                                     //   DL=0  (4 bits bus)             
00146                                     //    N=0  (1-line mode, N=1 2-line mode)
00147                                     //   RE=0  (Dis. Extended Regs, special mode for KS0073)
00148                                     //   DH=1  (Disp shift enable, special mode for KS0073)                                
00149                                     //   REV=0 (Reverse normal, special mode for KS0073)
00150                                     
00151               _function_1 = 0x04;   // Function set 001 DL N RE(1) BE LP (Ext Regs)
00152                                     //   DL=0  (4 bits bus)             
00153                                     //    N=0  (1-line mode, N=1 2-line mode)
00154                                     //   RE=1  (Ena Extended Regs, special mode for KS0073)
00155                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0073)                                
00156                                     //   LP=0  (LP=1 Low power mode, LP=0 Normal)
00157 
00158               _function_x = 0x00;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00159                                     //    NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0073)                                
00160               break;                                
00161 
00162 //            case LCD12x3D:         // Special mode for KS0073, KS0078 and PCF21XX            
00163 //            case LCD12x3D1:        // Special mode for KS0073, KS0078 and PCF21XX            
00164             case LCD12x4D:         // Special mode for KS0073, KS0078 and PCF21XX            
00165 //            case LCD16x3D:         // Special mode for KS0073, KS0078             
00166 //            case LCD16x4D:         // Special mode for KS0073, KS0078            
00167             case LCD20x4D:         // Special mode for KS0073, KS0078            
00168               _function  = 0x02;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00169                                     //   DL=0  (4 bits bus)             
00170                                     //    N=0  (dont care for 4 line mode)              
00171                                     //   RE=0  (Dis. Extended Regs, special mode for KS0073)
00172                                     //   DH=1  (Disp shift enable, special mode for KS0073)                                
00173                                     //   REV=0 (Reverse normal, special mode for KS0073)
00174                                     
00175               _function_1 = 0x04;   // Function set 001 DL N RE(1) BE LP (Ext Regs)
00176                                     //   DL=0  (4 bits bus)             
00177                                     //    N=0  (1-line mode), N=1 (2-line mode)
00178                                     //   RE=1  (Ena Extended Regs, special mode for KS0073)
00179                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0073)                                
00180                                     //   LP=0  (LP=1 Low power mode, LP=0 Normal)                                    
00181 
00182               _function_x = 0x01;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00183                                     //    NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0073)                                
00184               break;                                
00185 
00186 
00187             case LCD16x3G:            // Special mode for ST7036                        
00188 //            case LCD24x3D:         // Special mode for KS0078
00189 //            case LCD24x3D1:        // Special mode for KS0078
00190             case LCD24x4D:         // Special mode for KS0078
00191               error("Error: LCD Controller type does not support this Display type\n\r"); 
00192               break;  
00193 
00194             default:
00195               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)            
00196               _function  = 0x0A;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00197                                     //   DL=0  (4 bits bus)             
00198                                     //    N=1  (2-line mode), N=0 (1-line mode)
00199                                     //   RE=0  (Dis. Extended Regs, special mode for KS0073)
00200                                     //   DH=1  (Disp shift enable, special mode for KS0073)                                
00201                                     //   REV=0 (Reverse normal, special mode for KS0073)
00202                                     
00203               _function_1 = 0x0C;   // Function set 001 DL N RE(1) BE LP (Ext Regs)
00204                                     //   DL=0  (4 bits bus)             
00205                                     //    N=1  (2 line mode), N=0 (1-line mode)
00206                                     //   RE=1  (Ena Extended Regs, special mode for KS0073)
00207                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0073)                   
00208                                     //   LP=0  (LP=1 Low power mode, LP=0 Normal)                                                                                     
00209 
00210               _function_x = 0x00;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00211                                     //   NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0073)                                
00212               break;
00213           } // switch type
00214 
00215           // init special features
00216           _writeCommand(0x20 | _function_1);// Function set 001 DL N RE(1) BE LP (Ext Regs)
00217                                            //   DL=0 (4 bits bus), DL=1 (8 bits mode)            
00218                                            //    N=0 (1 line mode), N=1 (2 line mode)
00219                                            //   RE=1 (Ena Extended Regs, special mode for KS0073)
00220                                            //   BE=0 (Blink Enable/Disable, CG/SEG RAM, special mode for KS0073)                                
00221                                            //   LP=0  (LP=1 Low power mode, LP=0 Normal)                                                                                                                                
00222 
00223           _writeCommand(0x08 | _function_x); // Ext Function set 0000 1 FW BW NW (Ext Regs)
00224                                            //   FW=0  (5-dot font, special mode for KS0073)
00225                                            //   BW=0  (Cur BW invert disable, special mode for KS0073)
00226                                            //   NW=0  (1,2 Line), NW=1 (4 line, special mode for KS0073)                                
00227 
00228           _writeCommand(0x10);             // Scroll/Shift set 0001 DS/HS4 DS/HS3 DS/HS2 DS/HS1 (Ext Regs)
00229                                            //   Dotscroll/Display shift enable (Special mode for KS0073)
00230 
00231           _writeCommand(0x80);             // Scroll Quantity set 1 0 SQ5 SQ4 SQ3 SQ2 SQ1 SQ0 (Ext Regs)
00232                                            //   Scroll quantity (Special mode for KS0073)
00233 
00234           _writeCommand(0x20 | _function); // Function set 001 DL N RE(0) DH REV (Std Regs)
00235                                            //   DL=0  (4 bits bus), DL=1 (8 bits mode)             
00236                                            //    N=0  (1 line mode), N=1 (2 line mode)
00237                                            //   RE=0  (Dis. Extended Regs, special mode for KS0073)
00238                                            //   DH=1  (Disp shift enable/disable, special mode for KS0073)                                
00239                                            //   REV=0 (Reverse/Normal, special mode for KS0073)
00240           break; // case KS0073 Controller
00241 
00242 
00243       case KS0078:
00244           // Initialise Display configuration
00245           switch (_type) {
00246             case LCD8x1:         //8x1 is a regular 1 line display
00247             case LCD8x2B:        //8x2B is a special case of 16x1
00248 //            case LCD12x1:                                
00249             case LCD16x1:                                            
00250 //            case LCD20x1:
00251             case LCD24x1:
00252               _function  = 0x02;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00253                                     //   DL=0  (4 bits bus)             
00254                                     //    N=0  (1 line mode), N=1 (2 line mode)
00255                                     //   RE=0  (Dis. Extended Regs, special mode for KS0078)
00256                                     //   DH=1  (Disp shift enable, special mode for KS0078)                                
00257                                     //   REV=0 (Reverse normal, special mode for KS0078)
00258                                     
00259               _function_1 = 0x04;   // Function set 001 DL N RE(1) BE 0 (Ext Regs)
00260                                     //   DL=0  (4 bits bus)             
00261                                     //    N=0  (1 line mode), N=1 (2 line mode)
00262                                     //   RE=1  (Ena Extended Regs, special mode for KS0078)
00263                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0078)                                
00264                                     //      0 
00265 
00266               _function_x = 0x00;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00267                                     //    NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0078)                                
00268               break;                                
00269 
00270 //            case LCD12x3D:         // Special mode for KS0073, KS0078 and PCF21XX            
00271 //            case LCD12x3D1:        // Special mode for KS0073, KS0078 and PCF21XX            
00272 //            case LCD12x4D:         // Special mode for KS0073, KS0078 and PCF21XX            
00273 //            case LCD16x3D:         // Special mode for KS0073, KS0078             
00274 //            case LCD16x4D:         // Special mode for KS0073, KS0078            
00275 //            case LCD20x4D:         // Special mode for KS0073, KS0078            
00276 //            case LCD24x3D:         // Special mode for KS0078
00277 //            case LCD24x3D1:        // Special mode for KS0078
00278             case LCD24x4D:         // Special mode for KS0078
00279               _function  = 0x02;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00280                                     //   DL=0  (4 bits bus)             
00281                                     //    N=0  (dont care for 4 line mode)              
00282                                     //   RE=0  (Dis. Extended Regs, special mode for KS0078)
00283                                     //   DH=1  (Disp shift enable, special mode for KS0078)                                
00284                                     //   REV=0 (Reverse normal, special mode for KS0078)
00285                                     
00286               _function_1 = 0x04;   // Function set 001 DL N RE(1) BE 0 (Ext Regs)
00287                                     //   DL=0  (4 bits bus)             
00288                                     //    N=0  (1 line mode), N=1 (2 line mode)
00289                                     //   RE=1  (Ena Extended Regs, special mode for KS0078)
00290                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0078)                                
00291                                     //      0 
00292 
00293               _function_x = 0x01;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00294                                     //    NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0078)                                
00295               break;                                
00296 
00297             case LCD16x3G:            // Special mode for ST7036                        
00298               error("Error: LCD Controller type does not support this Display type\n\r"); 
00299               break;  
00300               
00301             default:
00302               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)            
00303               _function  = 0x0A;    // Function set 001 DL N RE(0) DH REV (Std Regs)
00304                                     //   DL=0  (4 bits bus)             
00305                                     //    N=1  (1 line mode), N=1 (2 line mode)
00306                                     //   RE=0  (Dis. Extended Regs, special mode for KS0078)
00307                                     //   DH=1  (Disp shift enable, special mode for KS0078)                                
00308                                     //   REV=0 (Reverse normal, special mode for KS0078)
00309                                     
00310               _function_1 = 0x0C;   // Function set 001 DL N RE(1) BE 0 (Ext Regs)
00311                                     //   DL=0  (4 bits bus)             
00312                                     //    N=1  (1 line mode), N=1 (2 line mode)
00313                                     //   RE=1  (Ena Extended Regs, special mode for KS0078)
00314                                     //   BE=0  (Blink Enable, CG/SEG RAM, special mode for KS0078)                                
00315                                     //      0 
00316 
00317               _function_x = 0x00;   // Ext Function set 0000 1 FW BW NW (Ext Regs)
00318                                     //   NW=0  (1,2 line), NW=1 (4 Line, special mode for KS0078)                                
00319               break;
00320           } // switch type
00321 
00322           // init special features
00323           _writeCommand(0x20 | _function_1);// Function set 001 DL N RE(1) BE 0 (Ext Regs)
00324                                            //   DL=0 (4 bits bus), DL=1 (8 bits mode)            
00325                                            //    N=0 (1 line mode), N=1 (2 line mode)
00326                                            //   RE=1 (Ena Extended Regs, special mode for KS0078)
00327                                            //   BE=0 (Blink Enable/Disable, CG/SEG RAM, special mode for KS0078)                                
00328                                            //      0 
00329 
00330           _writeCommand(0x08 | _function_x); // Ext Function set 0000 1 FW BW NW (Ext Regs)
00331                                            //   FW=0  (5-dot font, special mode for KS0078)
00332                                            //   BW=0  (Cur BW invert disable, special mode for KS0078)
00333                                            //   NW=0  (1,2 Line), NW=1 (4 line, special mode for KS0078)                                
00334 
00335           _writeCommand(0x10);             // Scroll/Shift set 0001 DS/HS4 DS/HS3 DS/HS2 DS/HS1 (Ext Regs)
00336                                            //   Dotscroll/Display shift enable (Special mode for KS0078)
00337 
00338           _writeCommand(0x80);             // Scroll Quantity set 1 0 SQ5 SQ4 SQ3 SQ2 SQ1 SQ0 (Ext Regs)
00339                                            //   Scroll quantity (Special mode for KS0078)
00340 
00341           _writeCommand(0x20 | _function); // Function set 001 DL N RE(0) DH REV (Std Regs)
00342                                            //   DL=0  (4 bits bus), DL=1 (8 bits mode)             
00343                                            //    N=0  (1 line mode), N=1 (2 line mode)
00344                                            //   RE=0  (Dis. Extended Regs, special mode for KS0078)
00345                                            //   DH=1  (Disp shift enable/disable, special mode for KS0078)                                
00346                                            //   REV=0 (Reverse/Normal, special mode for KS0078)
00347           break; // case KS0078 Controller
00348               
00349       case ST7032_3V3:
00350           // ST7032 controller: Initialise Voltage booster for VLCD. VDD=3V3
00351       case ST7032_5V:
00352           // ST7032 controller: Disable Voltage booster for VLCD. VDD=5V
00353 
00354           // Initialise Display configuration
00355           switch (_type) {
00356             case LCD8x1:         //8x1 is a regular 1 line display
00357             case LCD8x2B:        //8x2B is a special case of 16x1
00358 //            case LCD12x1:                                
00359             case LCD16x1:                                            
00360 //            case LCD20x1:                    
00361             case LCD24x1:
00362               _function = 0x00;       // FUNCTION SET 0 0 1 DL=0 (4 bit), N=0 (1-line display mode), F=0 (5*7dot), 0, IS
00363                                       // Note: 4 bit mode is ignored for native SPI and I2C devices
00364                                       // Saved to allow switch between Instruction sets at later time
00365               break;  
00366 
00367             case LCD12x3D:            // Special mode for KS0078 and PCF21XX
00368             case LCD12x3D1:           // Special mode for KS0078 and PCF21XX
00369             case LCD12x4D:            // Special mode for KS0078 and PCF21XX
00370             case LCD16x3G:            // Special mode for ST7036                        
00371             case LCD24x4D:            // Special mode for KS0078
00372               error("Error: LCD Controller type does not support this Display type\n\r"); 
00373               break;  
00374 
00375             default:
00376               // All other LCD types are initialised as 2 Line displays        
00377               _function = 0x08;       // FUNCTION SET 0 0 1 DL=0 (4 bit), N=1 (2-line display mode), F=0 (5*7dot), 0, IS              
00378                                       // Note: 4 bit mode is ignored for native SPI and I2C devices
00379                                       // Saved to allow switch between Instruction sets at later time
00380               break;                                                                        
00381           } // switch type    
00382                                      
00383           // init special features 
00384           _writeCommand(0x20 | _function | 0x01);           // Set function,  0 0 1 DL N F 0 IS=1 Select Instr Set = 1              
00385 
00386           _writeCommand(0x1C);                              // Internal OSC frequency adjustment Framefreq=183HZ, Bias will be 1/4 (Instr Set=1)
00387 
00388           _contrast = LCD_ST7032_CONTRAST;              
00389           _writeCommand(0x70 | (_contrast & 0x0F));         // Set Contrast Low bits, 0 1 1 1 C3 C2 C1 C0 (IS=1)
00390 
00391 
00392           if (_ctrl == ST7032_3V3) {
00393 //            _icon_power = 0x04;                             // Icon display off, Booster circuit is turned on  (IS=1)
00394             _icon_power = 0x0C;                             // Icon display on, Booster circuit is turned on  (IS=1)            
00395                                                             // Saved to allow contrast change at later time
00396           }
00397           else { 
00398 //            _icon_power = 0x00;                             // Icon display off, Booster circuit is turned off  (IS=1)
00399             _icon_power = 0x08;                             // Icon display on, Booster circuit is turned off  (IS=1)            
00400                                                             // Saved to allow contrast change at later time
00401           }
00402           _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03));  // Set Icon, Booster and Contrast High bits, 0 1 0 1 Ion Bon C5 C4 (IS=1)
00403           wait_ms(10);            // Wait 10ms to ensure powered up
00404           
00405           _writeCommand(0x68 | (LCD_ST7032_RAB & 0x07));      // Voltage follower, 0 1 1 0 FOn=1, Ampl ratio Rab2=1, Rab1=0, Rab0=0  (IS=1)
00406           wait_ms(10);            // Wait 10ms to ensure powered up
00407           
00408           _writeCommand(0x20 | _function);                  // Select Instruction Set = 0
00409 
00410           break; // case ST7032_3V3 Controller
00411                  // case ST7032_5V Controller
00412 
00413       case ST7036_3V3:
00414           // ST7036 controller: Initialise Voltage booster for VLCD. VDD=3V3
00415           // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G)
00416       case ST7036_5V:
00417           // ST7036 controller: Disable Voltage booster for VLCD. VDD=5V
00418           // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G)
00419                     
00420           // Initialise Display configuration
00421           switch (_type) {
00422             case LCD8x1:         //8x1 is a regular 1 line display
00423             case LCD8x2B:        //8x2D is a special case of 16x1
00424 //            case LCD12x1:                                
00425             case LCD16x1:   
00426             case LCD24x1:                                                                         
00427               _function = 0x00;     // Set function, 0 0 1 DL=0 (4-bit Databus), N=0 (1 Line), DH=0 (5x7font), IS2, IS1 (Select Instruction Set)
00428                                     // Note: 4 bit mode is ignored for native SPI and I2C devices
00429                                     // Saved to allow switch between Instruction sets at later time
00430               
00431               _bias_lines = 0x04;   // Bias: 1/5, 1 or 2-Lines LCD 
00432               break;  
00433 
00434 //            case LCD12x3G:          // Special mode for ST7036
00435             case LCD16x3G:          // Special mode for ST7036
00436               _function = 0x08;     // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set)              
00437                                     // Note: 4 bit mode is ignored for native SPI and I2C devices
00438                                     // Saved to allow switch between Instruction sets at later time
00439               
00440               _bias_lines = 0x05;   // Bias: 1/5, 3-Lines LCD           
00441               break;  
00442 
00443 //            case LCD12x3D1:           // Special mode for KS0078 and PCF21XX
00444 //            case LCD16x3D1:           // Special mode for SSD1803
00445             case LCD12x4D:            // Special mode for PCF2116
00446             case LCD24x4D:            // Special mode for KS0078
00447               error("Error: LCD Controller type does not support this Display type\n\r"); 
00448               break;  
00449 
00450             default:
00451               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)       
00452               _function = 0x08;     // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set)
00453                                     // Note: 4 bit mode is ignored for native SPI and I2C devices
00454                                     // Saved to allow switch between Instruction sets at later time
00455               
00456               _bias_lines = 0x04;   // Bias: 1/5, 1 or 2-Lines LCD 
00457               break;                
00458           } // switch type
00459 
00460 
00461           // init special features 
00462           _writeCommand(0x20 | _function | 0x01);   // Set function, IS2,IS1 = 01 (Select Instr Set = 1)
00463           _writeCommand(0x10 | _bias_lines);        // Set Bias and 1,2 or 3 lines (Instr Set 1)
00464 
00465           _contrast = LCD_ST7036_CONTRAST;
00466           _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast, 0 1 1 1 C3 C2 C1 C0 (Instr Set 1)
00467                            
00468           if (_ctrl == ST7036_3V3) {
00469             _icon_power = 0x0C;                       // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=1 Bon=1 C5 C4 (Instr Set 1)            
00470 //            _icon_power = 0x04;                       // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=1 C5 C4 (Instr Set 1)
00471                                                       // Saved to allow contrast change at later time
00472           } 
00473           else {
00474             _icon_power = 0x08;                       // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=1 Bon=0 C5 C4 (Instr Set 1)             
00475 //            _icon_power = 0x00;                       // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=0 C5 C4 (Instr Set 1)                         
00476           }
00477           
00478           _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03));   // Set Contrast C5, C4 (Instr Set 1)
00479           wait_ms(10);            // Wait 10ms to ensure powered up
00480 
00481           _writeCommand(0x68 | (LCD_ST7036_RAB & 0x07));  // Voltagefollower On = 1, Ampl ratio Rab2, Rab1, Rab0 = 1 0 1 (Instr Set 1)
00482           wait_ms(10);            // Wait 10ms to ensure powered up
00483 
00484           _writeCommand(0x20 | _function);          // Set function, IS2,IS1 = 00 (Select Instruction Set = 0)
00485          
00486           break; // case ST7036_3V3 Controller
00487                  // case ST7036_5V Controller
00488 
00489       case ST7070:                   
00490           // Initialise Display configuration
00491           switch (_type) {
00492             case LCD8x1:         //8x1 is a regular 1 line display
00493             case LCD8x2B:        //8x2D is a special case of 16x1
00494 //            case LCD12x1:                                
00495             case LCD16x1:   
00496             case LCD24x1:                                                                         
00497               _function = dl | 0x00;      // Set function, 0 0 1 DL=0 (4-bit Databus), N=0 (1 Line), EXT=0, x, x 
00498                                           // Note: 4 bit mode is NOT ignored for native SPI !
00499                                           // Saved to allow switch between Instruction sets at later time
00500               break;  
00501 
00502 //            case LCD12x3D1:           // Special mode for KS0078 and PCF21XX
00503 //            case LCD16x3D1:           // Special mode for SSD1803
00504             case LCD12x4D:            // Special mode for PCF2116
00505             case LCD24x4D:            // Special mode for KS0078
00506 //            case LCD12x3G:          // Special mode for ST7036
00507             case LCD16x3G:          // Special mode for ST7036           
00508               error("Error: LCD Controller type does not support this Display type\n\r"); 
00509               break;  
00510 
00511             default:
00512               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)       
00513               _function = dl | 0x08;   // Set function, 0 0 1 DL, N=1 (2 Line), EXT=0, x, x                                                                 
00514                                        // Note: 4 bit mode is NOT ignored for native SPI !
00515                                        // Saved to allow switch between Instruction sets at later time
00516               break;                
00517           } // switch type
00518 
00519 //          _writeCommand(0x00);                      // NOP, make sure to sync SPI
00520           
00521           // init special features                                                    
00522           _writeCommand(0x20 | _function | 0x04);   // Set function, 0 0 1 DL N EXT=1 x x (Select Instr Set = 1)
00523 
00524           _writeCommand(0x04 | 0x00);               // Set Bias resistors  0 0 0 0 0 1 Rb1,Rb0= 0 0 (Extern Res) (Instr Set 1)
00525 
00526           _writeCommand(0x40 | 0x00);               // COM/SEG directions 0 1 0 0 C1, C2, S1, S2  (Instr Set 1)
00527                                                     // C1=1: Com1-8 -> Com8-1;   C2=1: Com9-16 -> Com16-9
00528                                                     // S1=1: Seg1-40 -> Seg40-1; S2=1: Seg41-80 -> Seg80-41                                                    
00529           
00530           _writeCommand(0x20 | _function);          // Set function, EXT=0 (Select Instr Set = 0)
00531          
00532           break; // case ST7070 Controller
00533          
00534       case SSD1803_3V3:
00535           // SSD1803 controller: Initialise Voltage booster for VLCD. VDD=3V3
00536           // Note: supports 1,2, 3 or 4 lines
00537 //      case SSD1803_5V:
00538           // SSD1803 controller: No Voltage booster for VLCD. VDD=5V
00539                     
00540           // Initialise Display configuration
00541           switch (_type) {
00542             case LCD8x1:         //8x1 is a regular 1 line display
00543             case LCD8x2B:        //8x2D is a special case of 16x1
00544 //            case LCD12x1:                                
00545             case LCD16x1:   
00546             case LCD24x1:                                                                         
00547               _function = 0x00;     //  Set function 0 0 1 DL N DH RE(0) IS 
00548                                     //  Saved to allow switch between Instruction sets at later time
00549                                     //    DL=0 4-bit Databus,
00550                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00551                                     //     N=0 1 Line / 3 Line
00552                                     //    DH=0 Double Height disable 
00553                                     //    IS=0
00554           
00555               _function_1 = 0x02;   // Set function, 0 0 1 DL N BE RE(1) REV
00556                                     //  Saved to allow switch between Instruction sets at later time
00557                                     //    DL=0 4-bit Databus,
00558                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00559                                     //     N=0 1 Line / 3 Line
00560                                     //    BE=0 Blink Enable off, special feature of SSD1803
00561                                     //   REV=0 Reverse off, special feature of SSD1803            
00562                         
00563               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
00564                                     //    NW=0 1-Line LCD (N=0)
00565               break;  
00566 
00567             case LCD12x3D:          // Special mode for KS0078 and PCF21XX                                  
00568 //            case LCD12x3D1:           // Special mode for KS0078 and PCF21XX            
00569             case LCD16x3D:          // Special mode for KS0078
00570 //            case LCD16x3D1:           // Special mode for SSD1803
00571 //            case LCD20x3D:            // Special mode for SSD1803
00572               _function = 0x00;     //  Set function 0 0 1 DL N DH RE(0) IS 
00573                                     //  Saved to allow switch between Instruction sets at later time
00574                                     //    DL=0 4-bit Databus,
00575                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00576                                     //     N=0 1 Line / 3 Line
00577                                     //    DH=0 Double Height disable 
00578                                     //    IS=0
00579           
00580               _function_1 = 0x02;   // Set function, 0 0 1 DL N BE RE(1) REV
00581                                     //  Saved to allow switch between Instruction sets at later time
00582                                     //    DL=0 4-bit Databus,
00583                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00584                                     //     N=0 1 Line / 3 Line
00585                                     //    BE=0 Blink Enable off, special feature of SSD1803
00586                                     //   REV=0 Reverse off, special feature of SSD1803            
00587                         
00588               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
00589                                     //    NW=1 3-Line LCD (N=0)
00590               break;  
00591 
00592             case LCD20x4D:          // Special mode for SSD1803
00593               _function = 0x08;     //  Set function 0 0 1 DL N DH RE(0) IS 
00594                                     //  Saved to allow switch between Instruction sets at later time
00595                                     //    DL=0 4-bit Databus,
00596                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00597                                     //     N=1 4 Line
00598                                     //    DH=0 Double Height disable 
00599                                     //    IS=0
00600           
00601               _function_1 = 0x0A;   // Set function, 0 0 1 DL N BE RE(1) REV
00602                                     //  Saved to allow switch between Instruction sets at later time
00603                                     //    DL=0 4-bit Databus,
00604                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00605                                     //     N=1 4 Line
00606                                     //    BE=0 Blink Enable off, special feature of SSD1803
00607                                     //   REV=0 Reverse off, special feature of SSD1803            
00608                         
00609               _lines = 0x01;        // Ext function set 0 0 0 0 1 FW BW NW 
00610                                     //    NW=1 4-Line LCD (N=1)
00611               break;  
00612 
00613             case LCD16x3G:          // Special mode for ST7036            
00614             case LCD24x4D:          // Special mode for KS0078
00615               error("Error: LCD Controller type does not support this Display type\n\r"); 
00616               break;  
00617 
00618             default:
00619               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)       
00620               _function = 0x08;     //  Set function 0 0 1 DL N DH RE(0) IS 
00621                                     //  Saved to allow switch between Instruction sets at later time
00622                                     //    DL=0 4-bit Databus,
00623                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00624                                     //     N=1 2 line / 4 Line
00625                                     //    DH=0 Double Height disable 
00626                                     //    RE=0
00627                                     //    IS=0
00628           
00629               _function_1 = 0x0A;   // Set function, 0 0 1 DL N BE RE(1) REV
00630                                     //  Saved to allow switch between Instruction sets at later time
00631                                     //    DL=0 4-bit Databus,
00632                                     //         Note: 4 bit mode is ignored for native SPI and I2C devices
00633                                     //     N=1 2 line / 4 Line
00634                                     //    BE=0 Blink Enable off, special feature of SSD1803
00635                                     //    RE=1
00636                                     //   REV=0 Reverse off, special feature of SSD1803            
00637                         
00638               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
00639                                     //    NW=0 2-Line LCD (N=1)
00640               break;                
00641           } // switch type
00642 
00643 
00644           // init special features 
00645           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N BE RE(1) REV 
00646                                                     // Select Extended Instruction Set
00647           
00648           _writeCommand(0x06);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=1 COM1-32, BDS=0 SEG100-1    "Bottom View" (Ext Instr Set)
00649 //          _writeCommand(0x05);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=0 COM32-1, BDS=1 SEG1-100    "Top View" (Ext Instr Set)          
00650           wait_ms(5);                               // Wait to ensure completion or SSD1803 fails to set Top/Bottom after reset..
00651          
00652           _writeCommand(0x08 | _lines);             // Set ext function 0 0 0 0 1 FW BW NW 1,2,3 or 4 lines (Ext Instr Set)
00653 
00654           _writeCommand(0x10);                      // Double Height and Bias, 0 0 0 1 UD2=0, UD1=0, BS1=0 Bias 1/5, DH=0 (Ext Instr Set)
00655 
00656 //          _writeCommand(0x76);                      // Set TC Control, 0 1 1 1 0 1 1 0 (Ext Instr Set)
00657 //          _writeData(0x02);                         // Set TC data,    0 0 0 0 0 TC2,TC1,TC0 = 0 1 0 (Ext Instr Set)
00658 
00659           _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 DL N DH RE(0) IS=1 Select Instruction Set 1
00660                                                     // Select Std Instr set, Select IS=1  
00661 
00662           _contrast = LCD_SSD1_CONTRAST;
00663           _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast 0 1 1 1 C3, C2, C1, C0 (Instr Set 1)
00664                            
00665 //          _icon_power = 0x04;                       // Icon off, Booster on (Instr Set 1)
00666           _icon_power = 0x0C;                       // Icon on, Booster on (Instr Set 1)          
00667                                                     // Saved to allow contrast change at later time
00668           _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03));   // Set Power, Icon and Contrast, 0 1 0 1 Ion Bon C5 C4 (Instr Set 1)
00669           wait_ms(10);            // Wait 10ms to ensure powered up
00670 
00671           _writeCommand(0x68 | (LCD_SSD1_RAB & 0x07));  // Set Voltagefollower 0 1 1 0 Don = 1, Ampl ratio Rab2, Rab1, Rab0 = 1 1 0  (Instr Set 1)
00672           wait_ms(10);            // Wait 10ms to ensure powered up
00673 
00674           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N BE RE(1) REV 
00675                                                     // Select Extended Instruction Set 1
00676           _writeCommand(0x10);                      // Shift/Scroll enable, 0 0 0 1 DS4/HS4 DS3/HS3 DS2/HS2 DS1/HS1  (Ext Instr Set 1)
00677 
00678 
00679           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
00680                                                     // Select Std Instr set, Select IS=0
00681          
00682           break; // case SSD1803 Controller
00683 
00684           
00685       // Note1: The PCF21XX family of controllers has several types that dont have an onboard voltage generator for V-LCD.
00686       //        You must supply this LCD voltage externally and not try to enable VGen. 
00687       // Note2: The early versions of PCF2116 controllers (eg PCF2116C) can not generate sufficiently negative voltage for the LCD at a VDD of 3V3. 
00688       //        You must supply this voltage externally and not enable VGen or you must use a higher VDD (e.g. 5V) and enable VGen.
00689       //        More recent versions of the controller (eg PCF2116K) have an improved VGen that will work with 3V3.
00690       // Note3: See datasheet, PCF2116 and other types provide a V0 pin to control the LCD contrast voltage that is provided by VGen. This pins allows 
00691       //        contrast control similar to that of pin 3 on the standard 14pin LCD module connector.
00692       //        You can disable VGen by connecting Vo to VDD. VLCD will then be used directly as LCD voltage.
00693       // Note4: PCF2113 and PCF2119 are different wrt to VLCD generator! There is no V0 pin. The contrast voltage is software controlled by setting the VA and VB registers.
00694       //        Vgen is automatically switched off when the contrast voltage VA or VB is set to 0x00. Note that certain limits apply to allowed values for VA and VB.                    
00695       // Note5: See datasheet, members of the PCF21XX family support different numbers of rows/columns. Not all can support 3 or 4 rows.
00696       // Note6: See datasheet, the PCF21XX-C and PCF21XX-K use a non-standard character set. This may result is strange looking text when not corrected..
00697 
00698       case PCF2103_3V3:
00699           // PCF2103 controller: No Voltage generator for VLCD, VDD=3V3..5V, VLCD input controls contrast voltage.                 
00700           // Initialise Display configuration
00701           switch (_type) {
00702             case LCD24x1:                    
00703               _function = 0x00;       //FUNCTION SET 0 0 1 DL=0 4-bit, 0, M=0 1-line/24 chars display mode, 0, H=0 
00704                                       //Note: 4 bit mode is ignored for I2C mode
00705               break;  
00706 
00707 //            case LCD12x1D:            //Special mode for PCF21XX, Only top line used
00708             case LCD12x2:
00709               _function = 0x04;       //FUNCTION SET 0 0 1 DL=0 4-bit, 0, M=1 2-line/12 chars display mode, 0, H=0
00710                                       //Note: 4 bit mode is ignored for I2C mode
00711               break;  
00712               
00713             default:
00714               error("Error: LCD Controller type does not support this Display type\n\r"); 
00715               break;  
00716             
00717           } // switch type    
00718 
00719           _writeCommand(0x20 | _function | 0x01);          // Set function, Select Instr Set = 1              
00720           wait_ms(10);            // Wait 10ms to ensure powered up                                                    
00721 
00722 // Note: Display from GA628 shows 12 chars. This is actually the right half of a 24x1 display. The commons have been connected in reverse order.
00723           _writeCommand(0x05);                             // Display Conf Set         0000 0, 1, P=0, Q=1               (Instr. Set 1)
00724                                                         
00725           _writeCommand(0x02);                             // Screen Config            0000 001, L=0  (Instr. Set 1)
00726           _writeCommand(0x08);                             // ICON Conf                0000 1, IM=0 (Char mode), IB=0 (no Icon blink), 0 (Instr. Set 1) 
00727 
00728           _writeCommand(0x20 | _function);                 // Set function, Select Instr Set = 0             
00729           
00730 #if(0)
00731           // Select CG RAM
00732           _writeCommand(0x40); //Set CG-RAM address, 8 sequential locations needed per UDC
00733           // Store UDC/Icon pattern: 
00734           //   3 x 8 rows x 5 bits = 120 bits for Normal pattern (UDC 0..2) and
00735           //   3 x 8 rows x 5 bits = 120 bits for Blink pattern (UDC 4..6) 
00736           for (int i=0; i<(8 * 8); i++) {
00737 //            _writeData(0x1F);  // All On
00738             _writeData(0x00);  // All Off            
00739           }
00740 #endif
00741           break; // case PCF2103_3V3 Controller
00742 
00743       case PCF2113_3V3:
00744           // PCF2113 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
00745           // Initialise Display configuration
00746           switch (_type) {
00747 //            case LCD12x1:                                
00748 //              _function = 0x02;       // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=0 1-line/12 chars display mode, SL=1, IS=0
00749                                       // Note: 4 bit mode is ignored for I2C mode
00750             case LCD24x1:                    
00751               _function = 0x00;       // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=0 1-line/24 chars display mode, SL=0, IS=0            
00752                                       // Note: 4 bit mode is ignored for I2C mode
00753               break;  
00754 
00755             case LCD12x2:                    
00756               _function = 0x04;       // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=1 2-line/12 chars display mode, SL=0, IS=0            
00757               break;  
00758              
00759             default:
00760               error("Error: LCD Controller type does not support this Display type\n\r"); 
00761               break;  
00762                          
00763           } // switch type    
00764 
00765           // Init special features
00766           _writeCommand(0x20 | _function | 0x01);          // Set function, Select Instr Set = 1              
00767 
00768           _writeCommand(0x04);                             // Display Conf Set         0000 0, 1, P=0, Q=0               (Instr. Set 1)
00769           _writeCommand(0x10);                             // Temp Compensation Set    0001 0, 0, TC1=0, TC2=0           (Instr. Set 1)
00770 //          _writeCommand(0x42);                             // HV GEN                   0100 S1=1, S2=0 (2x multiplier)   (Instr. Set 1)
00771           _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03));     // HV Gen                   0100 S1=1, S2=0 (2x multiplier)   (Instr. Set 1)
00772           
00773           _contrast = LCD_PCF2_CONTRAST;              
00774           _writeCommand(0x80 | 0x00 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)  1, V=0, VA=contrast
00775           _writeCommand(0x80 | 0x40 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)  1, V=1, VB=contrast
00776           wait_ms(10);            // Wait 10ms to ensure powered up
00777           
00778           _writeCommand(0x02);                             // Screen Config            0000 001, L=0  (Instr. Set 1)
00779           _writeCommand(0x08);                             // ICON Conf                0000 1, IM=0 (Char mode), IB=0 (no icon blink) DM=0 (no direct mode) (Instr. Set 1) 
00780 
00781           _writeCommand(0x20 | _function);                 // Set function, Select Instr Set = 0             
00782 
00783           break; // case PCF2113_3V3 Controller
00784 
00785 
00786 //      case PCF2113_5V:
00787           // PCF2113 controller: No Voltage generator for VLCD. VDD=5V. Contrast voltage controlled by VA or VB.
00788 //@TODO                            
00789 
00790 
00791       case PCF2116_3V3:
00792           // PCF2116 controller: Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage.                 
00793           // Initialise Display configuration
00794           switch (_type) {
00795 //            case LCD12x1:
00796 //            case LCD12x2:                                                                            
00797             case LCD24x1:                    
00798               _writeCommand(0x22);    //FUNCTION SET 0 0 1 DL=0 4-bit, N=0/M=0 1-line/24 chars display mode, G=1 Vgen on, 0 
00799                                       //Note: 4 bit mode is ignored for I2C mode
00800               wait_ms(10);            // Wait 10ms to ensure powered up                                                    
00801               break;  
00802 
00803             case LCD12x3D:            // Special mode for KS0078 and PCF21XX                            
00804             case LCD12x3D1:           // Special mode for PCF21XX                     
00805             case LCD12x4D:            // Special mode for PCF21XX:
00806               _writeCommand(0x2E);    //FUNCTION SET 0 0 1 DL=0 4-bit, N=1/M=1 4-line/12 chars display mode, G=1 VGen on, 0                               
00807                                       //Note: 4 bit mode is ignored for I2C mode              
00808               wait_ms(10);            // Wait 10ms to ensure powered up                                                    
00809               break;  
00810 
00811             case LCD24x2:
00812               _writeCommand(0x2A);    //FUNCTION SET 0 0 1 DL=0 4-bit, N=1/M=0 2-line/24 chars display mode, G=1 VGen on, 0
00813                                       //Note: 4 bit mode is ignored for I2C mode
00814               wait_ms(10);            // Wait 10ms to ensure powered up   
00815               break;  
00816               
00817             default:
00818               error("Error: LCD Controller type does not support this Display type\n\r"); 
00819               break;  
00820             
00821           } // switch type    
00822 
00823           break; // case PCF2116_3V3 Controller
00824 
00825 
00826 //Experimental for cellphone 3-line display, SA=0x74, No Ack supported, Character set C or K, DL = 8 bit, N=0,M=1 (reserved mode !!), external VLCD -2V5
00827 //@TODO                            
00828       case PCF2116_5V:
00829           // PCF2116 controller: No Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage.                           
00830           // Initialise Display configuration
00831           switch (_type) {
00832 //            case LCD12x1:
00833 //            case LCD12x2:                                                                            
00834 //            case LCD24x1:                    
00835 //              _writeCommand(0x20);    //FUNCTION SET 0 0 1 DL=0 4-bit, N=0/M=0 1-line/24 chars display mode, G=0 no Vgen, 0 
00836                                       //Note: 4 bit mode is ignored for I2C mode
00837 //              wait_ms(10);            // Wait 10ms to ensure powered up                                                    
00838 //              break;  
00839 
00840             case LCD12x3D:            // Special mode for KS0078 and PCF21XX                            
00841             case LCD12x3D1:           // Special mode for PCF21XX                     
00842             case LCD12x4D:            // Special mode for PCF21XX:
00843 //              _writeCommand(0x34);    //FUNCTION SET 8 bit, N=0/M=1 4-line/12 chars display mode      OK
00844 //              _writeCommand(0x24);    //FUNCTION SET 4 bit, N=0/M=1 4-line/12 chars display mode      OK                                            
00845               _writeCommand(0x2C);    //FUNCTION SET 0 0 1 DL=0 4-bit, N=1/M=1 4-line/12 chars display mode, G=0 no Vgen, 0  OK       
00846                                       //Note: 4 bit mode is ignored for I2C mode              
00847               wait_ms(10);            // Wait 10ms to ensure powered up                                                    
00848               break;  
00849 
00850 //            case LCD24x2:
00851 //              _writeCommand(0x28);    //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode
00852                                       //Note: 4 bit mode is ignored for I2C mode
00853 //              wait_ms(10);            // Wait 10ms to ensure powered up   
00854 //              break;  
00855               
00856             default:
00857               error("Error: LCD Controller type does not support this Display type\n\r"); 
00858               break;  
00859             
00860           } // switch type    
00861 
00862           break; // case PCF2116_5V Controller
00863 
00864       case PCF2119_3V3:
00865           // PCF2119 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
00866           // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters.
00867           // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00.
00868                   
00869 //POR or Hardware Reset should be applied
00870           wait_ms(10);            // Wait 10ms to ensure powered up   
00871 
00872           // Initialise Display configuration
00873           switch (_type) {
00874             case LCD8x1:
00875 //            case LCD12x1:
00876             case LCD16x1:           
00877               _function = 0x02;       // FUNCTION SET 0 0 1 DL=0 4-bit, 0 , M=0 1-line/16 chars display mode, SL=1
00878                                       // Note: 4 bit mode is ignored for I2C mode
00879               break;  
00880             
00881             case LCD24x1:                    
00882 //            case LCD32x1:                                
00883               _function = 0x00;       // FUNCTION SET 0 0 1 DL=0 4-bit, 0 , M=0 1-line/32 chars display mode, SL=0
00884                                       // Note: 4 bit mode is ignored for I2C mode
00885               break;  
00886 
00887             case LCD8x2:
00888 //            case LCD12x2:            
00889             case LCD16x2:
00890               _function = 0x04;       // FUNCTION SET 0 0 1 DL=0 4-bit, 0, M=1 2-line/16 chars display mode, SL=0
00891                                       // Note: 4 bit mode is ignored for I2C mode
00892               break;  
00893              
00894             default:
00895               error("Error: LCD Controller type does not support this Display type\n\r"); 
00896               break;  
00897             
00898           } // switch type    
00899 
00900           // Init special features 
00901           _writeCommand(0x20 | _function | 0x01);           // Set function, Select Instruction Set = 1              
00902 
00903           _writeCommand(0x04);    // DISP CONF SET (Instr. Set 1)   0000, 0, 1, P=0, Q=0 
00904           _writeCommand(0x10);    // TEMP CTRL SET (Instr. Set 1)   0001, 0, 0, TC1=0, TC2=0
00905 //          _writeCommand(0x42);    // HV GEN (Instr. Set 1)          0100, 0, 0, S1=1, S2=0 (2x multiplier)
00906           _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03));      // HV GEN (Instr. Set 1)          0100, 0, 0, S1=1, S2=0 (2x multiplier)
00907 
00908           _contrast = LCD_PCF2_CONTRAST;              
00909           _writeCommand(0x80 | 0x00 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)    V=0, VA=contrast
00910           _writeCommand(0x80 | 0x40 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)    V=1, VB=contrast
00911           wait_ms(10);            // Wait 10ms to ensure powered up
00912           
00913           _writeCommand(0x02);    // SCRN CONF (Instr. Set 1)    L=0
00914           _writeCommand(0x08);    // ICON CONF (Instr. Set 1)    IM=0 (Char mode) IB=0 (no icon blink) DM=0 (no direct mode)
00915 
00916           _writeCommand(0x20 | _function);                  // Select Instruction Set = 0
00917 
00918           break; // case PCF2119_3V3 Controller
00919 
00920 //      case PCF2119_5V:
00921           // PCF2119 controller: No Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
00922           // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters.
00923           // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00.                     
00924 //@TODO                            
00925 
00926       case WS0010:         
00927           // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs
00928           // Note1: Identical to RS0010  
00929           // Note2: supports 1 or 2 lines (and 16x100 graphics)
00930           //        supports 4 fonts (English/Japanese (default), Western European-I, English/Russian, Western European-II)
00931                            // Cursor/Disp shift set 0001 SC RL  0 0
00932                            //
00933                            // Mode and Power set    0001 GC PWR 1 1                           
00934                            //  GC  = 0 (Graph Mode=1, Char Mode=0)             
00935                            //  PWR = 1 (DC/DC On/Off)
00936    
00937 //@Todo: This may be needed to enable a warm reboot
00938           //_writeCommand(0x13);   // Char mode, DC/DC off              
00939           //wait_ms(10);           // Wait 10ms to ensure powered down                  
00940           _writeCommand(0x17);   // Char mode, DC/DC on        
00941           wait_ms(10);           // Wait 10ms to ensure powered up        
00942 
00943           // Initialise Display configuration
00944           switch (_type) {                    
00945             case LCD8x1:         //8x1 is a regular 1 line display
00946             case LCD8x2B:        //8x2B is a special case of 16x1
00947 //            case LCD12x1:                                
00948             case LCD16x1:                                            
00949             case LCD24x1:
00950               _writeCommand(0x20); // Function set 001 DL N F FT1 FT0
00951                                    //  DL=0  (4 bits bus)             
00952                                    //   N=0  (1 line)
00953                                    //   F=0  (5x7 dots font)
00954                                    //  FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2
00955               break;  
00956 
00957             case LCD12x3D:            // Special mode for KS0078 and PCF21XX                            
00958             case LCD12x3D1:           // Special mode for PCF21XX                     
00959             case LCD12x4D:            // Special mode for PCF21XX:
00960             case LCD16x3G:            // Special mode for ST7036            
00961             case LCD24x4D:            // Special mode for KS0078
00962               error("Error: LCD Controller type does not support this Display type\n\r"); 
00963               break;  
00964 
00965             default:
00966               // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)       
00967               _writeCommand(0x28); // Function set 001 DL N F FT1 FT0
00968                                    //  DL=0  (4 bits bus)
00969                                    //   N=1  (2 lines)
00970                                    //   F=0  (5x7 dots font)
00971                                    //  FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2
00972 
00973               break;
00974            } // switch type
00975            
00976            break; // case WS0010 Controller
00977 
00978 
00979       case US2066_3V3:
00980           // US2066/SSD1311 OLED controller, Initialise for VDD=3V3
00981           // Note: supports 1,2, 3 or 4 lines
00982 //      case USS2066_5V:
00983           // US2066 controller, VDD=5V
00984                     
00985           // Initialise Display configuration
00986           switch (_type) {
00987             case LCD8x1:         //8x1 is a regular 1 line display
00988             case LCD8x2B:        //8x2D is a special case of 16x1
00989 //            case LCD12x1:                                
00990             case LCD16x1:   
00991 //            case LCD20x1:                                                                         
00992               _function = 0x00;     //  Set function 0 0 1 X N DH RE(0) IS 
00993                                     //  Saved to allow switch between Instruction sets at later time
00994                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead
00995                                     //     N=0 1 Line / 3 Line
00996                                     //    DH=0 Double Height disable 
00997                                     //    IS=0
00998           
00999               _function_1 = 0x02;   // Set function, 0 0 1 X N BE RE(1) REV
01000                                     //  Saved to allow switch between Instruction sets at later time
01001                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead                                    
01002                                     //     N=0 1 Line / 3 Line
01003                                     //    BE=0 Blink Enable off, special feature of SSD1803, US2066
01004                                     //   REV=0 Reverse off, special feature of SSD1803, US2066            
01005                         
01006               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
01007                                     //    NW=0 1-Line LCD (N=0)
01008               break;  
01009 
01010             case LCD16x1C:
01011             case LCD8x2:
01012             case LCD16x2:
01013             case LCD20x2:            
01014               _function = 0x08;     //  Set function 0 0 1 X N DH RE(0) IS 
01015                                     //  Saved to allow switch between Instruction sets at later time
01016                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead                                                                        
01017                                     //     N=1 2 line / 4 Line
01018                                     //    DH=0 Double Height disable 
01019                                     //    IS=0
01020           
01021               _function_1 = 0x0A;   // Set function, 0 0 1 X N BE RE(1) REV
01022                                     //  Saved to allow switch between Instruction sets at later time
01023                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead                                                                        
01024                                     //     N=1 2 line / 4 Line
01025                                     //    BE=0 Blink Enable off, special feature of SSD1803, US2066
01026                                     //   REV=0 Reverse off, special feature of SSD1803, US2066            
01027                         
01028               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
01029                                     //    NW=0 2-Line LCD (N=1)
01030               break;                
01031 
01032             case LCD12x3D:          // Special mode for KS0078 and PCF21XX 
01033 //            case LCD12x3D1:           // Special mode for KS0078 and PCF21XX            
01034             case LCD16x3D:          // Special mode for KS0078, SSD1803 and US2066
01035 //            case LCD16x3D1:           // Special mode for SSD1803, US2066
01036 //            case LCD20x3D:            // Special mode for SSD1803, US2066
01037               _function = 0x00;     //  Set function 0 0 1 X N DH RE(0) IS 
01038                                     //  Saved to allow switch between Instruction sets at later time
01039                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead                                    
01040                                     //     N=0 1 Line / 3 Line
01041                                     //    DH=0 Double Height disable 
01042                                     //    IS=0
01043           
01044               _function_1 = 0x02;   // Set function, 0 0 1 X N BE RE(1) REV
01045                                     //  Saved to allow switch between Instruction sets at later time
01046                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead                                    
01047                                     //     N=0 1 Line / 3 Line
01048                                     //    BE=0 Blink Enable off, special feature of SSD1803, US2066
01049                                     //   REV=0 Reverse off, special feature of SSD1803, US2066            
01050                         
01051               _lines = 0x00;        // Ext function set 0 0 0 0 1 FW BW NW 
01052                                     //    NW=1 3-Line LCD (N=0)
01053               break;  
01054 
01055             case LCD20x4D:          // Special mode for SSD1803, US2066
01056               _function = 0x08;     //  Set function 0 0 1 X N DH RE(0) IS 
01057                                     //  Saved to allow switch between Instruction sets at later time
01058                                     //    DL=X bit is ignored for US2066. Uses hardwired pins instead
01059                                     //     N=1 2 line / 4 Line
01060                                     //    DH=0 Double Height disable 
01061                                     //    IS=0
01062           
01063               _function_1 = 0x0A;   // Set function, 0 0 1 DL N BE RE(1) REV
01064                                     //  Saved to allow switch between Instruction sets at later time
01065                                     //    DL=0 bit is ignored for US2066. Uses hardwired pins instead                                    
01066                                     //     N=1 2 line / 4 Line
01067                                     //    BE=0 Blink Enable off, special feature of SSD1803, US2066
01068                                     //   REV=0 Reverse off, special feature of SSD1803, US2066            
01069                         
01070               _lines = 0x01;        // Ext function set 0 0 0 0 1 FW BW NW 
01071                                     //    NW=1 4-Line LCD (N=1)
01072               break;  
01073 
01074 //            case LCD24x1:                                                                         
01075 //            case LCD16x3G:          // Special mode for ST7036            
01076 //            case LCD24x4D:          // Special mode for KS0078
01077             default:            
01078               error("Error: LCD Controller type does not support this Display type\n\r"); 
01079               break;  
01080 
01081           } // switch type
01082 
01083           _writeCommand(0x00);                      // NOP, make sure to sync SPI
01084 
01085           // init special features 
01086           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
01087                                                     // Select Extended Instruction Set
01088 
01089           _writeCommand(0x71);                      // Function Select A: 0 1 1 1 0 0 0 1 (Ext Instr Set)
01090           _writeData(0x00);                         // Disable Internal VDD
01091 
01092           _writeCommand(0x79);                      // Function Select OLED:  0 1 1 1 1 0 0 1 (Ext Instr Set)
01093 
01094           _writeCommand(0xD5);                      // Display Clock Divide Ratio: 1 1 0 1 0 1 0 1 (Ext Instr Set, OLED Instr Set)
01095           _writeCommand(0x70);                      // Display Clock Divide Ratio value: 0 1 1 1 0 0 0 0 (Ext Instr Set, OLED Instr Set)
01096                     
01097           _writeCommand(0x78);                      // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set)
01098           
01099 //          _writeCommand(0x06);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=1 COM1-32, BDS=0 SEG100-1    "Bottom View" (Ext Instr Set)
01100           _writeCommand(0x05);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=0 COM32-1, BDS=1 SEG1-100    "Top View" (Ext Instr Set)          
01101          
01102           _writeCommand(0x08 | _lines);             // Set ext function 0 0 0 0 1 FW BW NW 1,2,3 or 4 lines (Ext Instr Set)
01103 
01104 //          _writeCommand(0x1C);                      // Double Height, 0 0 0 1 UD2=1, UD1=1, X, DH'=0 (Ext Instr Set)
01105 //                                                    // Default
01106 
01107           _writeCommand(0x72);                      // Function Select B: 0 1 1 1 0 0 1 0 (Ext Instr Set)
01108           _writeData(0x01);                         // Select ROM A (CGRAM 8, CGROM 248)
01109 
01110           _writeCommand(0x79);                      // Function Select OLED:  0 1 1 1 1 0 0 1 (Ext Instr Set)
01111 
01112           _writeCommand(0xDA);                      // Set Segm Pins Config:  1 1 0 1 1 0 1 0 (Ext Instr Set, OLED)
01113           _writeCommand(0x10);                      // Set Segm Pins Config value: Altern Odd/Even, Disable Remap (Ext Instr Set, OLED)
01114 
01115           _writeCommand(0xDC);                      // Function Select C: 1 1 0 1 1 1 0 0 (Ext Instr Set, OLED)
01116 //          _writeCommand(0x00);                      // Set internal VSL, GPIO pin HiZ (always read low)
01117           _writeCommand(0x80);                      // Set external VSL, GPIO pin HiZ (always read low)
01118 
01119           _contrast = LCD_US20_CONTRAST;
01120           _writeCommand(0x81);                      // Set Contrast Control: 1 0 0 0 0 0 0 1 (Ext Instr Set, OLED)
01121           _writeCommand((_contrast << 2) | 0x03);   // Set Contrast Value: 8 bits, use 6 bits for compatibility 
01122 
01123           _writeCommand(0xD9);                      // Set Phase Length: 1 1 0 1 1 0 0 1 (Ext Instr Set, OLED)
01124           _writeCommand(0xF1);                      // Set Phase Length Value: 
01125 
01126           _writeCommand(0xDB);                      // Set VCOMH Deselect Lvl: 1 1 0 1 1 0 1 1 (Ext Instr Set, OLED)
01127           _writeCommand(0x30);                      // Set VCOMH Deselect Value: 0.83 x VCC
01128 
01129           wait_ms(10);            // Wait 10ms to ensure powered up
01130 
01131 //Test Fade/Blinking. Hard Blink on/off, No fade in/out ??
01132 //          _writeCommand(0x23);                      // Set (Ext Instr Set, OLED)
01133 //          _writeCommand(0x3F);                      // Set interval 128 frames
01134 //End Test Blinking
01135 
01136           _writeCommand(0x78);                      // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set)
01137           
01138           _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 X N DH RE(0) IS=1 Select Instruction Set 1
01139                                                     // Select Std Instr set, Select IS=1  
01140 
01141           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
01142                                                     // Select Ext Instr Set, IS=1
01143           _writeCommand(0x10);                      // Shift/Scroll enable, 0 0 0 1 DS4/HS4 DS3/HS3 DS2/HS2 DS1/HS1  (Ext Instr Set, IS=1)
01144 
01145           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
01146                                                     // Select Std Instr set, Select IS=0        
01147           break; // case US2066/SSD1311 Controller
01148 
01149       //not yet tested on hardware
01150       case PT6314 :
01151           // Initialise Display configuration
01152           switch (_type) {
01153             case LCD8x1:         //8x1 is a regular 1 line display
01154             case LCD8x2B:        //8x2B is a special case of 16x1
01155 //            case LCD12x1:                                
01156             case LCD16x1:                                            
01157             case LCD20x1:                                                        
01158             case LCD24x1:
01159               _function = 0x00;    // Function set 001 DL N X BR1 BR0
01160                                    //  DL=0 (4 bits bus)
01161                                    //  Note: 4 bit mode is ignored for native SPI and I2C devices                                                                                 
01162                                    //  N=0 (1 line)
01163                                    //  X
01164                                    //  BR1=0 (2 significant bits for brightness
01165                                    //  BR0=0 
01166                                    //           0x0 = 100%
01167                                    //           0x1 =  75%
01168                                    //           0x2 =  50%
01169                                    //           0x3 =  25%                
01170 
01171               break;                                
01172                                                   
01173             // All other valid LCD types are initialised as 2 Line displays
01174             case LCD8x2:  
01175             case LCD16x2:  
01176             case LCD20x2:
01177             case LCD24x2:
01178               _function = 0x08;    // Function set 001 DL N X BR1 BR2
01179                                    //  DL=0 (4 bits bus)
01180                                    //  Note: 4 bit mode is ignored for native SPI and I2C devices                                 
01181                                    //  N=1 (2 lines)
01182                                    //  X
01183                                    //  BR1=0 (2 significant bits for brightness
01184                                    //  BR0=0 
01185               break;
01186               
01187             default:            
01188               error("Error: LCD Controller type does not support this Display type\n\r"); 
01189               break;               
01190           } // switch type
01191            
01192           _contrast = LCD_PT63_CONTRAST;
01193           _writeCommand(0x20 | _function | ((~_contrast) >> 4));        // Invert and shift to use 2 MSBs     
01194           break; // case PT6314 Controller (VFD)
01195            
01196         default:
01197           // Devices fully compatible to HD44780 that do not use any DC/DC Voltage converters but external VLCD, no icons etc
01198 
01199           // Initialise Display configuration
01200           switch (_type) {
01201             case LCD8x1:         //8x1 is a regular 1 line display
01202             case LCD8x2B:        //8x2B is a special case of 16x1
01203 //            case LCD12x1:                                
01204             case LCD16x1:                                            
01205 //            case LCD20x1:                                                        
01206             case LCD24x1:
01207 //            case LCD40x1:            
01208               _function = 0x00;    // Function set 001 DL N F - -
01209                                    //  DL=0 (4 bits bus)             
01210                                    //   N=0 (1 line)
01211                                    //   F=0 (5x7 dots font)
01212               break;                                
01213                                                   
01214             case LCD12x3D:            // Special mode for KS0078 and PCF21XX                            
01215             case LCD12x3D1:           // Special mode for KS0078 and PCF21XX                     
01216             case LCD12x4D:            // Special mode for KS0078 and PCF21XX:
01217             case LCD16x3D:            // Special mode for KS0078
01218 //            case LCD16x3D1:           // Special mode for KS0078
01219 //            case LCD24x3D:            // Special mode for KS0078
01220 //            case LCD24x3D1:           // Special mode for KS0078            
01221             case LCD24x4D:            // Special mode for KS0078
01222               error("Error: LCD Controller type does not support this Display type\n\r"); 
01223               break;  
01224 
01225             // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
01226             default:
01227               _function = 0x08;    // Function set 001 DL N F - -
01228                                    //  DL=0 (4 bits bus)
01229                                    //  Note: 4 bit mode is ignored for native SPI and I2C devices                                 
01230                                    //   N=1 (2 lines)
01231                                    //   F=0 (5x7 dots font, only option for 2 line display)
01232                                    //    -  (Don't care)
01233               break;
01234           } // switch type
01235 
01236           _writeCommand(0x20 | _function);                         
01237           break; // case default Controller
01238           
01239     } // switch Controller specific initialisations    
01240 
01241     // Controller general initialisations                                          
01242 //    _writeCommand(0x01); // cls, and set cursor to 0
01243 //    wait_ms(10);         // The CLS command takes 1.64 ms.
01244 //                         // Since we are not using the Busy flag, Lets be safe and take 10 ms  
01245 
01246     _writeCommand(0x02); // Return Home 
01247                          //   Cursor Home, DDRAM Address to Origin
01248 
01249     _writeCommand(0x06); // Entry Mode 0000 0 1 I/D S 
01250                          //   Cursor Direction and Display Shift
01251                          //   I/D=1 (Cur incr)
01252                          //     S=0 (No display shift)                        
01253 
01254     _writeCommand(0x14); // Cursor or Display shift 0001 S/C R/L x x 
01255                          //   S/C=0 Cursor moves
01256                          //   R/L=1 Right
01257                          // 
01258 
01259 //    _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
01260 //                         //   Display On, Cursor Off, Blink Off   
01261 
01262     setCursor(CurOff_BlkOff);     
01263     setMode(DispOn);     
01264 }
01265 
01266 
01267 /** Clear the screen, Cursor home. 
01268   */
01269 void TextLCD_Base::cls() {
01270 
01271   // Select and configure second LCD controller when needed
01272   if(_type==LCD40x4) {
01273     _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
01274 
01275     // Second LCD controller Cursor always Off
01276     _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
01277 
01278     // Second LCD controller Clearscreen
01279     _writeCommand(0x01);  // cls, and set cursor to 0    
01280     wait_ms(10);          // The CLS command takes 1.64 ms.
01281                           // Since we are not using the Busy flag, Lets be safe and take 10 ms
01282   
01283     _ctrl_idx=_LCDCtrl_0; // Select primary controller
01284   }
01285   
01286   // Primary LCD controller Clearscreen
01287   _writeCommand(0x01);    // cls, and set cursor to 0
01288   wait_ms(10);            // The CLS command takes 1.64 ms.
01289                           // Since we are not using the Busy flag, Lets be safe and take 10 ms
01290 
01291   // Restore cursormode on primary LCD controller when needed
01292   if(_type==LCD40x4) {
01293     _setCursorAndDisplayMode(_currentMode,_currentCursor);     
01294   }
01295                    
01296   setAddress(0, 0);  // Reset Cursor location
01297                      // Note: This is needed because some displays (eg PCF21XX) don't use line 0 in the '3 Line' mode.   
01298 }
01299 
01300 /** Locate cursor to a screen column and row
01301   *
01302   * @param column  The horizontal position from the left, indexed from 0
01303   * @param row     The vertical position from the top, indexed from 0
01304   */ 
01305 void TextLCD_Base::locate(int column, int row) {
01306     
01307    // setAddress() does all the heavy lifting:
01308    //   check column and row sanity, 
01309    //   switch controllers for LCD40x4 if needed
01310    //   switch cursor for LCD40x4 if needed
01311    //   set the new memory address to show cursor at correct location
01312    setAddress(column, row);      
01313 }
01314    
01315 
01316 /** Write a single character (Stream implementation)
01317   */
01318 int TextLCD_Base::_putc(int value) {
01319   int addr;
01320     
01321     if (value == '\n') {
01322       //No character to write
01323       
01324       //Update Cursor      
01325       _column = 0;
01326       _row++;
01327       if (_row >= rows()) {
01328         _row = 0;
01329       }      
01330     }
01331     else {
01332       //Character to write      
01333       _writeData(value); 
01334               
01335       //Update Cursor
01336       _column++;
01337       if (_column >= columns()) {
01338         _column = 0;
01339         _row++;
01340         if (_row >= rows()) {
01341           _row = 0;
01342         }
01343       }          
01344     } //else
01345 
01346     //Set next memoryaddress, make sure cursor blinks at next location
01347     addr = getAddress(_column, _row);
01348     _writeCommand(0x80 | addr);
01349             
01350     return value;
01351 }
01352 
01353 
01354 // get a single character (Stream implementation)
01355 int TextLCD_Base::_getc() {
01356     return -1;
01357 }
01358 
01359 
01360 #if(LCD_PRINTF != 1)
01361 /** Write a character to the LCD
01362   *
01363   * @param c The character to write to the display
01364   */
01365 int TextLCD_Base::putc(int c){
01366   return _putc(c);
01367 }  
01368 
01369 
01370 /** Write a raw string to the LCD
01371   *
01372   * @param string text, may be followed by variables to emulate formatting the string.
01373   *                     However, printf formatting is NOT supported and variables will be ignored! 
01374   */
01375 int TextLCD_Base::printf(const char* text, ...) {
01376   
01377   while (*text !=0) {
01378     _putc(*text);
01379     text++;
01380   }
01381   return 0;
01382 }
01383 #endif    
01384 
01385 
01386 
01387 // Write a nibble using the 4-bit interface
01388 void TextLCD_Base::_writeNibble(int value) {
01389 
01390 // Enable is Low
01391     this->_setEnable(true);        
01392     this->_setData(value & 0x0F);   // Low nibble
01393     wait_us(1); // Data setup time        
01394     this->_setEnable(false);    
01395     wait_us(1); // Datahold time
01396 
01397 // Enable is Low
01398 }
01399 
01400 // Write a byte using the 4-bit interface
01401 void TextLCD_Base::_writeByte(int value) {
01402 
01403 // Enable is Low
01404     this->_setEnable(true);          
01405     this->_setData(value >> 4);   // High nibble
01406     wait_us(1); // Data setup time    
01407     this->_setEnable(false);   
01408     wait_us(1); // Data hold time
01409     
01410     this->_setEnable(true);        
01411     this->_setData(value >> 0);   // Low nibble
01412     wait_us(1); // Data setup time        
01413     this->_setEnable(false);    
01414     wait_us(1); // Datahold time
01415 
01416 // Enable is Low
01417 }
01418 
01419 // Write a command byte to the LCD controller
01420 void TextLCD_Base::_writeCommand(int command) {
01421 
01422     this->_setRS(false);        
01423     wait_us(1);  // Data setup time for RS       
01424     
01425     this->_writeByte(command);   
01426     wait_us(40); // most instructions take 40us            
01427 }
01428 
01429 // Write a data byte to the LCD controller
01430 void TextLCD_Base::_writeData(int data) {
01431 
01432     this->_setRS(true);            
01433     wait_us(1);  // Data setup time for RS 
01434         
01435     this->_writeByte(data);
01436     wait_us(40); // data writes take 40us                
01437 }
01438 
01439 
01440 // This replaces the original _address() method.
01441 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
01442 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
01443 int TextLCD_Base::_address(int column, int row) {
01444   return 0x80 | getAddress(column, row);
01445 }
01446 
01447 
01448 // This is new method to return the memory address based on row, column and displaytype.
01449 //
01450 /** Return the memoryaddress of screen column and row location
01451    *
01452    * @param column  The horizontal position from the left, indexed from 0
01453    * @param row     The vertical position from the top, indexed from 0
01454    * @return        The memoryaddress of screen column and row location
01455    *
01456    */
01457 int TextLCD_Base::getAddress(int column, int row) {
01458 
01459     switch (_addr_mode) {
01460 
01461         case LCD_T_A:
01462           //Default addressing mode for 1, 2 and 4 rows (except 40x4)
01463           //The two available rows are split and stacked on top of eachother. Addressing for 3rd and 4th line continues where lines 1 and 2 were split.          
01464           //Displays top rows when less than four are used.          
01465           switch (row) {
01466             case 0:
01467               return 0x00 + column;
01468             case 1:
01469               return 0x40 + column;
01470             case 2:
01471               return 0x00 + _nr_cols + column;
01472             case 3:
01473               return 0x40 + _nr_cols + column;
01474             // Should never get here.
01475             default:            
01476               return 0x00;                    
01477             }
01478           
01479         case LCD_T_B:
01480           // LCD8x2B is a special layout of LCD16x1
01481           if (row==0) 
01482             return 0x00 + column;                        
01483           else   
01484 //            return _nr_cols + column;                                    
01485             return 0x08 + column;                        
01486 
01487         case LCD_T_C:
01488           // LCD16x1C is a special layout of LCD8x2
01489           // LCD32x1C is a special layout of LCD16x2                    
01490           // LCD40x1C is a special layout of LCD20x2          
01491 #if(0)
01492           if (column < 8) 
01493             return 0x00 + column;                        
01494           else   
01495             return 0x40 + (column - 8);                        
01496 #else
01497           if (column < (_nr_cols >> 1)) 
01498             return 0x00 + column;                        
01499           else   
01500             return 0x40 + (column - (_nr_cols >> 1));                        
01501 #endif
01502 
01503 // Not sure about this one, seems wrong.
01504 // Left in for compatibility with original library
01505 //        case LCD16x2B:      
01506 //            return 0x00 + (row * 40) + column;
01507 
01508         case LCD_T_D:
01509           //Alternate addressing mode for 3 and 4 row displays (except 40x4). Used by PCF21XX, KS0073, KS0078, SSD1803
01510           //The 4 available rows start at a hardcoded address.                    
01511           //Displays top rows when less than four are used.
01512           switch (row) {
01513             case 0:
01514               return 0x00 + column;
01515             case 1:
01516               return 0x20 + column;
01517             case 2:
01518               return 0x40 + column;
01519             case 3:
01520               return 0x60 + column;
01521             // Should never get here.
01522             default:            
01523               return 0x00;                    
01524             }
01525 
01526         case LCD_T_D1:
01527           //Alternate addressing mode for 3 row displays. Used by PCF21XX, KS0073, KS0078, SSD1803
01528           //The 4 available rows start at a hardcoded address.                              
01529           //Skips top row of 4 row display and starts display at row 1
01530           switch (row) {
01531             case 0:
01532               return 0x20 + column;
01533             case 1:
01534               return 0x40 + column;
01535             case 2:
01536               return 0x60 + column;
01537             // Should never get here.
01538             default:            
01539               return 0x00;                    
01540             }
01541         
01542         case LCD_T_E:                
01543           // LCD40x4 is a special case since it has 2 controllers.
01544           // Each controller is configured as 40x2 (Type A)
01545           if (row<2) { 
01546             // Test to see if we need to switch between controllers  
01547             if (_ctrl_idx != _LCDCtrl_0) {
01548 
01549               // Second LCD controller Cursor Off
01550               _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);    
01551 
01552               // Select primary controller
01553               _ctrl_idx = _LCDCtrl_0;
01554 
01555               // Restore cursormode on primary LCD controller
01556               _setCursorAndDisplayMode(_currentMode, _currentCursor);    
01557             }           
01558             
01559             return 0x00 + (row * 0x40) + column;          
01560           }
01561           else {
01562 
01563             // Test to see if we need to switch between controllers  
01564             if (_ctrl_idx != _LCDCtrl_1) {
01565               // Primary LCD controller Cursor Off
01566               _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);    
01567 
01568               // Select secondary controller
01569               _ctrl_idx = _LCDCtrl_1;
01570 
01571               // Restore cursormode on secondary LCD controller
01572               _setCursorAndDisplayMode(_currentMode, _currentCursor);    
01573             }           
01574                                    
01575             return 0x00 + ((row-2) * 0x40) + column;          
01576           } 
01577             
01578         case LCD_T_F:
01579           //Alternate addressing mode for 3 row displays.
01580           //The first half of 3rd row continues from 1st row, the second half continues from 2nd row.                              
01581           switch (row) {
01582             case 0:
01583               return 0x00 + column;
01584             case 1:
01585               return 0x40 + column;
01586             case 2:
01587               if (column < (_nr_cols >> 1)) // check first or second half of line
01588                 return (0x00 + _nr_cols + column);                        
01589               else   
01590                 return (0x40 + _nr_cols + (column - (_nr_cols >> 1)));                        
01591             // Should never get here.
01592             default:            
01593               return 0x00;                    
01594           }
01595 
01596         case LCD_T_G:
01597           //Alternate addressing mode for 3 row displays. Used by ST7036
01598           switch (row) {
01599             case 0:
01600               return 0x00 + column;
01601             case 1:
01602               return 0x10 + column;
01603             case 2:
01604               return 0x20 + column;
01605             // Should never get here.
01606             default:            
01607               return 0x00;                    
01608             }
01609 
01610         // Should never get here.
01611         default:            
01612             return 0x00;        
01613 
01614     } // switch _addr_mode
01615 }
01616 
01617 
01618 /** Set the memoryaddress of screen column and row location
01619   *
01620   * @param column  The horizontal position from the left, indexed from 0
01621   * @param row     The vertical position from the top, indexed from 0
01622   */
01623 void TextLCD_Base::setAddress(int column, int row) {
01624    
01625 // Sanity Check column
01626     if (column < 0) {
01627       _column = 0;
01628     }
01629     else if (column >= _nr_cols) {
01630       _column = _nr_cols - 1;
01631     } else _column = column;
01632     
01633 // Sanity Check row
01634     if (row < 0) {
01635       _row = 0;
01636     }
01637     else if (row >= _nr_rows) {
01638       _row = _nr_rows - 1;
01639     } else _row = row;
01640     
01641     
01642 // Compute the memory address
01643 // For LCD40x4:  switch controllers if needed
01644 //               switch cursor if needed
01645     int addr = getAddress(_column, _row);
01646     
01647     _writeCommand(0x80 | addr);
01648 }
01649 
01650 
01651 /** Return the number of columns
01652   *
01653   * @return  The number of columns
01654   *
01655   * Note: some configurations are commented out because they have not yet been tested due to lack of hardware     
01656   */   
01657 int TextLCD_Base::columns() {
01658     
01659   // Columns encoded in b7..b0
01660   //return (_type & 0xFF);          
01661   return _nr_cols;           
01662 }
01663 
01664 /** Return the number of rows
01665   *
01666   * @return  The number of rows
01667   *
01668   * Note: some configurations are commented out because they have not yet been tested due to lack of hardware     
01669   */
01670 int TextLCD_Base::rows() {
01671 
01672   // Rows encoded in b15..b8  
01673   //return ((_type >> 8) & 0xFF); 
01674   return _nr_rows;          
01675 }
01676 
01677 /** Set the Cursormode
01678   *
01679   * @param cursorMode  The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
01680   */
01681 void TextLCD_Base::setCursor(LCDCursor cursorMode) { 
01682 
01683   // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
01684   _currentCursor = cursorMode;
01685     
01686   // Configure only current LCD controller
01687   _setCursorAndDisplayMode(_currentMode, _currentCursor);    
01688 }
01689 
01690 /** Set the Displaymode
01691   *
01692   * @param displayMode The Display mode (DispOff, DispOn)
01693   */
01694 void TextLCD_Base::setMode(LCDMode displayMode) { 
01695 
01696   // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
01697   _currentMode = displayMode;
01698     
01699   // Select and configure second LCD controller when needed
01700   if(_type==LCD40x4) {
01701     if (_ctrl_idx==_LCDCtrl_0) {      
01702       // Configure primary LCD controller
01703       _setCursorAndDisplayMode(_currentMode, _currentCursor);
01704 
01705       // Select 2nd controller
01706       _ctrl_idx=_LCDCtrl_1;
01707   
01708       // Configure secondary LCD controller    
01709       _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
01710 
01711       // Restore current controller
01712       _ctrl_idx=_LCDCtrl_0;       
01713     }
01714     else {
01715       // Select primary controller
01716       _ctrl_idx=_LCDCtrl_0;
01717     
01718       // Configure primary LCD controller
01719       _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
01720        
01721       // Restore current controller
01722       _ctrl_idx=_LCDCtrl_1;
01723 
01724       // Configure secondary LCD controller    
01725       _setCursorAndDisplayMode(_currentMode, _currentCursor);
01726     }
01727   }
01728   else {
01729     // Configure primary LCD controller
01730     _setCursorAndDisplayMode(_currentMode, _currentCursor);
01731   }       
01732 }
01733 
01734 /** Low level method to restore the cursortype and display mode for current controller
01735   */     
01736 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {    
01737 
01738   // Configure current LCD controller   
01739   switch (_ctrl) {
01740     case ST7070: 
01741       //ST7070 does not support Cursorblink. The P bit selects the font instead !   
01742       _writeCommand(0x08 | displayMode | (cursorType & 0x02));    
01743       break;
01744     default:      
01745       _writeCommand(0x08 | displayMode | cursorType);
01746       break;
01747   } //switch      
01748 }
01749 
01750 /** Set the Backlight mode
01751   *
01752   *  @param backlightMode The Backlight mode (LightOff, LightOn)
01753   */
01754 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
01755 
01756 #if (BACKLIGHT_INV==0)      
01757     // Positive Backlight control pin logic
01758     if (backlightMode == LightOn) {
01759       this->_setBL(true);     
01760     }
01761     else {
01762       this->_setBL(false);    
01763     }
01764 #else
01765     // Inverted Backlight control pin logic
01766     if (backlightMode == LightOn) {
01767       this->_setBL(false);    
01768     }
01769     else {
01770       this->_setBL(true);           
01771     }
01772 #endif    
01773 } 
01774 
01775 /** Set User Defined Characters
01776   *
01777   * @param unsigned char c   The Index of the UDC (0..7) for HD44780 or clones and (0..15) for some more advanced controllers 
01778   * @param char *udc_data    The bitpatterns for the UDC (8 bytes of 5 significant bits for bitpattern and 3 bits for blinkmode (advanced types))     
01779   */
01780 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
01781   
01782   // Select and configure second LCD controller when needed
01783   if(_type==LCD40x4) {
01784     _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
01785    
01786     // Select primary controller     
01787     _ctrl_idx=_LCDCtrl_0;
01788     
01789     // Configure primary LCD controller
01790     _setUDC(c, udc_data);
01791 
01792     // Select 2nd controller
01793     _ctrl_idx=_LCDCtrl_1;
01794   
01795     // Configure secondary LCD controller    
01796     _setUDC(c, udc_data);
01797 
01798     // Restore current controller
01799     _ctrl_idx=current_ctrl_idx;       
01800   }
01801   else {
01802     // Configure primary LCD controller
01803     _setUDC(c, udc_data); 
01804   }   
01805 }
01806 
01807 /** Low level method to store user defined characters for current controller
01808   *
01809   * @param unsigned char c   The Index of the UDC (0..7) for HD44780 clones and (0..15) for some more advanced controllers 
01810   * @param char *udc_data    The bitpatterns for the UDC (8 bytes of 5 significant bits for bitpattern and 3 bits for blinkmode (advanced types))       
01811   */     
01812 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
01813   
01814   switch (_ctrl) {
01815     case PCF2103_3V3 : // Some UDCs may be used for Icons                  
01816     case PCF2113_3V3 : // Some UDCs may be used for Icons                      
01817     case PCF2116_3V3 :          
01818     case PCF2116_5V  :              
01819     case PCF2119_3V3 : // Some UDCs may be used for Icons             
01820       c = c & 0x0F; // mask down to valid range
01821       break;
01822 
01823     default:     
01824       c = c & 0x07; // mask down to valid range    
01825       break;  
01826   } //switch _ctrl
01827 
01828   // Select DD RAM for current LCD controller
01829   // This is needed to correctly set Bit 6 of the addresspointer for controllers that support 16 UDCs
01830   _writeCommand(0x80 | ((c << 3) & 0x40)) ;  
01831     
01832   // Select CG RAM for current LCD controller
01833   _writeCommand(0x40 | ((c << 3) & 0x3F)); //Set CG-RAM address, (note that Bit 6 is retained and can not be set by this command !)
01834                                            //8 sequential locations needed per UDC
01835   // Store UDC pattern 
01836   for (int i=0; i<8; i++) {
01837     _writeData(*udc_data++);
01838   }
01839    
01840   //Select DD RAM again for current LCD controller and restore the addresspointer
01841   int addr = getAddress(_column, _row);
01842   _writeCommand(0x80 | addr);  
01843 }
01844 
01845 /** Set UDC Blink and Icon blink
01846   * setUDCBlink method is supported by some compatible devices (eg SSD1803) 
01847   *
01848   * @param blinkMode The Blink mode (BlinkOff, BlinkOn)
01849   */
01850 void TextLCD_Base::setUDCBlink(LCDBlink blinkMode){
01851   // Blinking UDCs (and icons) are enabled when a specific controlbit (BE) is set.
01852   // The blinking pixels in the UDC and icons can be controlled by setting additional bits in the UDC or icon bitpattern.
01853   // UDCs are defined by an 8 byte bitpattern. The P0..P4 form the character pattern.
01854   //     P7 P6 P5 P4 P3 P2 P1 P0 
01855   // 0   B1 B0  x  0  1  1  1  0
01856   // 1   B1 B0  x  1  0  0  0  1
01857   //        .............
01858   // 7   B1 B0  x  1  0  0  0  1
01859   //
01860   // Bit 6 and Bit 7 in the pattern will control the blinking mode when Blink is enabled through BE. 
01861   //     B1 B0  Mode
01862   //      0  0  No Blinking in this row of the UDC
01863   //      0  1  Enabled pixels in P4 will blink
01864   //      1  x  Enabled pixels in P0..P4 will blink
01865   //
01866   // Note: the PCF2103 and PCF2113 use UDCs to set Icons 
01867   //   3 x 8 rows x 5 bits = 120 bits Icons for Normal pattern (UDC 0..2) and
01868   //   3 x 8 rows x 5 bits = 120 bits Icons for Blink pattern (UDC 4..6) 
01869   // Note: the PCF2119 uses UDCs to set Icons 
01870   //   4 x 8 rows x 5 bits = 160 bits Icons for Normal pattern (UDC 0..3) and
01871   //   4 x 8 rows x 5 bits = 160 bits Icons for Blink pattern (UDC 4..7) 
01872   switch (blinkMode) {
01873     case BlinkOn: 
01874       // Controllers that support UDC/Icon Blink  
01875       switch (_ctrl) {
01876         case KS0073 :            
01877         case KS0078 :            
01878           _function_1 |= 0x02; // Enable UDC/Icon Blink        
01879           _writeCommand(0x20 | _function_1);        // Function set 0 0 1 DL N RE(1) BE 0/LP (Ext Regs)
01880 
01881           _writeCommand(0x20 | _function);          // Function set 0 0 1 DL N RE(0) DH REV (Std Regs)
01882           break; // case KS0073, KS0078 Controller
01883     
01884         case US2066_3V3 :  
01885         case SSD1803_3V3 :  
01886           _function_1 |= 0x04; // Enable UDC/Icon Blink
01887           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N BE RE(1) REV 
01888                                                     // Select Ext Instr Set
01889 
01890           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
01891                                                     // Select Std Instr set, Select IS=0
01892           break; // case SSD1803, US2066
01893 
01894         case PCF2103_3V3 :  
01895         case PCF2113_3V3 :  
01896         case PCF2119_3V3 :                  
01897           // Enable Icon Blink
01898           _writeCommand(0x20 | _function | 0x01);   // Set function, Select Instr Set = 1              
01899           _writeCommand(0x08 | 0x02);               // ICON Conf 0000 1, IM=0 (Char mode), IB=1 (Icon blink), 0 (Instr. Set 1) 
01900           _writeCommand(0x20 | _function);          // Set function, Select Instr Set = 0             
01901 
01902           break; 
01903        
01904         default:
01905           //Unsupported feature for other controllers        
01906           break; 
01907       } //switch _ctrl     
01908     
01909       break; // BlinkOn 
01910 
01911     case BlinkOff:
01912       // Controllers that support UDC Blink  
01913       switch (_ctrl) {
01914         case KS0073 :            
01915         case KS0078 :            
01916           _function_1 &= ~0x02; // Disable UDC/Icon Blink        
01917           _writeCommand(0x20 | _function_1);        // Function set 0 0 1 DL N RE(1) BE 0/LP (Ext Regs)
01918 
01919           _writeCommand(0x20 | _function);          // Function set 0 0 1 DL N RE(0) DH REV (Std Regs)
01920           break; // case KS0073, KS0078 Controller
01921     
01922         case US2066_3V3 :  
01923         case SSD1803_3V3 :  
01924           _function_1 &= ~0x04; // Disable UDC/Icon Blink
01925           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N BE RE(1) REV 
01926                                                     // Select Ext Instr Set
01927 
01928           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
01929                                                     // Select Std Instr set, Select IS=0
01930           break; // case SSD1803, US2066          
01931  
01932         case PCF2103_3V3 :
01933         case PCF2113_3V3 :  
01934         case PCF2119_3V3 :       
01935           // Disable Icon Blink
01936           _writeCommand(0x20 | _function | 0x01);   // Set function, Select Instr Set = 1              
01937           _writeCommand(0x08);                      // ICON Conf 0000 1, IM=0 (Char mode), IB=1 (Icon blink), 0 (Instr. Set 1) 
01938           _writeCommand(0x20 | _function);          // Set function, Select Instr Set = 0             
01939 
01940           break; 
01941        
01942         default:
01943           //Unsupported feature for other controllers        
01944           break; 
01945       } //switch _ctrl     
01946     
01947       break; //BlinkOff
01948       
01949     default:
01950       break;      
01951   } // blinkMode
01952   
01953 } // setUDCBlink()
01954 
01955 
01956 /** Set Contrast
01957   * setContrast method is supported by some compatible devices (eg ST7032i) that have onboard LCD voltage generation
01958   * Initial code for ST70XX imported from fork by JH1PJL
01959   *
01960   * @param unsigned char c   contrast data (6 significant bits, valid range 0..63, Value 0 will disable the Vgen)  
01961   * @return none
01962   */
01963 //@TODO Add support for 40x4 dual controller
01964 void TextLCD_Base::setContrast(unsigned char c) {
01965 
01966 // Function set mode stored during Init. Make sure we dont accidentally switch between 1-line and 2-line mode!
01967 // Icon/Booster mode stored during Init. Make sure we dont accidentally change this!
01968  
01969   _contrast = c & 0x3F; // Sanity check
01970   
01971   switch (_ctrl) {   
01972     case PCF2113_3V3 :  
01973     case PCF2119_3V3 :  
01974        if (_contrast <  5) _contrast = 0;  // See datasheet. Sanity check for PCF2113/PCF2119
01975        if (_contrast > 55) _contrast = 55;
01976       
01977        _writeCommand(0x20 | _function | 0x01);               // Set function, Select Instruction Set = 1              
01978        _writeCommand(0x80 | 0x00 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)    V=0, VA=contrast
01979        _writeCommand(0x80 | 0x40 | (_contrast & 0x3F));      // VLCD_set (Instr. Set 1)    V=1, VB=contrast
01980        _writeCommand(0x20 | _function);                      // Select Instruction Set = 0
01981        break;
01982         
01983     case ST7032_3V3 :  
01984     case ST7032_5V :      
01985     case ST7036_3V3 :      
01986 //    case ST7036_5V :          
01987     case SSD1803_3V3 :      
01988       _writeCommand(0x20 | _function | 0x01);                        // Select Instruction Set = 1
01989       _writeCommand(0x70 | (_contrast & 0x0F));                      // Contrast Low bits
01990       _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Contrast High bits 
01991       _writeCommand(0x20 | _function);                               // Select Instruction Set = 0
01992       break;
01993 
01994     case US2066_3V3 :      
01995       _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N BE RE(1) REV 
01996                                                 // Select Extended Instruction Set
01997 
01998       _writeCommand(0x79);                      // Function Select OLED:  0 1 1 1 1 0 0 1 (Ext Instr Set)
01999          
02000       _writeCommand(0x81);                      // Set Contrast Control: 1 0 0 0 0 0 0 1 (Ext Instr Set, OLED)
02001       _writeCommand((_contrast << 2) | 0x03);   // Set Contrast Value: 8 bits. Use 6 bits for compatibility    
02002       
02003       _writeCommand(0x78);                      // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set)          
02004 
02005       _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02006                                                 // Select Std Instr set, Select IS=0
02007       break;
02008 
02009     //not yet tested on hardware
02010     case PT6314 :
02011       // Only 2 significant bits
02012       //   0x00 = 100%
02013       //   0x01 =  75%
02014       //   0x02 =  50%
02015       //   0x03 =  25%                
02016       _writeCommand(0x20 | _function | ((~_contrast) >> 4));        // Invert and shift to use 2 MSBs     
02017       break;
02018             
02019     default:  
02020       //Unsupported feature for other controllers
02021       break;               
02022   } // end switch     
02023 } // end setContrast()
02024 
02025 
02026 /** Set Power
02027   * setPower method is supported by some compatible devices (eg SSD1803) that have power down modes
02028   *
02029   * @param bool powerOn  Power on/off   
02030   * @return none
02031   */
02032 //@TODO Add support for 40x4 dual controller  
02033 void TextLCD_Base::setPower(bool powerOn) {
02034   
02035   if (powerOn) {
02036     // Switch on  
02037     setMode(DispOn);       
02038 
02039     // Controllers that supports specific Power Down mode
02040     switch (_ctrl) {
02041     
02042 //    case PCF2113_3V3 :  
02043 //    case PCF2119_3V3 :  
02044 //    case ST7032_3V3 :  
02045 //@todo
02046 //    enable Booster Bon
02047 
02048       case WS0010:      
02049         _writeCommand(0x17);   // Char mode, DC/DC on        
02050         wait_ms(10);           // Wait 10ms to ensure powered up             
02051         break;
02052 
02053       case KS0073:        
02054       case KS0078:        
02055       case SSD1803_3V3 :      
02056 //      case SSD1803_5V :            
02057         _writeCommand(0x20 | _function_1);                             // Select Ext Instr Set
02058         _writeCommand(0x02);                                           // Power On
02059         _writeCommand(0x20 | _function);                               // Select Std Instr Set
02060         break;
02061                     
02062       default:  
02063         //Unsupported feature for other controllers
02064         break;              
02065     } // end switch  
02066   }  
02067   else {
02068     // Switch off        
02069     setMode(DispOff);       
02070 
02071     // Controllers that support specific Power Down mode
02072     switch (_ctrl) {
02073     
02074 //    case PCF2113_3V3 :  
02075 //    case PCF2119_3V3 :  
02076 //    case ST7032_3V3 :  
02077 //@todo
02078 //    disable Booster Bon
02079 
02080       case WS0010:      
02081         _writeCommand(0x13);   // Char mode, DC/DC off              
02082         break;
02083         
02084       case KS0073:
02085       case KS0078:
02086       case SSD1803_3V3 :      
02087 //      case SSD1803_5V :            
02088         _writeCommand(0x20 | _function_1);                             // Select Ext Instr Set
02089         _writeCommand(0x03);                                           // Power Down
02090         _writeCommand(0x20 | _function);                               // Select Std Instr Set
02091         break;
02092 
02093       default:  
02094         //Unsupported feature for other controllers
02095         break;              
02096     } // end switch  
02097   }
02098 } // end setPower()
02099 
02100 
02101 /** Set Orient
02102   * setOrient method is supported by some compatible devices (eg SSD1803, US2066) that have top/bottom view modes
02103   *
02104   * @param LCDOrient orient Orientation 
02105   * @return none
02106   */
02107 void TextLCD_Base::setOrient(LCDOrient orient){
02108 
02109   switch (orient) {
02110        
02111     case Top:
02112       switch (_ctrl) {
02113         case PCF2103_3V3:              
02114         case PCF2116_3V3:        
02115         case PCF2116_5V:                
02116         case PCF2119_3V3:                
02117           _writeCommand(0x20 | _function | 0x01);          // Set function, Select Instr Set = 1              
02118           _writeCommand(0x05);                             // Display Conf Set         0000 0, 1, P=0, Q=1               (Instr. Set 1)
02119           _writeCommand(0x20 | _function);                 // Set function, Select Instr Set = 0             
02120           break;
02121                                
02122         case SSD1803_3V3 :      
02123 //      case SSD1803_5V :
02124         case US2066_3V3 :      
02125           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02126                                                     // Select Extended Instruction Set
02127 //          _writeCommand(0x06);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=1 COM1-32, BDS=0 SEG100-1    "Bottom View" (Ext Instr Set)
02128           _writeCommand(0x05);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=0 COM32-1, BDS=1 SEG1-100    "Top View" (Ext Instr Set)          
02129 
02130           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02131                                                     // Select Std Instr set, Select IS=0       
02132           break;
02133 
02134         case ST7070:      
02135           _writeCommand(0x20 | _function | 0x04);   // Set function, 0 0 1 DL, N, EXT=1, x, x (Select Instr Set = 1)
02136 
02137           _writeCommand(0x40 | 0x00);               // COM/SEG directions 0 1 0 0 C1, C2, S1, S2  (Instr Set 1)
02138                                                     // C1=1: Com1-8 -> Com8-1;   C2=1: Com9-16 -> Com16-9
02139                                                     // S1=1: Seg1-40 -> Seg40-1; S2=1: Seg41-80 -> Seg80-41                                                    
02140           wait_ms(5);                               // Wait to ensure completion or ST7070 fails to set Top/Bottom after reset..
02141           
02142           _writeCommand(0x20 | _function);          // Set function, EXT=0 (Select Instr Set = 0)
02143         
02144           break; // case ST7070 Controller
02145           
02146         default:  
02147           //Unsupported feature for other controllers
02148           break;              
02149 
02150       } // end switch _ctrl     
02151       break; // end Top
02152                 
02153     case Bottom:
02154       switch (_ctrl) {
02155         case PCF2103_3V3:              
02156         case PCF2116_3V3:        
02157         case PCF2116_5V:                
02158         case PCF2119_3V3:                       
02159           _writeCommand(0x20 | _function | 0x01);          // Set function, Select Instr Set = 1              
02160           _writeCommand(0x06);                             // Display Conf Set         0000 0, 1, P=1, Q=0               (Instr. Set 1)
02161           _writeCommand(0x20 | _function);                 // Set function, Select Instr Set = 0             
02162           break;
02163         
02164         case SSD1803_3V3 :      
02165 //      case SSD1803_5V :
02166         case US2066_3V3 :      
02167           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02168                                                     // Select Extended Instruction Set
02169           _writeCommand(0x06);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=1 COM1-32, BDS=0 SEG100-1    "Bottom View" (Ext Instr Set)
02170 //          _writeCommand(0x05);                      // Set ext entry mode, 0 0 0 0 0 1 BDC=0 COM32-1, BDS=1 SEG1-100    "Top View" (Ext Instr Set)          
02171 
02172           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02173                                                     // Select Std Instr set, Select IS=0       
02174           break;
02175 
02176         case ST7070:
02177           //Note: this does not result in correct top/bottom view. 
02178           //The left and right half of each row are reversed and the addressing of both rows is also incorrect:
02179           //Top/bottomline when orientation is flipped:
02180           //  0x48...0x4F  0x40...0x47
02181           //  0x08...0x0F  0x00...0x07
02182           _writeCommand(0x20 | _function | 0x04);   // Set function, 0 0 1 DL N EXT=1 x x (Select Instr Set = 1)
02183 
02184           _writeCommand(0x40 | 0x0F);               // COM/SEG directions 0 1 0 0 C1, C2, S1, S2  (Instr Set 1)
02185                                                     // C1=1: Com1-8 -> Com8-1;   C2=1: Com9-16 -> Com16-9
02186                                                     // S1=1: Seg1-40 -> Seg40-1; S2=1: Seg41-80 -> Seg80-41                                                    
02187           wait_ms(5);                               // Wait to ensure completion or ST7070 fails to set Top/Bottom after reset..
02188           
02189           _writeCommand(0x20 | _function);          // Set function, EXT=0 (Select Instr Set = 0)
02190         
02191           break; // case ST7070 Controller
02192           
02193         default:  
02194           //Unsupported feature for other controllers
02195           break;              
02196 
02197       } // end switch _ctrl     
02198     
02199       break; // end Bottom
02200   } // end switch orient
02201 } // end setOrient()
02202 
02203 /** Set Big Font
02204   * setBigFont method is supported by some compatible devices (eg SSD1803, US2066) 
02205   *
02206   * @param lines  The selected Big Font lines (None, TopLine, CenterLine, BottomLine, TopBottomLine)
02207   *                                            Double height characters can be shown on lines 1+2, 2+3, 3+4 or 1+2 and 3+4
02208   *                                            Valid double height lines depend on the LCDs number of rows.
02209   */
02210 void TextLCD_Base::setBigFont(LCDBigFont lines) {
02211 
02212   switch (lines) {
02213     case None:
02214       switch (_ctrl) {
02215         case SSD1803_3V3 :      
02216         case US2066_3V3 :      
02217           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02218                                                     // Select Extended Instruction Set
02219           _writeCommand(0x1C);                      // Double Height, 0 0 0 1 UD2=1, UD1=1, X, DH'=0 (Ext Instr Set)
02220                                                     // Default
02221           _function = _function & ~0x04;            // Set function, 0 0 1 DL N DH=0 RE(0) IS=0 Select Instruction Set 0
02222           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02223                                                     // Select Std Instr set, Select IS=0        
02224           break; // end US2066      
02225 
02226         default:
02227           break; // end default      
02228       } // end switch _ctrl     
02229       break; // end None      
02230     
02231     case TopLine:
02232       if (_nr_rows < 2) return; //Sanity check  
02233 
02234       switch (_ctrl) {
02235         case SSD1803_3V3 :              
02236         case US2066_3V3 :      
02237           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02238                                                     // Select Extended Instruction Set
02239           _writeCommand(0x1C);                      // Double Height, 0 0 0 1 UD2=1, UD1=1, X, DH'=0 (Ext Instr Set)
02240                                                     // Default
02241           _function = _function | 0x04;             // Set function, 0 0 1 DL N DH=1 RE(0) IS=0 Select Instruction Set 0
02242           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02243                                                     // Select Std Instr set, Select IS=0        
02244           break; // end US2066, SSD1803      
02245 
02246         default:
02247           break; // end default      
02248       } // end switch _ctrl     
02249       break; // end TopLine              
02250 
02251     case CenterLine:
02252       if (_nr_rows != 4) return; //Sanity check  
02253           
02254       switch (_ctrl) {
02255         case SSD1803_3V3 :              
02256         case US2066_3V3 :      
02257           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02258                                                     // Select Extended Instruction Set
02259           _writeCommand(0x14);                      // Double Height, 0 0 0 1 UD2=0, UD1=1, X, DH'=0 (Ext Instr Set)
02260                                                     // Default
02261           _function = _function | 0x04;             // Set function, 0 0 1 DL N DH=1 RE(0) IS=0 Select Instruction Set 0
02262           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02263                                                     // Select Std Instr set, Select IS=0        
02264           break; // end US2066, SSD1803      
02265 
02266         default:
02267           break; // end default      
02268       } // end switch _ctrl        
02269       break; // end CenterLine              
02270 
02271     case BottomLine:
02272       if (_nr_rows < 3) return; //Sanity check  
02273           
02274       switch (_ctrl) {
02275         case SSD1803_3V3 :              
02276         case US2066_3V3 :      
02277           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02278                                                     // Select Extended Instruction Set
02279           if (_nr_rows == 3) {
02280             _writeCommand(0x14);                      // Double Height, 0 0 0 1 UD2=0, UD1=1, X, DH'=0 (Ext Instr Set)
02281           }  
02282           else {
02283             _writeCommand(0x10);                      // Double Height, 0 0 0 1 UD2=0, UD1=0, X, DH'=0 (Ext Instr Set)
02284           }  
02285           _function = _function | 0x04;             // Set function, 0 0 1 DL N DH=1 RE(0) IS=0 Select Instruction Set 0
02286           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02287                                                     // Select Std Instr set, Select IS=0        
02288           break; // end US2066, SSD1803      
02289 
02290         default:
02291           break; // end default      
02292       } // end switch _ctrl           
02293       break; // end BottomLine          
02294       
02295     case TopBottomLine:
02296       if (_nr_rows != 4) return; //Sanity check  
02297       
02298       switch (_ctrl) {
02299         case SSD1803_3V3 :        
02300         case US2066_3V3 :      
02301           _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 X N BE RE(1) REV 
02302                                                     // Select Extended Instruction Set
02303           _writeCommand(0x18);                      // Double Height, 0 0 0 1 UD2=1, UD1=0, X, DH'=0 (Ext Instr Set)
02304                                                     // Default
02305           _function = _function | 0x04;             // Set function, 0 0 1 DL N DH=1 RE(0) IS=0 Select Instruction Set 0
02306           _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
02307                                                     // Select Std Instr set, Select IS=0        
02308           break; // end US2066, SSD1803      
02309 
02310         default:
02311           break; // end default      
02312       } // end switch _ctrl           
02313       break; // end TopBottomLine          
02314 
02315   } // end switch lines
02316 
02317 } // end setBigFont()
02318 
02319 
02320 /** Set Icons
02321   *
02322   * @param unsigned char idx   The Index of the icon pattern (0..15) for KS0073 and similar controllers
02323   *                            and Index (0..31) for PCF2103 and similar controllers  
02324   * @param unsigned char data  The bitpattern for the icons (6 lsb for KS0073 bitpattern (5 lsb for KS0078) and 2 msb for blinkmode)       
02325   *                            The bitpattern for the PCF2103 icons is 5 lsb (UDC 0..2) and 5 lsb for blinkmode (UDC 4..6)         
02326   */
02327 void TextLCD_Base::setIcon(unsigned char idx, unsigned char data) {
02328   // Blinking icons are enabled when a specific controlbit (BE) is set.
02329   // The blinking pixels in the icons can be controlled by setting additional bits in the icon bitpattern.
02330   // Icons are defined by a byte bitpattern. The P0..P5 form the Icon pattern for KS0073, and P0..P4 for KS0078
02331   //     P7 P6 P5 P4 P3 P2 P1 P0 
02332   // 0   B1 B0  0  0  1  1  1  0
02333   // 1   B1 B0  1  1  0  0  0  1
02334   //        .............
02335   // 15  B1 B0  1  1  0  0  0  1
02336   //
02337   // Bit 6 and Bit 7 in the pattern will control the blinking mode when Blink is enabled through BE. 
02338   //     B1 B0  Mode
02339   //      0  0  No Blinking for this icon row
02340   //      0  1  Enabled pixels in P5 will blink
02341   //      1  x  Enabled pixels in P0..P5 will blink
02342   //
02343   // Note: the PCF2103 and PCF2113 use UDCs to set Icons 
02344   //   3 x 8 rows x 5 bits = 120 bits Icons for Normal pattern (UDC 0..2) and
02345   //   3 x 8 rows x 5 bits = 120 bits Icons for Blink pattern (UDC 4..6) 
02346   // Note: the PCF2119 uses UDCs to set Icons 
02347   //   4 x 8 rows x 5 bits = 160 bits Icons for Normal pattern (UDC 0..3) and
02348   //   4 x 8 rows x 5 bits = 160 bits Icons for Blink pattern (UDC 4..7) 
02349   
02350   switch (_ctrl) {
02351     case KS0073:
02352     case KS0078:    
02353        _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N RE(1) BE LP 
02354                                                  // Select Extended Instruction Set
02355        _writeCommand(0x40 | (idx & 0x0F));       // Set Icon Address, mask Address to valid range (Ext Instr Set)
02356 
02357        _writeData(data);                         // Set Icon pattern (Ext Instr Set)
02358 
02359        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N RE(0) DH REV Select Instruction Set 0
02360                                                  // Select Std Instr set, Select IS=0        
02361        break; // end KS0073, KS0078
02362 
02363     case ST7032_3V3:
02364     case ST7032_5V:
02365        _writeCommand(0x20 | _function | 0x01);   // Set function,  0 0 1 DL N F 0 IS=1 Select Instr Set = 1              
02366        _writeCommand(0x40 | (idx & 0x0F));       // Set Icon Address, mask Address to valid range (Instr Set 1)
02367 
02368        _writeData(data & 0x1F);                  // Set Icon pattern, no blink support (Instr Set 1) 
02369 
02370        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N RE(0) DH REV Select Instruction Set 0
02371                                                  // Select Std Instr set, Select IS=0        
02372        break; // end ST7032
02373 
02374     case ST7036_3V3:
02375     case ST7036_5V:
02376        _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 DL N DH IS2,IS1 = 01 (Select Instr Set = 1)    
02377        _writeCommand(0x40 | (idx & 0x0F));       // Set Icon Address, mask Address to valid range (Instr Set 1)
02378 
02379        _writeData(data & 0x1F);                  // Set Icon pattern, no blink support (Instr Set 1) 
02380 
02381        _writeCommand(0x20 | _function);          // Set function, IS2,IS1 = 00 (Select Instr Set = 0)    
02382                                                  // Select Std Instr set, Select IS=0        
02383        break; // end ST7036
02384 
02385     case SSD1803_3V3:                  
02386 //    case SSD1803_5V:                      
02387        _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 DL N DH RE(0) IS 
02388                                                  // Select Instruction Set 1
02389        _writeCommand(0x40 | (idx & 0x0F));       // Set Icon Address, mask Address to valid range (Instr Set = 1)
02390        _writeData(data);                         // Set Icon pattern (Instr Set = 1)
02391 
02392        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS
02393                                                  // Select IS=0        
02394        break; // end SSD1803      
02395 
02396     case PCF2103_3V3:
02397     case PCF2113_3V3:    
02398     case PCF2119_3V3:        
02399        // Store UDC/Icon pattern for PCF2103 and PCF2113: 
02400        //   3 x 8 rows x 5 bits = 120 bits for Normal pattern (UDC 0..2) and
02401        //   3 x 8 rows x 5 bits = 120 bits for Blink pattern (UDC 4..6) 
02402        // Store UDC/Icon pattern for PCF2119: 
02403        //   4 x 8 rows x 5 bits = 160 bits for Normal pattern (UDC 0..3) and
02404        //   4 x 8 rows x 5 bits = 160 bits for Blink pattern (UDC 4..7)        
02405        _writeCommand(0x40 | (idx & 0x3F));       //Set CG-RAM address, 8 sequential locations needed per UDC
02406        _writeData(data);                         // Set Icon pattern (Instr Set = 1)
02407        break; // case PCF2103_3V3 Controller
02408                  
02409     default:
02410        break; // end default      
02411   } // end switch _ctrl           
02412   
02413   //Select DD RAM again for current LCD controller and restore the addresspointer
02414   int addr = getAddress(_column, _row);
02415   _writeCommand(0x80 | addr);  
02416          
02417 } // end setIcon()
02418 
02419 /** Clear Icons
02420   *
02421   * @param  none
02422   * @return none
02423   */
02424   //@TODO Add support for 40x4 dual controller    
02425 void TextLCD_Base::clrIcon() {
02426   // Icons are defined by a byte bitpattern. The P0..P5 form the Icon pattern for KS0073, and P0..P4 for KS0078
02427   //     P7 P6 P5 P4 P3 P2 P1 P0 
02428   // 0   B1 B0  0  0  0  0  0  0
02429   // 1   B1 B0  0  0  0  0  0  0
02430   //        .............
02431   // 15  B1 B0  0  0  0  0  0  0
02432   //
02433   // Bit 6 and Bit 7 in the pattern will control the blinking mode when Blink is enabled through BE. 
02434   //     B1 B0  Mode
02435   //      0  0  No Blinking for this icon row
02436   //      0  1  Enabled pixels in P5 will blink
02437   //      1  x  Enabled pixels in P0..P5 will blink
02438   //
02439   // Note: the PCF2103 and PCF2113 use UDCs to set Icons 
02440   //   3 x 8 rows x 5 bits = 120 bits Icons for Normal pattern (UDC 0..2) and
02441   //   3 x 8 rows x 5 bits = 120 bits Icons for Blink pattern (UDC 4..6)  
02442   // Note: the PCF2119 uses UDCs to set Icons 
02443   //   4 x 8 rows x 5 bits = 160 bits Icons for Normal pattern (UDC 0..3) and
02444   //   4 x 8 rows x 5 bits = 160 bits Icons for Blink pattern (UDC 4..7)  
02445   int idx;
02446   
02447   switch (_ctrl) {
02448     case KS0073:              
02449     case KS0078:                  
02450        _writeCommand(0x20 | _function_1);        // Set function, 0 0 1 DL N RE(1) BE LP 
02451                                                  // Select Extended Instruction Set
02452        for (idx=0; idx<16; idx++) { 
02453          _writeCommand(0x40 | idx);              // Set Icon Address, mask Address to valid range (Ext Instr Set)
02454          _writeData(0x00);                       // Clear Icon pattern (Ext Instr Set)
02455        }  
02456        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N RE(0) DH REV Select Std Instruction Set
02457                                                  // Select Std Instr set        
02458        break; // end KS0073, KS0078      
02459 
02460     case ST7032_3V3:
02461     case ST7032_5V:
02462        _writeCommand(0x20 | _function | 0x01);   // Set function,  0 0 1 DL N F 0 IS=1 Select Instr Set = 1              
02463 
02464        for (idx=0; idx<16; idx++) { 
02465          _writeCommand(0x40 | idx);              // Set Icon Address, mask Address to valid range (Instr Set 1)
02466          _writeData(0x00);                       // Clear Icon pattern (Instr Set 1)
02467        }  
02468 
02469        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N RE(0) DH REV Select Instruction Set 0
02470                                                  // Select Std Instr set, Select IS=0        
02471        break; // end ST7032
02472 
02473     case ST7036_3V3:
02474     case ST7036_5V:
02475        _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 DL N DH IS2,IS1 = 01 (Select Instr Set = 1)    
02476 
02477        for (idx=0; idx<16; idx++) { 
02478          _writeCommand(0x40 | idx);              // Set Icon Address, mask Address to valid range (Instr Set 1)
02479          _writeData(0x00);                       // Clear Icon pattern (Instr Set 1)
02480        }  
02481 
02482        _writeCommand(0x20 | _function);          // Set function, IS2,IS1 = 00 (Select Instr Set = 0)    
02483                                                  // Select Std Instr set, Select IS=0        
02484        break; // end ST7036
02485 
02486     case SSD1803_3V3:                  
02487 //    case SSD1803_5V:                      
02488        _writeCommand(0x20 | _function | 0x01);   // Set function, 0 0 1 DL N DH RE(0) IS 
02489                                                  // Select Instruction Set 1
02490        for (idx=0; idx<16; idx++) { 
02491          _writeCommand(0x40 | idx);              // Set Icon Address, mask Address to valid range (Ext Instr Set)
02492          _writeData(0x00);                       // Clear Icon pattern (Ext Instr Set)
02493        }  
02494        _writeCommand(0x20 | _function);          // Set function, 0 0 1 DL N DH RE(0) IS
02495                                                  // Select IS=0        
02496        break; // end SSD1803      
02497 
02498      case PCF2103_3V3:
02499      case PCF2113_3V3:         
02500        // PCF2103 and PCF2113 use part of the UDC RAM to control Icons   
02501        // Select CG RAM
02502 
02503        _writeCommand(0x40 | (0 * 8)); //Set CG-RAM address, 8 sequential locations needed per UDC
02504        // Store UDC/Icon pattern: 
02505        //   3 x 8 rows x 5 bits = 120 bits for Normal pattern (UDC 0..2) and
02506        for (int i=0; i<(3 * 8); i++) {
02507 //       _writeData(0x1F);  // All On
02508          _writeData(0x00);  // All Off            
02509        }
02510 
02511        _writeCommand(0x40 | (4 * 8)); //Set CG-RAM address, 8 sequential locations needed per UDC
02512        //   3 x 8 rows x 5 bits = 120 bits for Blink pattern (UDC 4..6) 
02513        for (int i=0; i<(3 * 8); i++) {
02514 //       _writeData(0x1F);  // All On
02515          _writeData(0x00);  // All Off            
02516        }
02517        break; // case PCF2103_3V3 Controller
02518 
02519      case PCF2119_3V3:              
02520        // PCF2119 uses part of the UDC RAM to control Icons   
02521        // Select CG RAM
02522 
02523        _writeCommand(0x40 | (0 * 8)); //Set CG-RAM address, 8 sequential locations needed per UDC
02524        // Store UDC/Icon pattern: 
02525        //   4 x 8 rows x 5 bits = 160 bits for Normal pattern (UDC 0..3) and
02526        for (int i=0; i<(4 * 8); i++) {
02527 //       _writeData(0x1F);  // All On
02528          _writeData(0x00);  // All Off            
02529        }
02530 
02531        _writeCommand(0x40 | (4 * 8)); //Set CG-RAM address, 8 sequential locations needed per UDC
02532        //   4 x 8 rows x 5 bits = 160 bits for Blink pattern (UDC 4..7) 
02533        for (int i=0; i<(4 * 8); i++) {
02534 //       _writeData(0x1F);  // All On
02535          _writeData(0x00);  // All Off            
02536        }
02537        break; // case PCF2119_3V3 Controller
02538 
02539     default:
02540        break; // end default      
02541   } // end switch _ctrl           
02542   
02543   //Select DD RAM again for current LCD controller and restore the addresspointer
02544   int addr = getAddress(_column, _row);
02545   _writeCommand(0x80 | addr);
02546 } //end clrIcon()
02547 
02548 
02549 /** Set Invert
02550   * setInvert method is supported by some compatible devices (eg KS0073) to swap between black and white 
02551   *
02552   * @param bool invertOn  Invert on/off   
02553   * @return none
02554   */
02555 //@TODO Add support for 40x4 dual controller  
02556 void TextLCD_Base::setInvert(bool invertOn) {
02557   
02558   if (invertOn) {
02559     // Controllers that support Invert
02560     switch (_ctrl) {   
02561       case KS0073:        
02562       case KS0078:        
02563         _function = _function | 0x01;                                  // Enable Invert
02564         _writeCommand(0x20 | _function);                               // Activate Invert (Std Instr Set)
02565         break;
02566       case SSD1803_3V3 :      
02567 //      case SSD1803_5V :                 
02568       case US2066_3V3:
02569 //      case USS2066_5V:
02570         _function_1 = _function_1 | 0x01;                              // Enable Invert 
02571                                                                        // Set function, 0 0 1 DL N BE RE(1) REV  (SSD1803)
02572                                                                        // Set function, 0 0 1 X  N BE RE(1) REV  (US2066)    
02573         _writeCommand(0x20 | _function_1);                             // Activate Invert (Ext Instr Set)
02574         _writeCommand(0x20 | _function);                               // Return to Std Instr Set                            
02575         break;
02576       default:  
02577         //Unsupported feature for other controllers
02578         break;              
02579     } // end switch  
02580   }  
02581   else {
02582     // Controllers that support Invert
02583     switch (_ctrl) {    
02584       case KS0073:
02585       case KS0078:
02586         _function = _function & ~0x01;                                 // Disable Invert
02587         _writeCommand(0x20 | _function);                               // Disable Invert (Std Instr Set)
02588         break;
02589       case SSD1803_3V3 :      
02590 //      case SSD1803_5V :                 
02591       case US2066_3V3:
02592 //      case USS2066_5V:
02593         _function_1 = _function_1 & ~0x01;                             // Disable Invert 
02594                                                                        // Set function, 0 0 1 DL N BE RE(1) REV  (SSD1803)
02595                                                                        // Set function, 0 0 1 X  N BE RE(1) REV  (US2066)                                                                                                                                              
02596         _writeCommand(0x20 | _function_1);                             // Activate Invert (Ext Instr Set)
02597         _writeCommand(0x20 | _function);                               // Return to Std Instr Set                            
02598         break;
02599 
02600       default:  
02601         //Unsupported feature for other controllers
02602         break;              
02603     } // end switch  
02604   }
02605 } // end setInvert()
02606 
02607 //--------- End TextLCD_Base -----------
02608 
02609 
02610 //--------- Start TextLCD Bus -----------
02611 
02612 /* Create a TextLCD interface for using regular mbed pins
02613  *
02614  * @param rs     Instruction/data control line
02615  * @param e      Enable line (clock)
02616  * @param d4-d7  Data lines for using as a 4-bit interface
02617  * @param type   Sets the panel size/addressing mode (default = LCD16x2)
02618  * @param bl     Backlight control line (optional, default = NC)  
02619  * @param e2     Enable2 line (clock for second controller, LCD40x4 only) 
02620  * @param ctrl   LCD controller (default = HD44780)   
02621  */ 
02622 TextLCD::TextLCD(PinName rs, PinName e,
02623                  PinName d4, PinName d5, PinName d6, PinName d7,
02624                  LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) :
02625                  TextLCD_Base(type, ctrl), 
02626                  _rs(rs), _e(e), _d(d4, d5, d6, d7) {
02627 
02628   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
02629   if (bl != NC) {
02630     _bl = new DigitalOut(bl);   //Construct new pin 
02631     _bl->write(0);              //Deactivate    
02632   }
02633   else {
02634     // No Hardware Backlight pin       
02635     _bl = NULL;                 //Construct dummy pin     
02636   }  
02637 
02638   // The hardware Enable2 pin is only needed for LCD40x4. Test and make sure whether it exists or not to prevent illegal access.
02639   if (e2 != NC) {
02640     _e2 = new DigitalOut(e2);   //Construct new pin 
02641     _e2->write(0);              //Deactivate    
02642   }
02643   else {
02644     // No Hardware Enable pin       
02645     _e2 = NULL;                 //Construct dummy pin     
02646   }  
02647                                                                            
02648   _init();
02649 }
02650 
02651 /** Destruct a TextLCD interface for using regular mbed pins
02652   *
02653   * @param  none
02654   * @return none
02655   */ 
02656 TextLCD::~TextLCD() {
02657    if (_bl != NULL) {delete _bl;}  // BL pin
02658    if (_e2 != NULL) {delete _e2;}  // E2 pin
02659 }
02660 
02661 /** Set E pin (or E2 pin)
02662   * Used for mbed pins, I2C bus expander or SPI shiftregister
02663   * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
02664   *   @param  value true or false
02665   *   @return none 
02666   */
02667 void TextLCD::_setEnable(bool value) {
02668 
02669   if(_ctrl_idx==_LCDCtrl_0) {
02670     if (value) {
02671       _e  = 1;    // Set E bit 
02672     }  
02673     else { 
02674       _e  = 0;    // Reset E bit  
02675     }  
02676   }    
02677   else { 
02678     if (value) {
02679       if (_e2 != NULL) {_e2->write(1);}  //Set E2 bit
02680     }  
02681     else { 
02682       if (_e2 != NULL) {_e2->write(0);}  //Reset E2 bit     
02683     }  
02684   }    
02685 }    
02686 
02687 // Set RS pin
02688 // Used for mbed pins, I2C bus expander or SPI shiftregister
02689 void TextLCD::_setRS(bool value) {
02690 
02691   if (value) {
02692     _rs  = 1;    // Set RS bit 
02693   }  
02694   else  {
02695     _rs  = 0;    // Reset RS bit 
02696   }  
02697 }    
02698 
02699 /** Set BL pin
02700   * Used for mbed pins, I2C bus expander or SPI shiftregister
02701   * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
02702   *   @param  value true or false
02703   *   @return none  
02704   */
02705 void TextLCD::_setBL(bool value) {
02706 
02707   if (value) {
02708     if (_bl != NULL) {_bl->write(1);}  //Set BL bit
02709   }  
02710   else { 
02711     if (_bl != NULL) {_bl->write(0);}  //Reset BL bit  
02712   }  
02713 }    
02714 
02715 // Place the 4bit data on the databus
02716 // Used for mbed pins, I2C bus expander or SPI shifregister
02717 void TextLCD::_setData(int value) {
02718   _d = value & 0x0F;   // Write Databits 
02719 }    
02720 
02721 //----------- End TextLCD ---------------
02722 
02723 
02724 //--------- Start TextLCD_I2C -----------
02725 #if(LCD_I2C == 1) /* I2C Expander PCF8574/MCP23008 */
02726 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander
02727   *
02728   * @param i2c             I2C Bus
02729   * @param deviceAddress   I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40)
02730   * @param type            Sets the panel size/addressing mode (default = LCD16x2)
02731   * @param ctrl            LCD controller (default = HD44780)    
02732   */
02733 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
02734                          TextLCD_Base(type, ctrl), 
02735                          _i2c(i2c){
02736                               
02737   _slaveAddress = deviceAddress & 0xFE;
02738 
02739   // Setup the I2C bus
02740   // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit, 
02741   _i2c->frequency(100000);
02742   
02743 #if (MCP23008==1)
02744   // MCP23008 portexpander Init
02745   _write_register(IODIR,   0x00);  // All outputs
02746   _write_register(IPOL,    0x00);  // No reverse polarity 
02747   _write_register(GPINTEN, 0x00);  // No interrupt 
02748   _write_register(DEFVAL,  0x00);  // Default value to compare against for interrupts
02749   _write_register(INTCON,  0x00);  // No interrupt on changes 
02750   _write_register(IOCON,   0x00);  // Interrupt polarity   
02751   _write_register(GPPU,    0x00);  // No Pullup 
02752   _write_register(INTF,    0x00);  //    
02753   _write_register(INTCAP,  0x00);  //    
02754   _write_register(GPIO,    0x00);  // Output/Input pins   
02755   _write_register(OLAT,    0x00);  // Output Latch  
02756     
02757   // Init the portexpander bus
02758   _lcd_bus = D_LCD_BUS_DEF;
02759   
02760   // write the new data to the portexpander
02761   _write_register(GPIO, _lcd_bus);      
02762 #else
02763   // PCF8574 of PCF8574A portexpander
02764 
02765   // Init the portexpander bus
02766   _lcd_bus = D_LCD_BUS_DEF;
02767 
02768   // write the new data to the portexpander
02769   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
02770 #endif
02771 
02772   _init();    
02773 }
02774 
02775 // Set E pin (or E2 pin)
02776 // Used for mbed pins, I2C bus expander or SPI shiftregister
02777 void TextLCD_I2C::_setEnable(bool value) {
02778 
02779   if(_ctrl_idx==_LCDCtrl_0) {
02780     if (value) {
02781       _lcd_bus |= D_LCD_E;     // Set E bit 
02782     }  
02783     else {                    
02784       _lcd_bus &= ~D_LCD_E;    // Reset E bit                     
02785     }  
02786   }
02787   else {
02788     if (value) {
02789       _lcd_bus |= D_LCD_E2;    // Set E2 bit 
02790     }  
02791     else {
02792       _lcd_bus &= ~D_LCD_E2;   // Reset E2bit                     
02793     }  
02794   }    
02795 
02796 #if (MCP23008==1)
02797   // MCP23008 portexpander
02798   
02799   // write the new data to the portexpander
02800   _write_register(GPIO, _lcd_bus);      
02801 #else
02802   // PCF8574 of PCF8574A portexpander
02803 
02804   // write the new data to the I2C portexpander
02805   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
02806 #endif
02807 }    
02808 
02809 // Set RS pin
02810 // Used for mbed pins, I2C bus expander or SPI shiftregister
02811 void TextLCD_I2C::_setRS(bool value) {
02812 
02813   if (value) {
02814     _lcd_bus |= D_LCD_RS;    // Set RS bit 
02815   }  
02816   else {                    
02817     _lcd_bus &= ~D_LCD_RS;   // Reset RS bit                     
02818   }
02819 
02820 #if (MCP23008==1)
02821   // MCP23008 portexpander
02822   
02823   // write the new data to the portexpander
02824   _write_register(GPIO, _lcd_bus);      
02825 #else
02826   // PCF8574 of PCF8574A portexpander
02827 
02828   // write the new data to the I2C portexpander
02829   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
02830 #endif                  
02831 }    
02832 
02833 // Set BL pin
02834 // Used for mbed pins, I2C bus expander or SPI shiftregister
02835 void TextLCD_I2C::_setBL(bool value) {
02836 
02837   if (value) {
02838     _lcd_bus |= D_LCD_BL;    // Set BL bit 
02839   }  
02840   else {                    
02841     _lcd_bus &= ~D_LCD_BL;   // Reset BL bit                     
02842   }
02843   
02844 #if (MCP23008==1)
02845   // MCP23008 portexpander
02846   
02847   // write the new data to the portexpander
02848   _write_register(GPIO, _lcd_bus);      
02849 #else
02850   // PCF8574 of PCF8574A portexpander
02851 
02852   // write the new data to the I2C portexpander
02853   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
02854 #endif                 
02855 }    
02856 
02857 
02858 // Place the 4bit data on the databus
02859 // Used for mbed pins, I2C bus expander or SPI shifregister
02860 void TextLCD_I2C::_setData(int value) {
02861   int data;
02862 
02863   // Set bit by bit to support any mapping of expander portpins to LCD pins
02864   
02865   data = value & 0x0F;
02866   if (data & 0x01){
02867     _lcd_bus |= D_LCD_D4;   // Set Databit 
02868   }  
02869   else { 
02870     _lcd_bus &= ~D_LCD_D4;  // Reset Databit
02871   }  
02872 
02873   if (data & 0x02){
02874     _lcd_bus |= D_LCD_D5;   // Set Databit 
02875   }  
02876   else {
02877     _lcd_bus &= ~D_LCD_D5;  // Reset Databit
02878   }  
02879 
02880   if (data & 0x04) {
02881     _lcd_bus |= D_LCD_D6;   // Set Databit 
02882   }  
02883   else {                    
02884     _lcd_bus &= ~D_LCD_D6;  // Reset Databit
02885   }  
02886 
02887   if (data & 0x08) {
02888     _lcd_bus |= D_LCD_D7;   // Set Databit 
02889   }  
02890   else {
02891     _lcd_bus &= ~D_LCD_D7;  // Reset Databit
02892   }  
02893                     
02894 #if (MCP23008==1)
02895   // MCP23008 portexpander
02896   
02897   // write the new data to the portexpander
02898   _write_register(GPIO, _lcd_bus);      
02899 #else
02900   // PCF8574 of PCF8574A portexpander
02901 
02902   // write the new data to the I2C portexpander
02903   _i2c->write(_slaveAddress, &_lcd_bus, 1);    
02904 #endif
02905                  
02906 }    
02907 
02908 // Write data to MCP23008 I2C portexpander
02909 void TextLCD_I2C::_write_register (int reg, int value) {
02910   char data[] = {reg, value};
02911     
02912   _i2c->write(_slaveAddress, data, 2); 
02913 }
02914 #endif /* I2C Expander PCF8574/MCP23008 */
02915 //---------- End TextLCD_I2C ------------
02916 
02917 
02918 //--------- Start TextLCD_I2C_N ---------
02919 #if(LCD_I2C_N == 1)  /* Native I2C */
02920 
02921  /** Create a TextLCD interface using a controller with native I2C interface
02922    *
02923    * @param i2c             I2C Bus
02924    * @param deviceAddress   I2C slave address (default = 0x7C)  
02925    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
02926    * @param bl              Backlight control line (optional, default = NC)     
02927    * @param ctrl            LCD controller (default = ST7032_3V3)                     
02928    */
02929 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) : 
02930                                TextLCD_Base(type, ctrl), 
02931 
02932                                _i2c(i2c){
02933   
02934   _slaveAddress = deviceAddress & 0xFE;
02935   
02936   // Setup the I2C bus
02937   // The max bitrate for ST7032i is 400kbit, lets stick to default here
02938   _i2c->frequency(100000);
02939 
02940        
02941   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
02942   if (bl != NC) {
02943     _bl = new DigitalOut(bl);   //Construct new pin 
02944     _bl->write(0);              //Deactivate    
02945   }
02946   else {
02947     // No Hardware Backlight pin       
02948     _bl = NULL;                 //Construct dummy pin     
02949   }  
02950   
02951   //Sanity check
02952   if (_ctrl & LCD_C_I2C) {
02953     _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces      
02954   }
02955   else {
02956     error("Error: LCD Controller type does not support native I2C interface\n\r");           
02957   }
02958 }
02959 
02960 TextLCD_I2C_N::~TextLCD_I2C_N() {
02961    if (_bl != NULL) {delete _bl;}  // BL pin
02962 }
02963 
02964 // Not used in this mode
02965 void TextLCD_I2C_N::_setEnable(bool value) {
02966 }    
02967 
02968 // Set RS pin
02969 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI
02970 void TextLCD_I2C_N::_setRS(bool value) {
02971 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
02972 // Start Slaveaddress+RW  b7 b6 b5 b4 b3 b2 b1 b0   b7...........b0  Stop
02973 //                        Co RS RW  0  0  0  0  0   command or data
02974 //
02975 //   C0=1 indicates that another controlbyte will follow after the next data or command byte 
02976 //   RS=1 means that next byte is data, RS=0 means that next byte is command
02977 //   RW=0 means write to controller. RW=1 means that controller will be read from after the next command. 
02978 //        Many native I2C controllers dont support this option and it is not used by this lib. 
02979 //
02980 
02981   if (value) {
02982     _controlbyte = 0x40; // Next byte is data, No more control bytes will follow
02983   }
02984   else {
02985     _controlbyte = 0x00; // Next byte is command, No more control bytes will follow     
02986   }
02987 }    
02988 
02989 // Set BL pin
02990 void TextLCD_I2C_N::_setBL(bool value) {
02991     if (_bl) {
02992         _bl->write(value);   
02993     }    
02994 }    
02995     
02996 // Not used in this mode
02997 void TextLCD_I2C_N::_setData(int value) {
02998 }    
02999 
03000 // Write a byte using I2C
03001 void TextLCD_I2C_N::_writeByte(int value) {
03002 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
03003 // Start Slaveaddress+RW  b7 b6 b5 b4 b3 b2 b1 b0   b7...........b0  Stop
03004 //                        Co RS RW  0  0  0  0  0   command or data
03005 //
03006 //   C0=1 indicates that another controlbyte will follow after the next data or command byte 
03007 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03008 //   RW=0 means write to controller. RW=1 means that controller will be read from after the next command. 
03009 //        Many native I2C controllers dont support this option and it is not used by this lib. 
03010 //
03011   char data[] = {_controlbyte, value};
03012     
03013 #if(LCD_I2C_ACK==1)
03014 //Controllers that support ACK
03015   _i2c->write(_slaveAddress, data, 2); 
03016 #else  
03017 //Controllers that dont support ACK
03018   _i2c->start(); 
03019   _i2c->write(_slaveAddress);   
03020   _i2c->write(data[0]); 
03021   _i2c->write(data[1]);     
03022   _i2c->stop();   
03023 #endif  
03024 }
03025 #endif /* Native I2C */
03026 //-------- End TextLCD_I2C_N ------------
03027 
03028 
03029 //--------- Start TextLCD_SPI -----------
03030 #if(LCD_SPI == 1) /* SPI Expander SN74595          */
03031 
03032  /** Create a TextLCD interface using an SPI 74595 portexpander
03033    *
03034    * @param spi             SPI Bus
03035    * @param cs              chip select pin (active low)
03036    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03037    * @param ctrl            LCD controller (default = HD44780)      
03038    */
03039 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
03040                          TextLCD_Base(type, ctrl), 
03041                          _spi(spi),        
03042                          _cs(cs) {      
03043         
03044   // Init cs
03045   _setCS(true);  
03046 
03047   // Setup the spi for 8 bit data, low steady state clock,
03048   // rising edge capture, with a 500KHz or 1MHz clock rate  
03049   _spi->format(8,0);
03050   _spi->frequency(500000);    
03051   //_spi.frequency(1000000);    
03052 
03053   // Init the portexpander bus
03054   _lcd_bus = D_LCD_BUS_DEF;
03055   
03056   // write the new data to the portexpander
03057   _setCS(false);  
03058   _spi->write(_lcd_bus);   
03059   _setCS(true);  
03060 
03061   _init();   
03062 }
03063 
03064 // Set E pin (or E2 pin)
03065 // Used for mbed pins, I2C bus expander or SPI shiftregister
03066 void TextLCD_SPI::_setEnable(bool value) {
03067 
03068   if(_ctrl_idx==_LCDCtrl_0) {
03069     if (value) {
03070       _lcd_bus |= D_LCD_E;     // Set E bit 
03071     }  
03072     else {                    
03073       _lcd_bus &= ~D_LCD_E;    // Reset E bit                     
03074     }  
03075   }
03076   else {
03077     if (value) {
03078       _lcd_bus |= D_LCD_E2;    // Set E2 bit 
03079     }  
03080     else {
03081       _lcd_bus &= ~D_LCD_E2;   // Reset E2 bit                     
03082     }  
03083   }
03084                   
03085   // write the new data to the SPI portexpander
03086   _setCS(false);  
03087   _spi->write(_lcd_bus);   
03088   _setCS(true);    
03089 }    
03090 
03091 // Set RS pin
03092 // Used for mbed pins, I2C bus expander or SPI shiftregister and SPI_N
03093 void TextLCD_SPI::_setRS(bool value) {
03094 
03095   if (value) {
03096     _lcd_bus |= D_LCD_RS;    // Set RS bit 
03097   }  
03098   else {                    
03099     _lcd_bus &= ~D_LCD_RS;   // Reset RS bit                     
03100   }
03101      
03102   // write the new data to the SPI portexpander
03103   _setCS(false);  
03104   _spi->write(_lcd_bus);   
03105   _setCS(true);     
03106 }    
03107 
03108 // Set BL pin
03109 // Used for mbed pins, I2C bus expander or SPI shiftregister
03110 void TextLCD_SPI::_setBL(bool value) {
03111 
03112   if (value) {
03113     _lcd_bus |= D_LCD_BL;    // Set BL bit 
03114   }  
03115   else {
03116     _lcd_bus &= ~D_LCD_BL;   // Reset BL bit                     
03117   }
03118       
03119   // write the new data to the SPI portexpander
03120   _setCS(false);  
03121   _spi->write(_lcd_bus);   
03122   _setCS(true);      
03123 }    
03124 
03125 // Place the 4bit data on the databus
03126 // Used for mbed pins, I2C bus expander or SPI shiftregister
03127 void TextLCD_SPI::_setData(int value) {
03128   int data;
03129 
03130   // Set bit by bit to support any mapping of expander portpins to LCD pins
03131     
03132   data = value & 0x0F;
03133   if (data & 0x01) {
03134     _lcd_bus |= D_LCD_D4;   // Set Databit 
03135   }  
03136   else {                    
03137     _lcd_bus &= ~D_LCD_D4;  // Reset Databit                     
03138   }
03139   
03140   if (data & 0x02) {
03141     _lcd_bus |= D_LCD_D5;   // Set Databit 
03142   }  
03143   else {
03144     _lcd_bus &= ~D_LCD_D5;  // Reset Databit                     
03145   }
03146   
03147   if (data & 0x04) {
03148     _lcd_bus |= D_LCD_D6;   // Set Databit 
03149   }  
03150   else {
03151     _lcd_bus &= ~D_LCD_D6;  // Reset Databit                     
03152   }
03153   
03154   if (data & 0x08) {
03155     _lcd_bus |= D_LCD_D7;   // Set Databit 
03156   }  
03157   else {
03158     _lcd_bus &= ~D_LCD_D7;  // Reset Databit
03159   }  
03160                     
03161   // write the new data to the SPI portexpander
03162   _setCS(false);  
03163   _spi->write(_lcd_bus);   
03164   _setCS(true);          
03165 }    
03166 
03167 // Set CS line.
03168 // Only used for SPI bus
03169 void TextLCD_SPI::_setCS(bool value) {
03170 
03171   if (value) {   
03172     _cs  = 1;    // Set CS pin 
03173   }  
03174   else {
03175     _cs  = 0;    // Reset CS pin 
03176   }
03177 }
03178 #endif /* SPI Expander SN74595          */
03179 //---------- End TextLCD_SPI ------------
03180 
03181 
03182 //--------- Start TextLCD_SPI_N ---------
03183 #if(LCD_SPI_N == 1) /* Native SPI bus     */
03184  /** Create a TextLCD interface using a controller with a native SPI4 interface
03185    *
03186    * @param spi             SPI Bus
03187    * @param cs              chip select pin (active low)
03188    * @param rs              Instruction/data control line
03189    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03190    * @param bl              Backlight control line (optional, default = NC)  
03191    * @param ctrl            LCD controller (default = ST7032_3V3) 
03192    */       
03193 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) :
03194                              TextLCD_Base(type, ctrl), 
03195                              _spi(spi),        
03196                              _cs(cs),
03197                              _rs(rs) {      
03198         
03199   // Init CS
03200   _cs = 1;
03201 
03202   // Setup the spi for 8 bit data, high steady state clock,
03203   // rising edge capture, with a 500KHz or 1MHz clock rate    
03204 //  _spi->format(8,3);  
03205 //  _spi->frequency(1000000);    
03206   
03207   // Setup the spi for 8 bit data, low steady state clock,
03208   // rising edge capture, with a 500KHz or 1MHz clock rate  
03209   _spi->format(8,0);
03210 //  _spi->frequency(300000);    
03211 //  _spi->frequency(500000); 
03212   _spi->frequency(1000000);    
03213     
03214   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03215   if (bl != NC) {
03216     _bl = new DigitalOut(bl);   //Construct new pin 
03217     _bl->write(0);              //Deactivate    
03218   }
03219   else {
03220     // No Hardware Backlight pin       
03221     _bl = NULL;                 //Construct dummy pin     
03222   }  
03223 
03224   //Sanity check
03225   if (_ctrl & LCD_C_SPI4) {
03226     _init(_LCD_DL_8);   // Set Datalength to 8 bit for all native serial interfaces
03227                         // ST7070 must set datalength to 8 bits!
03228   }
03229   else {
03230     error("Error: LCD Controller type does not support native SPI4 interface\n\r");           
03231   }
03232 }
03233 
03234 TextLCD_SPI_N::~TextLCD_SPI_N() {
03235    if (_bl != NULL) {delete _bl;}  // BL pin
03236 }
03237 
03238 // Not used in this mode
03239 void TextLCD_SPI_N::_setEnable(bool value) {
03240 }    
03241 
03242 // Set RS pin
03243 // Used for mbed pins, I2C bus expander or SPI shiftregister, SPI_N
03244 void TextLCD_SPI_N::_setRS(bool value) {
03245     _rs = value;
03246 }    
03247 
03248 // Set BL pin
03249 void TextLCD_SPI_N::_setBL(bool value) {
03250     if (_bl) {
03251         _bl->write(value);   
03252     }    
03253 }    
03254 
03255 // Not used in this mode
03256 void TextLCD_SPI_N::_setData(int value) {
03257 }    
03258 
03259 // Write a byte using SPI
03260 void TextLCD_SPI_N::_writeByte(int value) {
03261     _cs = 0;
03262     wait_us(1);
03263     _spi->write(value);
03264     wait_us(1);
03265     _cs = 1;
03266 }
03267 #endif /* Native SPI bus     */  
03268 //-------- End TextLCD_SPI_N ------------
03269 
03270 
03271 //-------- Start TextLCD_SPI_N_3_8 --------
03272 #if(LCD_SPI_N_3_8 == 1) /* Native SPI bus     */
03273 
03274  /** Create a TextLCD interface using a controller with a native SPI3 8 bits interface
03275    * This mode is supported by ST7070. Note that implementation in TexTLCD is not very efficient due to
03276    * structure of the TextLCD library: each databyte is written separately and requires a separate 'count command' set to 1 byte.
03277    *
03278    * @param spi             SPI Bus
03279    * @param cs              chip select pin (active low)
03280    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03281    * @param bl              Backlight control line (optional, default = NC)  
03282    * @param ctrl            LCD controller (default = ST7070) 
03283    */       
03284 TextLCD_SPI_N_3_8::TextLCD_SPI_N_3_8(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
03285                                      TextLCD_Base(type, ctrl), 
03286                                      _spi(spi),        
03287                                      _cs(cs) {      
03288 
03289   // Init CS
03290   _cs = 1;
03291 
03292   // Setup the spi for 8 bit data, high steady state clock,
03293   // rising edge capture, with a 500KHz or 1MHz clock rate  
03294 //  _spi->format(8,3);  
03295 //  _spi->frequency(300000);    
03296 //  _spi->frequency(1000000);    
03297 
03298   // Setup the spi for 8 bit data, low steady state clock,
03299   // rising edge capture, with a 500KHz or 1MHz clock rate  
03300   _spi->format(8,0);
03301 //  _spi->frequency(300000);    
03302 //  _spi->frequency(500000); 
03303   _spi->frequency(1000000);    
03304   
03305   
03306   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03307   if (bl != NC) {
03308     _bl = new DigitalOut(bl);   //Construct new pin 
03309     _bl->write(0);              //Deactivate    
03310   }
03311   else {
03312     // No Hardware Backlight pin       
03313     _bl = NULL;                 //Construct dummy pin     
03314   }  
03315 
03316   //Sanity check
03317   if (_ctrl & LCD_C_SPI3_8) { 
03318     _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces   
03319   }
03320   else {
03321     error("Error: LCD Controller type does not support native SPI3 8 bits interface\n\r");           
03322   }
03323 }
03324 
03325 TextLCD_SPI_N_3_8::~TextLCD_SPI_N_3_8() {
03326    if (_bl != NULL) {delete _bl;}  // BL pin
03327 }
03328 
03329 // Not used in this mode
03330 void TextLCD_SPI_N_3_8::_setEnable(bool value) {
03331 }    
03332 
03333 // Used for mbed pins, I2C bus expander or SPI shiftregister, SPI_N
03334 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03335 void TextLCD_SPI_N_3_8::_setRS(bool value) {
03336   
03337   if (value) {
03338     _controlbyte = 0x01; // Next byte is data, No more control bytes will follow
03339   }
03340   else {
03341     _controlbyte = 0x00; // Next byte is command, No more control bytes will follow     
03342   }
03343 }      
03344   
03345 // Set BL pin
03346 void TextLCD_SPI_N_3_8::_setBL(bool value) {
03347     if (_bl) {
03348         _bl->write(value);   
03349     }    
03350 }    
03351 
03352 // Not used in this mode
03353 void TextLCD_SPI_N_3_8::_setData(int value) {
03354 }    
03355 
03356 // Write a byte using SPI3 8 bits mode (ST7070)
03357 void TextLCD_SPI_N_3_8::_writeByte(int value) {
03358     
03359   if (_controlbyte == 0x00) { // Byte is command 
03360     _cs = 0;
03361     wait_us(1);
03362     _spi->write(value);
03363     wait_us(1);
03364     _cs = 1;
03365   }  
03366   else {                      // Byte is data 
03367     // Select Extended Instr Set
03368     _cs = 0;
03369     wait_us(1);
03370     _spi->write(0x20 | _function | 0x04);   // Set function, 0 0 1 DL N EXT=1 x x (Select Instr Set = 1));
03371     wait_us(1);
03372     _cs = 1;     
03373 
03374     wait_us(40);                            // Wait until command has finished...    
03375         
03376     // Set Count to 1 databyte
03377     _cs = 0;
03378     wait_us(1);    
03379     _spi->write(0x80);                      // Set display data length, 1 L6 L5 L4 L3 L2 L1 L0 (Instr Set = 1)
03380     wait_us(1);
03381     _cs = 1;
03382 
03383     wait_us(40);    
03384                 
03385     // Write 1 databyte     
03386     _cs = 0;
03387     wait_us(1);    
03388     _spi->write(value);                     // Write data (Instr Set = 1)
03389     wait_us(1);
03390     _cs = 1;         
03391 
03392     wait_us(40);    
03393         
03394     // Select Standard Instr Set    
03395     _cs = 0;
03396     wait_us(1);    
03397     _spi->write(0x20 | _function);          // Set function, 0 0 1 DL N EXT=0 x x (Select Instr Set = 0));
03398     wait_us(1);
03399     _cs = 1;     
03400   }  
03401 }
03402 #endif /* Native SPI bus     */  
03403 //------- End TextLCD_SPI_N_3_8 -----------
03404 
03405 
03406 //-------- Start TextLCD_SPI_N_3_9 --------
03407 #if(LCD_SPI_N_3_9 == 1) /* Native SPI bus     */
03408 //Code checked out on logic analyser. Not yet tested on hardware..
03409 
03410  /** Create a TextLCD interface using a controller with a native SPI3 9 bits interface
03411    *
03412    * @param spi             SPI Bus
03413    * @param cs              chip select pin (active low)
03414    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03415    * @param bl              Backlight control line (optional, default = NC)  
03416    * @param ctrl            LCD controller (default = AIP31068) 
03417    */       
03418 TextLCD_SPI_N_3_9::TextLCD_SPI_N_3_9(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
03419                                      TextLCD_Base(type, ctrl), 
03420                                      _spi(spi),        
03421                                      _cs(cs) {      
03422 
03423   // Init CS
03424   _cs = 1;
03425 
03426   // Setup the spi for 9 bit data, high steady state clock,
03427   // rising edge capture, with a 500KHz or 1MHz clock rate  
03428   _spi->format(9,3);  
03429   _spi->frequency(1000000);    
03430   
03431   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03432   if (bl != NC) {
03433     _bl = new DigitalOut(bl);   //Construct new pin 
03434     _bl->write(0);              //Deactivate    
03435   }
03436   else {
03437     // No Hardware Backlight pin       
03438     _bl = NULL;                 //Construct dummy pin     
03439   }  
03440 
03441   //Sanity check
03442   if (_ctrl & LCD_C_SPI3_9) { 
03443     _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces   
03444   }
03445   else {
03446     error("Error: LCD Controller type does not support native SPI3 9 bits interface\n\r");           
03447   }
03448 }
03449 
03450 TextLCD_SPI_N_3_9::~TextLCD_SPI_N_3_9() {
03451    if (_bl != NULL) {delete _bl;}  // BL pin
03452 }
03453 
03454 // Not used in this mode
03455 void TextLCD_SPI_N_3_9::_setEnable(bool value) {
03456 }    
03457 
03458 // Set RS pin
03459 // Used for mbed pins, I2C bus expander or SPI shiftregister
03460 void TextLCD_SPI_N_3_9::_setRS(bool value) {
03461 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
03462 //   b8  b7...........b0 
03463 //   RS  command or data
03464 //
03465 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03466 //
03467 
03468   if (value) {
03469     _controlbyte = 0x01; // Next byte is data
03470   }
03471   else {
03472     _controlbyte = 0x00; // Next byte is command
03473   }  
03474 }    
03475 
03476 // Set BL pin
03477 void TextLCD_SPI_N_3_9::_setBL(bool value) {
03478     if (_bl) {
03479         _bl->write(value);   
03480     }    
03481 }    
03482 
03483 // Not used in this mode
03484 void TextLCD_SPI_N_3_9::_setData(int value) {
03485 }    
03486 
03487 // Write a byte using SPI3 9 bits mode
03488 void TextLCD_SPI_N_3_9::_writeByte(int value) {
03489     _cs = 0;
03490     wait_us(1);
03491     _spi->write( (_controlbyte << 8) | (value & 0xFF));
03492     wait_us(1);
03493     _cs = 1;
03494 }
03495 #endif /* Native SPI bus     */  
03496 //------- End TextLCD_SPI_N_3_9 -----------
03497 
03498 
03499 //------- Start TextLCD_SPI_N_3_10 --------
03500 #if(LCD_SPI_N_3_10 == 1) /* Native SPI bus     */
03501 
03502  /** Create a TextLCD interface using a controller with a native SPI3 10 bits interface
03503    *
03504    * @param spi             SPI Bus
03505    * @param cs              chip select pin (active low)
03506    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03507    * @param bl              Backlight control line (optional, default = NC)  
03508    * @param ctrl            LCD controller (default = AIP31068) 
03509    */       
03510 TextLCD_SPI_N_3_10::TextLCD_SPI_N_3_10(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
03511                                        TextLCD_Base(type, ctrl), 
03512                                        _spi(spi),        
03513                                        _cs(cs) {      
03514         
03515   // Init CS
03516   _cs = 1;
03517 
03518   // Setup the spi for 10 bit data, low steady state clock,
03519   // rising edge capture, with a 500KHz or 1MHz clock rate  
03520   _spi->format(10,0);
03521   _spi->frequency(1000000);    
03522   
03523   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03524   if (bl != NC) {
03525     _bl = new DigitalOut(bl);   //Construct new pin 
03526     _bl->write(0);              //Deactivate    
03527   }
03528   else {
03529     // No Hardware Backlight pin       
03530     _bl = NULL;                 //Construct dummy pin     
03531   }  
03532 
03533   //Sanity check
03534   if (_ctrl & LCD_C_SPI3_10) {
03535      _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces            
03536   }
03537   else {
03538     error("Error: LCD Controller type does not support native SPI3 10 bits interface\n\r");           
03539   }
03540 }
03541 
03542 TextLCD_SPI_N_3_10::~TextLCD_SPI_N_3_10() {
03543    if (_bl != NULL) {delete _bl;}  // BL pin
03544 }
03545 
03546 // Not used in this mode
03547 void TextLCD_SPI_N_3_10::_setEnable(bool value) {
03548 }    
03549 
03550 // Set RS pin
03551 // Used for mbed pins, I2C bus expander or SPI shiftregister
03552 void TextLCD_SPI_N_3_10::_setRS(bool value) {
03553 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
03554 //   b9 b8  b7...........b0 
03555 //   RS RW  command or data
03556 //
03557 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03558 //   RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
03559 //
03560 
03561   if (value) {
03562     _controlbyte = 0x02; // Next byte is data
03563   }
03564   else {
03565     _controlbyte = 0x00; // Next byte is command
03566   }  
03567 }    
03568 
03569 // Set BL pin
03570 void TextLCD_SPI_N_3_10::_setBL(bool value) {
03571     if (_bl) {
03572         _bl->write(value);   
03573     }    
03574 }    
03575 
03576 // Not used in this mode
03577 void TextLCD_SPI_N_3_10::_setData(int value) {
03578 }    
03579 
03580 // Write a byte using SPI3 10 bits mode
03581 void TextLCD_SPI_N_3_10::_writeByte(int value) {
03582     _cs = 0;
03583     wait_us(1);
03584     _spi->write( (_controlbyte << 8) | (value & 0xFF));
03585     wait_us(1);
03586     _cs = 1;
03587 }
03588 #endif /* Native SPI bus     */  
03589 //------- End TextLCD_SPI_N_3_10 ----------
03590 
03591 
03592 //------- Start TextLCD_SPI_N_3_16 --------
03593 #if(LCD_SPI_N_3_16 == 1) /* Native SPI bus     */
03594 
03595  /** Create a TextLCD interface using a controller with a native SPI3 16 bits interface
03596    *
03597    * @param spi             SPI Bus
03598    * @param cs              chip select pin (active low)
03599    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03600    * @param bl              Backlight control line (optional, default = NC)  
03601    * @param ctrl            LCD controller (default = PT6314) 
03602    */       
03603 TextLCD_SPI_N_3_16::TextLCD_SPI_N_3_16(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
03604                                        TextLCD_Base(type, ctrl), 
03605                                        _spi(spi),        
03606                                        _cs(cs) {      
03607         
03608   // Init CS
03609   _cs = 1;
03610 
03611   // Setup the spi for 8 bit data, low steady state clock,
03612   // rising edge capture, with a 500KHz or 1MHz clock rate  
03613   _spi->format(8,0);
03614   _spi->frequency(1000000);    
03615   
03616   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03617   if (bl != NC) {
03618     _bl = new DigitalOut(bl);   //Construct new pin 
03619     _bl->write(0);              //Deactivate    
03620   }
03621   else {
03622     // No Hardware Backlight pin       
03623     _bl = NULL;                 //Construct dummy pin     
03624   }  
03625 
03626   //Sanity check
03627   if (_ctrl & LCD_C_SPI3_16) {
03628      _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces            
03629   }
03630   else {
03631     error("Error: LCD Controller type does not support native SPI3 16 bits interface\n\r");           
03632   }
03633 }
03634 
03635 TextLCD_SPI_N_3_16::~TextLCD_SPI_N_3_16() {
03636    if (_bl != NULL) {delete _bl;}  // BL pin
03637 }
03638 
03639 // Not used in this mode
03640 void TextLCD_SPI_N_3_16::_setEnable(bool value) {
03641 }    
03642 
03643 // Set RS pin
03644 // Used for mbed pins, I2C bus expander or SPI shiftregister
03645 void TextLCD_SPI_N_3_16::_setRS(bool value) {
03646 // The 16bit mode is split in 2 bytes. The first byte is for synchronisation and controlbits. The controlbits define the meaning of the next byte.
03647 // The 8 actual bits represent either a data or a command byte.
03648 //   b15 b14 b13 b12 b11 b10  b9  b8 - b7 b6 b5 b4 b3 b2 b1 b0 
03649 //     1   1   1   1   1  RW  RS   0   d7 d6 d5 d4 d3 d2 d1 d0
03650 //
03651 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03652 //   RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
03653 //
03654 
03655   if (value) {
03656     _controlbyte = 0xFA; // Next byte is data
03657   }
03658   else {
03659     _controlbyte = 0xF8; // Next byte is command
03660   }  
03661 }    
03662 
03663 // Set BL pin
03664 void TextLCD_SPI_N_3_16::_setBL(bool value) {
03665     if (_bl) {
03666         _bl->write(value);   
03667     }    
03668 }    
03669 
03670 // Not used in this mode
03671 void TextLCD_SPI_N_3_16::_setData(int value) {
03672 }    
03673    
03674 // Write a byte using SPI3 16 bits mode
03675 void TextLCD_SPI_N_3_16::_writeByte(int value) {
03676     _cs = 0;
03677     wait_us(1);
03678 
03679     _spi->write(_controlbyte);
03680 
03681     _spi->write(value);     
03682 
03683     wait_us(1);
03684     _cs = 1;
03685 }
03686 #endif /* Native SPI bus     */  
03687 //------- End TextLCD_SPI_N_3_16 ----------
03688 
03689 
03690 //------- Start TextLCD_SPI_N_3_24 --------
03691 #if(LCD_SPI_N_3_24 == 1) /* Native SPI bus     */
03692 
03693  /** Create a TextLCD interface using a controller with a native SPI3 24 bits interface
03694    *
03695    * @param spi             SPI Bus
03696    * @param cs              chip select pin (active low)
03697    * @param type            Sets the panel size/addressing mode (default = LCD16x2)
03698    * @param bl              Backlight control line (optional, default = NC)  
03699    * @param ctrl            LCD controller (default = SSD1803) 
03700    */       
03701 TextLCD_SPI_N_3_24::TextLCD_SPI_N_3_24(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
03702                                        TextLCD_Base(type, ctrl), 
03703                                        _spi(spi),        
03704                                        _cs(cs) {      
03705         
03706   // Init CS
03707   _cs = 1;
03708 
03709   // Setup the spi for 8 bit data, high steady state clock,
03710   // rising edge capture, with a 500KHz or 1MHz clock rate  
03711   _spi->format(8,3);
03712   _spi->frequency(1000000);    
03713   
03714   // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
03715   if (bl != NC) {
03716     _bl = new DigitalOut(bl);   //Construct new pin 
03717     _bl->write(0);              //Deactivate    
03718   }
03719   else {
03720     // No Hardware Backlight pin       
03721     _bl = NULL;                 //Construct dummy pin     
03722   }  
03723 
03724   //Sanity check
03725   if (_ctrl & LCD_C_SPI3_24) {
03726     _init(_LCD_DL_8);  // Set Datalength to 8 bit for all native serial interfaces      
03727   }
03728   else {
03729     error("Error: LCD Controller type does not support native SPI3 24 bits interface\n\r");           
03730   }
03731 }
03732 
03733 TextLCD_SPI_N_3_24::~TextLCD_SPI_N_3_24() {
03734    if (_bl != NULL) {delete _bl;}  // BL pin
03735 }
03736 
03737 // Not used in this mode
03738 void TextLCD_SPI_N_3_24::_setEnable(bool value) {
03739 }    
03740 
03741 // Set RS pin
03742 // Used for mbed pins, I2C bus expander or SPI shiftregister
03743 void TextLCD_SPI_N_3_24::_setRS(bool value) {
03744 // The 24bit mode is split in 3 bytes. The first byte is for synchronisation and controlbits. The controlbits define the meaning of the next two bytes.
03745 // Each byte encodes 4 actual bits. The 8 actual bits represent either a data or a command byte.
03746 //   b23 b22 b21 b20 b19 b18 b17 b16 -  b15 b14 b13 b12 b11 b10 b9 b8 - b7 b6 b5 b4 b3 b2 b1 b0 
03747 //     1   1   1   1   1  RW  RS   0     d0  d1  d2  d3   0   0  0  0   d4 d5 d6 d7  0  0  0  0
03748 //
03749 //   RS=1 means that next byte is data, RS=0 means that next byte is command
03750 //   RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
03751 //
03752 // Note: SPI3_24 expects LSB first. This is inconsistent with regular SPI convention (and hardware) that sends MSB first.
03753 
03754   if (value) {
03755     _controlbyte = 0xFA; // Next byte is data
03756   }
03757   else {
03758     _controlbyte = 0xF8; // Next byte is command
03759   }   
03760 }    
03761 
03762 // Set BL pin
03763 void TextLCD_SPI_N_3_24::_setBL(bool value) {
03764     if (_bl) {
03765         _bl->write(value);   
03766     }    
03767 }    
03768 
03769 // Not used in this mode
03770 void TextLCD_SPI_N_3_24::_setData(int value) {
03771 }    
03772 
03773 //Mapping table to flip the bits around cause SPI3_24 expects LSB first.
03774 const uint8_t map3_24[16] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0};
03775     
03776 // Write a byte using SPI3 24 bits mode
03777 void TextLCD_SPI_N_3_24::_writeByte(int value) {
03778     _cs = 0;
03779     wait_us(1);
03780     _spi->write(_controlbyte);
03781 
03782     //Map and send the LSB nibble
03783     _spi->write( map3_24[value & 0x0F]);     
03784 
03785     //Map and send the MSB nibble
03786     _spi->write( map3_24[(value >> 4) & 0x0F]);     
03787 
03788     wait_us(1);
03789     _cs = 1;
03790 }
03791 #endif /* Native SPI bus     */  
03792 //------- End TextLCD_SPI_N_3_24 ----------