I bravi ragazzi / TextLCD1

Fork of TextLCD by tttt

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TextLCD.cpp Source File

TextLCD.cpp

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