LCDisplay with IIC (I2C)-bus and IC 8574
Fork of TextLCD by
Embed:
(wiki syntax)
Show/hide line numbers
TextLCD.cpp
00001 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780 00002 * Copyright (c) 2007-2010, sford, http://mbed.org 00003 * 2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs 00004 * 2013, v02: WH, Added I2C and SPI bus interfaces 00005 * 2013, v03: WH, Added support for LCD40x4 which uses 2 controllers 00006 * 2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess 00007 * 2013, v05: WH, Added support for 8x2B, added some UDCs 00008 * 2013, v06: WH, Added support for devices that use internal DC/DC converters 00009 * 2013, v07: WH, Added support for backlight and include portdefinitions for LCD2004 Module from DFROBOT 00010 * 2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined pins 00011 * 2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032 00012 * 2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module 00013 * 2014, v11: WH, Added support for native I2C controllers such as PCF21XX, Improved the _initCtrl() method to deal with differences between all supported controllers 00014 * 2014, v12: WH, Added support for native I2C controller PCF2119 and native I2C/SPI controllers SSD1803, ST7036, added setContrast method (by JH1PJL) for supported devices (eg ST7032i) 00015 * 2014, v13: WH, Added support for controllers US2066/SSD1311 (OLED), added setUDCBlink method for supported devices (eg SSD1803), fixed issue in setPower() 00016 *@Todo Add AC780S/KS0066i 00017 * 00018 * Permission is hereby granted, free of charge, to any person obtaining a copy 00019 * of this software and associated documentation files (the "Software"), to deal 00020 * in the Software without restriction, including without limitation the rights 00021 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00022 * copies of the Software, and to permit persons to whom the Software is 00023 * furnished to do so, subject to the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be included in 00026 * all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00029 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00030 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00031 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00032 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00033 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00034 * THE SOFTWARE. 00035 */ 00036 00037 #include "TextLCD.h" 00038 #include "mbed.h" 00039 00040 //For Testing only 00041 //DigitalOut led1(LED1); 00042 //DigitalOut led2(LED2); 00043 // led2=!led2; 00044 00045 00046 // User Defined Characters (UDCs) are defined by an 8 byte bitpattern. The P0..P5 form the character pattern. 00047 // P7 P6 P5 P4 P3 P2 P1 P0 00048 // 0 B1 B0 x 0 1 1 1 0 00049 // 1 B1 B0 x 1 0 0 0 1 00050 // . ............. 00051 // 7 B1 B0 x 1 0 0 0 1 00052 // 00053 // Blinking UDCs are enabled when a specific controlbit (BE) is set. 00054 // The blinking pixels in the UDC can be controlled by setting additional bits in the UDC bitpattern. 00055 // Bit 6 and Bit 7 in the pattern will control the blinking mode when Blink is enabled through BE. 00056 // B1 B0 Mode 00057 // 0 0 No Blinking in this row of the UDC 00058 // 0 1 Enabled pixels in P4 will blink 00059 // 1 x Enabled pixels in P0..P4 will blink 00060 00061 /** Some sample User Defined Chars 5x7 dots */ 00062 //const char udc_ae[] = {0x00, 0x00, 0x1B, 0x05, 0x1F, 0x14, 0x1F, 0x00}; //æ 00063 //const char udc_0e[] = {0x00, 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00}; //ø 00064 //const char udc_ao[] = {0x0E, 0x0A, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x00}; //å 00065 //const char udc_AE[] = {0x0F, 0x14, 0x14, 0x1F, 0x14, 0x14, 0x17, 0x00}; //Æ 00066 //const char udc_0E[] = {0x0E, 0x13, 0x15, 0x15, 0x15, 0x19, 0x0E, 0x00}; //Ø 00067 //const char udc_Ao[] = {0x0E, 0x0A, 0x0E, 0x11, 0x1F, 0x11, 0x11, 0x00}; //Å 00068 //const char udc_PO[] = {0x04, 0x0A, 0x0A, 0x1F, 0x1B, 0x1B, 0x1F, 0x00}; //Padlock Open 00069 //const char udc_PC[] = {0x1C, 0x10, 0x08, 0x1F, 0x1B, 0x1B, 0x1F, 0x00}; //Padlock Closed 00070 00071 //const char udc_alpha[] = {0x00, 0x00, 0x0D, 0x12, 0x12, 0x12, 0x0D, 0x00}; //alpha 00072 //const char udc_ohm[] = {0x0E, 0x11, 0x11, 0x11, 0x0A, 0x0A, 0x1B, 0x00}; //ohm 00073 //const char udc_sigma[] = {0x1F, 0x08, 0x04, 0x02, 0x04, 0x08, 0x1F, 0x00}; //sigma 00074 //const char udc_pi[] = {0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x00}; //pi 00075 //const char udc_root[] = {0x07, 0x04, 0x04, 0x04, 0x14, 0x0C, 0x04, 0x00}; //root 00076 00077 const char udc_0[] = {0x18, 0x14, 0x12, 0x11, 0x12, 0x14, 0x18, 0x00}; // |> 00078 const char udc_1[] = {0x03, 0x05, 0x09, 0x11, 0x09, 0x05, 0x03, 0x00}; // <| 00079 const char udc_2[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00}; // | 00080 const char udc_3[] = {0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00}; // || 00081 const char udc_4[] = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00}; // ||| 00082 const char udc_5[] = {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00}; // = 00083 const char udc_6[] = {0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x00}; // checkerboard 00084 const char udc_7[] = {0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x10, 0x00}; // \ 00085 00086 const char udc_degr[] = {0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00}; // Degree symbol 00087 00088 const char udc_TM_T[] = {0x1F, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; // Trademark T 00089 const char udc_TM_M[] = {0x11, 0x1B, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00}; // Trademark M 00090 00091 //const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Full 00092 //const char udc_Bat_Ha[] = {0x0E, 0x11, 0x13, 0x17, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Half 00093 //const char udc_Bat_Lo[] = {0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x00}; // Battery Low 00094 //const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Full 00095 //const char udc_Bat_Ha[] = {0x0E, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Half 00096 //const char udc_Bat_Lo[] = {0x0E, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x00}; // Battery Low 00097 const char udc_Bat_Hi[] = {0x8E, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x00}; // Battery Full, Blink 00098 const char udc_Bat_Ha[] = {0x8E, 0x91, 0x91, 0x9F, 0x9F, 0x9F, 0x9F, 0x00}; // Battery Half, Blink 00099 const char udc_Bat_Lo[] = {0x8E, 0x91, 0x91, 0x91, 0x91, 0x9F, 0x9F, 0x00}; // Battery Low, Blink 00100 const char udc_AC[] = {0x0A, 0x0A, 0x1F, 0x11, 0x0E, 0x04, 0x04, 0x00}; // AC Power 00101 00102 //const char udc_smiley[] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00, 0x00}; // Smiley 00103 //const char udc_droopy[] = {0x00, 0x0A, 0x00, 0x04, 0x00, 0x0E, 0x11, 0x00}; // Droopey 00104 //const char udc_note[] = {0x01, 0x03, 0x05, 0x09, 0x0B, 0x1B, 0x18, 0x00}; // Note 00105 00106 //const char udc_bar_1[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00}; // Bar 1 00107 //const char udc_bar_2[] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}; // Bar 11 00108 //const char udc_bar_3[] = {0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00}; // Bar 111 00109 //const char udc_bar_4[] = {0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x00}; // Bar 1111 00110 //const char udc_bar_5[] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Bar 11111 00111 00112 //const char udc_ch_1[] = {0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00}; // Hor bars 4 00113 //const char udc_ch_2[] = {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f}; // Hor bars 4 (inverted) 00114 //const char udc_ch_3[] = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15}; // Ver bars 3 00115 //const char udc_ch_4[] = {0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}; // Ver bars 3 (inverted) 00116 //const char udc_ch_yr[] = {0x08, 0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02}; // Year (kana) 00117 //const char udc_ch_mo[] = {0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x09, 0x13}; // Month (kana) 00118 //const char udc_ch_dy[] = {0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x1F}; // Day (kana) 00119 //const char udc_ch_mi[] = {0x0C, 0x0a, 0x11, 0x1f, 0x09, 0x09, 0x09, 0x13}; // minute (kana) 00120 00121 //const char udc_bell[] = {0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04}; 00122 //const char udc_note[] = {0x02,0x03,0x02,0x0E,0x1E,0x0C,0x00}; 00123 //const char udc_clock[] = {0x00,0x0E,0x15,0x17,0x11,0x0E,0x00}; 00124 //const char udc_heart[] = {0x00,0x0a,0x1F,0x1F,0x0E,0x04,0x00}; 00125 //const char udc_duck[] = {0x00,0x0c,0x1D,0x0F,0x0F,0x06,0x00}; 00126 //const char udc_check[] = {0x00,0x01,0x03,0x16,0x1C,0x08,0x00}; 00127 //const char udc_cross[] = {0x00,0x1B,0x0E,0x04,0x0E,0x1B,0x00}; 00128 //const char udc_retarrow[] = {0x01,0x01,0x05,0x09,0x1f,0x08,0x04}; 00129 00130 const char udc_None[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00131 const char udc_All[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 00132 00133 /** Create a TextLCD_Base interface 00134 * 00135 * @param type Sets the panel size/addressing mode (default = LCD16x2) 00136 * @param ctrl LCD controller (default = HD44780) 00137 */ 00138 TextLCD_Base::TextLCD_Base(LCDType type, LCDCtrl ctrl) : _type(type), _ctrl(ctrl) { 00139 00140 // Extract LCDType data 00141 00142 // Columns encoded in b7..b0 00143 _nr_cols = (_type & 0xFF); 00144 00145 // Rows encoded in b15..b8 00146 _nr_rows = ((_type >> 8) & 0xFF); 00147 00148 // Addressing mode encoded in b19..b16 00149 _addr_mode = _type & LCD_T_ADR_MSK; 00150 } 00151 00152 00153 /** Init the LCD Controller(s) 00154 * Clear display 00155 */ 00156 void TextLCD_Base::_init() { 00157 00158 // Select and configure second LCD controller when needed 00159 if(_type==LCD40x4) { 00160 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller 00161 _initCtrl(); // Init 2nd controller 00162 } 00163 00164 // Select and configure primary LCD controller 00165 _ctrl_idx=_LCDCtrl_0; // Select primary controller 00166 _initCtrl(); // Init primary controller 00167 00168 // Clear whole display and Reset Cursor location 00169 // Note: This will make sure that some 3-line displays that skip topline of a 4-line configuration 00170 // are cleared and init cursor correctly. 00171 cls(); 00172 } 00173 00174 /** Init the LCD controller 00175 * 4-bit mode, number of lines, fonttype, no cursor etc 00176 * 00177 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware 00178 */ 00179 void TextLCD_Base::_initCtrl() { 00180 int _bias_lines=0; // Set Bias and lines (Instr Set 1), temporary variable. 00181 int _lines=0; // Set lines (Ext Instr Set), temporary variable. 00182 00183 this->_setRS(false); // command mode 00184 00185 wait_ms(20); // Wait 20ms to ensure powered up 00186 00187 // The Controller could be in 8 bit mode (power-on reset) or in 4 bit mode (warm reboot) at this point. 00188 // Follow this procedure to make sure the Controller enters the correct state. The hardware interface 00189 // between the uP and the LCD can only write the 4 most significant bits (Most Significant Nibble, MSN). 00190 // In 4 bit mode the LCD expects the MSN first, followed by the LSN. 00191 // 00192 // Current state: 8 bit mode | 4 bit mode, MSN is next | 4 bit mode, LSN is next 00193 //------------------------------------------------------------------------------------------------- 00194 _writeNibble(0x3); // set 8 bit mode (MSN) and dummy LSN, | set 8 bit mode (MSN), | set dummy LSN, 00195 // remains in 8 bit mode | change to 8 bit mode | remains in 4 bit mode 00196 wait_ms(15); // 00197 00198 _writeNibble(0x3); // set 8 bit mode and dummy LSN, | set 8 bit mode and dummy LSN, | set 8bit mode (MSN), 00199 // remains in 8 bit mode | remains in 8 bit mode | remains in 4 bit mode 00200 wait_ms(15); // 00201 00202 _writeNibble(0x3); // set 8 bit mode and dummy LSN, | set 8 bit mode and dummy LSN, | set dummy LSN, 00203 // remains in 8 bit mode | remains in 8 bit mode | change to 8 bit mode 00204 wait_ms(15); // 00205 00206 // Controller is now in 8 bit mode 00207 00208 _writeNibble(0x2); // Change to 4-bit mode (MSN), the LSN is undefined dummy 00209 wait_us(40); // most instructions take 40us 00210 00211 // Display is now in 4-bit mode 00212 // Note: 4/8 bit mode is ignored for most native SPI and I2C devices. They dont use the parallel bus. 00213 // However, _writeNibble() method is void anyway for native SPI and I2C devices. 00214 00215 // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc 00216 switch (_ctrl) { 00217 00218 case KS0078: 00219 // Initialise Display configuration 00220 switch (_type) { 00221 case LCD8x1: //8x1 is a regular 1 line display 00222 case LCD8x2B: //8x2B is a special case of 16x1 00223 // case LCD12x1: 00224 case LCD16x1: 00225 // case LCD20x1: 00226 case LCD24x1: 00227 _function = 0x02; // Function set 001 DL N RE(0) DH REV (Std Regs) 00228 // DL=0 (4 bits bus) 00229 // N=0 (1 line mode), N=1 (2 line mode) 00230 // RE=0 (Dis. Extended Regs, special mode for KS0078) 00231 // DH=1 (Disp shift enable, special mode for KS0078) 00232 // REV=0 (Reverse normal, special mode for KS0078) 00233 00234 _function_1 = 0x04; // Function set 001 DL N RE(1) BE 0 (Ext Regs) 00235 // DL=0 (4 bits bus) 00236 // N=0 (1 line mode), N=1 (2 line mode) 00237 // RE=1 (Ena Extended Regs, special mode for KS0078) 00238 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078) 00239 // 0 00240 00241 _function_x = 0x00; // Ext Function set 0000 1 FW BW NW (Ext Regs) 00242 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078) 00243 break; 00244 00245 // case LCD12x3D: // Special mode for KS0078 and PCF21XX 00246 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX 00247 // case LCD12x4D: // Special mode for KS0078 and PCF21XX 00248 // case LCD16x3D: // Special mode for KS0078 00249 // case LCD16x4D: // Special mode for KS0078 00250 // case LCD24x3D: // Special mode for KS0078 00251 // case LCD24x3D1: // Special mode for KS0078 00252 case LCD24x4D: // Special mode for KS0078 00253 _function = 0x02; // Function set 001 DL N RE(0) DH REV (Std Regs) 00254 // DL=0 (4 bits bus) 00255 // N=0 (dont care for 4 line mode) 00256 // RE=0 (Dis. Extended Regs, special mode for KS0078) 00257 // DH=1 (Disp shift enable, special mode for KS0078) 00258 // REV=0 (Reverse normal, special mode for KS0078) 00259 00260 _function_1 = 0x04; // Function set 001 DL N RE(1) BE 0 (Ext Regs) 00261 // DL=0 (4 bits bus) 00262 // N=0 (1 line mode), N=1 (2 line mode) 00263 // RE=1 (Ena Extended Regs, special mode for KS0078) 00264 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078) 00265 // 0 00266 00267 _function_x = 0x01; // Ext Function set 0000 1 FW BW NW (Ext Regs) 00268 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078) 00269 break; 00270 00271 case LCD16x3G: // Special mode for ST7036 00272 error("Error: LCD Controller type does not support this Display type\n\r"); 00273 break; 00274 00275 default: 00276 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4) 00277 _function = 0x0A; // Function set 001 DL N RE(0) DH REV (Std Regs) 00278 // DL=0 (4 bits bus) 00279 // N=1 (1 line mode), N=1 (2 line mode) 00280 // RE=0 (Dis. Extended Regs, special mode for KS0078) 00281 // DH=1 (Disp shift enable, special mode for KS0078) 00282 // REV=0 (Reverse normal, special mode for KS0078) 00283 00284 _function_1 = 0x0C; // Function set 001 DL N RE(1) BE 0 (Ext Regs) 00285 // DL=0 (4 bits bus) 00286 // N=1 (1 line mode), N=1 (2 line mode) 00287 // RE=1 (Ena Extended Regs, special mode for KS0078) 00288 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078) 00289 // 0 00290 00291 _function_x = 0x00; // Ext Function set 0000 1 FW BW NW (Ext Regs) 00292 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078) 00293 break; 00294 } // switch type 00295 00296 // init special features 00297 _writeCommand(0x20 | _function_1);// Function set 001 DL N RE(1) BE 0 (Ext Regs) 00298 // DL=0 (4 bits bus), DL=1 (8 bits mode) 00299 // N=0 (1 line mode), N=1 (2 line mode) 00300 // RE=1 (Ena Extended Regs, special mode for KS0078) 00301 // BE=0 (Blink Enable/Disable, CG/SEG RAM, special mode for KS0078) 00302 // 0 00303 00304 _writeCommand(0x08 | _function_x); // Ext Function set 0000 1 FW BW NW (Ext Regs) 00305 // FW=0 (5-dot font, special mode for KS0078) 00306 // BW=0 (Cur BW invert disable, special mode for KS0078) 00307 // NW=0 (1,2 Line), NW=1 (4 line, special mode for KS0078) 00308 00309 _writeCommand(0x10); // Scroll/Shift set 0001 DS/HS4 DS/HS3 DS/HS2 DS/HS1 (Ext Regs) 00310 // Dotscroll/Display shift enable (Special mode for KS0078) 00311 00312 _writeCommand(0x80); // Scroll Quantity set 1 0 SQ5 SQ4 SQ3 SQ2 SQ1 SQ0 (Ext Regs) 00313 // Scroll quantity (Special mode for KS0078) 00314 00315 _writeCommand(0x20 | _function); // Function set 001 DL N RE(0) DH REV (Std Regs) 00316 // DL=0 (4 bits bus), DL=1 (8 bits mode) 00317 // N=0 (1 line mode), N=1 (2 line mode) 00318 // RE=0 (Dis. Extended Regs, special mode for KS0078) 00319 // DH=1 (Disp shift enable/disable, special mode for KS0078) 00320 // REV=0 (Reverse/Normal, special mode for KS0078) 00321 break; // case KS0078 Controller 00322 00323 case ST7032_3V3: 00324 // ST7032 controller: Initialise Voltage booster for VLCD. VDD=3V3 00325 case ST7032_5V: 00326 // ST7032 controller: Disable Voltage booster for VLCD. VDD=5V 00327 00328 // Initialise Display configuration 00329 switch (_type) { 00330 case LCD8x1: //8x1 is a regular 1 line display 00331 case LCD8x2B: //8x2B is a special case of 16x1 00332 // case LCD12x1: 00333 case LCD16x1: 00334 // case LCD20x1: 00335 case LCD24x1: 00336 _function = 0x00; // FUNCTION SET 0 0 1 DL=0 (4 bit), N=0 (1-line display mode), F=0 (5*7dot), 0, IS 00337 // Note: 4 bit mode is ignored for native SPI and I2C devices 00338 // Saved to allow switch between Instruction sets at later time 00339 break; 00340 00341 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00342 case LCD12x3D1: // Special mode for KS0078 and PCF21XX 00343 case LCD12x4D: // Special mode for KS0078 and PCF21XX 00344 case LCD16x3G: // Special mode for ST7036 00345 case LCD24x4D: // Special mode for KS0078 00346 error("Error: LCD Controller type does not support this Display type\n\r"); 00347 break; 00348 00349 default: 00350 // All other LCD types are initialised as 2 Line displays 00351 _function = 0x08; // FUNCTION SET 0 0 1 DL=0 (4 bit), N=1 (2-line display mode), F=0 (5*7dot), 0, IS 00352 // Note: 4 bit mode is ignored for native SPI and I2C devices 00353 // Saved to allow switch between Instruction sets at later time 00354 break; 00355 } // switch type 00356 00357 // init special features 00358 _writeCommand(0x20 | _function | 0x01); // Set function, 0 0 1 DL N F 0 IS=1 Select Instr Set = 1 00359 00360 _writeCommand(0x1C); // Internal OSC frequency adjustment Framefreq=183HZ, Bias will be 1/4 (Instr Set=1) 00361 00362 _contrast = LCD_ST7032_CONTRAST; 00363 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast Low bits, 0 1 1 1 C3 C2 C1 C0 (IS=1) 00364 00365 00366 if (_ctrl == ST7032_3V3) { 00367 _icon_power = 0x04; // Icon display off, Booster circuit is turned on (IS=1) 00368 // Saved to allow contrast change at later time 00369 } 00370 else { 00371 _icon_power = 0x00; // Icon display off, Booster circuit is turned off (IS=1) 00372 // Saved to allow contrast change at later time 00373 } 00374 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Icon, Booster and Contrast High bits, 0 1 0 1 Ion Bon C5 C4 (IS=1) 00375 wait_ms(10); // Wait 10ms to ensure powered up 00376 00377 _writeCommand(0x68 | (LCD_ST7032_RAB & 0x07)); // Voltage follower, 0 1 1 0 FOn=1, Ampl ratio Rab2=1, Rab1=0, Rab0=0 (IS=1) 00378 wait_ms(10); // Wait 10ms to ensure powered up 00379 00380 _writeCommand(0x20 | _function); // Select Instruction Set = 0 00381 00382 break; // case ST7032_3V3 Controller 00383 // case ST7032_5V Controller 00384 00385 case ST7036_3V3: 00386 // ST7036 controller: Initialise Voltage booster for VLCD. VDD=3V3 00387 // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G) 00388 case ST7036_5V: 00389 // ST7036 controller: Disable Voltage booster for VLCD. VDD=5V 00390 // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G) 00391 00392 // Initialise Display configuration 00393 switch (_type) { 00394 case LCD8x1: //8x1 is a regular 1 line display 00395 case LCD8x2B: //8x2D is a special case of 16x1 00396 // case LCD12x1: 00397 case LCD16x1: 00398 case LCD24x1: 00399 _function = 0x00; // Set function, 0 0 1 DL=0 (4-bit Databus), N=0 (1 Line), DH=0 (5x7font), IS2, IS1 (Select Instruction Set) 00400 // Note: 4 bit mode is ignored for native SPI and I2C devices 00401 // Saved to allow switch between Instruction sets at later time 00402 00403 _bias_lines = 0x04; // Bias: 1/5, 1 or 2-Lines LCD 00404 break; 00405 00406 // case LCD12x3G: // Special mode for ST7036 00407 case LCD16x3G: // Special mode for ST7036 00408 _function = 0x08; // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set) 00409 // Note: 4 bit mode is ignored for native SPI and I2C devices 00410 // Saved to allow switch between Instruction sets at later time 00411 00412 _bias_lines = 0x05; // Bias: 1/5, 3-Lines LCD 00413 break; 00414 00415 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX 00416 // case LCD16x3D1: // Special mode for SSD1803 00417 case LCD12x4D: // Special mode for PCF2116 00418 case LCD24x4D: // Special mode for KS0078 00419 error("Error: LCD Controller type does not support this Display type\n\r"); 00420 break; 00421 00422 default: 00423 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4) 00424 _function = 0x08; // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set) 00425 // Note: 4 bit mode is ignored for native SPI and I2C devices 00426 // Saved to allow switch between Instruction sets at later time 00427 00428 _bias_lines = 0x04; // Bias: 1/5, 1 or 2-Lines LCD 00429 break; 00430 } // switch type 00431 00432 00433 // init special features 00434 _writeCommand(0x20 | _function | 0x01); // Set function, IS2,IS1 = 01 (Select Instr Set = 1) 00435 _writeCommand(0x10 | _bias_lines); // Set Bias and 1,2 or 3 lines (Instr Set 1) 00436 00437 _contrast = LCD_ST7036_CONTRAST; 00438 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast, 0 1 1 1 C3 C2 C1 C0 (Instr Set 1) 00439 00440 if (_ctrl == ST7036_3V3) { 00441 _icon_power = 0x04; // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=1 C5 C4 (Instr Set 1) 00442 // Saved to allow contrast change at later time 00443 } 00444 else { 00445 _icon_power = 0x00; // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=0 C5 C4 (Instr Set 1) 00446 } 00447 00448 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Contrast C5, C4 (Instr Set 1) 00449 wait_ms(10); // Wait 10ms to ensure powered up 00450 00451 _writeCommand(0x68 | (LCD_ST7036_RAB & 0x07)); // Voltagefollower On = 1, Ampl ratio Rab2, Rab1, Rab0 = 1 0 1 (Instr Set 1) 00452 wait_ms(10); // Wait 10ms to ensure powered up 00453 00454 _writeCommand(0x20 | _function); // Set function, IS2,IS1 = 00 (Select Instruction Set = 0) 00455 00456 break; // case ST7036_3V3 Controller 00457 // case ST7036_5V Controller 00458 00459 case SSD1803_3V3: 00460 // SSD1803 controller: Initialise Voltage booster for VLCD. VDD=3V3 00461 // Note: supports 1,2, 3 or 4 lines 00462 // case SSD1803_5V: 00463 // SSD1803 controller: No Voltage booster for VLCD. VDD=5V 00464 00465 // Initialise Display configuration 00466 switch (_type) { 00467 case LCD8x1: //8x1 is a regular 1 line display 00468 case LCD8x2B: //8x2D is a special case of 16x1 00469 // case LCD12x1: 00470 case LCD16x1: 00471 case LCD24x1: 00472 _function = 0x00; // Set function 0 0 1 DL N DH RE(0) IS 00473 // Saved to allow switch between Instruction sets at later time 00474 // DL=0 4-bit Databus, 00475 // Note: 4 bit mode is ignored for native SPI and I2C devices 00476 // N=0 1 Line / 3 Line 00477 // DH=0 Double Height disable 00478 // IS=0 00479 00480 _function_1 = 0x02; // Set function, 0 0 1 DL N BE RE(1) REV 00481 // Saved to allow switch between Instruction sets at later time 00482 // DL=0 4-bit Databus, 00483 // Note: 4 bit mode is ignored for native SPI and I2C devices 00484 // N=0 1 Line / 3 Line 00485 // BE=0 Blink Enable off, special feature of SSD1803 00486 // REV=0 Reverse off, special feature of SSD1803 00487 00488 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00489 // NW=0 1-Line LCD (N=0) 00490 break; 00491 00492 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00493 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX 00494 case LCD16x3D: // Special mode for KS0078 00495 // case LCD16x3D1: // Special mode for SSD1803 00496 // case LCD20x3D: // Special mode for SSD1803 00497 _function = 0x00; // Set function 0 0 1 DL N DH RE(0) IS 00498 // Saved to allow switch between Instruction sets at later time 00499 // DL=0 4-bit Databus, 00500 // Note: 4 bit mode is ignored for native SPI and I2C devices 00501 // N=0 1 Line / 3 Line 00502 // DH=0 Double Height disable 00503 // IS=0 00504 00505 _function_1 = 0x02; // Set function, 0 0 1 DL N BE RE(1) REV 00506 // Saved to allow switch between Instruction sets at later time 00507 // DL=0 4-bit Databus, 00508 // Note: 4 bit mode is ignored for native SPI and I2C devices 00509 // N=0 1 Line / 3 Line 00510 // BE=0 Blink Enable off, special feature of SSD1803 00511 // REV=0 Reverse off, special feature of SSD1803 00512 00513 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00514 // NW=1 3-Line LCD (N=0) 00515 break; 00516 00517 case LCD20x4D: // Special mode for SSD1803 00518 _function = 0x08; // Set function 0 0 1 DL N DH RE(0) IS 00519 // Saved to allow switch between Instruction sets at later time 00520 // DL=0 4-bit Databus, 00521 // Note: 4 bit mode is ignored for native SPI and I2C devices 00522 // N=1 4 Line 00523 // DH=0 Double Height disable 00524 // IS=0 00525 00526 _function_1 = 0x0A; // Set function, 0 0 1 DL N BE RE(1) REV 00527 // Saved to allow switch between Instruction sets at later time 00528 // DL=0 4-bit Databus, 00529 // Note: 4 bit mode is ignored for native SPI and I2C devices 00530 // N=1 4 Line 00531 // BE=0 Blink Enable off, special feature of SSD1803 00532 // REV=0 Reverse off, special feature of SSD1803 00533 00534 _lines = 0x01; // Ext function set 0 0 0 0 1 FW BW NW 00535 // NW=1 4-Line LCD (N=1) 00536 break; 00537 00538 case LCD16x3G: // Special mode for ST7036 00539 case LCD24x4D: // Special mode for KS0078 00540 error("Error: LCD Controller type does not support this Display type\n\r"); 00541 break; 00542 00543 default: 00544 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4) 00545 _function = 0x08; // Set function 0 0 1 DL N DH RE(0) IS 00546 // Saved to allow switch between Instruction sets at later time 00547 // DL=0 4-bit Databus, 00548 // Note: 4 bit mode is ignored for native SPI and I2C devices 00549 // N=1 2 line / 4 Line 00550 // DH=0 Double Height disable 00551 // IS=0 00552 00553 _function_1 = 0x0A; // Set function, 0 0 1 DL N BE RE(1) REV 00554 // Saved to allow switch between Instruction sets at later time 00555 // DL=0 4-bit Databus, 00556 // Note: 4 bit mode is ignored for native SPI and I2C devices 00557 // N=1 2 line / 4 Line 00558 // BE=0 Blink Enable off, special feature of SSD1803 00559 // REV=0 Reverse off, special feature of SSD1803 00560 00561 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00562 // NW=0 2-Line LCD (N=1) 00563 break; 00564 } // switch type 00565 00566 00567 // init special features 00568 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 DL N BE RE(1) REV 00569 // Select Extended Instruction Set 00570 00571 _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) 00572 // _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) 00573 wait_ms(5); // Wait to ensure completion or SSD1803 fails to set Top/Bottom after reset.. 00574 00575 _writeCommand(0x08 | _lines); // Set ext function 0 0 0 0 1 FW BW NW 1,2,3 or 4 lines (Ext Instr Set) 00576 00577 _writeCommand(0x10); // Double Height and Bias, 0 0 0 1 UD2=0, UD1=0, BS1=0 Bias 1/5, DH=0 (Ext Instr Set) 00578 00579 // _writeCommand(0x76); // Set TC Control, 0 1 1 1 0 1 1 0 (Ext Instr Set) 00580 // _writeData(0x02); // Set TC data, 0 0 0 0 0 TC2,TC1,TC0 = 0 1 0 (Ext Instr Set) 00581 00582 _writeCommand(0x20 | _function | 0x01); // Set function, 0 0 1 DL N DH RE(0) IS=1 Select Instruction Set 1 00583 // Select Std Instr set, Select IS=1 00584 00585 _contrast = LCD_SSD1_CONTRAST; 00586 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast 0 1 1 1 C3, C2, C1, C0 (Instr Set 1) 00587 00588 _icon_power = 0x04; // Icon off, Booster on (Instr Set 1) 00589 // Saved to allow contrast change at later time 00590 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Power, Icon and Contrast, 0 1 0 1 Ion Bon C5 C4 (Instr Set 1) 00591 wait_ms(10); // Wait 10ms to ensure powered up 00592 00593 _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) 00594 wait_ms(10); // Wait 10ms to ensure powered up 00595 00596 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 DL N BE RE(1) REV 00597 // Select Extended Instruction Set 1 00598 _writeCommand(0x10); // Shift/Scroll enable, 0 0 0 1 DS4/HS4 DS3/HS3 DS2/HS2 DS1/HS1 (Ext Instr Set 1) 00599 00600 00601 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 00602 // Select Std Instr set, Select IS=0 00603 00604 break; // case SSD1803 Controller 00605 00606 00607 // Note1: The PCF21XX family of controllers has several types that dont have an onboard voltage generator for V-LCD. 00608 // You must supply this LCD voltage externally and not try to enable VGen. 00609 // Note2: The early versions of PCF2116 controllers (eg PCF2116C) can not generate sufficiently negative voltage for the LCD at a VDD of 3V3. 00610 // You must supply this voltage externally and not enable VGen or you must use a higher VDD (e.g. 5V) and enable VGen. 00611 // More recent versions of the controller (eg PCF2116K) have an improved VGen that will work with 3V3. 00612 // 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 00613 // contrast control similar to that of pin 3 on the standard 14pin LCD module connector. 00614 // You can disable VGen by connecting Vo to VDD. VLCD will then be used directly as LCD voltage. 00615 // 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. 00616 // 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. 00617 // Note5: See datasheet, members of the PCF21XX family support different numbers of rows/columns. Not all can support 3 or 4 rows. 00618 // 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.. 00619 00620 case PCF2113_3V3: 00621 // PCF2113 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast. 00622 // Initialise Display configuration 00623 switch (_type) { 00624 // case LCD12x1: 00625 // _function = 0x02; // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=0 1-line/12 chars display mode, SL=1, IS=0 00626 // Note: 4 bit mode is ignored for I2C mode 00627 case LCD24x1: 00628 _function = 0x00; // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=0 1-line/24 chars display mode, SL=0, IS=0 00629 // Note: 4 bit mode is ignored for I2C mode 00630 break; 00631 00632 //Tested OK for PCF2113 00633 case LCD12x2: 00634 _function = 0x04; // FUNCTION SET 0 0 1 DL=0 4 bit, 0, M=1 2-line/12 chars display mode, SL=0, IS=0 00635 break; 00636 00637 default: 00638 error("Error: LCD Controller type does not support this Display type\n\r"); 00639 break; 00640 00641 } // switch type 00642 00643 // Init special features 00644 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instr Set = 1 00645 00646 _writeCommand(0x04); // Display Conf Set 0000 0, 1, P=0, Q=0 (Instr. Set 1) 00647 _writeCommand(0x10); // Temp Compensation Set 0001 0, 0, TC1=0, TC2=0 (Instr. Set 1) 00648 // _writeCommand(0x42); // HV GEN 0100 S1=1, S2=0 (2x multiplier) (Instr. Set 1) 00649 _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03)); // HV Gen 0100 S1=1, S2=0 (2x multiplier) (Instr. Set 1) 00650 00651 _contrast = LCD_PCF2_CONTRAST; 00652 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) 1, V=0, VA=contrast 00653 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) 1, V=1, VB=contrast 00654 wait_ms(10); // Wait 10ms to ensure powered up 00655 00656 _writeCommand(0x02); // Screen Config 0000 001, L=0 (Instr. Set 1) 00657 _writeCommand(0x08); // ICON Conf 0000 1, IM=0 (Char mode), IB=0 (no icon blink) DM=0 (no direct mode) (Instr. Set 1) 00658 00659 _writeCommand(0x20 | _function); // Set function, Select Instr Set = 0 00660 00661 break; // case PCF2113_3V3 Controller 00662 00663 00664 // case PCF2113_5V: 00665 // PCF2113 controller: No Voltage generator for VLCD. VDD=5V. Contrast voltage controlled by VA or VB. 00666 //@TODO 00667 00668 00669 case PCF2116_3V3: 00670 // PCF2116 controller: Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage. 00671 // Initialise Display configuration 00672 switch (_type) { 00673 // case LCD12x1: 00674 // case LCD12x2: 00675 case LCD24x1: 00676 _writeCommand(0x22); //FUNCTION SET 4 bit, N/M=0 1-line/24 chars display mode, G=1 Vgen on 00677 //Note: 4 bit mode is ignored for I2C mode 00678 wait_ms(10); // Wait 10ms to ensure powered up 00679 break; 00680 00681 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00682 case LCD12x3D1: // Special mode for PCF21XX 00683 case LCD12x4D: // Special mode for PCF21XX: 00684 _writeCommand(0x2E); //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode, G=1 VGen on 00685 //Note: 4 bit mode is ignored for I2C mode 00686 wait_ms(10); // Wait 10ms to ensure powered up 00687 break; 00688 00689 case LCD24x2: 00690 _writeCommand(0x2A); //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode, G=1 VGen on 00691 //Note: 4 bit mode is ignored for I2C mode 00692 wait_ms(10); // Wait 10ms to ensure powered up 00693 break; 00694 00695 default: 00696 error("Error: LCD Controller type does not support this Display type\n\r"); 00697 break; 00698 00699 } // switch type 00700 00701 break; // case PCF2116_3V3 Controller 00702 00703 00704 //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 00705 //@TODO 00706 case PCF2116_5V: 00707 // PCF2116 controller: No Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage. 00708 // Initialise Display configuration 00709 switch (_type) { 00710 // case LCD12x1: 00711 // case LCD12x2: 00712 // case LCD24x1: 00713 // _writeCommand(0x20); //FUNCTION SET 4 bit, N/M=0 1-line/24 chars display mode 00714 //Note: 4 bit mode is ignored for I2C mode 00715 // wait_ms(10); // Wait 10ms to ensure powered up 00716 // break; 00717 00718 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00719 case LCD12x3D1: // Special mode for PCF21XX 00720 case LCD12x4D: // Special mode for PCF21XX: 00721 // _writeCommand(0x34); //FUNCTION SET 8 bit, N=0/M=1 4-line/12 chars display mode OK 00722 // _writeCommand(0x24); //FUNCTION SET 4 bit, N=0/M=1 4-line/12 chars display mode OK 00723 _writeCommand(0x2C); //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode OK 00724 //Note: 4 bit mode is ignored for I2C mode 00725 wait_ms(10); // Wait 10ms to ensure powered up 00726 break; 00727 00728 // case LCD24x2: 00729 // _writeCommand(0x28); //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode 00730 //Note: 4 bit mode is ignored for I2C mode 00731 // wait_ms(10); // Wait 10ms to ensure powered up 00732 // break; 00733 00734 default: 00735 error("Error: LCD Controller type does not support this Display type\n\r"); 00736 break; 00737 00738 } // switch type 00739 00740 break; // case PCF2116_5V Controller 00741 00742 case PCF2119_3V3: 00743 // PCF2119 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast. 00744 // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters. 00745 // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00. 00746 00747 //POR or Hardware Reset should be applied 00748 wait_ms(10); // Wait 10ms to ensure powered up 00749 00750 // Initialise Display configuration 00751 switch (_type) { 00752 case LCD8x1: 00753 // case LCD12x1: 00754 case LCD16x1: 00755 _function = 0x02; // FUNCTION SET DL=0 4 bit, 0 , M=0 1-line/16 chars display mode, SL=1 00756 // Note: 4 bit mode is ignored for I2C mode 00757 break; 00758 00759 case LCD24x1: 00760 // case LCD32x1: 00761 _function = 0x00; // FUNCTION SET DL=0 4 bit, 0 , M=0 1-line/32 chars display mode, SL=0 00762 // Note: 4 bit mode is ignored for I2C mode 00763 break; 00764 00765 case LCD8x2: 00766 // case LCD12x2: 00767 case LCD16x2: 00768 _function = 0x04; // FUNCTION SET DL=0 4 bit, 0, M=1 2-line/16 chars display mode, SL=0 00769 // Note: 4 bit mode is ignored for I2C mode 00770 break; 00771 00772 default: 00773 error("Error: LCD Controller type does not support this Display type\n\r"); 00774 break; 00775 00776 } // switch type 00777 00778 // Init special features 00779 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instruction Set = 1 00780 00781 _writeCommand(0x04); // DISP CONF SET (Instr. Set 1) 0000, 0, 1, P=0, Q=0 00782 _writeCommand(0x10); // TEMP CTRL SET (Instr. Set 1) 0001, 0, 0, TC1=0, TC2=0 00783 // _writeCommand(0x42); // HV GEN (Instr. Set 1) 0100, 0, 0, S1=1, S2=0 (2x multiplier) 00784 _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03)); // HV GEN (Instr. Set 1) 0100, 0, 0, S1=1, S2=0 (2x multiplier) 00785 00786 _contrast = LCD_PCF2_CONTRAST; 00787 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=0, VA=contrast 00788 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=1, VB=contrast 00789 wait_ms(10); // Wait 10ms to ensure powered up 00790 00791 _writeCommand(0x02); // SCRN CONF (Instr. Set 1) L=0 00792 _writeCommand(0x08); // ICON CONF (Instr. Set 1) IM=0 (Char mode) IB=0 (no icon blink) DM=0 (no direct mode) 00793 00794 _writeCommand(0x20 | _function); // Select Instruction Set = 0 00795 00796 break; // case PCF2119_3V3 Controller 00797 00798 // case PCF2119_5V: 00799 // PCF2119 controller: No Voltage booster for VLCD. VDD=3V3. VA and VB control contrast. 00800 // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters. 00801 // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00. 00802 //@TODO 00803 00804 case WS0010: 00805 // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs 00806 // Note1: Identical to RS0010 00807 // Note2: supports 1 or 2 lines (and 16x100 graphics) 00808 // supports 4 fonts (English/Japanese (default), Western European-I, English/Russian, Western European-II) 00809 // Cursor/Disp shift set 0001 SC RL 0 0 00810 // 00811 // Mode and Power set 0001 GC PWR 1 1 00812 // GC = 0 (Graph Mode=1, Char Mode=0) 00813 // PWR = 1 (DC/DC On/Off) 00814 00815 //@Todo: This may be needed to enable a warm reboot 00816 //_writeCommand(0x13); // Char mode, DC/DC off 00817 //wait_ms(10); // Wait 10ms to ensure powered down 00818 _writeCommand(0x17); // Char mode, DC/DC on 00819 wait_ms(10); // Wait 10ms to ensure powered up 00820 00821 // Initialise Display configuration 00822 switch (_type) { 00823 case LCD8x1: //8x1 is a regular 1 line display 00824 case LCD8x2B: //8x2B is a special case of 16x1 00825 // case LCD12x1: 00826 case LCD16x1: 00827 case LCD24x1: 00828 _writeCommand(0x20); // Function set 001 DL N F FT1 FT0 00829 // DL=0 (4 bits bus) 00830 // N=0 (1 line) 00831 // F=0 (5x7 dots font) 00832 // FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2 00833 break; 00834 00835 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00836 case LCD12x3D1: // Special mode for PCF21XX 00837 case LCD12x4D: // Special mode for PCF21XX: 00838 case LCD16x3G: // Special mode for ST7036 00839 case LCD24x4D: // Special mode for KS0078 00840 error("Error: LCD Controller type does not support this Display type\n\r"); 00841 break; 00842 00843 default: 00844 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4) 00845 _writeCommand(0x28); // Function set 001 DL N F FT1 FT0 00846 // DL=0 (4 bits bus) 00847 // N=1 (2 lines) 00848 // F=0 (5x7 dots font) 00849 // FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2 00850 00851 break; 00852 } // switch type 00853 00854 break; // case WS0010 Controller 00855 00856 00857 case US2066_3V3: 00858 // US2066/SSD1311 OLED controller, Initialise for VDD=3V3 00859 // Note: supports 1,2, 3 or 4 lines 00860 // case USS2066_5V: 00861 // US2066 controller, VDD=5V 00862 00863 // Initialise Display configuration 00864 switch (_type) { 00865 case LCD8x1: //8x1 is a regular 1 line display 00866 case LCD8x2B: //8x2D is a special case of 16x1 00867 // case LCD12x1: 00868 case LCD16x1: 00869 // case LCD20x1: 00870 _function = 0x00; // Set function 0 0 1 X N DH RE(0) IS 00871 // Saved to allow switch between Instruction sets at later time 00872 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00873 // N=0 1 Line / 3 Line 00874 // DH=0 Double Height disable 00875 // IS=0 00876 00877 _function_1 = 0x02; // Set function, 0 0 1 X N BE RE(1) REV 00878 // Saved to allow switch between Instruction sets at later time 00879 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00880 // N=0 1 Line / 3 Line 00881 // BE=0 Blink Enable off, special feature of SSD1803, US2066 00882 // REV=0 Reverse off, special feature of SSD1803, US2066 00883 00884 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00885 // NW=0 1-Line LCD (N=0) 00886 break; 00887 00888 case LCD16x1C: 00889 case LCD8x2: 00890 case LCD16x2: 00891 case LCD20x2: 00892 _function = 0x08; // Set function 0 0 1 X N DH RE(0) IS 00893 // Saved to allow switch between Instruction sets at later time 00894 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00895 // N=1 2 line / 4 Line 00896 // DH=0 Double Height disable 00897 // IS=0 00898 00899 _function_1 = 0x0A; // Set function, 0 0 1 X N BE RE(1) REV 00900 // Saved to allow switch between Instruction sets at later time 00901 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00902 // N=1 2 line / 4 Line 00903 // BE=0 Blink Enable off, special feature of SSD1803, US2066 00904 // REV=0 Reverse off, special feature of SSD1803, US2066 00905 00906 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00907 // NW=0 2-Line LCD (N=1) 00908 break; 00909 00910 case LCD12x3D: // Special mode for KS0078 and PCF21XX 00911 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX 00912 case LCD16x3D: // Special mode for KS0078, SSD1803 and US2066 00913 // case LCD16x3D1: // Special mode for SSD1803, US2066 00914 // case LCD20x3D: // Special mode for SSD1803, US2066 00915 _function = 0x00; // Set function 0 0 1 X N DH RE(0) IS 00916 // Saved to allow switch between Instruction sets at later time 00917 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00918 // N=0 1 Line / 3 Line 00919 // DH=0 Double Height disable 00920 // IS=0 00921 00922 _function_1 = 0x02; // Set function, 0 0 1 X N BE RE(1) REV 00923 // Saved to allow switch between Instruction sets at later time 00924 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00925 // N=0 1 Line / 3 Line 00926 // BE=0 Blink Enable off, special feature of SSD1803, US2066 00927 // REV=0 Reverse off, special feature of SSD1803, US2066 00928 00929 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW 00930 // NW=1 3-Line LCD (N=0) 00931 break; 00932 00933 case LCD20x4D: // Special mode for SSD1803, US2066 00934 _function = 0x08; // Set function 0 0 1 X N DH RE(0) IS 00935 // Saved to allow switch between Instruction sets at later time 00936 // DL=X bit is ignored for US2066. Uses hardwired pins instead 00937 // N=1 2 line / 4 Line 00938 // DH=0 Double Height disable 00939 // IS=0 00940 00941 _function_1 = 0x0A; // Set function, 0 0 1 DL N BE RE(1) REV 00942 // Saved to allow switch between Instruction sets at later time 00943 // DL=0 bit is ignored for US2066. Uses hardwired pins instead 00944 // N=1 2 line / 4 Line 00945 // BE=0 Blink Enable off, special feature of SSD1803, US2066 00946 // REV=0 Reverse off, special feature of SSD1803, US2066 00947 00948 _lines = 0x01; // Ext function set 0 0 0 0 1 FW BW NW 00949 // NW=1 4-Line LCD (N=1) 00950 break; 00951 00952 // case LCD24x1: 00953 // case LCD16x3G: // Special mode for ST7036 00954 // case LCD24x4D: // Special mode for KS0078 00955 default: 00956 error("Error: LCD Controller type does not support this Display type\n\r"); 00957 break; 00958 00959 } // switch type 00960 00961 00962 // init special features 00963 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 X N BE RE(1) REV 00964 // Select Extended Instruction Set 00965 00966 _writeCommand(0x71); // Function Select A: 0 1 1 1 0 0 0 1 (Ext Instr Set) 00967 _writeData(0x00); // Disable Internal VDD 00968 00969 _writeCommand(0x79); // Function Select OLED: 0 1 1 1 1 0 0 1 (Ext Instr Set) 00970 00971 _writeCommand(0xD5); // Display Clock Divide Ratio: 1 1 0 1 0 1 0 1 (Ext Instr Set, OLED Instr Set) 00972 _writeCommand(0x70); // Display Clock Divide Ratio value: 0 1 1 1 0 0 0 0 (Ext Instr Set, OLED Instr Set) 00973 00974 _writeCommand(0x78); // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set) 00975 00976 // _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) 00977 _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) 00978 00979 _writeCommand(0x08 | _lines); // Set ext function 0 0 0 0 1 FW BW NW 1,2,3 or 4 lines (Ext Instr Set) 00980 00981 // _writeCommand(0x1C); // Double Height and Bias, 0 0 0 1 UD2=1, UD1=1, X, DH=0 (Ext Instr Set) 00982 // // Default 00983 00984 _writeCommand(0x72); // Function Select B: 0 1 1 1 0 0 1 0 (Ext Instr Set) 00985 _writeData(0x01); // Select ROM A (CGRAM 8, CGROM 248) 00986 00987 _writeCommand(0x79); // Function Select OLED: 0 1 1 1 1 0 0 1 (Ext Instr Set) 00988 00989 _writeCommand(0xDA); // Set Segm Pins Config: 1 1 0 1 1 0 1 0 (Ext Instr Set, OLED) 00990 _writeCommand(0x10); // Set Segm Pins Config value: Altern Odd/Even, Disable Remap (Ext Instr Set, OLED) 00991 00992 _writeCommand(0xDC); // Function Select C: 1 1 0 1 1 1 0 0 (Ext Instr Set, OLED) 00993 // _writeCommand(0x00); // Set internal VSL, GPIO pin HiZ (always read low) 00994 _writeCommand(0x80); // Set external VSL, GPIO pin HiZ (always read low) 00995 00996 _contrast = LCD_US20_CONTRAST; 00997 _writeCommand(0x81); // Set Contrast Control: 1 0 0 0 0 0 0 1 (Ext Instr Set, OLED) 00998 _writeCommand((_contrast << 2) | 0x03); // Set Contrast Value: 8 bits, use 6 bits for compatibility 00999 01000 _writeCommand(0xD9); // Set Phase Length: 1 1 0 1 1 0 0 1 (Ext Instr Set, OLED) 01001 _writeCommand(0xF1); // Set Phase Length Value: 01002 01003 _writeCommand(0xDB); // Set VCOMH Deselect Lvl: 1 1 0 1 1 0 1 1 (Ext Instr Set, OLED) 01004 _writeCommand(0x30); // Set VCOMH Deselect Value: 0.83 x VCC 01005 01006 wait_ms(10); // Wait 10ms to ensure powered up 01007 01008 //Test Fade/Blinking. Hard Blink on/off, No fade in/out ?? 01009 // _writeCommand(0x23); // Set (Ext Instr Set, OLED) 01010 // _writeCommand(0x3F); // Set interval 128 frames 01011 //End Test Blinking 01012 01013 _writeCommand(0x78); // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set) 01014 01015 _writeCommand(0x20 | _function | 0x01); // Set function, 0 0 1 X N DH RE(0) IS=1 Select Instruction Set 1 01016 // Select Std Instr set, Select IS=1 01017 01018 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 X N BE RE(1) REV 01019 // Select Ext Instr Set, IS=1 01020 _writeCommand(0x10); // Shift/Scroll enable, 0 0 0 1 DS4/HS4 DS3/HS3 DS2/HS2 DS1/HS1 (Ext Instr Set, IS=1) 01021 01022 01023 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01024 // Select Std Instr set, Select IS=0 01025 01026 break; // case US2066/SSD1311 Controller 01027 01028 01029 default: 01030 // Devices fully compatible to HD44780 that do not use any DC/DC Voltage converters but external VLCD, no icons etc 01031 01032 // Initialise Display configuration 01033 switch (_type) { 01034 case LCD8x1: //8x1 is a regular 1 line display 01035 case LCD8x2B: //8x2B is a special case of 16x1 01036 // case LCD12x1: 01037 case LCD16x1: 01038 // case LCD20x1: 01039 case LCD24x1: 01040 // case LCD40x1: 01041 _function = 0x00; // Function set 001 DL N F - - 01042 // DL=0 (4 bits bus) 01043 // N=0 (1 line) 01044 // F=0 (5x7 dots font) 01045 _writeCommand(0x20 | _function); 01046 break; 01047 01048 case LCD12x3D: // Special mode for KS0078 and PCF21XX 01049 case LCD12x3D1: // Special mode for KS0078 and PCF21XX 01050 case LCD12x4D: // Special mode for KS0078 and PCF21XX: 01051 case LCD16x3D: // Special mode for KS0078 01052 // case LCD16x3D1: // Special mode for KS0078 01053 // case LCD24x3D: // Special mode for KS0078 01054 // case LCD24x3D1: // Special mode for KS0078 01055 case LCD24x4D: // Special mode for KS0078 01056 error("Error: LCD Controller type does not support this Display type\n\r"); 01057 break; 01058 01059 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4) 01060 default: 01061 _function = 0x08; // Function set 001 DL N F - - 01062 // DL=0 (4 bits bus) 01063 // Note: 4 bit mode is ignored for native SPI and I2C devices 01064 // N=1 (2 lines) 01065 // F=0 (5x7 dots font, only option for 2 line display) 01066 // - (Don't care) 01067 _writeCommand(0x20 | _function); 01068 break; 01069 } // switch type 01070 01071 break; // case default Controller 01072 01073 } // switch Controller specific initialisations 01074 01075 01076 // Controller general initialisations 01077 // _writeCommand(0x01); // cls, and set cursor to 0 01078 // wait_ms(10); // The CLS command takes 1.64 ms. 01079 // // Since we are not using the Busy flag, Lets be safe and take 10 ms 01080 01081 _writeCommand(0x02); // Return Home 01082 // Cursor Home, DDRAM Address to Origin 01083 01084 _writeCommand(0x06); // Entry Mode 0000 0 1 I/D S 01085 // Cursor Direction and Display Shift 01086 // I/D=1 (Cur incr) 01087 // S=0 (No display shift) 01088 01089 _writeCommand(0x14); // Cursor or Display shift 0001 S/C R/L x x 01090 // S/C=0 Cursor moves 01091 // R/L=1 Right 01092 // 01093 01094 // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B 01095 // // Display On, Cursor Off, Blink Off 01096 setCursor(CurOff_BlkOff); 01097 setMode(DispOn); 01098 } 01099 01100 01101 /** Clear the screen, Cursor home. 01102 */ 01103 void TextLCD_Base::cls() { 01104 01105 // Select and configure second LCD controller when needed 01106 if(_type==LCD40x4) { 01107 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller 01108 01109 // Second LCD controller Cursor always Off 01110 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff); 01111 01112 // Second LCD controller Clearscreen 01113 _writeCommand(0x01); // cls, and set cursor to 0 01114 wait_ms(10); // The CLS command takes 1.64 ms. 01115 // Since we are not using the Busy flag, Lets be safe and take 10 ms 01116 01117 _ctrl_idx=_LCDCtrl_0; // Select primary controller 01118 } 01119 01120 // Primary LCD controller Clearscreen 01121 _writeCommand(0x01); // cls, and set cursor to 0 01122 wait_ms(10); // The CLS command takes 1.64 ms. 01123 // Since we are not using the Busy flag, Lets be safe and take 10 ms 01124 01125 // Restore cursormode on primary LCD controller when needed 01126 if(_type==LCD40x4) { 01127 _setCursorAndDisplayMode(_currentMode,_currentCursor); 01128 } 01129 01130 setAddress(0, 0); // Reset Cursor location 01131 // Note: This is needed because some displays (eg PCF21XX) don't use line 0 in the '3 Line' mode. 01132 } 01133 01134 /** Locate cursor to a screen column and row 01135 * 01136 * @param column The horizontal position from the left, indexed from 0 01137 * @param row The vertical position from the top, indexed from 0 01138 */ 01139 void TextLCD_Base::locate(int column, int row) { 01140 01141 // setAddress() does all the heavy lifting: 01142 // check column and row sanity, 01143 // switch controllers for LCD40x4 if needed 01144 // switch cursor for LCD40x4 if needed 01145 // set the new memory address to show cursor at correct location 01146 setAddress(column, row); 01147 } 01148 01149 01150 /** Write a single character (Stream implementation) 01151 */ 01152 int TextLCD_Base::_putc(int value) { 01153 int addr; 01154 01155 if (value == '\n') { 01156 //No character to write 01157 01158 //Update Cursor 01159 _column = 0; 01160 _row++; 01161 if (_row >= rows()) { 01162 _row = 0; 01163 } 01164 } 01165 else { 01166 //Character to write 01167 _writeData(value); 01168 01169 //Update Cursor 01170 _column++; 01171 if (_column >= columns()) { 01172 _column = 0; 01173 _row++; 01174 if (_row >= rows()) { 01175 _row = 0; 01176 } 01177 } 01178 } //else 01179 01180 //Set next memoryaddress, make sure cursor blinks at next location 01181 addr = getAddress(_column, _row); 01182 _writeCommand(0x80 | addr); 01183 01184 return value; 01185 } 01186 01187 01188 // get a single character (Stream implementation) 01189 int TextLCD_Base::_getc() { 01190 return -1; 01191 } 01192 01193 01194 // Write a nibble using the 4-bit interface 01195 void TextLCD_Base::_writeNibble(int value) { 01196 01197 // Enable is Low 01198 this->_setEnable(true); 01199 this->_setData(value & 0x0F); // Low nibble 01200 wait_us(1); // Data setup time 01201 this->_setEnable(false); 01202 wait_us(1); // Datahold time 01203 01204 // Enable is Low 01205 } 01206 01207 // Write a byte using the 4-bit interface 01208 void TextLCD_Base::_writeByte(int value) { 01209 01210 // Enable is Low 01211 this->_setEnable(true); 01212 this->_setData(value >> 4); // High nibble 01213 wait_us(1); // Data setup time 01214 this->_setEnable(false); 01215 wait_us(1); // Data hold time 01216 01217 this->_setEnable(true); 01218 this->_setData(value >> 0); // Low nibble 01219 wait_us(1); // Data setup time 01220 this->_setEnable(false); 01221 wait_us(1); // Datahold time 01222 01223 // Enable is Low 01224 } 01225 01226 // Write a command byte to the LCD controller 01227 void TextLCD_Base::_writeCommand(int command) { 01228 01229 this->_setRS(false); 01230 wait_us(1); // Data setup time for RS 01231 01232 this->_writeByte(command); 01233 wait_us(40); // most instructions take 40us 01234 } 01235 01236 // Write a data byte to the LCD controller 01237 void TextLCD_Base::_writeData(int data) { 01238 01239 this->_setRS(true); 01240 wait_us(1); // Data setup time for RS 01241 01242 this->_writeByte(data); 01243 wait_us(40); // data writes take 40us 01244 } 01245 01246 01247 // This replaces the original _address() method. 01248 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80. 01249 // Left it in here for compatibility with older code. New applications should use getAddress() instead. 01250 int TextLCD_Base::_address(int column, int row) { 01251 return 0x80 | getAddress(column, row); 01252 } 01253 01254 01255 // This is new method to return the memory address based on row, column and displaytype. 01256 // 01257 /** Return the memoryaddress of screen column and row location 01258 * 01259 * @param column The horizontal position from the left, indexed from 0 01260 * @param row The vertical position from the top, indexed from 0 01261 * @param return The memoryaddress of screen column and row location 01262 * 01263 */ 01264 int TextLCD_Base::getAddress(int column, int row) { 01265 01266 switch (_addr_mode) { 01267 01268 case LCD_T_A: 01269 //Default addressing mode for 1, 2 and 4 rows (except 40x4) 01270 //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. 01271 //Displays top rows when less than four are used. 01272 switch (row) { 01273 case 0: 01274 return 0x00 + column; 01275 case 1: 01276 return 0x40 + column; 01277 case 2: 01278 return 0x00 + _nr_cols + column; 01279 case 3: 01280 return 0x40 + _nr_cols + column; 01281 // Should never get here. 01282 default: 01283 return 0x00; 01284 } 01285 01286 case LCD_T_B: 01287 // LCD8x2B is a special layout of LCD16x1 01288 if (row==0) 01289 return 0x00 + column; 01290 else 01291 // return _nr_cols + column; 01292 return 0x08 + column; 01293 01294 case LCD_T_C: 01295 // LCD16x1C is a special layout of LCD8x2 01296 // LCD32x1C is a special layout of LCD16x2 01297 // LCD40x1C is a special layout of LCD20x2 01298 #if(0) 01299 if (column < 8) 01300 return 0x00 + column; 01301 else 01302 return 0x40 + (column - 8); 01303 #else 01304 if (column < (_nr_cols >> 1)) 01305 return 0x00 + column; 01306 else 01307 return 0x40 + (column - (_nr_cols >> 1)); 01308 #endif 01309 01310 // Not sure about this one, seems wrong. 01311 // Left in for compatibility with original library 01312 // case LCD16x2B: 01313 // return 0x00 + (row * 40) + column; 01314 01315 case LCD_T_D: 01316 //Alternate addressing mode for 3 and 4 row displays (except 40x4). Used by PCF21XX, KS0078, SSD1803 01317 //The 4 available rows start at a hardcoded address. 01318 //Displays top rows when less than four are used. 01319 switch (row) { 01320 case 0: 01321 return 0x00 + column; 01322 case 1: 01323 return 0x20 + column; 01324 case 2: 01325 return 0x40 + column; 01326 case 3: 01327 return 0x60 + column; 01328 // Should never get here. 01329 default: 01330 return 0x00; 01331 } 01332 01333 case LCD_T_D1: 01334 //Alternate addressing mode for 3 row displays. Used by PCF21XX, KS0078, SSD1803 01335 //The 4 available rows start at a hardcoded address. 01336 //Skips top row of 4 row display and starts display at row 1 01337 switch (row) { 01338 case 0: 01339 return 0x20 + column; 01340 case 1: 01341 return 0x40 + column; 01342 case 2: 01343 return 0x60 + column; 01344 // Should never get here. 01345 default: 01346 return 0x00; 01347 } 01348 01349 case LCD_T_E: 01350 // LCD40x4 is a special case since it has 2 controllers. 01351 // Each controller is configured as 40x2 (Type A) 01352 if (row<2) { 01353 // Test to see if we need to switch between controllers 01354 if (_ctrl_idx != _LCDCtrl_0) { 01355 01356 // Second LCD controller Cursor Off 01357 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff); 01358 01359 // Select primary controller 01360 _ctrl_idx = _LCDCtrl_0; 01361 01362 // Restore cursormode on primary LCD controller 01363 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01364 } 01365 01366 return 0x00 + (row * 0x40) + column; 01367 } 01368 else { 01369 01370 // Test to see if we need to switch between controllers 01371 if (_ctrl_idx != _LCDCtrl_1) { 01372 // Primary LCD controller Cursor Off 01373 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff); 01374 01375 // Select secondary controller 01376 _ctrl_idx = _LCDCtrl_1; 01377 01378 // Restore cursormode on secondary LCD controller 01379 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01380 } 01381 01382 return 0x00 + ((row-2) * 0x40) + column; 01383 } 01384 01385 case LCD_T_F: 01386 //Alternate addressing mode for 3 row displays. 01387 //The first half of 3rd row continues from 1st row, the second half continues from 2nd row. 01388 switch (row) { 01389 case 0: 01390 return 0x00 + column; 01391 case 1: 01392 return 0x40 + column; 01393 case 2: 01394 if (column < (_nr_cols >> 1)) // check first or second half of line 01395 return (0x00 + _nr_cols + column); 01396 else 01397 return (0x40 + _nr_cols + (column - (_nr_cols >> 1))); 01398 // Should never get here. 01399 default: 01400 return 0x00; 01401 } 01402 01403 case LCD_T_G: 01404 //Alternate addressing mode for 3 row displays. Used by ST7036 01405 switch (row) { 01406 case 0: 01407 return 0x00 + column; 01408 case 1: 01409 return 0x10 + column; 01410 case 2: 01411 return 0x20 + column; 01412 // Should never get here. 01413 default: 01414 return 0x00; 01415 } 01416 01417 // Should never get here. 01418 default: 01419 return 0x00; 01420 01421 } // switch _addr_mode 01422 } 01423 01424 01425 /** Set the memoryaddress of screen column and row location 01426 * 01427 * @param column The horizontal position from the left, indexed from 0 01428 * @param row The vertical position from the top, indexed from 0 01429 */ 01430 void TextLCD_Base::setAddress(int column, int row) { 01431 01432 // Sanity Check column 01433 if (column < 0) { 01434 _column = 0; 01435 } 01436 else if (column >= columns()) { 01437 _column = columns() - 1; 01438 } else _column = column; 01439 01440 // Sanity Check row 01441 if (row < 0) { 01442 _row = 0; 01443 } 01444 else if (row >= rows()) { 01445 _row = rows() - 1; 01446 } else _row = row; 01447 01448 01449 // Compute the memory address 01450 // For LCD40x4: switch controllers if needed 01451 // switch cursor if needed 01452 int addr = getAddress(_column, _row); 01453 01454 _writeCommand(0x80 | addr); 01455 } 01456 01457 01458 /** Return the number of columns 01459 * 01460 * @param return The number of columns 01461 * 01462 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware 01463 */ 01464 int TextLCD_Base::columns() { 01465 01466 // Columns encoded in b7..b0 01467 //return (_type & 0xFF); 01468 return _nr_cols; 01469 } 01470 01471 /** Return the number of rows 01472 * 01473 * @param return The number of rows 01474 * 01475 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware 01476 */ 01477 int TextLCD_Base::rows() { 01478 01479 // Rows encoded in b15..b8 01480 //return ((_type >> 8) & 0xFF); 01481 return _nr_rows; 01482 } 01483 01484 /** Set the Cursormode 01485 * 01486 * @param cursorMode The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn) 01487 */ 01488 void TextLCD_Base::setCursor(LCDCursor cursorMode) { 01489 01490 // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on 01491 _currentCursor = cursorMode; 01492 01493 // Configure only current LCD controller 01494 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01495 } 01496 01497 /** Set the Displaymode 01498 * 01499 * @param displayMode The Display mode (DispOff, DispOn) 01500 */ 01501 void TextLCD_Base::setMode(LCDMode displayMode) { 01502 01503 // Save new displayMode, needed when 2 controllers are in use or when cursor is changed 01504 _currentMode = displayMode; 01505 01506 // Select and configure second LCD controller when needed 01507 if(_type==LCD40x4) { 01508 if (_ctrl_idx==_LCDCtrl_0) { 01509 // Configure primary LCD controller 01510 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01511 01512 // Select 2nd controller 01513 _ctrl_idx=_LCDCtrl_1; 01514 01515 // Configure secondary LCD controller 01516 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff); 01517 01518 // Restore current controller 01519 _ctrl_idx=_LCDCtrl_0; 01520 } 01521 else { 01522 // Select primary controller 01523 _ctrl_idx=_LCDCtrl_0; 01524 01525 // Configure primary LCD controller 01526 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff); 01527 01528 // Restore current controller 01529 _ctrl_idx=_LCDCtrl_1; 01530 01531 // Configure secondary LCD controller 01532 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01533 } 01534 } 01535 else { 01536 // Configure primary LCD controller 01537 _setCursorAndDisplayMode(_currentMode, _currentCursor); 01538 } 01539 } 01540 01541 01542 /** Low level method to restore the cursortype and display mode for current controller 01543 */ 01544 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) { 01545 01546 // Configure current LCD controller 01547 _writeCommand(0x08 | displayMode | cursorType); 01548 } 01549 01550 /** Set the Backlight mode 01551 * 01552 * @param backlightMode The Backlight mode (LightOff, LightOn) 01553 */ 01554 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) { 01555 01556 if (backlightMode == LightOn) { 01557 this->_setBL(true); 01558 } 01559 else { 01560 this->_setBL(false); 01561 } 01562 } 01563 01564 /** Set User Defined Characters 01565 * 01566 * @param unsigned char c The Index of the UDC (0..7) 01567 * @param char *udc_data The bitpatterns for the UDC (8 bytes of 5 significant bits) 01568 */ 01569 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) { 01570 01571 // Select and configure second LCD controller when needed 01572 if(_type==LCD40x4) { 01573 _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller 01574 01575 // Select primary controller 01576 _ctrl_idx=_LCDCtrl_0; 01577 01578 // Configure primary LCD controller 01579 _setUDC(c, udc_data); 01580 01581 // Select 2nd controller 01582 _ctrl_idx=_LCDCtrl_1; 01583 01584 // Configure secondary LCD controller 01585 _setUDC(c, udc_data); 01586 01587 // Restore current controller 01588 _ctrl_idx=current_ctrl_idx; 01589 } 01590 else { 01591 // Configure primary LCD controller 01592 _setUDC(c, udc_data); 01593 } 01594 01595 } 01596 01597 /** Low level method to store user defined characters for current controller 01598 */ 01599 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) { 01600 01601 // Select CG RAM for current LCD controller 01602 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address, 01603 //8 sequential locations needed per UDC 01604 // Store UDC pattern 01605 for (int i=0; i<8; i++) { 01606 _writeData(*udc_data++); 01607 } 01608 01609 //Select DD RAM again for current LCD controller 01610 int addr = getAddress(_column, _row); 01611 _writeCommand(0x80 | addr); 01612 } 01613 01614 01615 /** Set UDC Blink 01616 * setUDCBlink method is supported by some compatible devices (eg SSD1803) 01617 * 01618 * @param blinkMode The Blink mode (BlinkOff, BlinkOn) 01619 */ 01620 void TextLCD_Base::setUDCBlink(LCDBlink blinkMode){ 01621 // Blinking UDCs are enabled when a specific controlbit (BE) is set. 01622 // The blinking pixels in the UDC can be controlled by setting additional bits in the UDC bitpattern. 01623 // UDCs are defined by an 8 byte bitpattern. The P0..P5 form the character pattern. 01624 // P7 P6 P5 P4 P3 P2 P1 P0 01625 // 0 B1 B0 x 0 1 1 1 0 01626 // 1 B1 B0 x 1 0 0 0 1 01627 // ............. 01628 // 7 B1 B0 x 1 0 0 0 1 01629 // 01630 // Bit 6 and Bit 7 in the pattern will control the blinking mode when Blink is enabled through BE. 01631 // B1 B0 Mode 01632 // 0 0 No Blinking in this row of the UDC 01633 // 0 1 Enabled pixels in P4 will blink 01634 // 1 x Enabled pixels in P0..P4 will blink 01635 01636 switch (blinkMode) { 01637 case BlinkOn: 01638 // Controllers that support UDC Blink 01639 switch (_ctrl) { 01640 case KS0078 : 01641 _function_1 |= 0x02; // Enable UDC Blink 01642 _writeCommand(0x20 | _function_1); // Function set 0 0 1 DL N RE(1) BE 0 (Ext Regs) 01643 01644 _writeCommand(0x20 | _function); // Function set 0 0 1 DL N RE(0) DH REV (Std Regs) 01645 break; // case KS0078 Controller 01646 01647 case US2066_3V3 : 01648 case SSD1803_3V3 : 01649 _function_1 |= 0x04; // Enable UDC Blink 01650 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 DL N BE RE(1) REV 01651 // Select Ext Instr Set 01652 01653 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01654 // Select Std Instr set, Select IS=0 01655 break; // case SSD1803, US2066 01656 01657 default: 01658 //Unsupported feature for other controllers 01659 break; 01660 } //switch _ctrl 01661 01662 break; 01663 01664 case BlinkOff: 01665 // Controllers that support UDC Blink 01666 switch (_ctrl) { 01667 case KS0078 : 01668 _function_1 &= ~0x02; // Disable UDC Blink 01669 _writeCommand(0x20 | _function_1); // Function set 0 0 1 DL N RE(1) BE 0 (Ext Regs) 01670 01671 _writeCommand(0x20 | _function); // Function set 0 0 1 DL N RE(0) DH REV (Std Regs) 01672 break; // case KS0078 Controller 01673 01674 case US2066_3V3 : 01675 case SSD1803_3V3 : 01676 _function_1 &= ~0x04; // Disable UDC Blink 01677 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 DL N BE RE(1) REV 01678 // Select Ext Instr Set 01679 01680 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01681 // Select Std Instr set, Select IS=0 01682 break; // case SSD1803, US2066 01683 01684 default: 01685 //Unsupported feature for other controllers 01686 break; 01687 } //switch _ctrl 01688 01689 break; 01690 01691 default: 01692 break; 01693 } // blinkMode 01694 01695 } // setUDCBlink() 01696 01697 01698 /** Set Contrast 01699 * setContrast method is supported by some compatible devices (eg ST7032i) that have onboard LCD voltage generation 01700 * Initial code for ST70XX imported from fork by JH1PJL 01701 * 01702 * @param unsigned char c contrast data (6 significant bits, valid range 0..63, Value 0 will disable the Vgen) 01703 * @return none 01704 */ 01705 //@TODO Add support for 40x4 dual controller 01706 void TextLCD_Base::setContrast(unsigned char c) { 01707 01708 // Function set mode stored during Init. Make sure we dont accidentally switch between 1-line and 2-line mode! 01709 // Icon/Booster mode stored during Init. Make sure we dont accidentally change this! 01710 01711 _contrast = c & 0x3F; // Sanity check 01712 01713 switch (_ctrl) { 01714 case PCF2113_3V3 : 01715 case PCF2119_3V3 : 01716 if (_contrast < 5) _contrast = 0; // See datasheet. Sanity check for PCF2113/PCF2119 01717 if (_contrast > 55) _contrast = 55; 01718 01719 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instruction Set = 1 01720 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=0, VA=contrast 01721 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=1, VB=contrast 01722 _writeCommand(0x20 | _function); // Select Instruction Set = 0 01723 break; 01724 01725 case ST7032_3V3 : 01726 case ST7032_5V : 01727 case ST7036_3V3 : 01728 // case ST7036_5V : 01729 case SSD1803_3V3 : 01730 _writeCommand(0x20 | _function | 0x01); // Select Instruction Set = 1 01731 _writeCommand(0x70 | (_contrast & 0x0F)); // Contrast Low bits 01732 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Contrast High bits 01733 _writeCommand(0x20 | _function); // Select Instruction Set = 0 01734 break; 01735 01736 case US2066_3V3 : 01737 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 DL N BE RE(1) REV 01738 // Select Extended Instruction Set 01739 01740 _writeCommand(0x79); // Function Select OLED: 0 1 1 1 1 0 0 1 (Ext Instr Set) 01741 01742 _writeCommand(0x81); // Set Contrast Control: 1 0 0 0 0 0 0 1 (Ext Instr Set, OLED) 01743 _writeCommand((_contrast << 2) | 0x03); // Set Contrast Value: 8 bits. Use 6 bits for compatibility 01744 01745 _writeCommand(0x78); // Function Disable OLED: 0 1 1 1 1 0 0 0 (Ext Instr Set) 01746 01747 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01748 // Select Std Instr set, Select IS=0 01749 break; 01750 01751 #if(0) 01752 //not yet tested 01753 case PT6314 : 01754 // Only 2 significant bits 01755 // 0x00 = 100% 01756 // 0x01 = 75% 01757 // 0x02 = 50% 01758 // 0x03 = 25% 01759 _writeCommand(0x20 | _function | ((~_contrast) >> 4)); // Invert and shift to use 2 MSBs 01760 break; 01761 #endif 01762 01763 default: 01764 //Unsupported feature for other controllers 01765 break; 01766 } // end switch 01767 } // end setContrast() 01768 01769 01770 /** Set Power 01771 * setPower method is supported by some compatible devices (eg SSD1803) that have power down modes 01772 * 01773 * @param bool powerOn Power on/off 01774 * @return none 01775 */ 01776 //@TODO Add support for 40x4 dual controller 01777 void TextLCD_Base::setPower(bool powerOn) { 01778 01779 if (powerOn) { 01780 // Switch on 01781 setMode(DispOn); 01782 01783 // Controllers that supports specific Power Down mode 01784 switch (_ctrl) { 01785 01786 // case PCF2113_3V3 : 01787 // case PCF2119_3V3 : 01788 // case ST7032_3V3 : 01789 //@todo 01790 // enable Booster Bon 01791 01792 case WS0010: 01793 _writeCommand(0x17); // Char mode, DC/DC on 01794 wait_ms(10); // Wait 10ms to ensure powered up 01795 break; 01796 01797 case KS0078: 01798 case SSD1803_3V3 : 01799 // case SSD1803_5V : 01800 _writeCommand(0x20 | _function_1); // Select Ext Instr Set 01801 _writeCommand(0x02); // Power On 01802 _writeCommand(0x20 | _function); // Select Std Instr Set 01803 break; 01804 01805 default: 01806 //Unsupported feature for other controllers 01807 break; 01808 } // end switch 01809 } 01810 else { 01811 // Switch off 01812 setMode(DispOff); 01813 01814 // Controllers that support specific Power Down mode 01815 switch (_ctrl) { 01816 01817 // case PCF2113_3V3 : 01818 // case PCF2119_3V3 : 01819 // case ST7032_3V3 : 01820 //@todo 01821 // disable Booster Bon 01822 01823 case WS0010: 01824 _writeCommand(0x13); // Char mode, DC/DC off 01825 break; 01826 01827 case KS0078: 01828 case SSD1803_3V3 : 01829 // case SSD1803_5V : 01830 _writeCommand(0x20 | _function_1); // Select Ext Instr Set 01831 _writeCommand(0x03); // Power Down 01832 _writeCommand(0x20 | _function); // Select Std Instr Set 01833 break; 01834 01835 default: 01836 //Unsupported feature for other controllers 01837 break; 01838 } // end switch 01839 } 01840 } // end setPower() 01841 01842 01843 /** Set Orient 01844 * setOrient method is supported by some compatible devices (eg SSD1803, US2066) that have top/bottom view modes 01845 * 01846 * @param LCDOrient orient Orientation 01847 * @return none 01848 */ 01849 void TextLCD_Base::setOrient(LCDOrient orient){ 01850 01851 switch (orient) { 01852 01853 case Top: 01854 switch (_ctrl) { 01855 case SSD1803_3V3 : 01856 // case SSD1803_5V : 01857 case US2066_3V3 : 01858 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 X N BE RE(1) REV 01859 // Select Extended Instruction Set 01860 // _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) 01861 _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) 01862 01863 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01864 // Select Std Instr set, Select IS=0 01865 break; 01866 01867 default: 01868 //Unsupported feature for other controllers 01869 break; 01870 01871 } // end switch _ctrl 01872 break; // end Top 01873 01874 case Bottom: 01875 switch (_ctrl) { 01876 case SSD1803_3V3 : 01877 // case SSD1803_5V : 01878 case US2066_3V3 : 01879 _writeCommand(0x20 | _function_1); // Set function, 0 0 1 X N BE RE(1) REV 01880 // Select Extended Instruction Set 01881 _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) 01882 // _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) 01883 01884 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0 01885 // Select Std Instr set, Select IS=0 01886 break; 01887 01888 default: 01889 //Unsupported feature for other controllers 01890 break; 01891 01892 } // end switch _ctrl 01893 01894 break; // end Bottom 01895 } // end switch orient 01896 } // end setOrient() 01897 01898 01899 01900 //--------- End TextLCD_Base ----------- 01901 01902 01903 //--------- Start TextLCD Bus ----------- 01904 01905 /* Create a TextLCD interface for using regular mbed pins 01906 * 01907 * @param rs Instruction/data control line 01908 * @param e Enable line (clock) 01909 * @param d4-d7 Data lines for using as a 4-bit interface 01910 * @param type Sets the panel size/addressing mode (default = LCD16x2) 01911 * @param bl Backlight control line (optional, default = NC) 01912 * @param e2 Enable2 line (clock for second controller, LCD40x4 only) 01913 * @param ctrl LCD controller (default = HD44780) 01914 */ 01915 TextLCD::TextLCD(PinName rs, PinName e, 01916 PinName d4, PinName d5, PinName d6, PinName d7, 01917 LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) : 01918 TextLCD_Base(type, ctrl), 01919 _rs(rs), _e(e), _d(d4, d5, d6, d7) { 01920 01921 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 01922 if (bl != NC) { 01923 _bl = new DigitalOut(bl); //Construct new pin 01924 _bl->write(0); //Deactivate 01925 } 01926 else { 01927 // No Hardware Backlight pin 01928 _bl = NULL; //Construct dummy pin 01929 } 01930 01931 // The hardware Enable2 pin is only needed for LCD40x4. Test and make sure whether it exists or not to prevent illegal access. 01932 if (e2 != NC) { 01933 _e2 = new DigitalOut(e2); //Construct new pin 01934 _e2->write(0); //Deactivate 01935 } 01936 else { 01937 // No Hardware Enable pin 01938 _e2 = NULL; //Construct dummy pin 01939 } 01940 01941 _init(); 01942 } 01943 01944 /** Destruct a TextLCD interface for using regular mbed pins 01945 * 01946 * @param none 01947 * @return none 01948 */ 01949 TextLCD::~TextLCD() { 01950 if (_bl != NULL) {delete _bl;} // BL pin 01951 if (_e2 != NULL) {delete _e2;} // E2 pin 01952 } 01953 01954 01955 /** Set E pin (or E2 pin) 01956 * Used for mbed pins, I2C bus expander or SPI shiftregister 01957 * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins 01958 * @param value true or false 01959 * @return none 01960 */ 01961 void TextLCD::_setEnable(bool value) { 01962 01963 if(_ctrl_idx==_LCDCtrl_0) { 01964 if (value) { 01965 _e = 1; // Set E bit 01966 } 01967 else { 01968 _e = 0; // Reset E bit 01969 } 01970 } 01971 else { 01972 if (value) { 01973 if (_e2 != NULL) {_e2->write(1);} //Set E2 bit 01974 } 01975 else { 01976 if (_e2 != NULL) {_e2->write(0);} //Reset E2 bit 01977 } 01978 } 01979 } 01980 01981 // Set RS pin 01982 // Used for mbed pins, I2C bus expander or SPI shiftregister 01983 void TextLCD::_setRS(bool value) { 01984 01985 if (value) { 01986 _rs = 1; // Set RS bit 01987 } 01988 else { 01989 _rs = 0; // Reset RS bit 01990 } 01991 } 01992 01993 /** Set BL pin 01994 * Used for mbed pins, I2C bus expander or SPI shiftregister 01995 * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins 01996 * @param value true or false 01997 * @return none 01998 */ 01999 void TextLCD::_setBL(bool value) { 02000 02001 if (value) { 02002 if (_bl != NULL) {_bl->write(1);} //Set BL bit 02003 } 02004 else { 02005 if (_bl != NULL) {_bl->write(0);} //Reset BL bit 02006 } 02007 } 02008 02009 // Place the 4bit data on the databus 02010 // Used for mbed pins, I2C bus expander or SPI shifregister 02011 void TextLCD::_setData(int value) { 02012 _d = value & 0x0F; // Write Databits 02013 } 02014 02015 //----------- End TextLCD --------------- 02016 02017 02018 //--------- Start TextLCD_I2C ----------- 02019 02020 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander 02021 * 02022 * @param i2c I2C Bus 02023 * @param deviceAddress I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40) 02024 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02025 * @param ctrl LCD controller (default = HD44780) 02026 */ 02027 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) : 02028 TextLCD_Base(type, ctrl), 02029 _i2c(i2c){ 02030 02031 _slaveAddress = deviceAddress & 0xFE; 02032 02033 // Setup the I2C bus 02034 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit, 02035 _i2c->frequency(100000); 02036 02037 #if (MCP23008==1) 02038 // MCP23008 portexpander Init 02039 _write_register(IODIR, 0x00); // All outputs 02040 _write_register(IPOL, 0x00); // No reverse polarity 02041 _write_register(GPINTEN, 0x00); // No interrupt 02042 _write_register(DEFVAL, 0x00); // Default value to compare against for interrupts 02043 _write_register(INTCON, 0x00); // No interrupt on changes 02044 _write_register(IOCON, 0x00); // Interrupt polarity 02045 _write_register(GPPU, 0x00); // No Pullup 02046 _write_register(INTF, 0x00); // 02047 _write_register(INTCAP, 0x00); // 02048 _write_register(GPIO, 0x00); // Output/Input pins 02049 _write_register(OLAT, 0x00); // Output Latch 02050 02051 // Init the portexpander bus 02052 _lcd_bus = D_LCD_BUS_DEF; 02053 02054 // write the new data to the portexpander 02055 _write_register(GPIO, _lcd_bus); 02056 #else 02057 // PCF8574 of PCF8574A portexpander 02058 02059 // Init the portexpander bus 02060 _lcd_bus = D_LCD_BUS_DEF; 02061 02062 // write the new data to the portexpander 02063 _i2c->write(_slaveAddress, &_lcd_bus, 1); 02064 #endif 02065 02066 _init(); 02067 } 02068 02069 // Set E pin (or E2 pin) 02070 // Used for mbed pins, I2C bus expander or SPI shiftregister 02071 void TextLCD_I2C::_setEnable(bool value) { 02072 02073 if(_ctrl_idx==_LCDCtrl_0) { 02074 if (value) { 02075 _lcd_bus |= D_LCD_E; // Set E bit 02076 } 02077 else { 02078 _lcd_bus &= ~D_LCD_E; // Reset E bit 02079 } 02080 } 02081 else { 02082 if (value) { 02083 _lcd_bus |= D_LCD_E2; // Set E2 bit 02084 } 02085 else { 02086 _lcd_bus &= ~D_LCD_E2; // Reset E2bit 02087 } 02088 } 02089 02090 #if (MCP23008==1) 02091 // MCP23008 portexpander 02092 02093 // write the new data to the portexpander 02094 _write_register(GPIO, _lcd_bus); 02095 #else 02096 // PCF8574 of PCF8574A portexpander 02097 02098 // write the new data to the I2C portexpander 02099 _i2c->write(_slaveAddress, &_lcd_bus, 1); 02100 #endif 02101 } 02102 02103 // Set RS pin 02104 // Used for mbed pins, I2C bus expander or SPI shiftregister 02105 void TextLCD_I2C::_setRS(bool value) { 02106 02107 if (value) { 02108 _lcd_bus |= D_LCD_RS; // Set RS bit 02109 } 02110 else { 02111 _lcd_bus &= ~D_LCD_RS; // Reset RS bit 02112 } 02113 02114 #if (MCP23008==1) 02115 // MCP23008 portexpander 02116 02117 // write the new data to the portexpander 02118 _write_register(GPIO, _lcd_bus); 02119 #else 02120 // PCF8574 of PCF8574A portexpander 02121 02122 // write the new data to the I2C portexpander 02123 _i2c->write(_slaveAddress, &_lcd_bus, 1); 02124 #endif 02125 } 02126 02127 // Set BL pin 02128 // Used for mbed pins, I2C bus expander or SPI shiftregister 02129 void TextLCD_I2C::_setBL(bool value) { 02130 02131 #if (DFROBOT==1) 02132 value = !value; // The DFRobot module uses PNP transistor to drive the Backlight. Reverse logic level. 02133 #endif 02134 02135 if (value) { 02136 _lcd_bus |= D_LCD_BL; // Set BL bit 02137 } 02138 else { 02139 _lcd_bus &= ~D_LCD_BL; // Reset BL bit 02140 } 02141 02142 #if (MCP23008==1) 02143 // MCP23008 portexpander 02144 02145 // write the new data to the portexpander 02146 _write_register(GPIO, _lcd_bus); 02147 #else 02148 // PCF8574 of PCF8574A portexpander 02149 02150 // write the new data to the I2C portexpander 02151 _i2c->write(_slaveAddress, &_lcd_bus, 1); 02152 #endif 02153 } 02154 02155 02156 // Place the 4bit data on the databus 02157 // Used for mbed pins, I2C bus expander or SPI shifregister 02158 void TextLCD_I2C::_setData(int value) { 02159 int data; 02160 02161 // Set bit by bit to support any mapping of expander portpins to LCD pins 02162 02163 data = value & 0x0F; 02164 if (data & 0x01){ 02165 _lcd_bus |= D_LCD_D4; // Set Databit 02166 } 02167 else { 02168 _lcd_bus &= ~D_LCD_D4; // Reset Databit 02169 } 02170 02171 if (data & 0x02){ 02172 _lcd_bus |= D_LCD_D5; // Set Databit 02173 } 02174 else { 02175 _lcd_bus &= ~D_LCD_D5; // Reset Databit 02176 } 02177 02178 if (data & 0x04) { 02179 _lcd_bus |= D_LCD_D6; // Set Databit 02180 } 02181 else { 02182 _lcd_bus &= ~D_LCD_D6; // Reset Databit 02183 } 02184 02185 if (data & 0x08) { 02186 _lcd_bus |= D_LCD_D7; // Set Databit 02187 } 02188 else { 02189 _lcd_bus &= ~D_LCD_D7; // Reset Databit 02190 } 02191 02192 #if (MCP23008==1) 02193 // MCP23008 portexpander 02194 02195 // write the new data to the portexpander 02196 _write_register(GPIO, _lcd_bus); 02197 #else 02198 // PCF8574 of PCF8574A portexpander 02199 02200 // write the new data to the I2C portexpander 02201 _i2c->write(_slaveAddress, &_lcd_bus, 1); 02202 #endif 02203 02204 } 02205 02206 // Write data to MCP23008 I2C portexpander 02207 void TextLCD_I2C::_write_register (int reg, int value) { 02208 char data[] = {reg, value}; 02209 02210 _i2c->write(_slaveAddress, data, 2); 02211 } 02212 02213 //---------- End TextLCD_I2C ------------ 02214 02215 02216 //--------- Start TextLCD_I2C_N --------- 02217 02218 /** Create a TextLCD interface using a controller with native I2C interface 02219 * 02220 * @param i2c I2C Bus 02221 * @param deviceAddress I2C slave address (default = 0x7C) 02222 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02223 * @param bl Backlight control line (optional, default = NC) 02224 * @param ctrl LCD controller (default = ST7032_3V3) 02225 */ 02226 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) : 02227 TextLCD_Base(type, ctrl), 02228 02229 _i2c(i2c){ 02230 02231 _slaveAddress = deviceAddress & 0xFE; 02232 02233 // Setup the I2C bus 02234 // The max bitrate for ST7032i is 400kbit, lets stick to default here 02235 _i2c->frequency(100000); 02236 02237 02238 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02239 if (bl != NC) { 02240 _bl = new DigitalOut(bl); //Construct new pin 02241 _bl->write(0); //Deactivate 02242 } 02243 else { 02244 // No Hardware Backlight pin 02245 _bl = NULL; //Construct dummy pin 02246 } 02247 02248 //Sanity check 02249 if (_ctrl & LCD_C_I2C) { 02250 _init(); 02251 } 02252 else { 02253 error("Error: LCD Controller type does not support native I2C interface\n\r"); 02254 } 02255 02256 } 02257 02258 TextLCD_I2C_N::~TextLCD_I2C_N() { 02259 if (_bl != NULL) {delete _bl;} // BL pin 02260 } 02261 02262 // Not used in this mode 02263 void TextLCD_I2C_N::_setEnable(bool value) { 02264 } 02265 02266 // Set RS pin 02267 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI 02268 void TextLCD_I2C_N::_setRS(bool value) { 02269 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command. 02270 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop 02271 // Co RS RW 0 0 0 0 0 command or data 02272 // 02273 // C0=1 indicates that another controlbyte will follow after the next data or command byte 02274 // RS=1 means that next byte is data, RS=0 means that next byte is command 02275 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command. 02276 // Many native I2C controllers dont support this option and it is not used by this lib. 02277 // 02278 02279 if (value) { 02280 _controlbyte = 0x40; // Next byte is data, No more control bytes will follow 02281 } 02282 else { 02283 _controlbyte = 0x00; // Next byte is command, No more control bytes will follow 02284 } 02285 } 02286 02287 // Set BL pin 02288 void TextLCD_I2C_N::_setBL(bool value) { 02289 if (_bl) { 02290 _bl->write(value); 02291 } 02292 } 02293 02294 // Not used in this mode 02295 void TextLCD_I2C_N::_setData(int value) { 02296 } 02297 02298 // Write a byte using I2C 02299 void TextLCD_I2C_N::_writeByte(int value) { 02300 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command. 02301 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop 02302 // Co RS RW 0 0 0 0 0 command or data 02303 // 02304 // C0=1 indicates that another controlbyte will follow after the next data or command byte 02305 // RS=1 means that next byte is data, RS=0 means that next byte is command 02306 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command. 02307 // Many native I2C controllers dont support this option and it is not used by this lib. 02308 // 02309 char data[] = {_controlbyte, value}; 02310 02311 #if(LCD_I2C_ACK==1) 02312 //Controllers that support ACK 02313 _i2c->write(_slaveAddress, data, 2); 02314 #else 02315 //Controllers that dont support ACK 02316 _i2c->start(); 02317 _i2c->write(_slaveAddress); 02318 _i2c->write(data[0]); 02319 _i2c->write(data[1]); 02320 _i2c->stop(); 02321 #endif 02322 } 02323 02324 //-------- End TextLCD_I2C_N ------------ 02325 02326 02327 //--------- Start TextLCD_SPI ----------- 02328 02329 /** Create a TextLCD interface using an SPI 74595 portexpander 02330 * 02331 * @param spi SPI Bus 02332 * @param cs chip select pin (active low) 02333 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02334 * @param ctrl LCD controller (default = HD44780) 02335 */ 02336 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) : 02337 TextLCD_Base(type, ctrl), 02338 _spi(spi), 02339 _cs(cs) { 02340 02341 // Init cs 02342 _setCS(true); 02343 02344 // Setup the spi for 8 bit data, low steady state clock, 02345 // rising edge capture, with a 500KHz or 1MHz clock rate 02346 _spi->format(8,0); 02347 _spi->frequency(500000); 02348 //_spi.frequency(1000000); 02349 02350 // Init the portexpander bus 02351 _lcd_bus = D_LCD_BUS_DEF; 02352 02353 // write the new data to the portexpander 02354 _setCS(false); 02355 _spi->write(_lcd_bus); 02356 _setCS(true); 02357 02358 _init(); 02359 } 02360 02361 // Set E pin (or E2 pin) 02362 // Used for mbed pins, I2C bus expander or SPI shiftregister 02363 void TextLCD_SPI::_setEnable(bool value) { 02364 02365 if(_ctrl_idx==_LCDCtrl_0) { 02366 if (value) { 02367 _lcd_bus |= D_LCD_E; // Set E bit 02368 } 02369 else { 02370 _lcd_bus &= ~D_LCD_E; // Reset E bit 02371 } 02372 } 02373 else { 02374 if (value) { 02375 _lcd_bus |= D_LCD_E2; // Set E2 bit 02376 } 02377 else { 02378 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit 02379 } 02380 } 02381 02382 // write the new data to the SPI portexpander 02383 _setCS(false); 02384 _spi->write(_lcd_bus); 02385 _setCS(true); 02386 } 02387 02388 // Set RS pin 02389 // Used for mbed pins, I2C bus expander or SPI shiftregister 02390 void TextLCD_SPI::_setRS(bool value) { 02391 02392 if (value) { 02393 _lcd_bus |= D_LCD_RS; // Set RS bit 02394 } 02395 else { 02396 _lcd_bus &= ~D_LCD_RS; // Reset RS bit 02397 } 02398 02399 // write the new data to the SPI portexpander 02400 _setCS(false); 02401 _spi->write(_lcd_bus); 02402 _setCS(true); 02403 } 02404 02405 // Set BL pin 02406 // Used for mbed pins, I2C bus expander or SPI shiftregister 02407 void TextLCD_SPI::_setBL(bool value) { 02408 02409 if (value) { 02410 _lcd_bus |= D_LCD_BL; // Set BL bit 02411 } 02412 else { 02413 _lcd_bus &= ~D_LCD_BL; // Reset BL bit 02414 } 02415 02416 // write the new data to the SPI portexpander 02417 _setCS(false); 02418 _spi->write(_lcd_bus); 02419 _setCS(true); 02420 } 02421 02422 // Place the 4bit data on the databus 02423 // Used for mbed pins, I2C bus expander or SPI shiftregister 02424 void TextLCD_SPI::_setData(int value) { 02425 int data; 02426 02427 // Set bit by bit to support any mapping of expander portpins to LCD pins 02428 02429 data = value & 0x0F; 02430 if (data & 0x01) { 02431 _lcd_bus |= D_LCD_D4; // Set Databit 02432 } 02433 else { 02434 _lcd_bus &= ~D_LCD_D4; // Reset Databit 02435 } 02436 02437 if (data & 0x02) { 02438 _lcd_bus |= D_LCD_D5; // Set Databit 02439 } 02440 else { 02441 _lcd_bus &= ~D_LCD_D5; // Reset Databit 02442 } 02443 02444 if (data & 0x04) { 02445 _lcd_bus |= D_LCD_D6; // Set Databit 02446 } 02447 else { 02448 _lcd_bus &= ~D_LCD_D6; // Reset Databit 02449 } 02450 02451 if (data & 0x08) { 02452 _lcd_bus |= D_LCD_D7; // Set Databit 02453 } 02454 else { 02455 _lcd_bus &= ~D_LCD_D7; // Reset Databit 02456 } 02457 02458 // write the new data to the SPI portexpander 02459 _setCS(false); 02460 _spi->write(_lcd_bus); 02461 _setCS(true); 02462 } 02463 02464 // Set CS line. 02465 // Only used for SPI bus 02466 void TextLCD_SPI::_setCS(bool value) { 02467 02468 if (value) { 02469 _cs = 1; // Set CS pin 02470 } 02471 else { 02472 _cs = 0; // Reset CS pin 02473 } 02474 } 02475 02476 //---------- End TextLCD_SPI ------------ 02477 02478 02479 //--------- Start TextLCD_SPI_N --------- 02480 02481 /** Create a TextLCD interface using a controller with a native SPI4 interface 02482 * 02483 * @param spi SPI Bus 02484 * @param cs chip select pin (active low) 02485 * @param rs Instruction/data control line 02486 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02487 * @param bl Backlight control line (optional, default = NC) 02488 * @param ctrl LCD controller (default = ST7032_3V3) 02489 */ 02490 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) : 02491 TextLCD_Base(type, ctrl), 02492 _spi(spi), 02493 _cs(cs), 02494 _rs(rs) { 02495 02496 // Init CS 02497 _cs = 1; 02498 02499 // Setup the spi for 8 bit data, low steady state clock, 02500 // rising edge capture, with a 500KHz or 1MHz clock rate 02501 _spi->format(8,0); 02502 _spi->frequency(1000000); 02503 02504 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02505 if (bl != NC) { 02506 _bl = new DigitalOut(bl); //Construct new pin 02507 _bl->write(0); //Deactivate 02508 } 02509 else { 02510 // No Hardware Backlight pin 02511 _bl = NULL; //Construct dummy pin 02512 } 02513 02514 //Sanity check 02515 if (_ctrl & LCD_C_SPI4) { 02516 _init(); 02517 } 02518 else { 02519 error("Error: LCD Controller type does not support native SPI4 interface\n\r"); 02520 } 02521 } 02522 02523 TextLCD_SPI_N::~TextLCD_SPI_N() { 02524 if (_bl != NULL) {delete _bl;} // BL pin 02525 } 02526 02527 // Not used in this mode 02528 void TextLCD_SPI_N::_setEnable(bool value) { 02529 } 02530 02531 // Set RS pin 02532 // Used for mbed pins, I2C bus expander or SPI shiftregister 02533 void TextLCD_SPI_N::_setRS(bool value) { 02534 _rs = value; 02535 } 02536 02537 // Set BL pin 02538 void TextLCD_SPI_N::_setBL(bool value) { 02539 if (_bl) { 02540 _bl->write(value); 02541 } 02542 } 02543 02544 // Not used in this mode 02545 void TextLCD_SPI_N::_setData(int value) { 02546 } 02547 02548 // Write a byte using SPI 02549 void TextLCD_SPI_N::_writeByte(int value) { 02550 _cs = 0; 02551 wait_us(1); 02552 _spi->write(value); 02553 wait_us(1); 02554 _cs = 1; 02555 } 02556 02557 //-------- End TextLCD_SPI_N ------------ 02558 02559 02560 02561 #if(1) 02562 //Code checked out on logic analyser. Not yet tested on hardware.. 02563 02564 //-------- Start TextLCD_SPI_N_3_9 -------- 02565 02566 /** Create a TextLCD interface using a controller with a native SPI3 9 bits interface 02567 * 02568 * @param spi SPI Bus 02569 * @param cs chip select pin (active low) 02570 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02571 * @param bl Backlight control line (optional, default = NC) 02572 * @param ctrl LCD controller (default = AIP31068) 02573 */ 02574 TextLCD_SPI_N_3_9::TextLCD_SPI_N_3_9(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) : 02575 TextLCD_Base(type, ctrl), 02576 _spi(spi), 02577 _cs(cs) { 02578 02579 // Init CS 02580 _cs = 1; 02581 02582 // Setup the spi for 9 bit data, low steady state clock, 02583 // rising edge capture, with a 500KHz or 1MHz clock rate 02584 // _spi->format(9,0); 02585 _spi->format(9,3); 02586 _spi->frequency(1000000); 02587 02588 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02589 if (bl != NC) { 02590 _bl = new DigitalOut(bl); //Construct new pin 02591 _bl->write(0); //Deactivate 02592 } 02593 else { 02594 // No Hardware Backlight pin 02595 _bl = NULL; //Construct dummy pin 02596 } 02597 02598 //Sanity check 02599 if (_ctrl & LCD_C_SPI3_9) { 02600 _init(); 02601 } 02602 else { 02603 error("Error: LCD Controller type does not support native SPI3 9 bits interface\n\r"); 02604 } 02605 } 02606 02607 TextLCD_SPI_N_3_9::~TextLCD_SPI_N_3_9() { 02608 if (_bl != NULL) {delete _bl;} // BL pin 02609 } 02610 02611 // Not used in this mode 02612 void TextLCD_SPI_N_3_9::_setEnable(bool value) { 02613 } 02614 02615 // Set RS pin 02616 // Used for mbed pins, I2C bus expander or SPI shiftregister 02617 void TextLCD_SPI_N_3_9::_setRS(bool value) { 02618 // The controlbits define the meaning of the next byte. This next byte can either be data or command. 02619 // b8 b7...........b0 02620 // RS command or data 02621 // 02622 // RS=1 means that next byte is data, RS=0 means that next byte is command 02623 // 02624 02625 if (value) { 02626 _controlbyte = 0x01; // Next byte is data 02627 } 02628 else { 02629 _controlbyte = 0x00; // Next byte is command 02630 } 02631 02632 } 02633 02634 // Set BL pin 02635 void TextLCD_SPI_N_3_9::_setBL(bool value) { 02636 if (_bl) { 02637 _bl->write(value); 02638 } 02639 } 02640 02641 // Not used in this mode 02642 void TextLCD_SPI_N_3_9::_setData(int value) { 02643 } 02644 02645 // Write a byte using SPI3 9 bits mode 02646 void TextLCD_SPI_N_3_9::_writeByte(int value) { 02647 _cs = 0; 02648 wait_us(1); 02649 _spi->write( (_controlbyte << 8) | (value & 0xFF)); 02650 wait_us(1); 02651 _cs = 1; 02652 } 02653 02654 //------- End TextLCD_SPI_N_3_9 ----------- 02655 #endif 02656 02657 02658 #if(1) 02659 //------- Start TextLCD_SPI_N_3_10 -------- 02660 02661 /** Create a TextLCD interface using a controller with a native SPI3 10 bits interface 02662 * 02663 * @param spi SPI Bus 02664 * @param cs chip select pin (active low) 02665 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02666 * @param bl Backlight control line (optional, default = NC) 02667 * @param ctrl LCD controller (default = AIP31068) 02668 */ 02669 TextLCD_SPI_N_3_10::TextLCD_SPI_N_3_10(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) : 02670 TextLCD_Base(type, ctrl), 02671 _spi(spi), 02672 _cs(cs) { 02673 02674 // Init CS 02675 _cs = 1; 02676 02677 // Setup the spi for 10 bit data, low steady state clock, 02678 // rising edge capture, with a 500KHz or 1MHz clock rate 02679 _spi->format(10,0); 02680 _spi->frequency(1000000); 02681 02682 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02683 if (bl != NC) { 02684 _bl = new DigitalOut(bl); //Construct new pin 02685 _bl->write(0); //Deactivate 02686 } 02687 else { 02688 // No Hardware Backlight pin 02689 _bl = NULL; //Construct dummy pin 02690 } 02691 02692 //Sanity check 02693 if (_ctrl & LCD_C_SPI3_10) { 02694 _init(); 02695 } 02696 else { 02697 error("Error: LCD Controller type does not support native SPI3 10 bits interface\n\r"); 02698 } 02699 } 02700 02701 TextLCD_SPI_N_3_10::~TextLCD_SPI_N_3_10() { 02702 if (_bl != NULL) {delete _bl;} // BL pin 02703 } 02704 02705 // Not used in this mode 02706 void TextLCD_SPI_N_3_10::_setEnable(bool value) { 02707 } 02708 02709 // Set RS pin 02710 // Used for mbed pins, I2C bus expander or SPI shiftregister 02711 void TextLCD_SPI_N_3_10::_setRS(bool value) { 02712 // The controlbits define the meaning of the next byte. This next byte can either be data or command. 02713 // b9 b8 b7...........b0 02714 // RS RW command or data 02715 // 02716 // RS=1 means that next byte is data, RS=0 means that next byte is command 02717 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib) 02718 // 02719 02720 if (value) { 02721 _controlbyte = 0x02; // Next byte is data 02722 } 02723 else { 02724 _controlbyte = 0x00; // Next byte is command 02725 } 02726 02727 } 02728 02729 // Set BL pin 02730 void TextLCD_SPI_N_3_10::_setBL(bool value) { 02731 if (_bl) { 02732 _bl->write(value); 02733 } 02734 } 02735 02736 // Not used in this mode 02737 void TextLCD_SPI_N_3_10::_setData(int value) { 02738 } 02739 02740 // Write a byte using SPI3 10 bits mode 02741 void TextLCD_SPI_N_3_10::_writeByte(int value) { 02742 _cs = 0; 02743 wait_us(1); 02744 _spi->write( (_controlbyte << 8) | (value & 0xFF)); 02745 wait_us(1); 02746 _cs = 1; 02747 } 02748 02749 //------- End TextLCD_SPI_N_3_10 ---------- 02750 #endif 02751 02752 #if(0) 02753 //Code to be checked out on logic analyser. Not yet tested on hardware.. 02754 02755 //------- Start TextLCD_SPI_N_3_16 -------- 02756 02757 /** Create a TextLCD interface using a controller with a native SPI3 16 bits interface 02758 * 02759 * @param spi SPI Bus 02760 * @param cs chip select pin (active low) 02761 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02762 * @param bl Backlight control line (optional, default = NC) 02763 * @param ctrl LCD controller (default = PT6314) 02764 */ 02765 TextLCD_SPI_N_3_16::TextLCD_SPI_N_3_16(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) : 02766 TextLCD_Base(type, ctrl), 02767 _spi(spi), 02768 _cs(cs) { 02769 02770 // Init CS 02771 _cs = 1; 02772 02773 // Setup the spi for 8 bit data, low steady state clock, 02774 // rising edge capture, with a 500KHz or 1MHz clock rate 02775 _spi->format(8,0); 02776 _spi->frequency(1000000); 02777 02778 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02779 if (bl != NC) { 02780 _bl = new DigitalOut(bl); //Construct new pin 02781 _bl->write(0); //Deactivate 02782 } 02783 else { 02784 // No Hardware Backlight pin 02785 _bl = NULL; //Construct dummy pin 02786 } 02787 02788 //Sanity check 02789 if (_ctrl & LCD_C_SPI3_16) { 02790 _init(); 02791 } 02792 else { 02793 error("Error: LCD Controller type does not support native SPI3 16 bits interface\n\r"); 02794 } 02795 } 02796 02797 TextLCD_SPI_N_3_16::~TextLCD_SPI_N_3_16() { 02798 if (_bl != NULL) {delete _bl;} // BL pin 02799 } 02800 02801 // Not used in this mode 02802 void TextLCD_SPI_N_3_16::_setEnable(bool value) { 02803 } 02804 02805 // Set RS pin 02806 // Used for mbed pins, I2C bus expander or SPI shiftregister 02807 void TextLCD_SPI_N_3_16::_setRS(bool value) { 02808 // 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. 02809 // The 8 actual bits represent either a data or a command byte. 02810 // b15 b14 b13 b12 b11 b10 b9 b8 - b7 b6 b5 b4 b3 b2 b1 b0 02811 // 1 1 1 1 1 RW RS 0 d7 d6 d5 d4 d3 d2 d1 d0 02812 // 02813 // RS=1 means that next byte is data, RS=0 means that next byte is command 02814 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib) 02815 // 02816 02817 if (value) { 02818 _controlbyte = 0xFA; // Next byte is data 02819 } 02820 else { 02821 _controlbyte = 0xF8; // Next byte is command 02822 } 02823 } 02824 02825 // Set BL pin 02826 void TextLCD_SPI_N_3_16::_setBL(bool value) { 02827 if (_bl) { 02828 _bl->write(value); 02829 } 02830 } 02831 02832 // Not used in this mode 02833 void TextLCD_SPI_N_3_16::_setData(int value) { 02834 } 02835 02836 02837 // Write a byte using SPI3 16 bits mode 02838 void TextLCD_SPI_N_3_16::_writeByte(int value) { 02839 _cs = 0; 02840 wait_us(1); 02841 02842 _spi->write(_controlbyte); 02843 02844 _spi->write(value); 02845 02846 wait_us(1); 02847 _cs = 1; 02848 } 02849 02850 //------- End TextLCD_SPI_N_3_16 ---------- 02851 #endif 02852 02853 #if(1) 02854 //------- Start TextLCD_SPI_N_3_24 -------- 02855 02856 /** Create a TextLCD interface using a controller with a native SPI3 24 bits interface 02857 * 02858 * @param spi SPI Bus 02859 * @param cs chip select pin (active low) 02860 * @param type Sets the panel size/addressing mode (default = LCD16x2) 02861 * @param bl Backlight control line (optional, default = NC) 02862 * @param ctrl LCD controller (default = SSD1803) 02863 */ 02864 TextLCD_SPI_N_3_24::TextLCD_SPI_N_3_24(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) : 02865 TextLCD_Base(type, ctrl), 02866 _spi(spi), 02867 _cs(cs) { 02868 02869 // Init CS 02870 _cs = 1; 02871 02872 // Setup the spi for 8 bit data, low steady state clock, 02873 // rising edge capture, with a 500KHz or 1MHz clock rate 02874 _spi->format(8,0); 02875 _spi->frequency(1000000); 02876 02877 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access. 02878 if (bl != NC) { 02879 _bl = new DigitalOut(bl); //Construct new pin 02880 _bl->write(0); //Deactivate 02881 } 02882 else { 02883 // No Hardware Backlight pin 02884 _bl = NULL; //Construct dummy pin 02885 } 02886 02887 //Sanity check 02888 if (_ctrl & LCD_C_SPI3_24) { 02889 _init(); 02890 } 02891 else { 02892 error("Error: LCD Controller type does not support native SPI3 24 bits interface\n\r"); 02893 } 02894 } 02895 02896 TextLCD_SPI_N_3_24::~TextLCD_SPI_N_3_24() { 02897 if (_bl != NULL) {delete _bl;} // BL pin 02898 } 02899 02900 // Not used in this mode 02901 void TextLCD_SPI_N_3_24::_setEnable(bool value) { 02902 } 02903 02904 // Set RS pin 02905 // Used for mbed pins, I2C bus expander or SPI shiftregister 02906 void TextLCD_SPI_N_3_24::_setRS(bool value) { 02907 // 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. 02908 // Each byte encodes 4 actual bits. The 8 actual bits represent either a data or a command byte. 02909 // b23 b22 b21 b20 b19 b18 b17 b16 - b15 b14 b13 b12 b11 b10 b9 b8 - b7 b6 b5 b4 b3 b2 b1 b0 02910 // 1 1 1 1 1 RW RS 0 d0 d1 d2 d3 0 0 0 0 d4 d5 d6 d7 0 0 0 0 02911 // 02912 // RS=1 means that next byte is data, RS=0 means that next byte is command 02913 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib) 02914 // 02915 // Note: SPI3_24 expects LSB first. This is inconsistent with regular SPI convention (and hardware) that sends MSB first. 02916 02917 if (value) { 02918 _controlbyte = 0xFA; // Next byte is data 02919 } 02920 else { 02921 _controlbyte = 0xF8; // Next byte is command 02922 } 02923 02924 } 02925 02926 // Set BL pin 02927 void TextLCD_SPI_N_3_24::_setBL(bool value) { 02928 if (_bl) { 02929 _bl->write(value); 02930 } 02931 } 02932 02933 // Not used in this mode 02934 void TextLCD_SPI_N_3_24::_setData(int value) { 02935 } 02936 02937 //Mapping table to flip the bits around cause SPI3_24 expects LSB first. 02938 const uint8_t map3_24[16] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0}; 02939 02940 // Write a byte using SPI3 24 bits mode 02941 void TextLCD_SPI_N_3_24::_writeByte(int value) { 02942 _cs = 0; 02943 wait_us(1); 02944 _spi->write(_controlbyte); 02945 02946 //Map and send the LSB nibble 02947 _spi->write( map3_24[value & 0x0F]); 02948 02949 //Map and send the MSB nibble 02950 _spi->write( map3_24[(value >> 4) & 0x0F]); 02951 02952 wait_us(1); 02953 _cs = 1; 02954 } 02955 02956 //------- End TextLCD_SPI_N_3_24 ---------- 02957 #endif
Generated on Wed Jul 13 2022 08:07:13 by 1.7.2