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