Updated for more display types. Fixed memoryaddress confusion in address() method. Added new getAddress() method. Added support for UDCs, Backlight control and other features such as control through I2C and SPI port expanders and controllers with native I2C and SPI interfaces. Refactored to fix issue with pins that are default declared as NC.

Dependents:   GPSDevice TestTextLCD SD to Flash Data Transfer DrumMachine ... more

Fork of TextLCD by Simon Ford

Example

Hello World! for the TextLCD

#include "mbed.h"
#include "TextLCD.h"
 
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
 
// I2C Communication
I2C i2c_lcd(p28,p27); // SDA, SCL
 
// SPI Communication
SPI spi_lcd(p5, NC, p7); // MOSI, MISO, SCLK

//TextLCD lcd(p15, p16, p17, p18, p19, p20);                // RS, E, D4-D7, LCDType=LCD16x2, BL=NC, E2=NC, LCDTCtrl=HD44780
//TextLCD_SPI lcd(&spi_lcd, p8, TextLCD::LCD40x4);   // SPI bus, 74595 expander, CS pin, LCD Type  
TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD20x4);  // I2C bus, PCF8574 Slaveaddress, LCD Type
//TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C bus, PCF8574 Slaveaddress, LCD Type, Device Type
//TextLCD_SPI_N lcd(&spi_lcd, p8, p9);               // SPI bus, CS pin, RS pin, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032_3V3   
//TextLCD_I2C_N lcd(&i2c_lcd, ST7032_SA, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // I2C bus, Slaveaddress, LCD Type, BL=NC, LCDTCtrl=ST7032_3V3  

int main() {
    pc.printf("LCD Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());
    
    for (int row=0; row<lcd.rows(); row++) {
      int col=0;
      
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
//      lcd.putc('-');
      lcd.putc('0' + row);      
      
      for (col=1; col<lcd.columns()-1; col++) {    
        lcd.putc('*');
      }
 
      pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));      
      lcd.putc('+');
        
    }    
    
// Show cursor as blinking character
    lcd.setCursor(TextLCD::CurOff_BlkOn);
 
// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern. 
    lcd.setUDC(0, (char *) udc_0);  // Show |>
    lcd.putc(0);    
    lcd.setUDC(1, (char *) udc_1);  // Show <|
    lcd.putc(1);    

}

Handbook page

More info is here

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

Who changed what in which revision?

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