1

Dependents:   Program_R11

Committer:
wim
Date:
Fri Aug 22 19:50:49 2014 +0000
Revision:
32:59c4b8f648d4
Parent:
31:ef31cd8a00d1
Child:
33:900a94bc7585
Added support for controllers PCF2119 (native I2C) and SSD1803A, ST7036 (native I2C/SPI), added setContrast method (by JH1PJL) and setPower method for supported devices (eg ST7032i). Cleaned up Init method.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 1:ac48b187213c 1 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780
simon 6:e4cb7ddee0d3 2 * Copyright (c) 2007-2010, sford, http://mbed.org
wim 14:0c32b66b14b8 3 * 2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs
wim 14:0c32b66b14b8 4 * 2013, v02: WH, Added I2C and SPI bus interfaces
wim 15:b70ebfffb258 5 * 2013, v03: WH, Added support for LCD40x4 which uses 2 controllers
wim 18:bd65dc10f27f 6 * 2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess
wim 18:bd65dc10f27f 7 * 2013, v05: WH, Added support for 8x2B, added some UDCs
wim 19:c747b9e2e7b8 8 * 2013, v06: WH, Added support for devices that use internal DC/DC converters
wim 20:e0da005a777f 9 * 2013, v07: WH, Added support for backlight and include portdefinitions for LCD2004 Module from DFROBOT
wim 22:35742ec80c24 10 * 2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined pins
wim 25:6162b31128c9 11 * 2014, v09: WH/EO, Added Class for Native SPI controllers such as ST7032
wim 26:bd897a001012 12 * 2014, v10: WH, Added Class for Native I2C controllers such as ST7032i, Added support for MCP23008 I2C portexpander, Added support for Adafruit module
wim 30:033048611c01 13 * 2014, v11: WH, Added support for native I2C controllers such as PCF21XX, Improved the _initCtrl() method to deal with differences between all supported controllers
wim 32:59c4b8f648d4 14 * 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)
simon 1:ac48b187213c 15 *
simon 1:ac48b187213c 16 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:ac48b187213c 17 * of this software and associated documentation files (the "Software"), to deal
simon 1:ac48b187213c 18 * in the Software without restriction, including without limitation the rights
simon 1:ac48b187213c 19 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:ac48b187213c 20 * copies of the Software, and to permit persons to whom the Software is
simon 1:ac48b187213c 21 * furnished to do so, subject to the following conditions:
simon 1:ac48b187213c 22 *
simon 1:ac48b187213c 23 * The above copyright notice and this permission notice shall be included in
simon 1:ac48b187213c 24 * all copies or substantial portions of the Software.
simon 1:ac48b187213c 25 *
simon 1:ac48b187213c 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:ac48b187213c 27 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:ac48b187213c 28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:ac48b187213c 29 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:ac48b187213c 30 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:ac48b187213c 31 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:ac48b187213c 32 * THE SOFTWARE.
simon 1:ac48b187213c 33 */
simon 1:ac48b187213c 34
simon 1:ac48b187213c 35 #include "TextLCD.h"
simon 1:ac48b187213c 36 #include "mbed.h"
simon 1:ac48b187213c 37
wim 30:033048611c01 38 //For Testing only
wim 30:033048611c01 39 //DigitalOut led1(LED1);
wim 30:033048611c01 40 //DigitalOut led2(LED2);
wim 30:033048611c01 41 // led2=!led2;
wim 29:a3663151aa65 42
wim 29:a3663151aa65 43
wim 30:033048611c01 44 /** Some sample User Defined Chars 5x7 dots */
wim 32:59c4b8f648d4 45 //const char udc_ae[] = {0x00, 0x00, 0x1B, 0x05, 0x1F, 0x14, 0x1F, 0x00}; //æ
wim 32:59c4b8f648d4 46 //const char udc_0e[] = {0x00, 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00}; //ø
wim 32:59c4b8f648d4 47 //const char udc_ao[] = {0x0E, 0x0A, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x00}; //å
wim 32:59c4b8f648d4 48 //const char udc_AE[] = {0x0F, 0x14, 0x14, 0x1F, 0x14, 0x14, 0x17, 0x00}; //Æ
wim 32:59c4b8f648d4 49 //const char udc_0E[] = {0x0E, 0x13, 0x15, 0x15, 0x15, 0x19, 0x0E, 0x00}; //Ø
wim 32:59c4b8f648d4 50 //const char udc_Ao[] = {0x0E, 0x0A, 0x0E, 0x11, 0x1F, 0x11, 0x11, 0x00}; //Å
wim 32:59c4b8f648d4 51 //const char udc_PO[] = {0x04, 0x0A, 0x0A, 0x1F, 0x1B, 0x1B, 0x1F, 0x00}; //Padlock Open
wim 32:59c4b8f648d4 52 //const char udc_PC[] = {0x1C, 0x10, 0x08, 0x1F, 0x1B, 0x1B, 0x1F, 0x00}; //Padlock Closed
wim 32:59c4b8f648d4 53
wim 32:59c4b8f648d4 54 //const char udc_alpha[] = {0x00, 0x00, 0x0D, 0x12, 0x12, 0x12, 0x0D, 0x00}; //alpha
wim 32:59c4b8f648d4 55 //const char udc_ohm[] = {0x0E, 0x11, 0x11, 0x11, 0x0A, 0x0A, 0x1B, 0x00}; //ohm
wim 32:59c4b8f648d4 56 //const char udc_sigma[] = {0x1F, 0x08, 0x04, 0x02, 0x04, 0x08, 0x1F, 0x00}; //sigma
wim 32:59c4b8f648d4 57 //const char udc_pi[] = {0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x00}; //pi
wim 32:59c4b8f648d4 58 //const char udc_root[] = {0x07, 0x04, 0x04, 0x04, 0x14, 0x0C, 0x04, 0x00}; //root
wim 30:033048611c01 59
wim 30:033048611c01 60 const char udc_0[] = {0x18, 0x14, 0x12, 0x11, 0x12, 0x14, 0x18, 0x00}; // |>
wim 30:033048611c01 61 const char udc_1[] = {0x03, 0x05, 0x09, 0x11, 0x09, 0x05, 0x03, 0x00}; // <|
wim 30:033048611c01 62 const char udc_2[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00}; // |
wim 30:033048611c01 63 const char udc_3[] = {0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00}; // ||
wim 30:033048611c01 64 const char udc_4[] = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00}; // |||
wim 30:033048611c01 65 const char udc_5[] = {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00}; // =
wim 30:033048611c01 66 const char udc_6[] = {0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, 0x00}; // checkerboard
wim 30:033048611c01 67 const char udc_7[] = {0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x10, 0x00}; // \
wim 30:033048611c01 68
wim 30:033048611c01 69 const char udc_degr[] = {0x06, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00}; // Degree symbol
wim 30:033048611c01 70
wim 30:033048611c01 71 const char udc_TM_T[] = {0x1F, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00}; // Trademark T
wim 30:033048611c01 72 const char udc_TM_M[] = {0x11, 0x1B, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00}; // Trademark M
wim 30:033048611c01 73
wim 30:033048611c01 74 //const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Full
wim 30:033048611c01 75 //const char udc_Bat_Ha[] = {0x0E, 0x11, 0x13, 0x17, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Half
wim 30:033048611c01 76 //const char udc_Bat_Lo[] = {0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x00}; // Battery Low
wim 30:033048611c01 77 const char udc_Bat_Hi[] = {0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Full
wim 30:033048611c01 78 const char udc_Bat_Ha[] = {0x0E, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Battery Half
wim 30:033048611c01 79 const char udc_Bat_Lo[] = {0x0E, 0x11, 0x11, 0x11, 0x11, 0x1F, 0x1F, 0x00}; // Battery Low
wim 30:033048611c01 80 const char udc_AC[] = {0x0A, 0x0A, 0x1F, 0x11, 0x0E, 0x04, 0x04, 0x00}; // AC Power
wim 30:033048611c01 81
wim 30:033048611c01 82 //const char udc_smiley[] = {0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00, 0x00}; // Smiley
wim 30:033048611c01 83 //const char udc_droopy[] = {0x00, 0x0A, 0x00, 0x04, 0x00, 0x0E, 0x11, 0x00}; // Droopey
wim 30:033048611c01 84 //const char udc_note[] = {0x01, 0x03, 0x05, 0x09, 0x0B, 0x1B, 0x18, 0x00}; // Note
wim 30:033048611c01 85
wim 30:033048611c01 86 //const char udc_bar_1[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00}; // Bar 1
wim 30:033048611c01 87 //const char udc_bar_2[] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}; // Bar 11
wim 30:033048611c01 88 //const char udc_bar_3[] = {0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x00}; // Bar 111
wim 30:033048611c01 89 //const char udc_bar_4[] = {0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x00}; // Bar 1111
wim 30:033048611c01 90 //const char udc_bar_5[] = {0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00}; // Bar 11111
wim 30:033048611c01 91
wim 30:033048611c01 92 //const char udc_ch_1[] = {0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00}; // Hor bars 4
wim 30:033048611c01 93 //const char udc_ch_2[] = {0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f}; // Hor bars 4 (inverted)
wim 30:033048611c01 94 //const char udc_ch_3[] = {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15}; // Ver bars 3
wim 30:033048611c01 95 //const char udc_ch_4[] = {0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}; // Ver bars 3 (inverted)
wim 30:033048611c01 96 //const char udc_ch_yr[] = {0x08, 0x0f, 0x12, 0x0f, 0x0a, 0x1f, 0x02, 0x02}; // Year (kana)
wim 30:033048611c01 97 //const char udc_ch_mo[] = {0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x09, 0x09, 0x13}; // Month (kana)
wim 30:033048611c01 98 //const char udc_ch_dy[] = {0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x1F}; // Day (kana)
wim 30:033048611c01 99 //const char udc_ch_mi[] = {0x0C, 0x0a, 0x11, 0x1f, 0x09, 0x09, 0x09, 0x13}; // minute (kana)
wim 30:033048611c01 100
wim 32:59c4b8f648d4 101 const char udc_None[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
wim 32:59c4b8f648d4 102 const char udc_All[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
wim 30:033048611c01 103
wim 21:9eb628d9e164 104 /** Create a TextLCD_Base interface
wim 15:b70ebfffb258 105 *
wim 21:9eb628d9e164 106 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 107 * @param ctrl LCD controller (default = HD44780)
wim 15:b70ebfffb258 108 */
wim 21:9eb628d9e164 109 TextLCD_Base::TextLCD_Base(LCDType type, LCDCtrl ctrl) : _type(type), _ctrl(ctrl) {
wim 30:033048611c01 110
wim 30:033048611c01 111 // Extract LCDType data
wim 30:033048611c01 112
wim 30:033048611c01 113 // Columns encoded in b7..b0
wim 30:033048611c01 114 _nr_cols = (_type & 0xFF);
wim 30:033048611c01 115
wim 30:033048611c01 116 // Rows encoded in b15..b8
wim 30:033048611c01 117 _nr_rows = ((_type >> 8) & 0xFF);
wim 30:033048611c01 118
wim 30:033048611c01 119 // Addressing mode encoded in b19..b16
wim 30:033048611c01 120 _addr_mode = _type & LCD_T_ADR_MSK;
wim 14:0c32b66b14b8 121 }
wim 14:0c32b66b14b8 122
wim 14:0c32b66b14b8 123
wim 21:9eb628d9e164 124 /** Init the LCD Controller(s)
wim 21:9eb628d9e164 125 * Clear display
wim 21:9eb628d9e164 126 */
wim 21:9eb628d9e164 127 void TextLCD_Base::_init() {
wim 15:b70ebfffb258 128
wim 15:b70ebfffb258 129 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 130 if(_type==LCD40x4) {
wim 30:033048611c01 131 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
wim 30:033048611c01 132 _initCtrl(); // Init 2nd controller
wim 15:b70ebfffb258 133 }
wim 15:b70ebfffb258 134
wim 15:b70ebfffb258 135 // Select and configure primary LCD controller
wim 27:22d5086f6ba6 136 _ctrl_idx=_LCDCtrl_0; // Select primary controller
wim 19:c747b9e2e7b8 137 _initCtrl(); // Init primary controller
wim 28:30fa94f7341c 138
wim 32:59c4b8f648d4 139 // Clear whole display and Reset Cursor location
wim 32:59c4b8f648d4 140 // Note: This will make sure that some 3-line displays that skip topline of a 4-line configuration
wim 32:59c4b8f648d4 141 // are cleared and init cursor correctly.
wim 32:59c4b8f648d4 142 cls();
wim 15:b70ebfffb258 143 }
wim 15:b70ebfffb258 144
wim 21:9eb628d9e164 145 /** Init the LCD controller
wim 21:9eb628d9e164 146 * 4-bit mode, number of lines, fonttype, no cursor etc
wim 30:033048611c01 147 *
wim 30:033048611c01 148 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 21:9eb628d9e164 149 */
wim 21:9eb628d9e164 150 void TextLCD_Base::_initCtrl() {
wim 32:59c4b8f648d4 151 int _bias_lines=0; // Set Bias and lines (Instr Set 1), temporary variable.
wim 32:59c4b8f648d4 152 int _lines=0; // Set lines (Ext Instr Set), temporary variable.
wim 32:59c4b8f648d4 153 // int _function_x=0; // Set ext. function (Ext Instr Set), temporary variable.
wim 32:59c4b8f648d4 154
wim 26:bd897a001012 155 this->_setRS(false); // command mode
wim 13:24506ba22480 156
wim 26:bd897a001012 157 wait_ms(20); // Wait 20ms to ensure powered up
simon 1:ac48b187213c 158
wim 17:652ab113bc2e 159 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
wim 17:652ab113bc2e 160 for (int i=0; i<3; i++) {
wim 17:652ab113bc2e 161 _writeNibble(0x3);
wim 20:e0da005a777f 162 wait_ms(15); // This command takes 1.64ms, so wait for it
wim 17:652ab113bc2e 163 }
wim 17:652ab113bc2e 164 _writeNibble(0x2); // 4-bit mode
wim 17:652ab113bc2e 165 wait_us(40); // most instructions take 40us
wim 18:bd65dc10f27f 166
wim 18:bd65dc10f27f 167 // Display is now in 4-bit mode
wim 27:22d5086f6ba6 168 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 25:6162b31128c9 169
wim 29:a3663151aa65 170 // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc
wim 19:c747b9e2e7b8 171 switch (_ctrl) {
wim 32:59c4b8f648d4 172
wim 29:a3663151aa65 173 case KS0078:
wim 29:a3663151aa65 174 // Initialise Display configuration
wim 29:a3663151aa65 175 switch (_type) {
wim 29:a3663151aa65 176 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 177 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 178 // case LCD12x1:
wim 29:a3663151aa65 179 case LCD16x1:
wim 30:033048611c01 180 // case LCD20x1:
wim 29:a3663151aa65 181 case LCD24x1:
wim 32:59c4b8f648d4 182 _function = 0x02; // Function set 001 DL N RE(0) DH REV (Std Regs)
wim 32:59c4b8f648d4 183 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 184 // N=0 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 185 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 186 // DH=1 (Disp shift enable, special mode for KS0078)
wim 32:59c4b8f648d4 187 // REV=0 (Reverse normal, special mode for KS0078)
wim 32:59c4b8f648d4 188
wim 32:59c4b8f648d4 189 _function_1 = 0x04; // Function set 001 DL N RE(1) BE 0 (Ext Regs)
wim 32:59c4b8f648d4 190 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 191 // N=0 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 192 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 193 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078)
wim 32:59c4b8f648d4 194 // 0
wim 30:033048611c01 195
wim 32:59c4b8f648d4 196 _function_x = 0x00; // Ext Function set 0000 1 FW BW NW (Ext Regs)
wim 32:59c4b8f648d4 197 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078)
wim 29:a3663151aa65 198 break;
wim 29:a3663151aa65 199
wim 32:59c4b8f648d4 200 // case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 201 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 202 // case LCD12x4D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 203 // case LCD16x3D: // Special mode for KS0078
wim 32:59c4b8f648d4 204 // case LCD16x4D: // Special mode for KS0078
wim 30:033048611c01 205 // case LCD24x3D: // Special mode for KS0078
wim 30:033048611c01 206 // case LCD24x3D1: // Special mode for KS0078
wim 30:033048611c01 207 case LCD24x4D: // Special mode for KS0078
wim 32:59c4b8f648d4 208 _function = 0x02; // Function set 001 DL N RE(0) DH REV (Std Regs)
wim 32:59c4b8f648d4 209 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 210 // N=0 (dont care for 4 line mode)
wim 32:59c4b8f648d4 211 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 212 // DH=1 (Disp shift enable, special mode for KS0078)
wim 32:59c4b8f648d4 213 // REV=0 (Reverse normal, special mode for KS0078)
wim 32:59c4b8f648d4 214
wim 32:59c4b8f648d4 215 _function_1 = 0x04; // Function set 001 DL N RE(1) BE 0 (Ext Regs)
wim 32:59c4b8f648d4 216 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 217 // N=0 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 218 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 219 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078)
wim 32:59c4b8f648d4 220 // 0
wim 29:a3663151aa65 221
wim 32:59c4b8f648d4 222 _function_x = 0x01; // Ext Function set 0000 1 FW BW NW (Ext Regs)
wim 32:59c4b8f648d4 223 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078)
wim 30:033048611c01 224 break;
wim 30:033048611c01 225
wim 29:a3663151aa65 226 default:
wim 30:033048611c01 227 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
wim 32:59c4b8f648d4 228 _function = 0x0A; // Function set 001 DL N RE(0) DH REV (Std Regs)
wim 32:59c4b8f648d4 229 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 230 // N=1 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 231 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 232 // DH=1 (Disp shift enable, special mode for KS0078)
wim 32:59c4b8f648d4 233 // REV=0 (Reverse normal, special mode for KS0078)
wim 32:59c4b8f648d4 234
wim 32:59c4b8f648d4 235 _function_1 = 0x0C; // Function set 001 DL N RE(1) BE 0 (Ext Regs)
wim 32:59c4b8f648d4 236 // DL=0 (4 bits bus)
wim 32:59c4b8f648d4 237 // N=1 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 238 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 239 // BE=0 (Blink Enable, CG/SEG RAM, special mode for KS0078)
wim 32:59c4b8f648d4 240 // 0
wim 30:033048611c01 241
wim 32:59c4b8f648d4 242 _function_x = 0x00; // Ext Function set 0000 1 FW BW NW (Ext Regs)
wim 32:59c4b8f648d4 243 // NW=0 (1,2 line), NW=1 (4 Line, special mode for KS0078)
wim 29:a3663151aa65 244 break;
wim 29:a3663151aa65 245 } // switch type
wim 29:a3663151aa65 246
wim 32:59c4b8f648d4 247 // init special features
wim 32:59c4b8f648d4 248 _writeCommand(0x20 | _function_1);// Function set 001 DL N RE(1) BE 0 (Ext Regs)
wim 32:59c4b8f648d4 249 // DL=0 (4 bits bus), DL=1 (8 bits mode)
wim 32:59c4b8f648d4 250 // N=0 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 251 // RE=1 (Ena Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 252 // BE=0 (Blink Enable/Disable, CG/SEG RAM, special mode for KS0078)
wim 32:59c4b8f648d4 253 // 0
wim 32:59c4b8f648d4 254
wim 32:59c4b8f648d4 255 _writeCommand(0x08 | _function_x); // Ext Function set 0000 1 FW BW NW (Ext Regs)
wim 32:59c4b8f648d4 256 // FW=0 (5-dot font, special mode for KS0078)
wim 32:59c4b8f648d4 257 // BW=0 (Cur BW invert disable, special mode for KS0078)
wim 32:59c4b8f648d4 258 // NW=0 (1,2 Line), NW=1 (4 line, special mode for KS0078)
wim 32:59c4b8f648d4 259
wim 32:59c4b8f648d4 260 _writeCommand(0x10); // Scroll/Shift set 0001 DS/HS4 DS/HS3 DS/HS2 DS/HS1 (Ext Regs)
wim 32:59c4b8f648d4 261 // Dotscroll/Display shift enable (Special mode for KS0078)
wim 32:59c4b8f648d4 262
wim 32:59c4b8f648d4 263 _writeCommand(0x80); // Scroll Quantity set 1 0 SQ5 SQ4 SQ3 SQ2 SQ1 SQ0 (Ext Regs)
wim 32:59c4b8f648d4 264 // Scroll quantity (Special mode for KS0078)
wim 32:59c4b8f648d4 265
wim 32:59c4b8f648d4 266 _writeCommand(0x20 | _function); // Function set 001 DL N RE(0) DH REV (Std Regs)
wim 32:59c4b8f648d4 267 // DL=0 (4 bits bus), DL=1 (8 bits mode)
wim 32:59c4b8f648d4 268 // N=0 (1 line mode), N=1 (2 line mode)
wim 32:59c4b8f648d4 269 // RE=0 (Dis. Extended Regs, special mode for KS0078)
wim 32:59c4b8f648d4 270 // DH=1 (Disp shift enable/disable, special mode for KS0078)
wim 32:59c4b8f648d4 271 // REV=0 (Reverse/Normal, special mode for KS0078)
wim 29:a3663151aa65 272 break; // case KS0078 Controller
wim 29:a3663151aa65 273
wim 26:bd897a001012 274 case ST7032_3V3:
wim 26:bd897a001012 275 // ST7032 controller: Initialise Voltage booster for VLCD. VDD=3V3
wim 26:bd897a001012 276 case ST7032_5V:
wim 32:59c4b8f648d4 277 // ST7032 controller: Disable Voltage booster for VLCD. VDD=5V
wim 29:a3663151aa65 278
wim 29:a3663151aa65 279 // Initialise Display configuration
wim 29:a3663151aa65 280 switch (_type) {
wim 29:a3663151aa65 281 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 282 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 283 // case LCD12x1:
wim 29:a3663151aa65 284 case LCD16x1:
wim 30:033048611c01 285 // case LCD20x1:
wim 32:59c4b8f648d4 286 case LCD24x1:
wim 32:59c4b8f648d4 287 _function = 0x00; // FUNCTION SET 0 0 1 DL=0 (4 bit), N=0 (1-line display mode), F=0 (5*7dot), 0, IS
wim 32:59c4b8f648d4 288 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 289 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 290 break;
wim 28:30fa94f7341c 291
wim 32:59c4b8f648d4 292 case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 293 case LCD12x3D1: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 294 case LCD12x4D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 295 case LCD24x4D: // Special mode for KS0078
wim 32:59c4b8f648d4 296 error("Error: LCD Controller type does not support this Display type\n\r");
wim 30:033048611c01 297 break;
wim 29:a3663151aa65 298
wim 32:59c4b8f648d4 299 default:
wim 32:59c4b8f648d4 300 // All other LCD types are initialised as 2 Line displays
wim 32:59c4b8f648d4 301 _function = 0x08; // FUNCTION SET 0 0 1 DL=0 (4 bit), N=1 (2-line display mode), F=0 (5*7dot), 0, IS
wim 32:59c4b8f648d4 302 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 303 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 304 break;
wim 32:59c4b8f648d4 305 } // switch type
wim 32:59c4b8f648d4 306
wim 32:59c4b8f648d4 307 // init special features
wim 32:59c4b8f648d4 308 _writeCommand(0x20 | _function | 0x01); // Set function, 0 0 1 DL N F 0 IS=1 Select Instruction Set = 1
wim 32:59c4b8f648d4 309
wim 32:59c4b8f648d4 310 _writeCommand(0x1C); // Internal OSC frequency adjustment Framefreq=183HZ, Bias will be 1/4 (IS=1)
wim 32:59c4b8f648d4 311
wim 32:59c4b8f648d4 312 _contrast = LCD_ST7032_CONTRAST;
wim 32:59c4b8f648d4 313 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast Low bits, 0 1 1 1 C3 C2 C1 C0 (IS=1)
wim 32:59c4b8f648d4 314
wim 32:59c4b8f648d4 315
wim 32:59c4b8f648d4 316 if (_ctrl == ST7032_3V3) {
wim 32:59c4b8f648d4 317 _icon_power = 0x04; // Icon display off, Booster circuit is turned on (IS=1)
wim 32:59c4b8f648d4 318 // Saved to allow contrast change at later time
wim 32:59c4b8f648d4 319 }
wim 32:59c4b8f648d4 320 else {
wim 32:59c4b8f648d4 321 _icon_power = 0x00; // Icon display off, Booster circuit is turned off (IS=1)
wim 32:59c4b8f648d4 322 // Saved to allow contrast change at later time
wim 32:59c4b8f648d4 323 }
wim 32:59c4b8f648d4 324 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Icon, Booster and Contrast High bits, 0 1 0 1 Ion Bon C5 C4 (IS=1)
wim 32:59c4b8f648d4 325 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 326
wim 32:59c4b8f648d4 327 _writeCommand(0x68 | (LCD_ST7032_RAB & 0x07)); // Voltage follower, 0 1 1 0 FOn=1, Ampl ratio Rab2=1, Rab1=0, Rab0=0 (IS=1)
wim 32:59c4b8f648d4 328 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 329
wim 32:59c4b8f648d4 330 _writeCommand(0x20 | _function); // Select Instruction Set = 0
wim 32:59c4b8f648d4 331
wim 32:59c4b8f648d4 332 break; // case ST7032_3V3 Controller
wim 32:59c4b8f648d4 333 // case ST7032_5V Controller
wim 32:59c4b8f648d4 334
wim 32:59c4b8f648d4 335 case ST7036_3V3:
wim 32:59c4b8f648d4 336 // ST7036 controller: Initialise Voltage booster for VLCD. VDD=3V3
wim 32:59c4b8f648d4 337 // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G)
wim 32:59c4b8f648d4 338 case ST7036_5V:
wim 32:59c4b8f648d4 339 // ST7036 controller: Disable Voltage booster for VLCD. VDD=5V
wim 32:59c4b8f648d4 340 // Note: supports 1,2 (LCD_T_A) or 3 lines (LCD_T_G)
wim 32:59c4b8f648d4 341
wim 32:59c4b8f648d4 342 // Initialise Display configuration
wim 32:59c4b8f648d4 343 switch (_type) {
wim 32:59c4b8f648d4 344 case LCD8x1: //8x1 is a regular 1 line display
wim 32:59c4b8f648d4 345 case LCD8x2B: //8x2D is a special case of 16x1
wim 32:59c4b8f648d4 346 // case LCD12x1:
wim 32:59c4b8f648d4 347 case LCD16x1:
wim 32:59c4b8f648d4 348 case LCD24x1:
wim 32:59c4b8f648d4 349 _function = 0x00; // Set function, 0 0 1 DL=0 (4-bit Databus), N=0 (1 Line), DH=0 (5x7font), IS2, IS1 (Select Instruction Set)
wim 32:59c4b8f648d4 350 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 351 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 352
wim 32:59c4b8f648d4 353 _bias_lines = 0x04; // Bias: 1/5, 1 or 2-Lines LCD
wim 32:59c4b8f648d4 354 break;
wim 32:59c4b8f648d4 355
wim 32:59c4b8f648d4 356 // case LCD12x3G: // Special mode for ST7036
wim 32:59c4b8f648d4 357 case LCD16x3G: // Special mode for ST7036
wim 32:59c4b8f648d4 358 _function = 0x08; // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set)
wim 32:59c4b8f648d4 359 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 360 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 361
wim 32:59c4b8f648d4 362 _bias_lines = 0x05; // Bias: 1/5, 3-Lines LCD
wim 32:59c4b8f648d4 363 break;
wim 32:59c4b8f648d4 364
wim 32:59c4b8f648d4 365 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 366 // case LCD16x3D1: // Special mode for SSD1803
wim 30:033048611c01 367 case LCD12x4D: // Special mode for PCF2116
wim 30:033048611c01 368 case LCD24x4D: // Special mode for KS0078
wim 30:033048611c01 369 error("Error: LCD Controller type does not support this Display type\n\r");
wim 29:a3663151aa65 370 break;
wim 28:30fa94f7341c 371
wim 29:a3663151aa65 372 default:
wim 32:59c4b8f648d4 373 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
wim 32:59c4b8f648d4 374 _function = 0x08; // Set function, 0 0 1 DL=0 (4-bit Databus), N=1 (2 Line), DH=0 (5x7font), IS2,IS1 (Select Instruction Set)
wim 32:59c4b8f648d4 375 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 376 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 377
wim 32:59c4b8f648d4 378 _bias_lines = 0x04; // Bias: 1/5, 1 or 2-Lines LCD
wim 32:59c4b8f648d4 379 break;
wim 32:59c4b8f648d4 380 } // switch type
wim 32:59c4b8f648d4 381
wim 29:a3663151aa65 382
wim 32:59c4b8f648d4 383 // init special features
wim 32:59c4b8f648d4 384 _writeCommand(0x20 | _function | 0x01); // Set function, IS2,IS1 = 01 (Select Instruction Set = 1)
wim 32:59c4b8f648d4 385 _writeCommand(0x10 | _bias_lines); // Set Bias and 1,2 or 3 lines (Instr Set 1)
wim 29:a3663151aa65 386
wim 32:59c4b8f648d4 387 _contrast = LCD_ST7036_CONTRAST;
wim 32:59c4b8f648d4 388 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast, 0 1 1 1 C3 C2 C1 C0 (Instr Set 1)
wim 32:59c4b8f648d4 389
wim 32:59c4b8f648d4 390 if (_ctrl == ST7036_3V3) {
wim 32:59c4b8f648d4 391 _icon_power = 0x04; // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=1 C5 C4 (Instr Set 1)
wim 32:59c4b8f648d4 392 // Saved to allow contrast change at later time
wim 32:59c4b8f648d4 393 }
wim 32:59c4b8f648d4 394 else {
wim 32:59c4b8f648d4 395 _icon_power = 0x00; // Set Icon, Booster, Contrast High bits, 0 1 0 1 Ion=0 Bon=0 C5 C4 (Instr Set 1)
wim 32:59c4b8f648d4 396 }
wim 29:a3663151aa65 397
wim 32:59c4b8f648d4 398 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Contrast C5, C4 (Instr Set 1)
wim 32:59c4b8f648d4 399 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 400
wim 32:59c4b8f648d4 401 _writeCommand(0x68 | (LCD_ST7036_RAB & 0x07)); // Voltagefollower On = 1, Ampl ratio Rab2, Rab1, Rab0 = 1 0 1 (Instr Set 1)
wim 32:59c4b8f648d4 402 wait_ms(10); // Wait 10ms to ensure powered up
wim 28:30fa94f7341c 403
wim 32:59c4b8f648d4 404 _writeCommand(0x20 | _function); // Set function, IS2,IS1 = 00 (Select Instruction Set = 0)
wim 32:59c4b8f648d4 405
wim 32:59c4b8f648d4 406 break; // case ST7036_3V3 Controller
wim 32:59c4b8f648d4 407 // case ST7036_5V Controller
wim 32:59c4b8f648d4 408
wim 32:59c4b8f648d4 409 case SSD1803_3V3:
wim 32:59c4b8f648d4 410 // SSD1803 controller: Initialise Voltage booster for VLCD. VDD=3V3
wim 32:59c4b8f648d4 411 // Note: supports 1,2, 3 or 4 lines
wim 32:59c4b8f648d4 412 // case SSD1803_5V:
wim 32:59c4b8f648d4 413 // SSD1803 controller: No Voltage booster for VLCD. VDD=5V
wim 32:59c4b8f648d4 414
wim 29:a3663151aa65 415 // Initialise Display configuration
wim 29:a3663151aa65 416 switch (_type) {
wim 29:a3663151aa65 417 case LCD8x1: //8x1 is a regular 1 line display
wim 30:033048611c01 418 case LCD8x2B: //8x2D is a special case of 16x1
wim 29:a3663151aa65 419 // case LCD12x1:
wim 29:a3663151aa65 420 case LCD16x1:
wim 29:a3663151aa65 421 case LCD24x1:
wim 32:59c4b8f648d4 422 _function = 0x00; // Set function 0 0 1 DL N DH RE(0) IS
wim 32:59c4b8f648d4 423 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 424 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 425 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 426 // N=0 1 Line / 3 Line
wim 32:59c4b8f648d4 427 // DH=0 Double Height disable
wim 32:59c4b8f648d4 428 // IS=0
wim 32:59c4b8f648d4 429
wim 32:59c4b8f648d4 430 _function_1 = 0x00; // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 431 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 432 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 433 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 434 // N=0 1 Line / 3 Line
wim 32:59c4b8f648d4 435 // BE=0 Blink Enable off, special feature of SSD1803
wim 32:59c4b8f648d4 436 // REV=0 Reverse off, special feature of SSD1803
wim 32:59c4b8f648d4 437
wim 32:59c4b8f648d4 438 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW
wim 32:59c4b8f648d4 439 // NW=0 1-Line LCD (N=0)
wim 29:a3663151aa65 440 break;
wim 32:59c4b8f648d4 441
wim 32:59c4b8f648d4 442 case LCD12x3D: // Special mode for KS0078, ST7036 and PCF21XX
wim 32:59c4b8f648d4 443 // case LCD12x3D1: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 444 case LCD16x3D: // Special mode for KS0078 and ST7036
wim 32:59c4b8f648d4 445 // case LCD16x3D1: // Special mode for SSD1803
wim 32:59c4b8f648d4 446 // case LCD20x3D: // Special mode for SSD1803
wim 32:59c4b8f648d4 447 _function = 0x00; // Set function 0 0 1 DL N DH RE(0) IS
wim 32:59c4b8f648d4 448 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 449 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 450 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 451 // N=0 1 Line / 3 Line
wim 32:59c4b8f648d4 452 // DH=0 Double Height disable
wim 32:59c4b8f648d4 453 // IS=0
wim 32:59c4b8f648d4 454
wim 32:59c4b8f648d4 455 _function_1 = 0x00; // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 456 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 457 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 458 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 459 // N=0 1 Line / 3 Line
wim 32:59c4b8f648d4 460 // BE=0 Blink Enable off, special feature of SSD1803
wim 32:59c4b8f648d4 461 // REV=0 Reverse off, special feature of SSD1803
wim 32:59c4b8f648d4 462
wim 32:59c4b8f648d4 463 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW
wim 32:59c4b8f648d4 464 // NW=1 3-Line LCD (N=0)
wim 29:a3663151aa65 465 break;
wim 30:033048611c01 466
wim 32:59c4b8f648d4 467 case LCD20x4D: // Special mode for SSD1803
wim 32:59c4b8f648d4 468 _function = 0x08; // Set function 0 0 1 DL N DH RE(0) IS
wim 32:59c4b8f648d4 469 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 470 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 471 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 472 // N=1 4 Line
wim 32:59c4b8f648d4 473 // DH=0 Double Height disable
wim 32:59c4b8f648d4 474 // IS=0
wim 32:59c4b8f648d4 475
wim 32:59c4b8f648d4 476 _function_1 = 0x08; // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 477 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 478 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 479 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 480 // N=1 4 Line
wim 32:59c4b8f648d4 481 // BE=0 Blink Enable off, special feature of SSD1803
wim 32:59c4b8f648d4 482 // REV=0 Reverse off, special feature of SSD1803
wim 32:59c4b8f648d4 483
wim 32:59c4b8f648d4 484 _lines = 0x01; // Ext function set 0 0 0 0 1 FW BW NW
wim 32:59c4b8f648d4 485 // NW=1 4-Line LCD (N=1)
wim 32:59c4b8f648d4 486 break;
wim 32:59c4b8f648d4 487
wim 32:59c4b8f648d4 488 case LCD24x4D: // Special mode for KS0078
wim 30:033048611c01 489 error("Error: LCD Controller type does not support this Display type\n\r");
wim 30:033048611c01 490 break;
wim 30:033048611c01 491
wim 29:a3663151aa65 492 default:
wim 30:033048611c01 493 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
wim 32:59c4b8f648d4 494 _function = 0x08; // Set function 0 0 1 DL N DH RE(0) IS
wim 32:59c4b8f648d4 495 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 496 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 497 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 498 // N=1 2 line / 4 Line
wim 32:59c4b8f648d4 499 // DH=0 Double Height disable
wim 32:59c4b8f648d4 500 // IS=0
wim 29:a3663151aa65 501
wim 32:59c4b8f648d4 502 _function_1 = 0x08; // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 503 // Saved to allow switch between Instruction sets at later time
wim 32:59c4b8f648d4 504 // DL=0 4-bit Databus,
wim 32:59c4b8f648d4 505 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 32:59c4b8f648d4 506 // N=1 2 line / 4 Line
wim 32:59c4b8f648d4 507 // BE=0 Blink Enable off, special feature of SSD1803
wim 32:59c4b8f648d4 508 // REV=0 Reverse off, special feature of SSD1803
wim 32:59c4b8f648d4 509
wim 32:59c4b8f648d4 510 _lines = 0x00; // Ext function set 0 0 0 0 1 FW BW NW
wim 32:59c4b8f648d4 511 // NW=0 2-Line LCD (N=1)
wim 32:59c4b8f648d4 512 break;
wim 32:59c4b8f648d4 513 } // switch type
wim 32:59c4b8f648d4 514
wim 32:59c4b8f648d4 515
wim 32:59c4b8f648d4 516 // init special features
wim 32:59c4b8f648d4 517 _writeCommand(0x20 | _function_1 | 0x02); // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 518 // Select Extended Instruction Set
wim 32:59c4b8f648d4 519
wim 32:59c4b8f648d4 520 _writeCommand(0x10); // Double Height and Bias, 0 0 0 1 UD2=0, UD1=0, BS1=0 Bias 1/5, DH=0 (Ext Instr Set)
wim 32:59c4b8f648d4 521
wim 32:59c4b8f648d4 522 _writeCommand(0x08 | _lines); // Set ext function 0 0 0 0 1 FW BW NW 1,2,3 or 4 lines (Ext Instr Set)
wim 32:59c4b8f648d4 523
wim 32:59c4b8f648d4 524 _writeCommand(0x06); // Set ext entry mode, 0 0 0 0 0 1 BDC=1 COM1-31, BDS=0 SEG100-1 "Bottom View" (Ext Instr Set)
wim 32:59c4b8f648d4 525 // _writeCommand(0x04); // Set ext entry mode, 0 0 0 0 0 1 BDC=0 COM31-1, BDS=0 SEG100-1 "Top View" (Ext Instr Set)
wim 32:59c4b8f648d4 526
wim 32:59c4b8f648d4 527 // _writeCommand(0x76); // Set TC Control, 0 1 1 1 0 1 1 0 (Ext Instr Set)
wim 32:59c4b8f648d4 528 // _writeData(0x02); // Set TC data, 0 0 0 0 0 TC2,TC1,TC0 = 0 1 0 (Ext Instr Set)
wim 32:59c4b8f648d4 529
wim 32:59c4b8f648d4 530 _writeCommand(0x20 | _function | 0x01); // Set function, 0 0 1 DL N DH RE(0) IS=1 Select Instruction Set 1
wim 32:59c4b8f648d4 531 // Select Std Instr set, Select IS=1
wim 32:59c4b8f648d4 532
wim 32:59c4b8f648d4 533 _contrast = LCD_SSD1_CONTRAST;
wim 32:59c4b8f648d4 534 _writeCommand(0x70 | (_contrast & 0x0F)); // Set Contrast 0 1 1 1 C3, C2, C1, C0 (Instr Set 1)
wim 32:59c4b8f648d4 535
wim 32:59c4b8f648d4 536 _icon_power = 0x04; // Icon off, Booster on (Instr Set 1)
wim 32:59c4b8f648d4 537 // Saved to allow contrast change at later time
wim 32:59c4b8f648d4 538 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Set Power, Icon and Contrast, 0 1 0 1 Ion Bon C5 C4 (Instr Set 1)
wim 32:59c4b8f648d4 539 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 540
wim 32:59c4b8f648d4 541 _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)
wim 32:59c4b8f648d4 542 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 543
wim 32:59c4b8f648d4 544 _writeCommand(0x20 | _function_1 | 0x02); // Set function, 0 0 1 DL N BE RE(1) REV
wim 32:59c4b8f648d4 545 // Select Extended Instruction Set 1
wim 32:59c4b8f648d4 546 _writeCommand(0x10); // Shift/Scroll enable, 0 0 0 1 DS4/HS4 DS3/HS3 DS2/HS2 DS1/HS1 (Ext Instr Set 1)
wim 32:59c4b8f648d4 547
wim 32:59c4b8f648d4 548
wim 32:59c4b8f648d4 549 _writeCommand(0x20 | _function); // Set function, 0 0 1 DL N DH RE(0) IS=0 Select Instruction Set 0
wim 32:59c4b8f648d4 550 // Select Std Instr set, Select IS=0
wim 32:59c4b8f648d4 551
wim 32:59c4b8f648d4 552 break; // case SSD1803 Controller
wim 32:59c4b8f648d4 553
wim 29:a3663151aa65 554
wim 32:59c4b8f648d4 555 // Note1: The PCF21XX family of controllers has several types that dont have an onboard voltage generator for V-LCD.
wim 32:59c4b8f648d4 556 // You must supply this LCD voltage externally and not try to enable VGen.
wim 32:59c4b8f648d4 557 // Note2: The early versions of PCF2116 controllers (eg PCF2116C) can not generate sufficiently negative voltage for the LCD at a VDD of 3V3.
wim 32:59c4b8f648d4 558 // You must supply this voltage externally and not enable VGen or you must use a higher VDD (e.g. 5V) and enable VGen.
wim 32:59c4b8f648d4 559 // More recent versions of the controller (eg PCF2116K) have an improved VGen that will work with 3V3.
wim 32:59c4b8f648d4 560 // 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
wim 32:59c4b8f648d4 561 // contrast control similar to that of pin 3 on the standard 14pin LCD module connector.
wim 32:59c4b8f648d4 562 // You can disable VGen by connecting Vo to VDD. VLCD will then be used directly as LCD voltage.
wim 32:59c4b8f648d4 563 // 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.
wim 32:59c4b8f648d4 564 // 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.
wim 32:59c4b8f648d4 565 // Note5: See datasheet, members of the PCF21XX family support different numbers of rows/columns. Not all can support 3 or 4 rows.
wim 32:59c4b8f648d4 566 // 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..
wim 32:59c4b8f648d4 567
wim 30:033048611c01 568 case PCF2113_3V3:
wim 32:59c4b8f648d4 569 // PCF2113 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
wim 29:a3663151aa65 570 // Initialise Display configuration
wim 29:a3663151aa65 571 switch (_type) {
wim 29:a3663151aa65 572 // case LCD12x1:
wim 32:59c4b8f648d4 573 // _function = 0x02; // FUNCTION SET DL=0 4 bit, 0, M=0 1-line/12 chars display mode, SL=1
wim 32:59c4b8f648d4 574 // Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 575 case LCD24x1:
wim 32:59c4b8f648d4 576 _function = 0x00; // FUNCTION SET DL=0 4 bit, 0, M=0 1-line/24 chars display mode, SL=0
wim 32:59c4b8f648d4 577 // Note: 4 bit mode is ignored for I2C mode
wim 30:033048611c01 578 break;
wim 30:033048611c01 579
wim 30:033048611c01 580 //Tested OK for PCF2113
wim 30:033048611c01 581 case LCD12x2:
wim 32:59c4b8f648d4 582 _function = 0x04; // FUNCTION SET DL=0 4 bit, 0, M=1 2-line/12 chars display mode, SL=0
wim 30:033048611c01 583 break;
wim 30:033048611c01 584
wim 30:033048611c01 585 default:
wim 30:033048611c01 586 error("Error: LCD Controller type does not support this Display type\n\r");
wim 30:033048611c01 587 break;
wim 30:033048611c01 588
wim 30:033048611c01 589 } // switch type
wim 30:033048611c01 590
wim 32:59c4b8f648d4 591 // Init special features
wim 32:59c4b8f648d4 592 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instruction Set = 1
wim 32:59c4b8f648d4 593
wim 32:59c4b8f648d4 594 _writeCommand(0x04); // DISP CONF SET (Instr. Set 1) 0000 0, 1, P=0, Q=0
wim 32:59c4b8f648d4 595 _writeCommand(0x10); // TEMP CTRL SET (Instr. Set 1) 0001 0, 0, TC1=0, TC2=0
wim 32:59c4b8f648d4 596 // _writeCommand(0x42); // HV GEN (Instr. Set 1) 0100 S1=1, S2=0 (2x multiplier)
wim 32:59c4b8f648d4 597 _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03)); // HV GEN (Instr. Set 1) 0100 S1=1, S2=0 (2x multiplier)
wim 32:59c4b8f648d4 598
wim 32:59c4b8f648d4 599 _contrast = LCD_PCF2_CONTRAST;
wim 32:59c4b8f648d4 600 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=0, VA=contrast
wim 32:59c4b8f648d4 601 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=1, VB=contrast
wim 32:59c4b8f648d4 602 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 603
wim 32:59c4b8f648d4 604 _writeCommand(0x02); // SCRN CONF (Instr. Set 1) L=0
wim 32:59c4b8f648d4 605 _writeCommand(0x08); // ICON CONF (Instr. Set 1) IM=0 (Char mode) IB=0 (no icon blink) DM=0 (no direct mode)
wim 32:59c4b8f648d4 606
wim 32:59c4b8f648d4 607 _writeCommand(0x20 | _function); // Select Instruction Set = 0
wim 32:59c4b8f648d4 608
wim 30:033048611c01 609 break; // case PCF2113_3V3 Controller
wim 30:033048611c01 610
wim 30:033048611c01 611
wim 32:59c4b8f648d4 612 // case PCF2113_5V:
wim 32:59c4b8f648d4 613 // PCF2113 controller: No Voltage generator for VLCD. VDD=5V. Contrast voltage controlled by VA or VB.
wim 32:59c4b8f648d4 614 //@TODO
wim 32:59c4b8f648d4 615
wim 30:033048611c01 616
wim 30:033048611c01 617 case PCF2116_3V3:
wim 32:59c4b8f648d4 618 // PCF2116 controller: Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage.
wim 30:033048611c01 619 // Initialise Display configuration
wim 30:033048611c01 620 switch (_type) {
wim 30:033048611c01 621 // case LCD12x1:
wim 30:033048611c01 622 // case LCD12x2:
wim 30:033048611c01 623 case LCD24x1:
wim 32:59c4b8f648d4 624 _writeCommand(0x22); //FUNCTION SET 4 bit, N/M=0 1-line/24 chars display mode, G=1 Vgen on
wim 29:a3663151aa65 625 //Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 626 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 627 break;
wim 29:a3663151aa65 628
wim 32:59c4b8f648d4 629 case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 630 case LCD12x3D1: // Special mode for PCF21XX
wim 32:59c4b8f648d4 631 case LCD12x4D: // Special mode for PCF21XX:
wim 30:033048611c01 632 _writeCommand(0x2E); //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode, G=1 VGen on
wim 29:a3663151aa65 633 //Note: 4 bit mode is ignored for I2C mode
wim 29:a3663151aa65 634 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 635 break;
wim 30:033048611c01 636
wim 30:033048611c01 637 case LCD24x2:
wim 30:033048611c01 638 _writeCommand(0x2A); //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode, G=1 VGen on
wim 29:a3663151aa65 639 //Note: 4 bit mode is ignored for I2C mode
wim 30:033048611c01 640 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 641 break;
wim 32:59c4b8f648d4 642
wim 30:033048611c01 643 default:
wim 30:033048611c01 644 error("Error: LCD Controller type does not support this Display type\n\r");
wim 30:033048611c01 645 break;
wim 30:033048611c01 646
wim 29:a3663151aa65 647 } // switch type
wim 29:a3663151aa65 648
wim 30:033048611c01 649 break; // case PCF2116_3V3 Controller
wim 29:a3663151aa65 650
wim 32:59c4b8f648d4 651
wim 32:59c4b8f648d4 652 //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
wim 32:59c4b8f648d4 653 //@TODO
wim 32:59c4b8f648d4 654 case PCF2116_5V:
wim 32:59c4b8f648d4 655 // PCF2116 controller: No Voltage generator for VLCD. VDD=5V. V0 controls contrast voltage.
wim 32:59c4b8f648d4 656 // Initialise Display configuration
wim 32:59c4b8f648d4 657 switch (_type) {
wim 32:59c4b8f648d4 658 // case LCD12x1:
wim 32:59c4b8f648d4 659 // case LCD12x2:
wim 32:59c4b8f648d4 660 // case LCD24x1:
wim 32:59c4b8f648d4 661 // _writeCommand(0x20); //FUNCTION SET 4 bit, N/M=0 1-line/24 chars display mode
wim 32:59c4b8f648d4 662 //Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 663 // wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 664 // break;
wim 32:59c4b8f648d4 665
wim 32:59c4b8f648d4 666 case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 667 case LCD12x3D1: // Special mode for PCF21XX
wim 32:59c4b8f648d4 668 case LCD12x4D: // Special mode for PCF21XX:
wim 32:59c4b8f648d4 669 // _writeCommand(0x34); //FUNCTION SET 8 bit, N=0/M=1 4-line/12 chars display mode OK
wim 32:59c4b8f648d4 670 // _writeCommand(0x24); //FUNCTION SET 4 bit, N=0/M=1 4-line/12 chars display mode OK
wim 32:59c4b8f648d4 671 _writeCommand(0x2C); //FUNCTION SET 4 bit, N=1/M=1 4-line/12 chars display mode OK
wim 32:59c4b8f648d4 672 //Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 673 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 674 break;
wim 32:59c4b8f648d4 675
wim 32:59c4b8f648d4 676 // case LCD24x2:
wim 32:59c4b8f648d4 677 // _writeCommand(0x28); //FUNCTION SET 4 bit, N=1/M=0 2-line/24 chars display mode
wim 32:59c4b8f648d4 678 //Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 679 // wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 680 // break;
wim 32:59c4b8f648d4 681
wim 32:59c4b8f648d4 682 default:
wim 32:59c4b8f648d4 683 error("Error: LCD Controller type does not support this Display type\n\r");
wim 32:59c4b8f648d4 684 break;
wim 32:59c4b8f648d4 685
wim 32:59c4b8f648d4 686 } // switch type
wim 32:59c4b8f648d4 687
wim 32:59c4b8f648d4 688 break; // case PCF2116_5V Controller
wim 32:59c4b8f648d4 689
wim 32:59c4b8f648d4 690 case PCF2119_3V3:
wim 32:59c4b8f648d4 691 // PCF2119 controller: Initialise Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
wim 32:59c4b8f648d4 692 // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters.
wim 32:59c4b8f648d4 693 // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00.
wim 32:59c4b8f648d4 694
wim 32:59c4b8f648d4 695 //POR or Hardware Reset should be applied
wim 32:59c4b8f648d4 696 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 697
wim 32:59c4b8f648d4 698 // Initialise Display configuration
wim 32:59c4b8f648d4 699 switch (_type) {
wim 32:59c4b8f648d4 700 case LCD8x1:
wim 32:59c4b8f648d4 701 // case LCD12x1:
wim 32:59c4b8f648d4 702 case LCD16x1:
wim 32:59c4b8f648d4 703 _function = 0x02; // FUNCTION SET DL=0 4 bit, 0 , M=0 1-line/16 chars display mode, SL=1
wim 32:59c4b8f648d4 704 // Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 705 break;
wim 32:59c4b8f648d4 706
wim 32:59c4b8f648d4 707 case LCD24x1:
wim 32:59c4b8f648d4 708 // case LCD32x1:
wim 32:59c4b8f648d4 709 _function = 0x00; // FUNCTION SET DL=0 4 bit, 0 , M=0 1-line/32 chars display mode, SL=0
wim 32:59c4b8f648d4 710 // Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 711 break;
wim 32:59c4b8f648d4 712
wim 32:59c4b8f648d4 713 case LCD8x2:
wim 32:59c4b8f648d4 714 // case LCD12x2:
wim 32:59c4b8f648d4 715 case LCD16x2:
wim 32:59c4b8f648d4 716 _function = 0x04; // FUNCTION SET DL=0 4 bit, 0, M=1 2-line/16 chars display mode, SL=0
wim 32:59c4b8f648d4 717 // Note: 4 bit mode is ignored for I2C mode
wim 32:59c4b8f648d4 718 break;
wim 32:59c4b8f648d4 719
wim 32:59c4b8f648d4 720 default:
wim 32:59c4b8f648d4 721 error("Error: LCD Controller type does not support this Display type\n\r");
wim 32:59c4b8f648d4 722 break;
wim 32:59c4b8f648d4 723
wim 32:59c4b8f648d4 724 } // switch type
wim 32:59c4b8f648d4 725
wim 32:59c4b8f648d4 726 // Init special features
wim 32:59c4b8f648d4 727 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instruction Set = 1
wim 32:59c4b8f648d4 728
wim 32:59c4b8f648d4 729 _writeCommand(0x04); // DISP CONF SET (Instr. Set 1) 0000, 0, 1, P=0, Q=0
wim 32:59c4b8f648d4 730 _writeCommand(0x10); // TEMP CTRL SET (Instr. Set 1) 0001, 0, 0, TC1=0, TC2=0
wim 32:59c4b8f648d4 731 // _writeCommand(0x42); // HV GEN (Instr. Set 1) 0100, 0, 0, S1=1, S2=0 (2x multiplier)
wim 32:59c4b8f648d4 732 _writeCommand(0x40 | (LCD_PCF2_S12 & 0x03)); // HV GEN (Instr. Set 1) 0100, 0, 0, S1=1, S2=0 (2x multiplier)
wim 32:59c4b8f648d4 733
wim 32:59c4b8f648d4 734 _contrast = LCD_PCF2_CONTRAST;
wim 32:59c4b8f648d4 735 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=0, VA=contrast
wim 32:59c4b8f648d4 736 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=1, VB=contrast
wim 32:59c4b8f648d4 737 wait_ms(10); // Wait 10ms to ensure powered up
wim 32:59c4b8f648d4 738
wim 32:59c4b8f648d4 739 _writeCommand(0x02); // SCRN CONF (Instr. Set 1) L=0
wim 32:59c4b8f648d4 740 _writeCommand(0x08); // ICON CONF (Instr. Set 1) IM=0 (Char mode) IB=0 (no icon blink) DM=0 (no direct mode)
wim 32:59c4b8f648d4 741
wim 32:59c4b8f648d4 742 _writeCommand(0x20 | _function); // Select Instruction Set = 0
wim 32:59c4b8f648d4 743
wim 32:59c4b8f648d4 744 break; // case PCF2119_3V3 Controller
wim 32:59c4b8f648d4 745
wim 32:59c4b8f648d4 746 // case PCF2119_5V:
wim 32:59c4b8f648d4 747 // PCF2119 controller: No Voltage booster for VLCD. VDD=3V3. VA and VB control contrast.
wim 32:59c4b8f648d4 748 // Note1: See datasheet, the PCF2119 supports icons and provides separate constrast control for Icons and characters.
wim 32:59c4b8f648d4 749 // Note2: Vgen is switched off when the contrast voltage VA or VB is set to 0x00.
wim 30:033048611c01 750 //@TODO
wim 29:a3663151aa65 751
wim 19:c747b9e2e7b8 752 case WS0010:
wim 19:c747b9e2e7b8 753 // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs
wim 30:033048611c01 754 // Note1: Identical to RS0010
wim 30:033048611c01 755 // Note2: supports 1 or 2 lines (and 16x100 graphics)
wim 30:033048611c01 756 // supports 4 fonts (English/Japanese (default), Western European-I, English/Russian, Western European-II)
wim 19:c747b9e2e7b8 757 // Cursor/Disp shift set 0001 SC RL 0 0
wim 19:c747b9e2e7b8 758 //
wim 30:033048611c01 759 // Mode and Power set 0001 GC PWR 1 1
wim 19:c747b9e2e7b8 760 // GC = 0 (Graph Mode=1, Char Mode=0)
wim 30:033048611c01 761 // PWR = 1 (DC/DC On/Off)
wim 30:033048611c01 762
wim 30:033048611c01 763 //@Todo: This may be needed to enable a warm reboot
wim 32:59c4b8f648d4 764 //_writeCommand(0x13); // Char mode, DC/DC off
wim 30:033048611c01 765 //wait_ms(10); // Wait 10ms to ensure powered down
wim 32:59c4b8f648d4 766 _writeCommand(0x17); // Char mode, DC/DC on
wim 30:033048611c01 767 wait_ms(10); // Wait 10ms to ensure powered up
wim 29:a3663151aa65 768
wim 29:a3663151aa65 769 // Initialise Display configuration
wim 29:a3663151aa65 770 switch (_type) {
wim 29:a3663151aa65 771 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 772 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 773 // case LCD12x1:
wim 29:a3663151aa65 774 case LCD16x1:
wim 30:033048611c01 775 case LCD24x1:
wim 30:033048611c01 776 _writeCommand(0x20); // Function set 001 DL N F FT1 FT0
wim 30:033048611c01 777 // DL=0 (4 bits bus)
wim 30:033048611c01 778 // N=0 (1 line)
wim 30:033048611c01 779 // F=0 (5x7 dots font)
wim 30:033048611c01 780 // FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2
wim 30:033048611c01 781 break;
wim 30:033048611c01 782
wim 32:59c4b8f648d4 783 case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 784 case LCD12x3D1: // Special mode for PCF21XX
wim 32:59c4b8f648d4 785 case LCD12x4D: // Special mode for PCF21XX:
wim 30:033048611c01 786 case LCD24x4D: // Special mode for KS0078
wim 30:033048611c01 787 error("Error: LCD Controller type does not support this Display type\n\r");
wim 29:a3663151aa65 788 break;
wim 29:a3663151aa65 789
wim 29:a3663151aa65 790 default:
wim 30:033048611c01 791 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
wim 30:033048611c01 792 _writeCommand(0x28); // Function set 001 DL N F FT1 FT0
wim 30:033048611c01 793 // DL=0 (4 bits bus)
wim 30:033048611c01 794 // N=1 (2 lines)
wim 30:033048611c01 795 // F=0 (5x7 dots font)
wim 30:033048611c01 796 // FT=00 (00 = Engl/Jap, 01 = WestEur1, 10 = Engl/Russian, 11 = WestEur2
wim 30:033048611c01 797
wim 29:a3663151aa65 798 break;
wim 29:a3663151aa65 799 } // switch type
wim 29:a3663151aa65 800
wim 32:59c4b8f648d4 801 break; // case WS0010 Controller
wim 29:a3663151aa65 802
wim 19:c747b9e2e7b8 803 default:
wim 32:59c4b8f648d4 804 // Devices fully compatible to HD44780 that do not use any DC/DC Voltage converters but external VLCD, no icons etc
wim 10:dd9b3a696acd 805
wim 29:a3663151aa65 806 // Initialise Display configuration
wim 29:a3663151aa65 807 switch (_type) {
wim 29:a3663151aa65 808 case LCD8x1: //8x1 is a regular 1 line display
wim 29:a3663151aa65 809 case LCD8x2B: //8x2B is a special case of 16x1
wim 29:a3663151aa65 810 // case LCD12x1:
wim 29:a3663151aa65 811 case LCD16x1:
wim 30:033048611c01 812 // case LCD20x1:
wim 29:a3663151aa65 813 case LCD24x1:
wim 30:033048611c01 814 // case LCD40x1:
wim 32:59c4b8f648d4 815 _function = 0x00; // Function set 001 DL N F - -
wim 29:a3663151aa65 816 // DL=0 (4 bits bus)
wim 29:a3663151aa65 817 // N=0 (1 line)
wim 29:a3663151aa65 818 // F=0 (5x7 dots font)
wim 32:59c4b8f648d4 819 _writeCommand(0x20 | _function);
wim 29:a3663151aa65 820 break;
wim 29:a3663151aa65 821
wim 32:59c4b8f648d4 822 case LCD12x3D: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 823 case LCD12x3D1: // Special mode for KS0078 and PCF21XX
wim 32:59c4b8f648d4 824 case LCD12x4D: // Special mode for KS0078 and PCF21XX:
wim 32:59c4b8f648d4 825 case LCD16x3D: // Special mode for KS0078 and ST7036
wim 32:59c4b8f648d4 826 // case LCD16x3D1: // Special mode for KS0078
wim 30:033048611c01 827 // case LCD24x3D: // Special mode for KS0078
wim 32:59c4b8f648d4 828 // case LCD24x3D1: // Special mode for KS0078
wim 30:033048611c01 829 case LCD24x4D: // Special mode for KS0078
wim 30:033048611c01 830 error("Error: LCD Controller type does not support this Display type\n\r");
wim 30:033048611c01 831 break;
wim 30:033048611c01 832
wim 30:033048611c01 833 // All other LCD types are initialised as 2 Line displays (including LCD16x1C and LCD40x4)
wim 29:a3663151aa65 834 default:
wim 32:59c4b8f648d4 835 _function = 0x08; // Function set 001 DL N F - -
wim 29:a3663151aa65 836 // DL=0 (4 bits bus)
wim 29:a3663151aa65 837 // Note: 4 bit mode is ignored for native SPI and I2C devices
wim 29:a3663151aa65 838 // N=1 (2 lines)
wim 29:a3663151aa65 839 // F=0 (5x7 dots font, only option for 2 line display)
wim 32:59c4b8f648d4 840 // - (Don't care)
wim 32:59c4b8f648d4 841 _writeCommand(0x20 | _function);
wim 29:a3663151aa65 842 break;
wim 29:a3663151aa65 843 } // switch type
wim 10:dd9b3a696acd 844
wim 29:a3663151aa65 845 break; // case default Controller
wim 29:a3663151aa65 846
wim 29:a3663151aa65 847 } // switch Controller specific initialisations
wim 29:a3663151aa65 848
wim 10:dd9b3a696acd 849
wim 30:033048611c01 850 // Controller general initialisations
wim 32:59c4b8f648d4 851 // _writeCommand(0x01); // cls, and set cursor to 0
wim 32:59c4b8f648d4 852 // wait_ms(10); // The CLS command takes 1.64 ms.
wim 32:59c4b8f648d4 853 // // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 28:30fa94f7341c 854
wim 28:30fa94f7341c 855 _writeCommand(0x02); // Return Home
wim 28:30fa94f7341c 856 // Cursor Home, DDRAM Address to Origin
wim 28:30fa94f7341c 857
wim 28:30fa94f7341c 858 _writeCommand(0x06); // Entry Mode 0000 0 1 I/D S
wim 13:24506ba22480 859 // Cursor Direction and Display Shift
wim 28:30fa94f7341c 860 // I/D=1 (Cur incr)
wim 28:30fa94f7341c 861 // S=0 (No display shift)
wim 10:dd9b3a696acd 862
wim 29:a3663151aa65 863 _writeCommand(0x14); // Cursor or Display shift 0001 S/C R/L x x
wim 29:a3663151aa65 864 // S/C=0 Cursor moves
wim 29:a3663151aa65 865 // R/L=1 Right
wim 29:a3663151aa65 866 //
wim 29:a3663151aa65 867
wim 13:24506ba22480 868 // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
wim 17:652ab113bc2e 869 // // Display On, Cursor Off, Blink Off
wim 21:9eb628d9e164 870 setCursor(CurOff_BlkOff);
wim 21:9eb628d9e164 871 setMode(DispOn);
simon 1:ac48b187213c 872 }
simon 1:ac48b187213c 873
wim 8:03116f75b66e 874
wim 21:9eb628d9e164 875 /** Clear the screen, Cursor home.
wim 21:9eb628d9e164 876 */
wim 21:9eb628d9e164 877 void TextLCD_Base::cls() {
wim 15:b70ebfffb258 878
wim 15:b70ebfffb258 879 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 880 if(_type==LCD40x4) {
wim 21:9eb628d9e164 881 _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
wim 15:b70ebfffb258 882
wim 15:b70ebfffb258 883 // Second LCD controller Cursor always Off
wim 21:9eb628d9e164 884 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 15:b70ebfffb258 885
wim 15:b70ebfffb258 886 // Second LCD controller Clearscreen
wim 27:22d5086f6ba6 887 _writeCommand(0x01); // cls, and set cursor to 0
wim 29:a3663151aa65 888 wait_ms(10); // The CLS command takes 1.64 ms.
wim 29:a3663151aa65 889 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 890
wim 21:9eb628d9e164 891 _ctrl_idx=_LCDCtrl_0; // Select primary controller
wim 15:b70ebfffb258 892 }
wim 15:b70ebfffb258 893
wim 15:b70ebfffb258 894 // Primary LCD controller Clearscreen
wim 27:22d5086f6ba6 895 _writeCommand(0x01); // cls, and set cursor to 0
wim 29:a3663151aa65 896 wait_ms(10); // The CLS command takes 1.64 ms.
wim 29:a3663151aa65 897 // Since we are not using the Busy flag, Lets be safe and take 10 ms
wim 15:b70ebfffb258 898
wim 15:b70ebfffb258 899 // Restore cursormode on primary LCD controller when needed
wim 15:b70ebfffb258 900 if(_type==LCD40x4) {
wim 17:652ab113bc2e 901 _setCursorAndDisplayMode(_currentMode,_currentCursor);
wim 15:b70ebfffb258 902 }
wim 15:b70ebfffb258 903
wim 29:a3663151aa65 904 setAddress(0, 0); // Reset Cursor location
wim 32:59c4b8f648d4 905 // Note: This is needed because some displays (eg PCF21XX) don't use line 0 in the '3 Line' mode.
simon 1:ac48b187213c 906 }
simon 1:ac48b187213c 907
wim 29:a3663151aa65 908 /** Locate cursor to a screen column and row
wim 29:a3663151aa65 909 *
wim 29:a3663151aa65 910 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 911 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 912 */
wim 21:9eb628d9e164 913 void TextLCD_Base::locate(int column, int row) {
wim 15:b70ebfffb258 914
wim 15:b70ebfffb258 915 // setAddress() does all the heavy lifting:
wim 15:b70ebfffb258 916 // check column and row sanity,
wim 15:b70ebfffb258 917 // switch controllers for LCD40x4 if needed
wim 15:b70ebfffb258 918 // switch cursor for LCD40x4 if needed
wim 15:b70ebfffb258 919 // set the new memory address to show cursor at correct location
wim 32:59c4b8f648d4 920 setAddress(column, row);
wim 15:b70ebfffb258 921 }
wim 30:033048611c01 922
wim 15:b70ebfffb258 923
wim 21:9eb628d9e164 924 /** Write a single character (Stream implementation)
wim 21:9eb628d9e164 925 */
wim 21:9eb628d9e164 926 int TextLCD_Base::_putc(int value) {
wim 15:b70ebfffb258 927 int addr;
wim 15:b70ebfffb258 928
wim 15:b70ebfffb258 929 if (value == '\n') {
wim 15:b70ebfffb258 930 //No character to write
wim 15:b70ebfffb258 931
wim 15:b70ebfffb258 932 //Update Cursor
wim 15:b70ebfffb258 933 _column = 0;
wim 15:b70ebfffb258 934 _row++;
wim 15:b70ebfffb258 935 if (_row >= rows()) {
wim 15:b70ebfffb258 936 _row = 0;
wim 15:b70ebfffb258 937 }
wim 15:b70ebfffb258 938 }
wim 15:b70ebfffb258 939 else {
wim 15:b70ebfffb258 940 //Character to write
wim 15:b70ebfffb258 941 _writeData(value);
wim 15:b70ebfffb258 942
wim 15:b70ebfffb258 943 //Update Cursor
wim 15:b70ebfffb258 944 _column++;
wim 15:b70ebfffb258 945 if (_column >= columns()) {
wim 15:b70ebfffb258 946 _column = 0;
wim 15:b70ebfffb258 947 _row++;
wim 15:b70ebfffb258 948 if (_row >= rows()) {
wim 15:b70ebfffb258 949 _row = 0;
wim 15:b70ebfffb258 950 }
wim 15:b70ebfffb258 951 }
wim 15:b70ebfffb258 952 } //else
wim 15:b70ebfffb258 953
wim 15:b70ebfffb258 954 //Set next memoryaddress, make sure cursor blinks at next location
wim 15:b70ebfffb258 955 addr = getAddress(_column, _row);
wim 15:b70ebfffb258 956 _writeCommand(0x80 | addr);
wim 15:b70ebfffb258 957
wim 15:b70ebfffb258 958 return value;
wim 15:b70ebfffb258 959 }
wim 15:b70ebfffb258 960
wim 15:b70ebfffb258 961
wim 16:c276b75e6585 962 // get a single character (Stream implementation)
wim 21:9eb628d9e164 963 int TextLCD_Base::_getc() {
simon 1:ac48b187213c 964 return -1;
simon 1:ac48b187213c 965 }
simon 1:ac48b187213c 966
wim 14:0c32b66b14b8 967
wim 17:652ab113bc2e 968 // Write a nibble using the 4-bit interface
wim 21:9eb628d9e164 969 void TextLCD_Base::_writeNibble(int value) {
wim 17:652ab113bc2e 970
wim 17:652ab113bc2e 971 // Enable is Low
wim 21:9eb628d9e164 972 this->_setEnable(true);
wim 21:9eb628d9e164 973 this->_setData(value & 0x0F); // Low nibble
wim 17:652ab113bc2e 974 wait_us(1); // Data setup time
wim 21:9eb628d9e164 975 this->_setEnable(false);
wim 17:652ab113bc2e 976 wait_us(1); // Datahold time
wim 17:652ab113bc2e 977
wim 17:652ab113bc2e 978 // Enable is Low
wim 17:652ab113bc2e 979 }
wim 17:652ab113bc2e 980
wim 16:c276b75e6585 981 // Write a byte using the 4-bit interface
wim 21:9eb628d9e164 982 void TextLCD_Base::_writeByte(int value) {
wim 15:b70ebfffb258 983
wim 15:b70ebfffb258 984 // Enable is Low
wim 21:9eb628d9e164 985 this->_setEnable(true);
wim 21:9eb628d9e164 986 this->_setData(value >> 4); // High nibble
wim 15:b70ebfffb258 987 wait_us(1); // Data setup time
wim 21:9eb628d9e164 988 this->_setEnable(false);
wim 15:b70ebfffb258 989 wait_us(1); // Data hold time
wim 15:b70ebfffb258 990
wim 21:9eb628d9e164 991 this->_setEnable(true);
wim 21:9eb628d9e164 992 this->_setData(value >> 0); // Low nibble
wim 15:b70ebfffb258 993 wait_us(1); // Data setup time
wim 21:9eb628d9e164 994 this->_setEnable(false);
wim 15:b70ebfffb258 995 wait_us(1); // Datahold time
wim 15:b70ebfffb258 996
wim 15:b70ebfffb258 997 // Enable is Low
simon 1:ac48b187213c 998 }
simon 1:ac48b187213c 999
wim 21:9eb628d9e164 1000 // Write a command byte to the LCD controller
wim 21:9eb628d9e164 1001 void TextLCD_Base::_writeCommand(int command) {
wim 15:b70ebfffb258 1002
wim 21:9eb628d9e164 1003 this->_setRS(false);
wim 16:c276b75e6585 1004 wait_us(1); // Data setup time for RS
wim 15:b70ebfffb258 1005
wim 21:9eb628d9e164 1006 this->_writeByte(command);
wim 15:b70ebfffb258 1007 wait_us(40); // most instructions take 40us
simon 1:ac48b187213c 1008 }
simon 1:ac48b187213c 1009
wim 21:9eb628d9e164 1010 // Write a data byte to the LCD controller
wim 21:9eb628d9e164 1011 void TextLCD_Base::_writeData(int data) {
wim 15:b70ebfffb258 1012
wim 21:9eb628d9e164 1013 this->_setRS(true);
wim 16:c276b75e6585 1014 wait_us(1); // Data setup time for RS
wim 15:b70ebfffb258 1015
wim 21:9eb628d9e164 1016 this->_writeByte(data);
wim 15:b70ebfffb258 1017 wait_us(40); // data writes take 40us
simon 1:ac48b187213c 1018 }
simon 1:ac48b187213c 1019
wim 8:03116f75b66e 1020
wim 32:59c4b8f648d4 1021 // This replaces the original _address() method.
wim 8:03116f75b66e 1022 // It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
wim 8:03116f75b66e 1023 // Left it in here for compatibility with older code. New applications should use getAddress() instead.
wim 21:9eb628d9e164 1024 int TextLCD_Base::_address(int column, int row) {
wim 8:03116f75b66e 1025 return 0x80 | getAddress(column, row);
wim 8:03116f75b66e 1026 }
wim 8:03116f75b66e 1027
wim 30:033048611c01 1028
wim 30:033048611c01 1029 // This is new method to return the memory address based on row, column and displaytype.
wim 30:033048611c01 1030 //
wim 30:033048611c01 1031 /** Return the memoryaddress of screen column and row location
wim 30:033048611c01 1032 *
wim 30:033048611c01 1033 * @param column The horizontal position from the left, indexed from 0
wim 30:033048611c01 1034 * @param row The vertical position from the top, indexed from 0
wim 30:033048611c01 1035 * @param return The memoryaddress of screen column and row location
wim 30:033048611c01 1036 *
wim 30:033048611c01 1037 */
wim 30:033048611c01 1038 int TextLCD_Base::getAddress(int column, int row) {
wim 30:033048611c01 1039
wim 30:033048611c01 1040 switch (_addr_mode) {
wim 30:033048611c01 1041
wim 30:033048611c01 1042 case LCD_T_A:
wim 30:033048611c01 1043 //Default addressing mode for 1, 2 and 4 rows (except 40x4)
wim 30:033048611c01 1044 //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.
wim 30:033048611c01 1045 //Displays top rows when less than four are used.
wim 30:033048611c01 1046 switch (row) {
wim 30:033048611c01 1047 case 0:
wim 30:033048611c01 1048 return 0x00 + column;
wim 30:033048611c01 1049 case 1:
wim 30:033048611c01 1050 return 0x40 + column;
wim 30:033048611c01 1051 case 2:
wim 30:033048611c01 1052 return 0x00 + _nr_cols + column;
wim 30:033048611c01 1053 case 3:
wim 30:033048611c01 1054 return 0x40 + _nr_cols + column;
wim 30:033048611c01 1055 // Should never get here.
wim 30:033048611c01 1056 default:
wim 30:033048611c01 1057 return 0x00;
wim 30:033048611c01 1058 }
wim 30:033048611c01 1059
wim 30:033048611c01 1060 case LCD_T_B:
wim 30:033048611c01 1061 // LCD8x2B is a special layout of LCD16x1
wim 30:033048611c01 1062 if (row==0)
wim 30:033048611c01 1063 return 0x00 + column;
wim 30:033048611c01 1064 else
wim 30:033048611c01 1065 // return _nr_cols + column;
wim 30:033048611c01 1066 return 0x08 + column;
wim 30:033048611c01 1067
wim 30:033048611c01 1068 case LCD_T_C:
wim 30:033048611c01 1069 // LCD16x1C is a special layout of LCD8x2
wim 32:59c4b8f648d4 1070 #if(1)
wim 32:59c4b8f648d4 1071 if (column < 8)
wim 30:033048611c01 1072 return 0x00 + column;
wim 30:033048611c01 1073 else
wim 30:033048611c01 1074 return 0x40 + (column - 8);
wim 32:59c4b8f648d4 1075 #else
wim 32:59c4b8f648d4 1076 if (column < (_nr_cols >> 1))
wim 32:59c4b8f648d4 1077 return 0x00 + column;
wim 32:59c4b8f648d4 1078 else
wim 32:59c4b8f648d4 1079 return 0x40 + (column - (_nr_cols >> 1));
wim 32:59c4b8f648d4 1080 #endif
wim 30:033048611c01 1081
wim 30:033048611c01 1082 // Not sure about this one, seems wrong.
wim 30:033048611c01 1083 // Left in for compatibility with original library
wim 30:033048611c01 1084 // case LCD16x2B:
wim 30:033048611c01 1085 // return 0x00 + (row * 40) + column;
wim 30:033048611c01 1086
wim 30:033048611c01 1087
wim 30:033048611c01 1088 case LCD_T_D:
wim 32:59c4b8f648d4 1089 //Alternate addressing mode for 3 and 4 row displays (except 40x4). Used by PCF21XX, KS0078, ST7036, SSD1803
wim 30:033048611c01 1090 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 1091 //Displays top rows when less than four are used.
wim 30:033048611c01 1092 switch (row) {
wim 30:033048611c01 1093 case 0:
wim 30:033048611c01 1094 return 0x00 + column;
wim 30:033048611c01 1095 case 1:
wim 30:033048611c01 1096 return 0x20 + column;
wim 30:033048611c01 1097 case 2:
wim 30:033048611c01 1098 return 0x40 + column;
wim 30:033048611c01 1099 case 3:
wim 30:033048611c01 1100 return 0x60 + column;
wim 30:033048611c01 1101 // Should never get here.
wim 30:033048611c01 1102 default:
wim 30:033048611c01 1103 return 0x00;
wim 30:033048611c01 1104 }
wim 30:033048611c01 1105
wim 30:033048611c01 1106 case LCD_T_D1:
wim 32:59c4b8f648d4 1107 //Alternate addressing mode for 3 row displays. Used by PCF21XX, KS0078, SSD1803
wim 30:033048611c01 1108 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 1109 //Skips top row of 4 row display and starts display at row 1
wim 30:033048611c01 1110 switch (row) {
wim 30:033048611c01 1111 case 0:
wim 30:033048611c01 1112 return 0x20 + column;
wim 30:033048611c01 1113 case 1:
wim 30:033048611c01 1114 return 0x40 + column;
wim 30:033048611c01 1115 case 2:
wim 30:033048611c01 1116 return 0x60 + column;
wim 30:033048611c01 1117 // Should never get here.
wim 30:033048611c01 1118 default:
wim 30:033048611c01 1119 return 0x00;
wim 30:033048611c01 1120 }
wim 30:033048611c01 1121
wim 30:033048611c01 1122 case LCD_T_E:
wim 30:033048611c01 1123 // LCD40x4 is a special case since it has 2 controllers.
wim 30:033048611c01 1124 // Each controller is configured as 40x2 (Type A)
wim 30:033048611c01 1125 if (row<2) {
wim 30:033048611c01 1126 // Test to see if we need to switch between controllers
wim 30:033048611c01 1127 if (_ctrl_idx != _LCDCtrl_0) {
wim 30:033048611c01 1128
wim 30:033048611c01 1129 // Second LCD controller Cursor Off
wim 30:033048611c01 1130 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 1131
wim 30:033048611c01 1132 // Select primary controller
wim 30:033048611c01 1133 _ctrl_idx = _LCDCtrl_0;
wim 30:033048611c01 1134
wim 30:033048611c01 1135 // Restore cursormode on primary LCD controller
wim 30:033048611c01 1136 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1137 }
wim 30:033048611c01 1138
wim 30:033048611c01 1139 return 0x00 + (row * 0x40) + column;
wim 30:033048611c01 1140 }
wim 30:033048611c01 1141 else {
wim 30:033048611c01 1142
wim 30:033048611c01 1143 // Test to see if we need to switch between controllers
wim 30:033048611c01 1144 if (_ctrl_idx != _LCDCtrl_1) {
wim 30:033048611c01 1145 // Primary LCD controller Cursor Off
wim 30:033048611c01 1146 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 1147
wim 30:033048611c01 1148 // Select secondary controller
wim 30:033048611c01 1149 _ctrl_idx = _LCDCtrl_1;
wim 30:033048611c01 1150
wim 30:033048611c01 1151 // Restore cursormode on secondary LCD controller
wim 30:033048611c01 1152 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1153 }
wim 30:033048611c01 1154
wim 30:033048611c01 1155 return 0x00 + ((row-2) * 0x40) + column;
wim 30:033048611c01 1156 }
wim 30:033048611c01 1157
wim 32:59c4b8f648d4 1158 case LCD_T_F:
wim 32:59c4b8f648d4 1159 //Alternate addressing mode for 3 row displays.
wim 32:59c4b8f648d4 1160 //The first half of 3rd row continues from 1st row, the second half continues from 2nd row.
wim 32:59c4b8f648d4 1161 switch (row) {
wim 32:59c4b8f648d4 1162 case 0:
wim 32:59c4b8f648d4 1163 return 0x00 + column;
wim 32:59c4b8f648d4 1164 case 1:
wim 32:59c4b8f648d4 1165 return 0x40 + column;
wim 32:59c4b8f648d4 1166 case 2:
wim 32:59c4b8f648d4 1167 if (column < (_nr_cols >> 1)) // check first or second half of line
wim 32:59c4b8f648d4 1168 return (0x00 + _nr_cols + column);
wim 32:59c4b8f648d4 1169 else
wim 32:59c4b8f648d4 1170 return (0x40 + _nr_cols + (column - (_nr_cols >> 1)));
wim 32:59c4b8f648d4 1171 // Should never get here.
wim 32:59c4b8f648d4 1172 default:
wim 32:59c4b8f648d4 1173 return 0x00;
wim 32:59c4b8f648d4 1174 }
wim 32:59c4b8f648d4 1175
wim 32:59c4b8f648d4 1176 case LCD_T_G:
wim 32:59c4b8f648d4 1177 //Alternate addressing mode for 3 row displays. Used by ST7036
wim 32:59c4b8f648d4 1178 switch (row) {
wim 32:59c4b8f648d4 1179 case 0:
wim 32:59c4b8f648d4 1180 return 0x00 + column;
wim 32:59c4b8f648d4 1181 case 1:
wim 32:59c4b8f648d4 1182 return 0x10 + column;
wim 32:59c4b8f648d4 1183 case 2:
wim 32:59c4b8f648d4 1184 return 0x20 + column;
wim 32:59c4b8f648d4 1185 // Should never get here.
wim 32:59c4b8f648d4 1186 default:
wim 32:59c4b8f648d4 1187 return 0x00;
wim 32:59c4b8f648d4 1188 }
wim 32:59c4b8f648d4 1189
wim 30:033048611c01 1190 // Should never get here.
wim 30:033048611c01 1191 default:
wim 30:033048611c01 1192 return 0x00;
wim 32:59c4b8f648d4 1193
wim 32:59c4b8f648d4 1194 } // switch _addr_mode
wim 30:033048611c01 1195 }
wim 30:033048611c01 1196
wim 30:033048611c01 1197
wim 29:a3663151aa65 1198 /** Set the memoryaddress of screen column and row location
wim 29:a3663151aa65 1199 *
wim 29:a3663151aa65 1200 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 1201 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 1202 */
wim 21:9eb628d9e164 1203 void TextLCD_Base::setAddress(int column, int row) {
wim 15:b70ebfffb258 1204
wim 15:b70ebfffb258 1205 // Sanity Check column
wim 15:b70ebfffb258 1206 if (column < 0) {
wim 15:b70ebfffb258 1207 _column = 0;
wim 15:b70ebfffb258 1208 }
wim 15:b70ebfffb258 1209 else if (column >= columns()) {
wim 15:b70ebfffb258 1210 _column = columns() - 1;
wim 15:b70ebfffb258 1211 } else _column = column;
wim 8:03116f75b66e 1212
wim 15:b70ebfffb258 1213 // Sanity Check row
wim 15:b70ebfffb258 1214 if (row < 0) {
wim 15:b70ebfffb258 1215 _row = 0;
wim 15:b70ebfffb258 1216 }
wim 15:b70ebfffb258 1217 else if (row >= rows()) {
wim 15:b70ebfffb258 1218 _row = rows() - 1;
wim 15:b70ebfffb258 1219 } else _row = row;
wim 15:b70ebfffb258 1220
wim 15:b70ebfffb258 1221
wim 15:b70ebfffb258 1222 // Compute the memory address
wim 15:b70ebfffb258 1223 // For LCD40x4: switch controllers if needed
wim 15:b70ebfffb258 1224 // switch cursor if needed
wim 15:b70ebfffb258 1225 int addr = getAddress(_column, _row);
wim 8:03116f75b66e 1226
wim 13:24506ba22480 1227 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 1228 }
simon 1:ac48b187213c 1229
wim 29:a3663151aa65 1230
wim 29:a3663151aa65 1231 /** Return the number of columns
wim 29:a3663151aa65 1232 *
wim 29:a3663151aa65 1233 * @param return The number of columns
wim 30:033048611c01 1234 *
wim 30:033048611c01 1235 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 1236 */
wim 21:9eb628d9e164 1237 int TextLCD_Base::columns() {
wim 30:033048611c01 1238
wim 30:033048611c01 1239 // Columns encoded in b7..b0
wim 30:033048611c01 1240 //return (_type & 0xFF);
wim 31:ef31cd8a00d1 1241 return _nr_cols;
simon 1:ac48b187213c 1242 }
simon 1:ac48b187213c 1243
wim 29:a3663151aa65 1244 /** Return the number of rows
wim 29:a3663151aa65 1245 *
wim 29:a3663151aa65 1246 * @param return The number of rows
wim 30:033048611c01 1247 *
wim 30:033048611c01 1248 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 1249 */
wim 21:9eb628d9e164 1250 int TextLCD_Base::rows() {
wim 30:033048611c01 1251
wim 30:033048611c01 1252 // Rows encoded in b15..b8
wim 30:033048611c01 1253 //return ((_type >> 8) & 0xFF);
wim 30:033048611c01 1254 return _nr_rows;
simon 1:ac48b187213c 1255 }
wim 10:dd9b3a696acd 1256
wim 29:a3663151aa65 1257 /** Set the Cursormode
wim 29:a3663151aa65 1258 *
wim 29:a3663151aa65 1259 * @param cursorMode The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
wim 29:a3663151aa65 1260 */
wim 21:9eb628d9e164 1261 void TextLCD_Base::setCursor(LCDCursor cursorMode) {
wim 15:b70ebfffb258 1262
wim 17:652ab113bc2e 1263 // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
wim 17:652ab113bc2e 1264 _currentCursor = cursorMode;
wim 10:dd9b3a696acd 1265
wim 17:652ab113bc2e 1266 // Configure only current LCD controller
wim 31:ef31cd8a00d1 1267 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 1268 }
wim 15:b70ebfffb258 1269
wim 29:a3663151aa65 1270 /** Set the Displaymode
wim 29:a3663151aa65 1271 *
wim 29:a3663151aa65 1272 * @param displayMode The Display mode (DispOff, DispOn)
wim 29:a3663151aa65 1273 */
wim 21:9eb628d9e164 1274 void TextLCD_Base::setMode(LCDMode displayMode) {
wim 17:652ab113bc2e 1275
wim 17:652ab113bc2e 1276 // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
wim 17:652ab113bc2e 1277 _currentMode = displayMode;
wim 15:b70ebfffb258 1278
wim 17:652ab113bc2e 1279 // Select and configure second LCD controller when needed
wim 17:652ab113bc2e 1280 if(_type==LCD40x4) {
wim 21:9eb628d9e164 1281 if (_ctrl_idx==_LCDCtrl_0) {
wim 17:652ab113bc2e 1282 // Configure primary LCD controller
wim 17:652ab113bc2e 1283 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 11:9ec02df863a1 1284
wim 17:652ab113bc2e 1285 // Select 2nd controller
wim 21:9eb628d9e164 1286 _ctrl_idx=_LCDCtrl_1;
wim 17:652ab113bc2e 1287
wim 17:652ab113bc2e 1288 // Configure secondary LCD controller
wim 21:9eb628d9e164 1289 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 11:9ec02df863a1 1290
wim 17:652ab113bc2e 1291 // Restore current controller
wim 21:9eb628d9e164 1292 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1293 }
wim 17:652ab113bc2e 1294 else {
wim 17:652ab113bc2e 1295 // Select primary controller
wim 21:9eb628d9e164 1296 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1297
wim 17:652ab113bc2e 1298 // Configure primary LCD controller
wim 21:9eb628d9e164 1299 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 17:652ab113bc2e 1300
wim 17:652ab113bc2e 1301 // Restore current controller
wim 21:9eb628d9e164 1302 _ctrl_idx=_LCDCtrl_1;
wim 11:9ec02df863a1 1303
wim 17:652ab113bc2e 1304 // Configure secondary LCD controller
wim 17:652ab113bc2e 1305 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 10:dd9b3a696acd 1306 }
wim 17:652ab113bc2e 1307 }
wim 17:652ab113bc2e 1308 else {
wim 17:652ab113bc2e 1309 // Configure primary LCD controller
wim 17:652ab113bc2e 1310 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1311 }
wim 17:652ab113bc2e 1312 }
wim 17:652ab113bc2e 1313
wim 17:652ab113bc2e 1314
wim 29:a3663151aa65 1315 /** Low level method to restore the cursortype and display mode for current controller
wim 29:a3663151aa65 1316 */
wim 21:9eb628d9e164 1317 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {
wim 17:652ab113bc2e 1318
wim 17:652ab113bc2e 1319 // Configure current LCD controller
wim 17:652ab113bc2e 1320 _writeCommand(0x08 | displayMode | cursorType);
wim 10:dd9b3a696acd 1321 }
wim 10:dd9b3a696acd 1322
wim 29:a3663151aa65 1323 /** Set the Backlight mode
wim 29:a3663151aa65 1324 *
wim 29:a3663151aa65 1325 * @param backlightMode The Backlight mode (LightOff, LightOn)
wim 29:a3663151aa65 1326 */
wim 21:9eb628d9e164 1327 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
wim 20:e0da005a777f 1328
wim 20:e0da005a777f 1329 if (backlightMode == LightOn) {
wim 21:9eb628d9e164 1330 this->_setBL(true);
wim 20:e0da005a777f 1331 }
wim 20:e0da005a777f 1332 else {
wim 21:9eb628d9e164 1333 this->_setBL(false);
wim 20:e0da005a777f 1334 }
wim 20:e0da005a777f 1335 }
wim 20:e0da005a777f 1336
wim 29:a3663151aa65 1337 /** Set User Defined Characters
wim 29:a3663151aa65 1338 *
wim 29:a3663151aa65 1339 * @param unsigned char c The Index of the UDC (0..7)
wim 29:a3663151aa65 1340 * @param char *udc_data The bitpatterns for the UDC (8 bytes of 5 significant bits)
wim 29:a3663151aa65 1341 */
wim 21:9eb628d9e164 1342 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1343
wim 15:b70ebfffb258 1344 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 1345 if(_type==LCD40x4) {
wim 19:c747b9e2e7b8 1346 _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
wim 15:b70ebfffb258 1347
wim 15:b70ebfffb258 1348 // Select primary controller
wim 21:9eb628d9e164 1349 _ctrl_idx=_LCDCtrl_0;
wim 15:b70ebfffb258 1350
wim 15:b70ebfffb258 1351 // Configure primary LCD controller
wim 15:b70ebfffb258 1352 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1353
wim 15:b70ebfffb258 1354 // Select 2nd controller
wim 21:9eb628d9e164 1355 _ctrl_idx=_LCDCtrl_1;
wim 15:b70ebfffb258 1356
wim 15:b70ebfffb258 1357 // Configure secondary LCD controller
wim 15:b70ebfffb258 1358 _setUDC(c, udc_data);
wim 11:9ec02df863a1 1359
wim 15:b70ebfffb258 1360 // Restore current controller
wim 19:c747b9e2e7b8 1361 _ctrl_idx=current_ctrl_idx;
wim 15:b70ebfffb258 1362 }
wim 15:b70ebfffb258 1363 else {
wim 15:b70ebfffb258 1364 // Configure primary LCD controller
wim 15:b70ebfffb258 1365 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1366 }
wim 15:b70ebfffb258 1367
wim 15:b70ebfffb258 1368 }
wim 15:b70ebfffb258 1369
wim 29:a3663151aa65 1370 /** Low level method to store user defined characters for current controller
wim 29:a3663151aa65 1371 */
wim 21:9eb628d9e164 1372 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1373
wim 15:b70ebfffb258 1374 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 1375 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
wim 15:b70ebfffb258 1376 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 1377 // Store UDC pattern
wim 11:9ec02df863a1 1378 for (int i=0; i<8; i++) {
wim 13:24506ba22480 1379 _writeData(*udc_data++);
wim 11:9ec02df863a1 1380 }
wim 15:b70ebfffb258 1381
wim 15:b70ebfffb258 1382 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 1383 int addr = getAddress(_column, _row);
wim 30:033048611c01 1384 _writeCommand(0x80 | addr);
wim 11:9ec02df863a1 1385 }
wim 21:9eb628d9e164 1386
wim 32:59c4b8f648d4 1387
wim 32:59c4b8f648d4 1388 /** Set Contrast
wim 32:59c4b8f648d4 1389 * setContrast method is supported by some compatible devices (eg ST7032i) that have onboard LCD voltage generation
wim 32:59c4b8f648d4 1390 * Initial code for ST70XX imported from fork by JH1PJL
wim 32:59c4b8f648d4 1391 *
wim 32:59c4b8f648d4 1392 * @param unsigned char c contrast data (6 significant bits, valid range 0..63, Value 0 will disable the Vgen)
wim 32:59c4b8f648d4 1393 * @return none
wim 32:59c4b8f648d4 1394 */
wim 32:59c4b8f648d4 1395 //@TODO Add support for 40x4 dual controller
wim 32:59c4b8f648d4 1396 void TextLCD_Base::setContrast(unsigned char c) {
wim 32:59c4b8f648d4 1397
wim 32:59c4b8f648d4 1398 // Function set mode stored during Init. Make sure we dont accidentally switch between 1-line and 2-line mode!
wim 32:59c4b8f648d4 1399 // Icon/Booster mode stored during Init. Make sure we dont accidentally change this!
wim 32:59c4b8f648d4 1400
wim 32:59c4b8f648d4 1401 _contrast = c & 0x3F; // Sanity check
wim 32:59c4b8f648d4 1402
wim 32:59c4b8f648d4 1403 switch (_ctrl) {
wim 32:59c4b8f648d4 1404
wim 32:59c4b8f648d4 1405 case PCF2113_3V3 :
wim 32:59c4b8f648d4 1406 case PCF2119_3V3 :
wim 32:59c4b8f648d4 1407 if (_contrast < 5) _contrast = 0; // See datasheet. Sanity check for PCF2113/PCF2119
wim 32:59c4b8f648d4 1408 if (_contrast > 55) _contrast = 55;
wim 32:59c4b8f648d4 1409
wim 32:59c4b8f648d4 1410 _writeCommand(0x20 | _function | 0x01); // Set function, Select Instruction Set = 1
wim 32:59c4b8f648d4 1411 _writeCommand(0x80 | 0x00 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=0, VA=contrast
wim 32:59c4b8f648d4 1412 _writeCommand(0x80 | 0x40 | (_contrast & 0x3F)); // VLCD_set (Instr. Set 1) V=1, VB=contrast
wim 32:59c4b8f648d4 1413 _writeCommand(0x20 | _function); // Select Instruction Set = 0
wim 32:59c4b8f648d4 1414 break;
wim 32:59c4b8f648d4 1415
wim 32:59c4b8f648d4 1416 case ST7032_3V3 :
wim 32:59c4b8f648d4 1417 case ST7032_5V :
wim 32:59c4b8f648d4 1418 case ST7036_3V3 :
wim 32:59c4b8f648d4 1419 // case ST7036_5V :
wim 32:59c4b8f648d4 1420 case SSD1803_3V3 :
wim 32:59c4b8f648d4 1421 _writeCommand(0x20 | _function | 0x01); // Select Instruction Set = 1
wim 32:59c4b8f648d4 1422 _writeCommand(0x70 | (_contrast & 0x0F)); // Contrast Low bits
wim 32:59c4b8f648d4 1423 _writeCommand(0x50 | _icon_power | ((_contrast >> 4) & 0x03)); // Contrast High bits
wim 32:59c4b8f648d4 1424 _writeCommand(0x20 | _function); // Select Instruction Set = 0
wim 32:59c4b8f648d4 1425 break;
wim 32:59c4b8f648d4 1426
wim 32:59c4b8f648d4 1427 #if(0)
wim 32:59c4b8f648d4 1428 //not yet tested
wim 32:59c4b8f648d4 1429 case PT6314 :
wim 32:59c4b8f648d4 1430 // Only 2 significant bits
wim 32:59c4b8f648d4 1431 // 0x00 = 100%
wim 32:59c4b8f648d4 1432 // 0x01 = 75%
wim 32:59c4b8f648d4 1433 // 0x02 = 50%
wim 32:59c4b8f648d4 1434 // 0x03 = 25%
wim 32:59c4b8f648d4 1435 _writeCommand(0x20 | _function | ((~_contrast) >> 4)); // Invert and shift to use 2 MSBs
wim 32:59c4b8f648d4 1436 break;
wim 32:59c4b8f648d4 1437 #endif
wim 32:59c4b8f648d4 1438
wim 32:59c4b8f648d4 1439 default:
wim 32:59c4b8f648d4 1440 //Unsupported feature for other controllers
wim 32:59c4b8f648d4 1441 break;
wim 32:59c4b8f648d4 1442
wim 32:59c4b8f648d4 1443 } // end switch
wim 32:59c4b8f648d4 1444
wim 32:59c4b8f648d4 1445 }
wim 32:59c4b8f648d4 1446
wim 32:59c4b8f648d4 1447
wim 32:59c4b8f648d4 1448 /** Set Power
wim 32:59c4b8f648d4 1449 * setPower method is supported by some compatible devices (eg SSD1803) that have power down modes
wim 32:59c4b8f648d4 1450 *
wim 32:59c4b8f648d4 1451 * @param bool powerOn Power on/off
wim 32:59c4b8f648d4 1452 * @return none
wim 32:59c4b8f648d4 1453 */
wim 32:59c4b8f648d4 1454 //@TODO Add support for 40x4 dual controller
wim 32:59c4b8f648d4 1455 void TextLCD_Base::setPower(bool powerOn) {
wim 32:59c4b8f648d4 1456 static int _tmp_contrast = LCD_DEF_CONTRAST;
wim 32:59c4b8f648d4 1457
wim 32:59c4b8f648d4 1458 if (powerOn) {
wim 32:59c4b8f648d4 1459 // Switch on
wim 32:59c4b8f648d4 1460 setMode(DispOn);
wim 32:59c4b8f648d4 1461
wim 32:59c4b8f648d4 1462 // Try to set contrast=0
wim 32:59c4b8f648d4 1463 _tmp_contrast = _contrast; // Temp. save current contrast
wim 32:59c4b8f648d4 1464 setContrast(0); // Contrast 0
wim 32:59c4b8f648d4 1465
wim 32:59c4b8f648d4 1466 // Controllers that supports specific Power Down mode
wim 32:59c4b8f648d4 1467 switch (_ctrl) {
wim 32:59c4b8f648d4 1468
wim 32:59c4b8f648d4 1469 // case PCF2113_3V3 :
wim 32:59c4b8f648d4 1470 // case PCF2119_3V3 :
wim 32:59c4b8f648d4 1471 // case ST7032_3V3 :
wim 32:59c4b8f648d4 1472 // case ST7032_5V :
wim 32:59c4b8f648d4 1473 //@todo
wim 32:59c4b8f648d4 1474
wim 32:59c4b8f648d4 1475 case SSD1803_3V3 :
wim 32:59c4b8f648d4 1476 // case SSD1803_5V :
wim 32:59c4b8f648d4 1477 _writeCommand(0x20 | _function_1 | 0x02); // Select Ext Instr Set
wim 32:59c4b8f648d4 1478 _writeCommand(0x03); // Power Down
wim 32:59c4b8f648d4 1479 _writeCommand(0x20 | _function); // Select Std Instr Set
wim 32:59c4b8f648d4 1480 break;
wim 32:59c4b8f648d4 1481
wim 32:59c4b8f648d4 1482 case KS0078:
wim 32:59c4b8f648d4 1483 //@todo
wim 32:59c4b8f648d4 1484 break;
wim 32:59c4b8f648d4 1485
wim 32:59c4b8f648d4 1486 default:
wim 32:59c4b8f648d4 1487 //Unsupported feature for other controllers
wim 32:59c4b8f648d4 1488 break;
wim 32:59c4b8f648d4 1489 } // end switch
wim 32:59c4b8f648d4 1490 }
wim 32:59c4b8f648d4 1491 else {
wim 32:59c4b8f648d4 1492 // Switch off
wim 32:59c4b8f648d4 1493 setMode(DispOff);
wim 32:59c4b8f648d4 1494
wim 32:59c4b8f648d4 1495 // Try to restore contrast
wim 32:59c4b8f648d4 1496 setContrast(_tmp_contrast); // Contrast
wim 32:59c4b8f648d4 1497
wim 32:59c4b8f648d4 1498 // Controllers that support specific Power Down mode
wim 32:59c4b8f648d4 1499 switch (_ctrl) {
wim 32:59c4b8f648d4 1500
wim 32:59c4b8f648d4 1501 // case PCF2113_3V3 :
wim 32:59c4b8f648d4 1502 // case PCF2119_3V3 :
wim 32:59c4b8f648d4 1503 // case ST7032_3V3 :
wim 32:59c4b8f648d4 1504 // case ST7032_5V :
wim 32:59c4b8f648d4 1505 //@todo
wim 32:59c4b8f648d4 1506
wim 32:59c4b8f648d4 1507 case SSD1803_3V3 :
wim 32:59c4b8f648d4 1508 // case SSD1803_5V :
wim 32:59c4b8f648d4 1509 _writeCommand(0x20 | _function_1 | 0x02); // Select Ext Instr Set
wim 32:59c4b8f648d4 1510 _writeCommand(0x02); // Power On
wim 32:59c4b8f648d4 1511 _writeCommand(0x20 | _function); // Select Std Instr Set
wim 32:59c4b8f648d4 1512 break;
wim 32:59c4b8f648d4 1513
wim 32:59c4b8f648d4 1514 case KS0078:
wim 32:59c4b8f648d4 1515 //@todo
wim 32:59c4b8f648d4 1516 break;
wim 32:59c4b8f648d4 1517
wim 32:59c4b8f648d4 1518 default:
wim 32:59c4b8f648d4 1519 //Unsupported feature for other controllers
wim 32:59c4b8f648d4 1520 break;
wim 32:59c4b8f648d4 1521 } // end switch
wim 32:59c4b8f648d4 1522
wim 32:59c4b8f648d4 1523 }
wim 32:59c4b8f648d4 1524
wim 32:59c4b8f648d4 1525 }
wim 32:59c4b8f648d4 1526
wim 23:d47f226efb24 1527 //--------- End TextLCD_Base -----------
wim 21:9eb628d9e164 1528
wim 22:35742ec80c24 1529
wim 23:d47f226efb24 1530 //--------- Start TextLCD Bus -----------
wim 21:9eb628d9e164 1531
wim 21:9eb628d9e164 1532 /* Create a TextLCD interface for using regular mbed pins
wim 21:9eb628d9e164 1533 *
wim 21:9eb628d9e164 1534 * @param rs Instruction/data control line
wim 21:9eb628d9e164 1535 * @param e Enable line (clock)
wim 21:9eb628d9e164 1536 * @param d4-d7 Data lines for using as a 4-bit interface
wim 21:9eb628d9e164 1537 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 1538 * @param bl Backlight control line (optional, default = NC)
wim 21:9eb628d9e164 1539 * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
wim 21:9eb628d9e164 1540 * @param ctrl LCD controller (default = HD44780)
wim 21:9eb628d9e164 1541 */
wim 21:9eb628d9e164 1542 TextLCD::TextLCD(PinName rs, PinName e,
wim 21:9eb628d9e164 1543 PinName d4, PinName d5, PinName d6, PinName d7,
wim 21:9eb628d9e164 1544 LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1545 TextLCD_Base(type, ctrl),
wim 22:35742ec80c24 1546 _rs(rs), _e(e), _d(d4, d5, d6, d7) {
wim 22:35742ec80c24 1547
wim 22:35742ec80c24 1548 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1549 if (bl != NC) {
wim 22:35742ec80c24 1550 _bl = new DigitalOut(bl); //Construct new pin
wim 22:35742ec80c24 1551 _bl->write(0); //Deactivate
wim 22:35742ec80c24 1552 }
wim 22:35742ec80c24 1553 else {
wim 22:35742ec80c24 1554 // No Hardware Backlight pin
wim 22:35742ec80c24 1555 _bl = NULL; //Construct dummy pin
wim 22:35742ec80c24 1556 }
wim 22:35742ec80c24 1557
wim 22:35742ec80c24 1558 // The hardware Enable2 pin is only needed for LCD40x4. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1559 if (e2 != NC) {
wim 22:35742ec80c24 1560 _e2 = new DigitalOut(e2); //Construct new pin
wim 22:35742ec80c24 1561 _e2->write(0); //Deactivate
wim 22:35742ec80c24 1562 }
wim 22:35742ec80c24 1563 else {
wim 22:35742ec80c24 1564 // No Hardware Enable pin
wim 22:35742ec80c24 1565 _e2 = NULL; //Construct dummy pin
wim 22:35742ec80c24 1566 }
wim 21:9eb628d9e164 1567
wim 21:9eb628d9e164 1568 _init();
wim 21:9eb628d9e164 1569 }
wim 21:9eb628d9e164 1570
wim 29:a3663151aa65 1571 /** Destruct a TextLCD interface for using regular mbed pins
wim 29:a3663151aa65 1572 *
wim 29:a3663151aa65 1573 * @param none
wim 29:a3663151aa65 1574 * @return none
wim 29:a3663151aa65 1575 */
wim 29:a3663151aa65 1576 TextLCD::~TextLCD() {
wim 29:a3663151aa65 1577 if (_bl != NULL) {delete _bl;} // BL pin
wim 29:a3663151aa65 1578 if (_e2 != NULL) {delete _e2;} // E2 pin
wim 29:a3663151aa65 1579 }
wim 29:a3663151aa65 1580
wim 29:a3663151aa65 1581
wim 22:35742ec80c24 1582 /** Set E pin (or E2 pin)
wim 22:35742ec80c24 1583 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1584 * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1585 * @param value true or false
wim 22:35742ec80c24 1586 * @return none
wim 22:35742ec80c24 1587 */
wim 21:9eb628d9e164 1588 void TextLCD::_setEnable(bool value) {
wim 21:9eb628d9e164 1589
wim 22:35742ec80c24 1590 if(_ctrl_idx==_LCDCtrl_0) {
wim 22:35742ec80c24 1591 if (value) {
wim 22:35742ec80c24 1592 _e = 1; // Set E bit
wim 22:35742ec80c24 1593 }
wim 22:35742ec80c24 1594 else {
wim 22:35742ec80c24 1595 _e = 0; // Reset E bit
wim 22:35742ec80c24 1596 }
wim 22:35742ec80c24 1597 }
wim 22:35742ec80c24 1598 else {
wim 22:35742ec80c24 1599 if (value) {
wim 22:35742ec80c24 1600 if (_e2 != NULL) {_e2->write(1);} //Set E2 bit
wim 22:35742ec80c24 1601 }
wim 22:35742ec80c24 1602 else {
wim 22:35742ec80c24 1603 if (_e2 != NULL) {_e2->write(0);} //Reset E2 bit
wim 22:35742ec80c24 1604 }
wim 22:35742ec80c24 1605 }
wim 21:9eb628d9e164 1606 }
wim 21:9eb628d9e164 1607
wim 21:9eb628d9e164 1608 // Set RS pin
wim 21:9eb628d9e164 1609 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1610 void TextLCD::_setRS(bool value) {
wim 21:9eb628d9e164 1611
wim 22:35742ec80c24 1612 if (value) {
wim 21:9eb628d9e164 1613 _rs = 1; // Set RS bit
wim 22:35742ec80c24 1614 }
wim 22:35742ec80c24 1615 else {
wim 21:9eb628d9e164 1616 _rs = 0; // Reset RS bit
wim 22:35742ec80c24 1617 }
wim 21:9eb628d9e164 1618 }
wim 21:9eb628d9e164 1619
wim 22:35742ec80c24 1620 /** Set BL pin
wim 22:35742ec80c24 1621 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1622 * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1623 * @param value true or false
wim 22:35742ec80c24 1624 * @return none
wim 22:35742ec80c24 1625 */
wim 21:9eb628d9e164 1626 void TextLCD::_setBL(bool value) {
wim 21:9eb628d9e164 1627
wim 22:35742ec80c24 1628 if (value) {
wim 22:35742ec80c24 1629 if (_bl != NULL) {_bl->write(1);} //Set BL bit
wim 22:35742ec80c24 1630 }
wim 22:35742ec80c24 1631 else {
wim 22:35742ec80c24 1632 if (_bl != NULL) {_bl->write(0);} //Reset BL bit
wim 22:35742ec80c24 1633 }
wim 21:9eb628d9e164 1634
wim 21:9eb628d9e164 1635 }
wim 21:9eb628d9e164 1636
wim 21:9eb628d9e164 1637 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1638 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1639 void TextLCD::_setData(int value) {
wim 21:9eb628d9e164 1640 _d = value & 0x0F; // Write Databits
wim 21:9eb628d9e164 1641 }
wim 22:35742ec80c24 1642
wim 23:d47f226efb24 1643 //----------- End TextLCD ---------------
wim 21:9eb628d9e164 1644
wim 21:9eb628d9e164 1645
wim 23:d47f226efb24 1646 //--------- Start TextLCD_I2C -----------
wim 22:35742ec80c24 1647
wim 26:bd897a001012 1648 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander
wim 22:35742ec80c24 1649 *
wim 22:35742ec80c24 1650 * @param i2c I2C Bus
wim 26:bd897a001012 1651 * @param deviceAddress I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40)
wim 22:35742ec80c24 1652 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1653 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1654 */
wim 21:9eb628d9e164 1655 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1656 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1657 _i2c(i2c){
wim 21:9eb628d9e164 1658
wim 22:35742ec80c24 1659 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1660
wim 28:30fa94f7341c 1661 // Setup the I2C bus
wim 28:30fa94f7341c 1662 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit,
wim 32:59c4b8f648d4 1663 _i2c->frequency(100000);
wim 21:9eb628d9e164 1664
wim 26:bd897a001012 1665 #if (MCP23008==1)
wim 26:bd897a001012 1666 // MCP23008 portexpander Init
wim 27:22d5086f6ba6 1667 _write_register(IODIR, 0x00); // All outputs
wim 27:22d5086f6ba6 1668 _write_register(IPOL, 0x00); // No reverse polarity
wim 27:22d5086f6ba6 1669 _write_register(GPINTEN, 0x00); // No interrupt
wim 27:22d5086f6ba6 1670 _write_register(DEFVAL, 0x00); // Default value to compare against for interrupts
wim 27:22d5086f6ba6 1671 _write_register(INTCON, 0x00); // No interrupt on changes
wim 27:22d5086f6ba6 1672 _write_register(IOCON, 0x00); // Interrupt polarity
wim 27:22d5086f6ba6 1673 _write_register(GPPU, 0x00); // No Pullup
wim 27:22d5086f6ba6 1674 _write_register(INTF, 0x00); //
wim 27:22d5086f6ba6 1675 _write_register(INTCAP, 0x00); //
wim 27:22d5086f6ba6 1676 _write_register(GPIO, 0x00); // Output/Input pins
wim 27:22d5086f6ba6 1677 _write_register(OLAT, 0x00); // Output Latch
wim 26:bd897a001012 1678
wim 21:9eb628d9e164 1679 // Init the portexpander bus
wim 21:9eb628d9e164 1680 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1681
wim 21:9eb628d9e164 1682 // write the new data to the portexpander
wim 26:bd897a001012 1683 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1684 #else
wim 26:bd897a001012 1685 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1686
wim 26:bd897a001012 1687 // Init the portexpander bus
wim 26:bd897a001012 1688 _lcd_bus = D_LCD_BUS_DEF;
wim 26:bd897a001012 1689
wim 26:bd897a001012 1690 // write the new data to the portexpander
wim 21:9eb628d9e164 1691 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1692 #endif
wim 21:9eb628d9e164 1693
wim 30:033048611c01 1694 _init();
wim 21:9eb628d9e164 1695 }
wim 21:9eb628d9e164 1696
wim 21:9eb628d9e164 1697 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1698 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1699 void TextLCD_I2C::_setEnable(bool value) {
wim 21:9eb628d9e164 1700
wim 22:35742ec80c24 1701 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1702 if (value) {
wim 22:35742ec80c24 1703 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1704 }
wim 26:bd897a001012 1705 else {
wim 22:35742ec80c24 1706 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1707 }
wim 22:35742ec80c24 1708 }
wim 22:35742ec80c24 1709 else {
wim 26:bd897a001012 1710 if (value) {
wim 22:35742ec80c24 1711 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1712 }
wim 26:bd897a001012 1713 else {
wim 22:35742ec80c24 1714 _lcd_bus &= ~D_LCD_E2; // Reset E2bit
wim 26:bd897a001012 1715 }
wim 26:bd897a001012 1716 }
wim 26:bd897a001012 1717
wim 26:bd897a001012 1718 #if (MCP23008==1)
wim 26:bd897a001012 1719 // MCP23008 portexpander
wim 26:bd897a001012 1720
wim 26:bd897a001012 1721 // write the new data to the portexpander
wim 26:bd897a001012 1722 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1723 #else
wim 26:bd897a001012 1724 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1725
wim 22:35742ec80c24 1726 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1727 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1728 #endif
wim 21:9eb628d9e164 1729 }
wim 21:9eb628d9e164 1730
wim 21:9eb628d9e164 1731 // Set RS pin
wim 21:9eb628d9e164 1732 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1733 void TextLCD_I2C::_setRS(bool value) {
wim 21:9eb628d9e164 1734
wim 26:bd897a001012 1735 if (value) {
wim 22:35742ec80c24 1736 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 26:bd897a001012 1737 }
wim 26:bd897a001012 1738 else {
wim 22:35742ec80c24 1739 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 26:bd897a001012 1740 }
wim 26:bd897a001012 1741
wim 26:bd897a001012 1742 #if (MCP23008==1)
wim 26:bd897a001012 1743 // MCP23008 portexpander
wim 26:bd897a001012 1744
wim 26:bd897a001012 1745 // write the new data to the portexpander
wim 26:bd897a001012 1746 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1747 #else
wim 26:bd897a001012 1748 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1749
wim 22:35742ec80c24 1750 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1751 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1752 #endif
wim 21:9eb628d9e164 1753 }
wim 21:9eb628d9e164 1754
wim 21:9eb628d9e164 1755 // Set BL pin
wim 21:9eb628d9e164 1756 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1757 void TextLCD_I2C::_setBL(bool value) {
wim 21:9eb628d9e164 1758
wim 26:bd897a001012 1759 if (value) {
wim 21:9eb628d9e164 1760 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 26:bd897a001012 1761 }
wim 26:bd897a001012 1762 else {
wim 21:9eb628d9e164 1763 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 26:bd897a001012 1764 }
wim 26:bd897a001012 1765
wim 26:bd897a001012 1766 #if (MCP23008==1)
wim 26:bd897a001012 1767 // MCP23008 portexpander
wim 26:bd897a001012 1768
wim 26:bd897a001012 1769 // write the new data to the portexpander
wim 26:bd897a001012 1770 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1771 #else
wim 26:bd897a001012 1772 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1773
wim 21:9eb628d9e164 1774 // write the new data to the I2C portexpander
wim 21:9eb628d9e164 1775 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1776 #endif
wim 21:9eb628d9e164 1777 }
wim 21:9eb628d9e164 1778
wim 21:9eb628d9e164 1779
wim 21:9eb628d9e164 1780 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1781 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1782 void TextLCD_I2C::_setData(int value) {
wim 21:9eb628d9e164 1783 int data;
wim 22:35742ec80c24 1784
wim 22:35742ec80c24 1785 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 21:9eb628d9e164 1786
wim 22:35742ec80c24 1787 data = value & 0x0F;
wim 26:bd897a001012 1788 if (data & 0x01){
wim 22:35742ec80c24 1789 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1790 }
wim 26:bd897a001012 1791 else {
wim 26:bd897a001012 1792 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1793 }
wim 21:9eb628d9e164 1794
wim 26:bd897a001012 1795 if (data & 0x02){
wim 22:35742ec80c24 1796 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1797 }
wim 26:bd897a001012 1798 else {
wim 26:bd897a001012 1799 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1800 }
wim 21:9eb628d9e164 1801
wim 26:bd897a001012 1802 if (data & 0x04) {
wim 22:35742ec80c24 1803 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1804 }
wim 26:bd897a001012 1805 else {
wim 26:bd897a001012 1806 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1807 }
wim 21:9eb628d9e164 1808
wim 26:bd897a001012 1809 if (data & 0x08) {
wim 22:35742ec80c24 1810 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1811 }
wim 26:bd897a001012 1812 else {
wim 26:bd897a001012 1813 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1814 }
wim 21:9eb628d9e164 1815
wim 26:bd897a001012 1816 #if (MCP23008==1)
wim 26:bd897a001012 1817 // MCP23008 portexpander
wim 26:bd897a001012 1818
wim 26:bd897a001012 1819 // write the new data to the portexpander
wim 26:bd897a001012 1820 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1821 #else
wim 26:bd897a001012 1822 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1823
wim 22:35742ec80c24 1824 // write the new data to the I2C portexpander
wim 26:bd897a001012 1825 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1826 #endif
wim 22:35742ec80c24 1827
wim 22:35742ec80c24 1828 }
wim 21:9eb628d9e164 1829
wim 26:bd897a001012 1830 // Write data to MCP23008 I2C portexpander
wim 26:bd897a001012 1831 void TextLCD_I2C::_write_register (int reg, int value) {
wim 26:bd897a001012 1832 char data[] = {reg, value};
wim 26:bd897a001012 1833
wim 30:033048611c01 1834 _i2c->write(_slaveAddress, data, 2);
wim 26:bd897a001012 1835 }
wim 26:bd897a001012 1836
wim 23:d47f226efb24 1837 //---------- End TextLCD_I2C ------------
wim 21:9eb628d9e164 1838
wim 21:9eb628d9e164 1839
wim 28:30fa94f7341c 1840 //--------- Start TextLCD_I2C_N ---------
wim 28:30fa94f7341c 1841
wim 28:30fa94f7341c 1842 /** Create a TextLCD interface using a controller with native I2C interface
wim 28:30fa94f7341c 1843 *
wim 28:30fa94f7341c 1844 * @param i2c I2C Bus
wim 28:30fa94f7341c 1845 * @param deviceAddress I2C slave address (default = 0x7C)
wim 28:30fa94f7341c 1846 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 28:30fa94f7341c 1847 * @param bl Backlight control line (optional, default = NC)
wim 28:30fa94f7341c 1848 * @param ctrl LCD controller (default = ST7032_3V3)
wim 28:30fa94f7341c 1849 */
wim 28:30fa94f7341c 1850 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 28:30fa94f7341c 1851 TextLCD_Base(type, ctrl),
wim 32:59c4b8f648d4 1852
wim 32:59c4b8f648d4 1853 // _i2c(i2c){
wim 32:59c4b8f648d4 1854 _i2c(i2c), _ps(p20) {
wim 32:59c4b8f648d4 1855 //Test
wim 32:59c4b8f648d4 1856 // Init PS
wim 32:59c4b8f648d4 1857 wait_us(500);
wim 32:59c4b8f648d4 1858 _ps = 0;
wim 32:59c4b8f648d4 1859 wait_us(250);
wim 32:59c4b8f648d4 1860
wim 30:033048611c01 1861
wim 28:30fa94f7341c 1862 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1863
wim 28:30fa94f7341c 1864 // Setup the I2C bus
wim 29:a3663151aa65 1865 // The max bitrate for ST7032i is 400kbit, lets stick to default here
wim 29:a3663151aa65 1866 _i2c->frequency(100000);
wim 32:59c4b8f648d4 1867
wim 30:033048611c01 1868
wim 28:30fa94f7341c 1869 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 28:30fa94f7341c 1870 if (bl != NC) {
wim 28:30fa94f7341c 1871 _bl = new DigitalOut(bl); //Construct new pin
wim 28:30fa94f7341c 1872 _bl->write(0); //Deactivate
wim 28:30fa94f7341c 1873 }
wim 28:30fa94f7341c 1874 else {
wim 28:30fa94f7341c 1875 // No Hardware Backlight pin
wim 28:30fa94f7341c 1876 _bl = NULL; //Construct dummy pin
wim 28:30fa94f7341c 1877 }
wim 28:30fa94f7341c 1878
wim 30:033048611c01 1879 //Sanity check
wim 30:033048611c01 1880 if (_ctrl & LCD_C_I2C) {
wim 30:033048611c01 1881 _init();
wim 30:033048611c01 1882 }
wim 30:033048611c01 1883 else {
wim 30:033048611c01 1884 error("Error: LCD Controller type does not support native I2C interface\n\r");
wim 30:033048611c01 1885 }
wim 30:033048611c01 1886
wim 28:30fa94f7341c 1887 }
wim 28:30fa94f7341c 1888
wim 28:30fa94f7341c 1889 TextLCD_I2C_N::~TextLCD_I2C_N() {
wim 28:30fa94f7341c 1890 if (_bl != NULL) {delete _bl;} // BL pin
wim 28:30fa94f7341c 1891 }
wim 28:30fa94f7341c 1892
wim 28:30fa94f7341c 1893 // Not used in this mode
wim 28:30fa94f7341c 1894 void TextLCD_I2C_N::_setEnable(bool value) {
wim 28:30fa94f7341c 1895 }
wim 28:30fa94f7341c 1896
wim 28:30fa94f7341c 1897 // Set RS pin
wim 28:30fa94f7341c 1898 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI
wim 28:30fa94f7341c 1899 void TextLCD_I2C_N::_setRS(bool value) {
wim 30:033048611c01 1900 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1901 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1902 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1903 //
wim 30:033048611c01 1904 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1905 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1906 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1907 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1908 //
wim 30:033048611c01 1909
wim 28:30fa94f7341c 1910 if (value) {
wim 28:30fa94f7341c 1911 _controlbyte = 0x40; // Next byte is data, No more control bytes will follow
wim 28:30fa94f7341c 1912 }
wim 28:30fa94f7341c 1913 else {
wim 28:30fa94f7341c 1914 _controlbyte = 0x00; // Next byte is command, No more control bytes will follow
wim 28:30fa94f7341c 1915 }
wim 28:30fa94f7341c 1916 }
wim 28:30fa94f7341c 1917
wim 28:30fa94f7341c 1918 // Set BL pin
wim 28:30fa94f7341c 1919 void TextLCD_I2C_N::_setBL(bool value) {
wim 28:30fa94f7341c 1920 if (_bl) {
wim 28:30fa94f7341c 1921 _bl->write(value);
wim 28:30fa94f7341c 1922 }
wim 28:30fa94f7341c 1923 }
wim 29:a3663151aa65 1924
wim 29:a3663151aa65 1925 // Not used in this mode
wim 29:a3663151aa65 1926 void TextLCD_I2C_N::_setData(int value) {
wim 29:a3663151aa65 1927 }
wim 29:a3663151aa65 1928
wim 28:30fa94f7341c 1929 // Write a byte using I2C
wim 28:30fa94f7341c 1930 void TextLCD_I2C_N::_writeByte(int value) {
wim 30:033048611c01 1931 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1932 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1933 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1934 //
wim 30:033048611c01 1935 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1936 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1937 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1938 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1939 //
wim 28:30fa94f7341c 1940 char data[] = {_controlbyte, value};
wim 28:30fa94f7341c 1941
wim 32:59c4b8f648d4 1942 #if(LCD_I2C_ACK==1)
wim 32:59c4b8f648d4 1943 //Controllers that support ACK
wim 30:033048611c01 1944 _i2c->write(_slaveAddress, data, 2);
wim 32:59c4b8f648d4 1945 #else
wim 32:59c4b8f648d4 1946 //Controllers that dont support ACK
wim 32:59c4b8f648d4 1947 _i2c->start();
wim 32:59c4b8f648d4 1948 _i2c->write(_slaveAddress);
wim 32:59c4b8f648d4 1949 _i2c->write(data[0]);
wim 32:59c4b8f648d4 1950 _i2c->write(data[1]);
wim 32:59c4b8f648d4 1951 _i2c->stop();
wim 32:59c4b8f648d4 1952 #endif
wim 28:30fa94f7341c 1953 }
wim 28:30fa94f7341c 1954
wim 28:30fa94f7341c 1955 //-------- End TextLCD_I2C_N ------------
wim 28:30fa94f7341c 1956
wim 28:30fa94f7341c 1957
wim 23:d47f226efb24 1958 //--------- Start TextLCD_SPI -----------
wim 21:9eb628d9e164 1959
wim 22:35742ec80c24 1960 /** Create a TextLCD interface using an SPI 74595 portexpander
wim 22:35742ec80c24 1961 *
wim 22:35742ec80c24 1962 * @param spi SPI Bus
wim 22:35742ec80c24 1963 * @param cs chip select pin (active low)
wim 22:35742ec80c24 1964 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1965 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1966 */
wim 21:9eb628d9e164 1967 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1968 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1969 _spi(spi),
wim 21:9eb628d9e164 1970 _cs(cs) {
wim 21:9eb628d9e164 1971
wim 32:59c4b8f648d4 1972 // Init cs
wim 32:59c4b8f648d4 1973 _setCS(true);
wim 32:59c4b8f648d4 1974
wim 21:9eb628d9e164 1975 // Setup the spi for 8 bit data, low steady state clock,
wim 21:9eb628d9e164 1976 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 21:9eb628d9e164 1977 _spi->format(8,0);
wim 21:9eb628d9e164 1978 _spi->frequency(500000);
wim 21:9eb628d9e164 1979 //_spi.frequency(1000000);
wim 21:9eb628d9e164 1980
wim 21:9eb628d9e164 1981 // Init the portexpander bus
wim 21:9eb628d9e164 1982 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1983
wim 21:9eb628d9e164 1984 // write the new data to the portexpander
wim 21:9eb628d9e164 1985 _setCS(false);
wim 21:9eb628d9e164 1986 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1987 _setCS(true);
wim 30:033048611c01 1988
wim 30:033048611c01 1989 _init();
wim 21:9eb628d9e164 1990 }
wim 21:9eb628d9e164 1991
wim 21:9eb628d9e164 1992 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1993 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1994 void TextLCD_SPI::_setEnable(bool value) {
wim 21:9eb628d9e164 1995
wim 22:35742ec80c24 1996 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1997 if (value) {
wim 22:35742ec80c24 1998 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1999 }
wim 26:bd897a001012 2000 else {
wim 22:35742ec80c24 2001 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 2002 }
wim 22:35742ec80c24 2003 }
wim 22:35742ec80c24 2004 else {
wim 26:bd897a001012 2005 if (value) {
wim 22:35742ec80c24 2006 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 2007 }
wim 26:bd897a001012 2008 else {
wim 22:35742ec80c24 2009 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
wim 26:bd897a001012 2010 }
wim 22:35742ec80c24 2011 }
wim 21:9eb628d9e164 2012
wim 22:35742ec80c24 2013 // write the new data to the SPI portexpander
wim 22:35742ec80c24 2014 _setCS(false);
wim 22:35742ec80c24 2015 _spi->write(_lcd_bus);
wim 30:033048611c01 2016 _setCS(true);
wim 21:9eb628d9e164 2017 }
wim 21:9eb628d9e164 2018
wim 21:9eb628d9e164 2019 // Set RS pin
wim 21:9eb628d9e164 2020 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 2021 void TextLCD_SPI::_setRS(bool value) {
wim 21:9eb628d9e164 2022
wim 22:35742ec80c24 2023 if (value) {
wim 21:9eb628d9e164 2024 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 22:35742ec80c24 2025 }
wim 22:35742ec80c24 2026 else {
wim 21:9eb628d9e164 2027 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 22:35742ec80c24 2028 }
wim 21:9eb628d9e164 2029
wim 21:9eb628d9e164 2030 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 2031 _setCS(false);
wim 21:9eb628d9e164 2032 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 2033 _setCS(true);
wim 21:9eb628d9e164 2034 }
wim 21:9eb628d9e164 2035
wim 21:9eb628d9e164 2036 // Set BL pin
wim 21:9eb628d9e164 2037 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 2038 void TextLCD_SPI::_setBL(bool value) {
wim 21:9eb628d9e164 2039
wim 22:35742ec80c24 2040 if (value) {
wim 21:9eb628d9e164 2041 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 22:35742ec80c24 2042 }
wim 22:35742ec80c24 2043 else {
wim 21:9eb628d9e164 2044 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 22:35742ec80c24 2045 }
wim 21:9eb628d9e164 2046
wim 21:9eb628d9e164 2047 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 2048 _setCS(false);
wim 21:9eb628d9e164 2049 _spi->write(_lcd_bus);
wim 30:033048611c01 2050 _setCS(true);
wim 21:9eb628d9e164 2051 }
wim 21:9eb628d9e164 2052
wim 21:9eb628d9e164 2053 // Place the 4bit data on the databus
wim 21:9eb628d9e164 2054 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 2055 void TextLCD_SPI::_setData(int value) {
wim 21:9eb628d9e164 2056 int data;
wim 21:9eb628d9e164 2057
wim 22:35742ec80c24 2058 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 22:35742ec80c24 2059
wim 22:35742ec80c24 2060 data = value & 0x0F;
wim 26:bd897a001012 2061 if (data & 0x01) {
wim 22:35742ec80c24 2062 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 2063 }
wim 26:bd897a001012 2064 else {
wim 22:35742ec80c24 2065 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 2066 }
wim 26:bd897a001012 2067
wim 26:bd897a001012 2068 if (data & 0x02) {
wim 22:35742ec80c24 2069 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 2070 }
wim 26:bd897a001012 2071 else {
wim 22:35742ec80c24 2072 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 2073 }
wim 26:bd897a001012 2074
wim 26:bd897a001012 2075 if (data & 0x04) {
wim 22:35742ec80c24 2076 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 2077 }
wim 26:bd897a001012 2078 else {
wim 22:35742ec80c24 2079 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 2080 }
wim 26:bd897a001012 2081
wim 26:bd897a001012 2082 if (data & 0x08) {
wim 22:35742ec80c24 2083 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 2084 }
wim 26:bd897a001012 2085 else {
wim 26:bd897a001012 2086 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 2087 }
wim 21:9eb628d9e164 2088
wim 22:35742ec80c24 2089 // write the new data to the SPI portexpander
wim 22:35742ec80c24 2090 _setCS(false);
wim 22:35742ec80c24 2091 _spi->write(_lcd_bus);
wim 30:033048611c01 2092 _setCS(true);
wim 21:9eb628d9e164 2093 }
wim 21:9eb628d9e164 2094
wim 21:9eb628d9e164 2095 // Set CS line.
wim 21:9eb628d9e164 2096 // Only used for SPI bus
wim 21:9eb628d9e164 2097 void TextLCD_SPI::_setCS(bool value) {
wim 21:9eb628d9e164 2098
wim 21:9eb628d9e164 2099 if (value) {
wim 21:9eb628d9e164 2100 _cs = 1; // Set CS pin
wim 21:9eb628d9e164 2101 }
wim 22:35742ec80c24 2102 else {
wim 21:9eb628d9e164 2103 _cs = 0; // Reset CS pin
wim 22:35742ec80c24 2104 }
wim 21:9eb628d9e164 2105 }
wim 21:9eb628d9e164 2106
wim 23:d47f226efb24 2107 //---------- End TextLCD_SPI ------------
wim 22:35742ec80c24 2108
wim 22:35742ec80c24 2109
wim 25:6162b31128c9 2110 //--------- Start TextLCD_SPI_N ---------
Sissors 24:fb3399713710 2111
wim 30:033048611c01 2112 /** Create a TextLCD interface using a controller with a native SPI4 interface
Sissors 24:fb3399713710 2113 *
Sissors 24:fb3399713710 2114 * @param spi SPI Bus
Sissors 24:fb3399713710 2115 * @param cs chip select pin (active low)
wim 25:6162b31128c9 2116 * @param rs Instruction/data control line
Sissors 24:fb3399713710 2117 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 25:6162b31128c9 2118 * @param bl Backlight control line (optional, default = NC)
wim 26:bd897a001012 2119 * @param ctrl LCD controller (default = ST7032_3V3)
wim 25:6162b31128c9 2120 */
wim 25:6162b31128c9 2121 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 25:6162b31128c9 2122 TextLCD_Base(type, ctrl),
wim 25:6162b31128c9 2123 _spi(spi),
wim 25:6162b31128c9 2124 _cs(cs),
wim 25:6162b31128c9 2125 _rs(rs) {
Sissors 24:fb3399713710 2126
wim 32:59c4b8f648d4 2127 // Init CS
wim 32:59c4b8f648d4 2128 _cs = 1;
wim 32:59c4b8f648d4 2129
Sissors 24:fb3399713710 2130 // Setup the spi for 8 bit data, low steady state clock,
Sissors 24:fb3399713710 2131 // rising edge capture, with a 500KHz or 1MHz clock rate
Sissors 24:fb3399713710 2132 _spi->format(8,0);
Sissors 24:fb3399713710 2133 _spi->frequency(1000000);
Sissors 24:fb3399713710 2134
Sissors 24:fb3399713710 2135 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
Sissors 24:fb3399713710 2136 if (bl != NC) {
Sissors 24:fb3399713710 2137 _bl = new DigitalOut(bl); //Construct new pin
Sissors 24:fb3399713710 2138 _bl->write(0); //Deactivate
Sissors 24:fb3399713710 2139 }
Sissors 24:fb3399713710 2140 else {
Sissors 24:fb3399713710 2141 // No Hardware Backlight pin
Sissors 24:fb3399713710 2142 _bl = NULL; //Construct dummy pin
Sissors 24:fb3399713710 2143 }
wim 30:033048611c01 2144
wim 30:033048611c01 2145 //Sanity check
wim 30:033048611c01 2146 if (_ctrl & LCD_C_SPI4) {
wim 30:033048611c01 2147 _init();
wim 30:033048611c01 2148 }
wim 30:033048611c01 2149 else {
wim 30:033048611c01 2150 error("Error: LCD Controller type does not support native SPI4 interface\n\r");
wim 30:033048611c01 2151 }
Sissors 24:fb3399713710 2152 }
Sissors 24:fb3399713710 2153
wim 25:6162b31128c9 2154 TextLCD_SPI_N::~TextLCD_SPI_N() {
Sissors 24:fb3399713710 2155 if (_bl != NULL) {delete _bl;} // BL pin
Sissors 24:fb3399713710 2156 }
Sissors 24:fb3399713710 2157
Sissors 24:fb3399713710 2158 // Not used in this mode
wim 25:6162b31128c9 2159 void TextLCD_SPI_N::_setEnable(bool value) {
Sissors 24:fb3399713710 2160 }
Sissors 24:fb3399713710 2161
Sissors 24:fb3399713710 2162 // Set RS pin
Sissors 24:fb3399713710 2163 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 25:6162b31128c9 2164 void TextLCD_SPI_N::_setRS(bool value) {
Sissors 24:fb3399713710 2165 _rs = value;
Sissors 24:fb3399713710 2166 }
Sissors 24:fb3399713710 2167
Sissors 24:fb3399713710 2168 // Set BL pin
wim 25:6162b31128c9 2169 void TextLCD_SPI_N::_setBL(bool value) {
wim 26:bd897a001012 2170 if (_bl) {
Sissors 24:fb3399713710 2171 _bl->write(value);
wim 26:bd897a001012 2172 }
Sissors 24:fb3399713710 2173 }
Sissors 24:fb3399713710 2174
wim 29:a3663151aa65 2175 // Not used in this mode
wim 29:a3663151aa65 2176 void TextLCD_SPI_N::_setData(int value) {
wim 29:a3663151aa65 2177 }
wim 29:a3663151aa65 2178
Sissors 24:fb3399713710 2179 // Write a byte using SPI
wim 25:6162b31128c9 2180 void TextLCD_SPI_N::_writeByte(int value) {
Sissors 24:fb3399713710 2181 _cs = 0;
Sissors 24:fb3399713710 2182 wait_us(1);
Sissors 24:fb3399713710 2183 _spi->write(value);
Sissors 24:fb3399713710 2184 wait_us(1);
Sissors 24:fb3399713710 2185 _cs = 1;
Sissors 24:fb3399713710 2186 }
wim 30:033048611c01 2187
wim 25:6162b31128c9 2188 //-------- End TextLCD_SPI_N ------------
wim 21:9eb628d9e164 2189
wim 21:9eb628d9e164 2190
wim 21:9eb628d9e164 2191
wim 32:59c4b8f648d4 2192 #if(1)
wim 30:033048611c01 2193 //Code checked out on logic analyser. Not yet tested on hardware..
wim 30:033048611c01 2194
wim 30:033048611c01 2195 //-------- Start TextLCD_SPI_N_3_9 --------
wim 30:033048611c01 2196
wim 30:033048611c01 2197 /** Create a TextLCD interface using a controller with a native SPI3 9 bits interface
wim 30:033048611c01 2198 *
wim 30:033048611c01 2199 * @param spi SPI Bus
wim 30:033048611c01 2200 * @param cs chip select pin (active low)
wim 30:033048611c01 2201 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 2202 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 2203 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 2204 */
wim 30:033048611c01 2205 TextLCD_SPI_N_3_9::TextLCD_SPI_N_3_9(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 2206 TextLCD_Base(type, ctrl),
wim 30:033048611c01 2207 _spi(spi),
wim 32:59c4b8f648d4 2208 // _cs(cs) {
wim 32:59c4b8f648d4 2209
wim 32:59c4b8f648d4 2210 _cs(cs), _ps(p20) {
wim 32:59c4b8f648d4 2211
wim 32:59c4b8f648d4 2212 // Init PS
wim 32:59c4b8f648d4 2213 wait_us(500);
wim 32:59c4b8f648d4 2214 _ps = 0;
wim 32:59c4b8f648d4 2215 wait_us(250);
wim 32:59c4b8f648d4 2216
wim 32:59c4b8f648d4 2217 // Init CS
wim 32:59c4b8f648d4 2218 _cs = 1;
wim 32:59c4b8f648d4 2219
wim 30:033048611c01 2220 // Setup the spi for 9 bit data, low steady state clock,
wim 30:033048611c01 2221 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 32:59c4b8f648d4 2222 // _spi->format(9,0);
wim 32:59c4b8f648d4 2223 _spi->format(9,3);
wim 30:033048611c01 2224 _spi->frequency(1000000);
wim 30:033048611c01 2225
wim 30:033048611c01 2226 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 2227 if (bl != NC) {
wim 30:033048611c01 2228 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 2229 _bl->write(0); //Deactivate
wim 30:033048611c01 2230 }
wim 30:033048611c01 2231 else {
wim 30:033048611c01 2232 // No Hardware Backlight pin
wim 30:033048611c01 2233 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 2234 }
wim 30:033048611c01 2235
wim 30:033048611c01 2236 //Sanity check
wim 30:033048611c01 2237 if (_ctrl & LCD_C_SPI3_9) {
wim 30:033048611c01 2238 _init();
wim 30:033048611c01 2239 }
wim 30:033048611c01 2240 else {
wim 30:033048611c01 2241 error("Error: LCD Controller type does not support native SPI3 9 bits interface\n\r");
wim 30:033048611c01 2242 }
wim 30:033048611c01 2243 }
wim 30:033048611c01 2244
wim 30:033048611c01 2245 TextLCD_SPI_N_3_9::~TextLCD_SPI_N_3_9() {
wim 30:033048611c01 2246 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 2247 }
wim 30:033048611c01 2248
wim 30:033048611c01 2249 // Not used in this mode
wim 30:033048611c01 2250 void TextLCD_SPI_N_3_9::_setEnable(bool value) {
wim 30:033048611c01 2251 }
wim 30:033048611c01 2252
wim 30:033048611c01 2253 // Set RS pin
wim 30:033048611c01 2254 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 2255 void TextLCD_SPI_N_3_9::_setRS(bool value) {
wim 30:033048611c01 2256 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 2257 // b8 b7...........b0
wim 30:033048611c01 2258 // RS command or data
wim 30:033048611c01 2259 //
wim 30:033048611c01 2260 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 2261 //
wim 30:033048611c01 2262
wim 30:033048611c01 2263 if (value) {
wim 30:033048611c01 2264 _controlbyte = 0x01; // Next byte is data
wim 30:033048611c01 2265 }
wim 30:033048611c01 2266 else {
wim 30:033048611c01 2267 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 2268 }
wim 30:033048611c01 2269
wim 30:033048611c01 2270 }
wim 30:033048611c01 2271
wim 30:033048611c01 2272 // Set BL pin
wim 30:033048611c01 2273 void TextLCD_SPI_N_3_9::_setBL(bool value) {
wim 30:033048611c01 2274 if (_bl) {
wim 30:033048611c01 2275 _bl->write(value);
wim 30:033048611c01 2276 }
wim 30:033048611c01 2277 }
wim 30:033048611c01 2278
wim 30:033048611c01 2279 // Not used in this mode
wim 30:033048611c01 2280 void TextLCD_SPI_N_3_9::_setData(int value) {
wim 30:033048611c01 2281 }
wim 30:033048611c01 2282
wim 30:033048611c01 2283 // Write a byte using SPI3 9 bits mode
wim 30:033048611c01 2284 void TextLCD_SPI_N_3_9::_writeByte(int value) {
wim 30:033048611c01 2285 _cs = 0;
wim 30:033048611c01 2286 wait_us(1);
wim 30:033048611c01 2287 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 2288 wait_us(1);
wim 30:033048611c01 2289 _cs = 1;
wim 30:033048611c01 2290 }
wim 30:033048611c01 2291
wim 30:033048611c01 2292 //------- End TextLCD_SPI_N_3_9 -----------
wim 30:033048611c01 2293 #endif
wim 21:9eb628d9e164 2294
wim 21:9eb628d9e164 2295
wim 32:59c4b8f648d4 2296 #if(1)
wim 30:033048611c01 2297 //------- Start TextLCD_SPI_N_3_10 --------
wim 30:033048611c01 2298
wim 30:033048611c01 2299 /** Create a TextLCD interface using a controller with a native SPI3 10 bits interface
wim 30:033048611c01 2300 *
wim 30:033048611c01 2301 * @param spi SPI Bus
wim 30:033048611c01 2302 * @param cs chip select pin (active low)
wim 30:033048611c01 2303 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 2304 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 2305 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 2306 */
wim 30:033048611c01 2307 TextLCD_SPI_N_3_10::TextLCD_SPI_N_3_10(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 2308 TextLCD_Base(type, ctrl),
wim 30:033048611c01 2309 _spi(spi),
wim 30:033048611c01 2310 _cs(cs) {
wim 30:033048611c01 2311
wim 32:59c4b8f648d4 2312 // Init CS
wim 32:59c4b8f648d4 2313 _cs = 1;
wim 32:59c4b8f648d4 2314
wim 30:033048611c01 2315 // Setup the spi for 10 bit data, low steady state clock,
wim 30:033048611c01 2316 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 30:033048611c01 2317 _spi->format(10,0);
wim 30:033048611c01 2318 _spi->frequency(1000000);
wim 30:033048611c01 2319
wim 30:033048611c01 2320 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 2321 if (bl != NC) {
wim 30:033048611c01 2322 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 2323 _bl->write(0); //Deactivate
wim 30:033048611c01 2324 }
wim 30:033048611c01 2325 else {
wim 30:033048611c01 2326 // No Hardware Backlight pin
wim 30:033048611c01 2327 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 2328 }
wim 30:033048611c01 2329
wim 30:033048611c01 2330 //Sanity check
wim 30:033048611c01 2331 if (_ctrl & LCD_C_SPI3_10) {
wim 30:033048611c01 2332 _init();
wim 30:033048611c01 2333 }
wim 30:033048611c01 2334 else {
wim 30:033048611c01 2335 error("Error: LCD Controller type does not support native SPI3 10 bits interface\n\r");
wim 30:033048611c01 2336 }
wim 30:033048611c01 2337 }
wim 30:033048611c01 2338
wim 30:033048611c01 2339 TextLCD_SPI_N_3_10::~TextLCD_SPI_N_3_10() {
wim 30:033048611c01 2340 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 2341 }
wim 30:033048611c01 2342
wim 30:033048611c01 2343 // Not used in this mode
wim 30:033048611c01 2344 void TextLCD_SPI_N_3_10::_setEnable(bool value) {
wim 30:033048611c01 2345 }
wim 30:033048611c01 2346
wim 30:033048611c01 2347 // Set RS pin
wim 30:033048611c01 2348 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 2349 void TextLCD_SPI_N_3_10::_setRS(bool value) {
wim 30:033048611c01 2350 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 2351 // b9 b8 b7...........b0
wim 30:033048611c01 2352 // RS RW command or data
wim 30:033048611c01 2353 //
wim 30:033048611c01 2354 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 2355 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
wim 30:033048611c01 2356 //
wim 30:033048611c01 2357
wim 30:033048611c01 2358 if (value) {
wim 30:033048611c01 2359 _controlbyte = 0x02; // Next byte is data
wim 30:033048611c01 2360 }
wim 30:033048611c01 2361 else {
wim 30:033048611c01 2362 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 2363 }
wim 30:033048611c01 2364
wim 30:033048611c01 2365 }
wim 30:033048611c01 2366
wim 30:033048611c01 2367 // Set BL pin
wim 30:033048611c01 2368 void TextLCD_SPI_N_3_10::_setBL(bool value) {
wim 30:033048611c01 2369 if (_bl) {
wim 30:033048611c01 2370 _bl->write(value);
wim 30:033048611c01 2371 }
wim 30:033048611c01 2372 }
wim 30:033048611c01 2373
wim 30:033048611c01 2374 // Not used in this mode
wim 30:033048611c01 2375 void TextLCD_SPI_N_3_10::_setData(int value) {
wim 30:033048611c01 2376 }
wim 30:033048611c01 2377
wim 30:033048611c01 2378 // Write a byte using SPI3 10 bits mode
wim 30:033048611c01 2379 void TextLCD_SPI_N_3_10::_writeByte(int value) {
wim 30:033048611c01 2380 _cs = 0;
wim 30:033048611c01 2381 wait_us(1);
wim 30:033048611c01 2382 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 2383 wait_us(1);
wim 30:033048611c01 2384 _cs = 1;
wim 30:033048611c01 2385 }
wim 30:033048611c01 2386
wim 30:033048611c01 2387 //------- End TextLCD_SPI_N_3_10 ----------
wim 32:59c4b8f648d4 2388 #endif
wim 32:59c4b8f648d4 2389
wim 32:59c4b8f648d4 2390 #if(0)
wim 32:59c4b8f648d4 2391 //Code to be checked out on logic analyser. Not yet tested on hardware..
wim 32:59c4b8f648d4 2392
wim 32:59c4b8f648d4 2393 //------- Start TextLCD_SPI_N_3_16 --------
wim 32:59c4b8f648d4 2394
wim 32:59c4b8f648d4 2395 /** Create a TextLCD interface using a controller with a native SPI3 16 bits interface
wim 32:59c4b8f648d4 2396 *
wim 32:59c4b8f648d4 2397 * @param spi SPI Bus
wim 32:59c4b8f648d4 2398 * @param cs chip select pin (active low)
wim 32:59c4b8f648d4 2399 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 32:59c4b8f648d4 2400 * @param bl Backlight control line (optional, default = NC)
wim 32:59c4b8f648d4 2401 * @param ctrl LCD controller (default = PT6314)
wim 32:59c4b8f648d4 2402 */
wim 32:59c4b8f648d4 2403 TextLCD_SPI_N_3_16::TextLCD_SPI_N_3_16(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 32:59c4b8f648d4 2404 TextLCD_Base(type, ctrl),
wim 32:59c4b8f648d4 2405 _spi(spi),
wim 32:59c4b8f648d4 2406 _cs(cs) {
wim 32:59c4b8f648d4 2407
wim 32:59c4b8f648d4 2408 // Init CS
wim 32:59c4b8f648d4 2409 _cs = 1;
wim 32:59c4b8f648d4 2410
wim 32:59c4b8f648d4 2411 // Setup the spi for 8 bit data, low steady state clock,
wim 32:59c4b8f648d4 2412 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 32:59c4b8f648d4 2413 _spi->format(8,0);
wim 32:59c4b8f648d4 2414 _spi->frequency(1000000);
wim 32:59c4b8f648d4 2415
wim 32:59c4b8f648d4 2416 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 32:59c4b8f648d4 2417 if (bl != NC) {
wim 32:59c4b8f648d4 2418 _bl = new DigitalOut(bl); //Construct new pin
wim 32:59c4b8f648d4 2419 _bl->write(0); //Deactivate
wim 32:59c4b8f648d4 2420 }
wim 32:59c4b8f648d4 2421 else {
wim 32:59c4b8f648d4 2422 // No Hardware Backlight pin
wim 32:59c4b8f648d4 2423 _bl = NULL; //Construct dummy pin
wim 32:59c4b8f648d4 2424 }
wim 32:59c4b8f648d4 2425
wim 32:59c4b8f648d4 2426 //Sanity check
wim 32:59c4b8f648d4 2427 if (_ctrl & LCD_C_SPI3_16) {
wim 32:59c4b8f648d4 2428 _init();
wim 32:59c4b8f648d4 2429 }
wim 32:59c4b8f648d4 2430 else {
wim 32:59c4b8f648d4 2431 error("Error: LCD Controller type does not support native SPI3 16 bits interface\n\r");
wim 32:59c4b8f648d4 2432 }
wim 32:59c4b8f648d4 2433 }
wim 32:59c4b8f648d4 2434
wim 32:59c4b8f648d4 2435 TextLCD_SPI_N_3_16::~TextLCD_SPI_N_3_16() {
wim 32:59c4b8f648d4 2436 if (_bl != NULL) {delete _bl;} // BL pin
wim 32:59c4b8f648d4 2437 }
wim 32:59c4b8f648d4 2438
wim 32:59c4b8f648d4 2439 // Not used in this mode
wim 32:59c4b8f648d4 2440 void TextLCD_SPI_N_3_16::_setEnable(bool value) {
wim 32:59c4b8f648d4 2441 }
wim 32:59c4b8f648d4 2442
wim 32:59c4b8f648d4 2443 // Set RS pin
wim 32:59c4b8f648d4 2444 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 32:59c4b8f648d4 2445 void TextLCD_SPI_N_3_16::_setRS(bool value) {
wim 32:59c4b8f648d4 2446 // 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.
wim 32:59c4b8f648d4 2447 // The 8 actual bits represent either a data or a command byte.
wim 32:59c4b8f648d4 2448 // b15 b14 b13 b12 b11 b10 b9 b8 - b7 b6 b5 b4 b3 b2 b1 b0
wim 32:59c4b8f648d4 2449 // 1 1 1 1 1 RW RS 0 d7 d6 d5 d4 d3 d2 d1 d0
wim 32:59c4b8f648d4 2450 //
wim 32:59c4b8f648d4 2451 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 32:59c4b8f648d4 2452 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
wim 32:59c4b8f648d4 2453 //
wim 32:59c4b8f648d4 2454
wim 32:59c4b8f648d4 2455 if (value) {
wim 32:59c4b8f648d4 2456 _controlbyte = 0xFA; // Next byte is data
wim 32:59c4b8f648d4 2457 }
wim 32:59c4b8f648d4 2458 else {
wim 32:59c4b8f648d4 2459 _controlbyte = 0xF8; // Next byte is command
wim 32:59c4b8f648d4 2460 }
wim 32:59c4b8f648d4 2461 }
wim 32:59c4b8f648d4 2462
wim 32:59c4b8f648d4 2463 // Set BL pin
wim 32:59c4b8f648d4 2464 void TextLCD_SPI_N_3_16::_setBL(bool value) {
wim 32:59c4b8f648d4 2465 if (_bl) {
wim 32:59c4b8f648d4 2466 _bl->write(value);
wim 32:59c4b8f648d4 2467 }
wim 32:59c4b8f648d4 2468 }
wim 32:59c4b8f648d4 2469
wim 32:59c4b8f648d4 2470 // Not used in this mode
wim 32:59c4b8f648d4 2471 void TextLCD_SPI_N_3_16::_setData(int value) {
wim 32:59c4b8f648d4 2472 }
wim 32:59c4b8f648d4 2473
wim 32:59c4b8f648d4 2474
wim 32:59c4b8f648d4 2475 // Write a byte using SPI3 16 bits mode
wim 32:59c4b8f648d4 2476 void TextLCD_SPI_N_3_16::_writeByte(int value) {
wim 32:59c4b8f648d4 2477 _cs = 0;
wim 32:59c4b8f648d4 2478 wait_us(1);
wim 32:59c4b8f648d4 2479
wim 32:59c4b8f648d4 2480 _spi->write(_controlbyte);
wim 32:59c4b8f648d4 2481
wim 32:59c4b8f648d4 2482 _spi->write(value);
wim 32:59c4b8f648d4 2483
wim 32:59c4b8f648d4 2484 wait_us(1);
wim 32:59c4b8f648d4 2485 _cs = 1;
wim 32:59c4b8f648d4 2486 }
wim 32:59c4b8f648d4 2487
wim 32:59c4b8f648d4 2488 //------- End TextLCD_SPI_N_3_16 ----------
wim 32:59c4b8f648d4 2489 #endif
wim 32:59c4b8f648d4 2490
wim 32:59c4b8f648d4 2491 #if(1)
wim 32:59c4b8f648d4 2492 //Code to be checked out on logic analyser. Not yet tested on hardware..
wim 32:59c4b8f648d4 2493
wim 32:59c4b8f648d4 2494 //------- Start TextLCD_SPI_N_3_24 --------
wim 32:59c4b8f648d4 2495
wim 32:59c4b8f648d4 2496 /** Create a TextLCD interface using a controller with a native SPI3 24 bits interface
wim 32:59c4b8f648d4 2497 *
wim 32:59c4b8f648d4 2498 * @param spi SPI Bus
wim 32:59c4b8f648d4 2499 * @param cs chip select pin (active low)
wim 32:59c4b8f648d4 2500 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 32:59c4b8f648d4 2501 * @param bl Backlight control line (optional, default = NC)
wim 32:59c4b8f648d4 2502 * @param ctrl LCD controller (default = SSD1803)
wim 32:59c4b8f648d4 2503 */
wim 32:59c4b8f648d4 2504 TextLCD_SPI_N_3_24::TextLCD_SPI_N_3_24(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 32:59c4b8f648d4 2505 TextLCD_Base(type, ctrl),
wim 32:59c4b8f648d4 2506 _spi(spi),
wim 32:59c4b8f648d4 2507 _cs(cs) {
wim 32:59c4b8f648d4 2508
wim 32:59c4b8f648d4 2509 // Init CS
wim 32:59c4b8f648d4 2510 _cs = 1;
wim 32:59c4b8f648d4 2511
wim 32:59c4b8f648d4 2512 // Setup the spi for 8 bit data, low steady state clock,
wim 32:59c4b8f648d4 2513 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 32:59c4b8f648d4 2514 _spi->format(8,0);
wim 32:59c4b8f648d4 2515 _spi->frequency(1000000);
wim 32:59c4b8f648d4 2516
wim 32:59c4b8f648d4 2517 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 32:59c4b8f648d4 2518 if (bl != NC) {
wim 32:59c4b8f648d4 2519 _bl = new DigitalOut(bl); //Construct new pin
wim 32:59c4b8f648d4 2520 _bl->write(0); //Deactivate
wim 32:59c4b8f648d4 2521 }
wim 32:59c4b8f648d4 2522 else {
wim 32:59c4b8f648d4 2523 // No Hardware Backlight pin
wim 32:59c4b8f648d4 2524 _bl = NULL; //Construct dummy pin
wim 32:59c4b8f648d4 2525 }
wim 32:59c4b8f648d4 2526
wim 32:59c4b8f648d4 2527 //Sanity check
wim 32:59c4b8f648d4 2528 if (_ctrl & LCD_C_SPI3_24) {
wim 32:59c4b8f648d4 2529 _init();
wim 32:59c4b8f648d4 2530 }
wim 32:59c4b8f648d4 2531 else {
wim 32:59c4b8f648d4 2532 error("Error: LCD Controller type does not support native SPI3 24 bits interface\n\r");
wim 32:59c4b8f648d4 2533 }
wim 32:59c4b8f648d4 2534 }
wim 32:59c4b8f648d4 2535
wim 32:59c4b8f648d4 2536 TextLCD_SPI_N_3_24::~TextLCD_SPI_N_3_24() {
wim 32:59c4b8f648d4 2537 if (_bl != NULL) {delete _bl;} // BL pin
wim 32:59c4b8f648d4 2538 }
wim 32:59c4b8f648d4 2539
wim 32:59c4b8f648d4 2540 // Not used in this mode
wim 32:59c4b8f648d4 2541 void TextLCD_SPI_N_3_24::_setEnable(bool value) {
wim 32:59c4b8f648d4 2542 }
wim 32:59c4b8f648d4 2543
wim 32:59c4b8f648d4 2544 // Set RS pin
wim 32:59c4b8f648d4 2545 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 32:59c4b8f648d4 2546 void TextLCD_SPI_N_3_24::_setRS(bool value) {
wim 32:59c4b8f648d4 2547 // 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.
wim 32:59c4b8f648d4 2548 // Each byte encodes 4 actual bits. The 8 actual bits represent either a data or a command byte.
wim 32:59c4b8f648d4 2549 // b23 b22 b21 b20 b19 b18 b17 b16 - b15 b14 b13 b12 b11 b10 b9 b8 - b7 b6 b5 b4 b3 b2 b1 b0
wim 32:59c4b8f648d4 2550 // 1 1 1 1 1 RW RS 0 d0 d1 d2 d3 0 0 0 0 d4 d5 d6 d7 0 0 0 0
wim 32:59c4b8f648d4 2551 //
wim 32:59c4b8f648d4 2552 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 32:59c4b8f648d4 2553 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
wim 32:59c4b8f648d4 2554 //
wim 32:59c4b8f648d4 2555 // Note: SPI3_24 expects LSB first. This is inconsistent with regular SPI convention (and hardware) that sends MSB first.
wim 32:59c4b8f648d4 2556
wim 32:59c4b8f648d4 2557 if (value) {
wim 32:59c4b8f648d4 2558 _controlbyte = 0xFA; // Next byte is data
wim 32:59c4b8f648d4 2559 }
wim 32:59c4b8f648d4 2560 else {
wim 32:59c4b8f648d4 2561 _controlbyte = 0xF8; // Next byte is command
wim 32:59c4b8f648d4 2562 }
wim 32:59c4b8f648d4 2563
wim 32:59c4b8f648d4 2564 }
wim 32:59c4b8f648d4 2565
wim 32:59c4b8f648d4 2566 // Set BL pin
wim 32:59c4b8f648d4 2567 void TextLCD_SPI_N_3_24::_setBL(bool value) {
wim 32:59c4b8f648d4 2568 if (_bl) {
wim 32:59c4b8f648d4 2569 _bl->write(value);
wim 32:59c4b8f648d4 2570 }
wim 32:59c4b8f648d4 2571 }
wim 32:59c4b8f648d4 2572
wim 32:59c4b8f648d4 2573 // Not used in this mode
wim 32:59c4b8f648d4 2574 void TextLCD_SPI_N_3_24::_setData(int value) {
wim 32:59c4b8f648d4 2575 }
wim 32:59c4b8f648d4 2576
wim 32:59c4b8f648d4 2577 //Mapping table to flip the bits around cause SPI3_24 expects LSB first.
wim 32:59c4b8f648d4 2578 const uint8_t map3_24[16] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0};
wim 32:59c4b8f648d4 2579
wim 32:59c4b8f648d4 2580 // Write a byte using SPI3 24 bits mode
wim 32:59c4b8f648d4 2581 void TextLCD_SPI_N_3_24::_writeByte(int value) {
wim 32:59c4b8f648d4 2582 _cs = 0;
wim 32:59c4b8f648d4 2583 wait_us(1);
wim 32:59c4b8f648d4 2584 _spi->write(_controlbyte);
wim 32:59c4b8f648d4 2585
wim 32:59c4b8f648d4 2586 //Map and send the LSB nibble
wim 32:59c4b8f648d4 2587 _spi->write( map3_24[value & 0x0F]);
wim 32:59c4b8f648d4 2588
wim 32:59c4b8f648d4 2589 //Map and send the MSB nibble
wim 32:59c4b8f648d4 2590 _spi->write( map3_24[(value >> 4) & 0x0F]);
wim 32:59c4b8f648d4 2591
wim 32:59c4b8f648d4 2592 wait_us(1);
wim 32:59c4b8f648d4 2593 _cs = 1;
wim 32:59c4b8f648d4 2594 }
wim 32:59c4b8f648d4 2595
wim 32:59c4b8f648d4 2596 //------- End TextLCD_SPI_N_3_24 ----------
wim 30:033048611c01 2597 #endif