for

Dependents:   LV_FGSE_Controller_Interface

Committer:
wim
Date:
Thu Aug 28 15:44:08 2014 +0000
Revision:
33:900a94bc7585
Parent:
32:59c4b8f648d4
Child:
34:e5a0dcb43ecc
Added support for controllers US2066/SSD1311 (OLED), added setUDCBlink method for supported devices (eg SSD1803), fixed issue in setPower()

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