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:
Sat Jun 28 14:27:32 2014 +0000
Revision:
30:033048611c01
Parent:
29:a3663151aa65
Child:
31:ef31cd8a00d1
Tested AIP31068 for I2C, tested SPI3_9 and SPI3_10

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