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:
Sun Jun 29 14:55:50 2014 +0000
Revision:
31:ef31cd8a00d1
Parent:
30:033048611c01
Child:
32:59c4b8f648d4
Added Support for native I2C controllers (PCF21XX, AIP31068), added LCDTypes for 3 and 4 line displays. Encoded features in LCDTypes and LCDCtrl enumerators to ease code maintenance and improve sanity checks.

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
wim 30:033048611c01 816 // This is new method to return the memory address based on row, column and displaytype.
wim 30:033048611c01 817 //
wim 30:033048611c01 818 /** Return the memoryaddress of screen column and row location
wim 30:033048611c01 819 *
wim 30:033048611c01 820 * @param column The horizontal position from the left, indexed from 0
wim 30:033048611c01 821 * @param row The vertical position from the top, indexed from 0
wim 30:033048611c01 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 30:033048611c01 825 */
wim 30:033048611c01 826 int TextLCD_Base::getAddress(int column, int row) {
wim 30:033048611c01 827
wim 30:033048611c01 828 switch (_addr_mode) {
wim 30:033048611c01 829
wim 30:033048611c01 830 case LCD_T_A:
wim 30:033048611c01 831 //Default addressing mode for 1, 2 and 4 rows (except 40x4)
wim 30:033048611c01 832 //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 833 //Displays top rows when less than four are used.
wim 30:033048611c01 834 switch (row) {
wim 30:033048611c01 835 case 0:
wim 30:033048611c01 836 return 0x00 + column;
wim 30:033048611c01 837 case 1:
wim 30:033048611c01 838 return 0x40 + column;
wim 30:033048611c01 839 case 2:
wim 30:033048611c01 840 return 0x00 + _nr_cols + column;
wim 30:033048611c01 841 case 3:
wim 30:033048611c01 842 return 0x40 + _nr_cols + column;
wim 30:033048611c01 843 // Should never get here.
wim 30:033048611c01 844 default:
wim 30:033048611c01 845 return 0x00;
wim 30:033048611c01 846 }
wim 30:033048611c01 847
wim 30:033048611c01 848 case LCD_T_B:
wim 30:033048611c01 849 // LCD8x2B is a special layout of LCD16x1
wim 30:033048611c01 850 if (row==0)
wim 30:033048611c01 851 return 0x00 + column;
wim 30:033048611c01 852 else
wim 30:033048611c01 853 // return _nr_cols + column;
wim 30:033048611c01 854 return 0x08 + column;
wim 30:033048611c01 855
wim 30:033048611c01 856 case LCD_T_C:
wim 30:033048611c01 857 // LCD16x1C is a special layout of LCD8x2
wim 30:033048611c01 858 if (column<8)
wim 30:033048611c01 859 return 0x00 + column;
wim 30:033048611c01 860 else
wim 30:033048611c01 861 return 0x40 + (column - 8);
wim 30:033048611c01 862
wim 30:033048611c01 863 // Not sure about this one, seems wrong.
wim 30:033048611c01 864 // Left in for compatibility with original library
wim 30:033048611c01 865 // case LCD16x2B:
wim 30:033048611c01 866 // return 0x00 + (row * 40) + column;
wim 30:033048611c01 867
wim 30:033048611c01 868
wim 30:033048611c01 869 case LCD_T_D:
wim 30:033048611c01 870 //Alternate addressing mode for 3 and 4 row displays (except 40x4). Used by PCF21XX, KS0078
wim 30:033048611c01 871 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 872 //Displays top rows when less than four are used.
wim 30:033048611c01 873 switch (row) {
wim 30:033048611c01 874 case 0:
wim 30:033048611c01 875 return 0x00 + column;
wim 30:033048611c01 876 case 1:
wim 30:033048611c01 877 return 0x20 + column;
wim 30:033048611c01 878 case 2:
wim 30:033048611c01 879 return 0x40 + column;
wim 30:033048611c01 880 case 3:
wim 30:033048611c01 881 return 0x60 + column;
wim 30:033048611c01 882 // Should never get here.
wim 30:033048611c01 883 default:
wim 30:033048611c01 884 return 0x00;
wim 30:033048611c01 885 }
wim 30:033048611c01 886
wim 30:033048611c01 887 case LCD_T_D1:
wim 30:033048611c01 888 //Alternate addressing mode for 3 row displays. Used by PCF21XX, KS0078
wim 30:033048611c01 889 //The 4 available rows start at a hardcoded address.
wim 30:033048611c01 890 //Skips top row of 4 row display and starts display at row 1
wim 30:033048611c01 891 switch (row) {
wim 30:033048611c01 892 case 0:
wim 30:033048611c01 893 return 0x20 + column;
wim 30:033048611c01 894 case 1:
wim 30:033048611c01 895 return 0x40 + column;
wim 30:033048611c01 896 case 2:
wim 30:033048611c01 897 return 0x60 + column;
wim 30:033048611c01 898 // Should never get here.
wim 30:033048611c01 899 default:
wim 30:033048611c01 900 return 0x00;
wim 30:033048611c01 901 }
wim 30:033048611c01 902
wim 30:033048611c01 903 case LCD_T_E:
wim 30:033048611c01 904 // LCD40x4 is a special case since it has 2 controllers.
wim 30:033048611c01 905 // Each controller is configured as 40x2 (Type A)
wim 30:033048611c01 906 if (row<2) {
wim 30:033048611c01 907 // Test to see if we need to switch between controllers
wim 30:033048611c01 908 if (_ctrl_idx != _LCDCtrl_0) {
wim 30:033048611c01 909
wim 30:033048611c01 910 // Second LCD controller Cursor Off
wim 30:033048611c01 911 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 912
wim 30:033048611c01 913 // Select primary controller
wim 30:033048611c01 914 _ctrl_idx = _LCDCtrl_0;
wim 30:033048611c01 915
wim 30:033048611c01 916 // Restore cursormode on primary LCD controller
wim 30:033048611c01 917 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 918 }
wim 30:033048611c01 919
wim 30:033048611c01 920 return 0x00 + (row * 0x40) + column;
wim 30:033048611c01 921 }
wim 30:033048611c01 922 else {
wim 30:033048611c01 923
wim 30:033048611c01 924 // Test to see if we need to switch between controllers
wim 30:033048611c01 925 if (_ctrl_idx != _LCDCtrl_1) {
wim 30:033048611c01 926 // Primary LCD controller Cursor Off
wim 30:033048611c01 927 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 30:033048611c01 928
wim 30:033048611c01 929 // Select secondary controller
wim 30:033048611c01 930 _ctrl_idx = _LCDCtrl_1;
wim 30:033048611c01 931
wim 30:033048611c01 932 // Restore cursormode on secondary LCD controller
wim 30:033048611c01 933 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 934 }
wim 30:033048611c01 935
wim 30:033048611c01 936 return 0x00 + ((row-2) * 0x40) + column;
wim 30:033048611c01 937 }
wim 30:033048611c01 938
wim 30:033048611c01 939 // Should never get here.
wim 30:033048611c01 940 default:
wim 30:033048611c01 941 return 0x00;
wim 30:033048611c01 942 }
wim 30:033048611c01 943 }
wim 30:033048611c01 944
wim 30:033048611c01 945
wim 29:a3663151aa65 946 /** Set the memoryaddress of screen column and row location
wim 29:a3663151aa65 947 *
wim 29:a3663151aa65 948 * @param column The horizontal position from the left, indexed from 0
wim 29:a3663151aa65 949 * @param row The vertical position from the top, indexed from 0
wim 29:a3663151aa65 950 */
wim 21:9eb628d9e164 951 void TextLCD_Base::setAddress(int column, int row) {
wim 15:b70ebfffb258 952
wim 15:b70ebfffb258 953 // Sanity Check column
wim 15:b70ebfffb258 954 if (column < 0) {
wim 15:b70ebfffb258 955 _column = 0;
wim 15:b70ebfffb258 956 }
wim 15:b70ebfffb258 957 else if (column >= columns()) {
wim 15:b70ebfffb258 958 _column = columns() - 1;
wim 15:b70ebfffb258 959 } else _column = column;
wim 8:03116f75b66e 960
wim 15:b70ebfffb258 961 // Sanity Check row
wim 15:b70ebfffb258 962 if (row < 0) {
wim 15:b70ebfffb258 963 _row = 0;
wim 15:b70ebfffb258 964 }
wim 15:b70ebfffb258 965 else if (row >= rows()) {
wim 15:b70ebfffb258 966 _row = rows() - 1;
wim 15:b70ebfffb258 967 } else _row = row;
wim 15:b70ebfffb258 968
wim 15:b70ebfffb258 969
wim 15:b70ebfffb258 970 // Compute the memory address
wim 15:b70ebfffb258 971 // For LCD40x4: switch controllers if needed
wim 15:b70ebfffb258 972 // switch cursor if needed
wim 15:b70ebfffb258 973 int addr = getAddress(_column, _row);
wim 8:03116f75b66e 974
wim 13:24506ba22480 975 _writeCommand(0x80 | addr);
wim 8:03116f75b66e 976 }
simon 1:ac48b187213c 977
wim 29:a3663151aa65 978
wim 29:a3663151aa65 979 /** Return the number of columns
wim 29:a3663151aa65 980 *
wim 29:a3663151aa65 981 * @param return The number of columns
wim 30:033048611c01 982 *
wim 30:033048611c01 983 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 984 */
wim 21:9eb628d9e164 985 int TextLCD_Base::columns() {
wim 30:033048611c01 986
wim 30:033048611c01 987 // Columns encoded in b7..b0
wim 30:033048611c01 988 //return (_type & 0xFF);
wim 31:ef31cd8a00d1 989 return _nr_cols;
simon 1:ac48b187213c 990 }
simon 1:ac48b187213c 991
wim 29:a3663151aa65 992 /** Return the number of rows
wim 29:a3663151aa65 993 *
wim 29:a3663151aa65 994 * @param return The number of rows
wim 30:033048611c01 995 *
wim 30:033048611c01 996 * Note: some configurations are commented out because they have not yet been tested due to lack of hardware
wim 29:a3663151aa65 997 */
wim 21:9eb628d9e164 998 int TextLCD_Base::rows() {
wim 30:033048611c01 999
wim 30:033048611c01 1000 // Rows encoded in b15..b8
wim 30:033048611c01 1001 //return ((_type >> 8) & 0xFF);
wim 30:033048611c01 1002 return _nr_rows;
simon 1:ac48b187213c 1003 }
wim 10:dd9b3a696acd 1004
wim 29:a3663151aa65 1005 /** Set the Cursormode
wim 29:a3663151aa65 1006 *
wim 29:a3663151aa65 1007 * @param cursorMode The Cursor mode (CurOff_BlkOff, CurOn_BlkOff, CurOff_BlkOn, CurOn_BlkOn)
wim 29:a3663151aa65 1008 */
wim 21:9eb628d9e164 1009 void TextLCD_Base::setCursor(LCDCursor cursorMode) {
wim 15:b70ebfffb258 1010
wim 17:652ab113bc2e 1011 // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
wim 17:652ab113bc2e 1012 _currentCursor = cursorMode;
wim 10:dd9b3a696acd 1013
wim 17:652ab113bc2e 1014 // Configure only current LCD controller
wim 31:ef31cd8a00d1 1015 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 15:b70ebfffb258 1016 }
wim 15:b70ebfffb258 1017
wim 29:a3663151aa65 1018 /** Set the Displaymode
wim 29:a3663151aa65 1019 *
wim 29:a3663151aa65 1020 * @param displayMode The Display mode (DispOff, DispOn)
wim 29:a3663151aa65 1021 */
wim 21:9eb628d9e164 1022 void TextLCD_Base::setMode(LCDMode displayMode) {
wim 17:652ab113bc2e 1023
wim 17:652ab113bc2e 1024 // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
wim 17:652ab113bc2e 1025 _currentMode = displayMode;
wim 15:b70ebfffb258 1026
wim 17:652ab113bc2e 1027 // Select and configure second LCD controller when needed
wim 17:652ab113bc2e 1028 if(_type==LCD40x4) {
wim 21:9eb628d9e164 1029 if (_ctrl_idx==_LCDCtrl_0) {
wim 17:652ab113bc2e 1030 // Configure primary LCD controller
wim 17:652ab113bc2e 1031 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 11:9ec02df863a1 1032
wim 17:652ab113bc2e 1033 // Select 2nd controller
wim 21:9eb628d9e164 1034 _ctrl_idx=_LCDCtrl_1;
wim 17:652ab113bc2e 1035
wim 17:652ab113bc2e 1036 // Configure secondary LCD controller
wim 21:9eb628d9e164 1037 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 11:9ec02df863a1 1038
wim 17:652ab113bc2e 1039 // Restore current controller
wim 21:9eb628d9e164 1040 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1041 }
wim 17:652ab113bc2e 1042 else {
wim 17:652ab113bc2e 1043 // Select primary controller
wim 21:9eb628d9e164 1044 _ctrl_idx=_LCDCtrl_0;
wim 17:652ab113bc2e 1045
wim 17:652ab113bc2e 1046 // Configure primary LCD controller
wim 21:9eb628d9e164 1047 _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
wim 17:652ab113bc2e 1048
wim 17:652ab113bc2e 1049 // Restore current controller
wim 21:9eb628d9e164 1050 _ctrl_idx=_LCDCtrl_1;
wim 11:9ec02df863a1 1051
wim 17:652ab113bc2e 1052 // Configure secondary LCD controller
wim 17:652ab113bc2e 1053 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 10:dd9b3a696acd 1054 }
wim 17:652ab113bc2e 1055 }
wim 17:652ab113bc2e 1056 else {
wim 17:652ab113bc2e 1057 // Configure primary LCD controller
wim 17:652ab113bc2e 1058 _setCursorAndDisplayMode(_currentMode, _currentCursor);
wim 30:033048611c01 1059 }
wim 17:652ab113bc2e 1060 }
wim 17:652ab113bc2e 1061
wim 17:652ab113bc2e 1062
wim 29:a3663151aa65 1063 /** Low level method to restore the cursortype and display mode for current controller
wim 29:a3663151aa65 1064 */
wim 21:9eb628d9e164 1065 void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {
wim 17:652ab113bc2e 1066
wim 17:652ab113bc2e 1067 // Configure current LCD controller
wim 17:652ab113bc2e 1068 _writeCommand(0x08 | displayMode | cursorType);
wim 10:dd9b3a696acd 1069 }
wim 10:dd9b3a696acd 1070
wim 29:a3663151aa65 1071 /** Set the Backlight mode
wim 29:a3663151aa65 1072 *
wim 29:a3663151aa65 1073 * @param backlightMode The Backlight mode (LightOff, LightOn)
wim 29:a3663151aa65 1074 */
wim 21:9eb628d9e164 1075 void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
wim 20:e0da005a777f 1076
wim 20:e0da005a777f 1077 if (backlightMode == LightOn) {
wim 21:9eb628d9e164 1078 this->_setBL(true);
wim 20:e0da005a777f 1079 }
wim 20:e0da005a777f 1080 else {
wim 21:9eb628d9e164 1081 this->_setBL(false);
wim 20:e0da005a777f 1082 }
wim 20:e0da005a777f 1083 }
wim 20:e0da005a777f 1084
wim 29:a3663151aa65 1085 /** Set User Defined Characters
wim 29:a3663151aa65 1086 *
wim 29:a3663151aa65 1087 * @param unsigned char c The Index of the UDC (0..7)
wim 29:a3663151aa65 1088 * @param char *udc_data The bitpatterns for the UDC (8 bytes of 5 significant bits)
wim 29:a3663151aa65 1089 */
wim 21:9eb628d9e164 1090 void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1091
wim 15:b70ebfffb258 1092 // Select and configure second LCD controller when needed
wim 15:b70ebfffb258 1093 if(_type==LCD40x4) {
wim 19:c747b9e2e7b8 1094 _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
wim 15:b70ebfffb258 1095
wim 15:b70ebfffb258 1096 // Select primary controller
wim 21:9eb628d9e164 1097 _ctrl_idx=_LCDCtrl_0;
wim 15:b70ebfffb258 1098
wim 15:b70ebfffb258 1099 // Configure primary LCD controller
wim 15:b70ebfffb258 1100 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1101
wim 15:b70ebfffb258 1102 // Select 2nd controller
wim 21:9eb628d9e164 1103 _ctrl_idx=_LCDCtrl_1;
wim 15:b70ebfffb258 1104
wim 15:b70ebfffb258 1105 // Configure secondary LCD controller
wim 15:b70ebfffb258 1106 _setUDC(c, udc_data);
wim 11:9ec02df863a1 1107
wim 15:b70ebfffb258 1108 // Restore current controller
wim 19:c747b9e2e7b8 1109 _ctrl_idx=current_ctrl_idx;
wim 15:b70ebfffb258 1110 }
wim 15:b70ebfffb258 1111 else {
wim 15:b70ebfffb258 1112 // Configure primary LCD controller
wim 15:b70ebfffb258 1113 _setUDC(c, udc_data);
wim 15:b70ebfffb258 1114 }
wim 15:b70ebfffb258 1115
wim 15:b70ebfffb258 1116 }
wim 15:b70ebfffb258 1117
wim 29:a3663151aa65 1118 /** Low level method to store user defined characters for current controller
wim 29:a3663151aa65 1119 */
wim 21:9eb628d9e164 1120 void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
wim 15:b70ebfffb258 1121
wim 15:b70ebfffb258 1122 // Select CG RAM for current LCD controller
wim 15:b70ebfffb258 1123 _writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
wim 15:b70ebfffb258 1124 //8 sequential locations needed per UDC
wim 15:b70ebfffb258 1125 // Store UDC pattern
wim 11:9ec02df863a1 1126 for (int i=0; i<8; i++) {
wim 13:24506ba22480 1127 _writeData(*udc_data++);
wim 11:9ec02df863a1 1128 }
wim 15:b70ebfffb258 1129
wim 15:b70ebfffb258 1130 //Select DD RAM again for current LCD controller
wim 15:b70ebfffb258 1131 int addr = getAddress(_column, _row);
wim 30:033048611c01 1132 _writeCommand(0x80 | addr);
wim 11:9ec02df863a1 1133 }
wim 21:9eb628d9e164 1134
wim 23:d47f226efb24 1135 //--------- End TextLCD_Base -----------
wim 21:9eb628d9e164 1136
wim 22:35742ec80c24 1137
wim 23:d47f226efb24 1138 //--------- Start TextLCD Bus -----------
wim 21:9eb628d9e164 1139
wim 21:9eb628d9e164 1140 /* Create a TextLCD interface for using regular mbed pins
wim 21:9eb628d9e164 1141 *
wim 21:9eb628d9e164 1142 * @param rs Instruction/data control line
wim 21:9eb628d9e164 1143 * @param e Enable line (clock)
wim 21:9eb628d9e164 1144 * @param d4-d7 Data lines for using as a 4-bit interface
wim 21:9eb628d9e164 1145 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 21:9eb628d9e164 1146 * @param bl Backlight control line (optional, default = NC)
wim 21:9eb628d9e164 1147 * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
wim 21:9eb628d9e164 1148 * @param ctrl LCD controller (default = HD44780)
wim 21:9eb628d9e164 1149 */
wim 21:9eb628d9e164 1150 TextLCD::TextLCD(PinName rs, PinName e,
wim 21:9eb628d9e164 1151 PinName d4, PinName d5, PinName d6, PinName d7,
wim 21:9eb628d9e164 1152 LCDType type, PinName bl, PinName e2, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1153 TextLCD_Base(type, ctrl),
wim 22:35742ec80c24 1154 _rs(rs), _e(e), _d(d4, d5, d6, d7) {
wim 22:35742ec80c24 1155
wim 22:35742ec80c24 1156 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 22:35742ec80c24 1157 if (bl != NC) {
wim 22:35742ec80c24 1158 _bl = new DigitalOut(bl); //Construct new pin
wim 22:35742ec80c24 1159 _bl->write(0); //Deactivate
wim 22:35742ec80c24 1160 }
wim 22:35742ec80c24 1161 else {
wim 22:35742ec80c24 1162 // No Hardware Backlight pin
wim 22:35742ec80c24 1163 _bl = NULL; //Construct dummy pin
wim 22:35742ec80c24 1164 }
wim 22:35742ec80c24 1165
wim 22:35742ec80c24 1166 // 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 1167 if (e2 != NC) {
wim 22:35742ec80c24 1168 _e2 = new DigitalOut(e2); //Construct new pin
wim 22:35742ec80c24 1169 _e2->write(0); //Deactivate
wim 22:35742ec80c24 1170 }
wim 22:35742ec80c24 1171 else {
wim 22:35742ec80c24 1172 // No Hardware Enable pin
wim 22:35742ec80c24 1173 _e2 = NULL; //Construct dummy pin
wim 22:35742ec80c24 1174 }
wim 21:9eb628d9e164 1175
wim 21:9eb628d9e164 1176 _init();
wim 21:9eb628d9e164 1177 }
wim 21:9eb628d9e164 1178
wim 29:a3663151aa65 1179 /** Destruct a TextLCD interface for using regular mbed pins
wim 29:a3663151aa65 1180 *
wim 29:a3663151aa65 1181 * @param none
wim 29:a3663151aa65 1182 * @return none
wim 29:a3663151aa65 1183 */
wim 29:a3663151aa65 1184 TextLCD::~TextLCD() {
wim 29:a3663151aa65 1185 if (_bl != NULL) {delete _bl;} // BL pin
wim 29:a3663151aa65 1186 if (_e2 != NULL) {delete _e2;} // E2 pin
wim 29:a3663151aa65 1187 }
wim 29:a3663151aa65 1188
wim 29:a3663151aa65 1189
wim 22:35742ec80c24 1190 /** Set E pin (or E2 pin)
wim 22:35742ec80c24 1191 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1192 * Default PinName value for E2 is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1193 * @param value true or false
wim 22:35742ec80c24 1194 * @return none
wim 22:35742ec80c24 1195 */
wim 21:9eb628d9e164 1196 void TextLCD::_setEnable(bool value) {
wim 21:9eb628d9e164 1197
wim 22:35742ec80c24 1198 if(_ctrl_idx==_LCDCtrl_0) {
wim 22:35742ec80c24 1199 if (value) {
wim 22:35742ec80c24 1200 _e = 1; // Set E bit
wim 22:35742ec80c24 1201 }
wim 22:35742ec80c24 1202 else {
wim 22:35742ec80c24 1203 _e = 0; // Reset E bit
wim 22:35742ec80c24 1204 }
wim 22:35742ec80c24 1205 }
wim 22:35742ec80c24 1206 else {
wim 22:35742ec80c24 1207 if (value) {
wim 22:35742ec80c24 1208 if (_e2 != NULL) {_e2->write(1);} //Set E2 bit
wim 22:35742ec80c24 1209 }
wim 22:35742ec80c24 1210 else {
wim 22:35742ec80c24 1211 if (_e2 != NULL) {_e2->write(0);} //Reset E2 bit
wim 22:35742ec80c24 1212 }
wim 22:35742ec80c24 1213 }
wim 21:9eb628d9e164 1214 }
wim 21:9eb628d9e164 1215
wim 21:9eb628d9e164 1216 // Set RS pin
wim 21:9eb628d9e164 1217 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1218 void TextLCD::_setRS(bool value) {
wim 21:9eb628d9e164 1219
wim 22:35742ec80c24 1220 if (value) {
wim 21:9eb628d9e164 1221 _rs = 1; // Set RS bit
wim 22:35742ec80c24 1222 }
wim 22:35742ec80c24 1223 else {
wim 21:9eb628d9e164 1224 _rs = 0; // Reset RS bit
wim 22:35742ec80c24 1225 }
wim 21:9eb628d9e164 1226 }
wim 21:9eb628d9e164 1227
wim 22:35742ec80c24 1228 /** Set BL pin
wim 22:35742ec80c24 1229 * Used for mbed pins, I2C bus expander or SPI shiftregister
wim 22:35742ec80c24 1230 * Default PinName value is NC, must be used as pointer to avoid issues with mbed lib and DigitalOut pins
wim 22:35742ec80c24 1231 * @param value true or false
wim 22:35742ec80c24 1232 * @return none
wim 22:35742ec80c24 1233 */
wim 21:9eb628d9e164 1234 void TextLCD::_setBL(bool value) {
wim 21:9eb628d9e164 1235
wim 22:35742ec80c24 1236 if (value) {
wim 22:35742ec80c24 1237 if (_bl != NULL) {_bl->write(1);} //Set BL bit
wim 22:35742ec80c24 1238 }
wim 22:35742ec80c24 1239 else {
wim 22:35742ec80c24 1240 if (_bl != NULL) {_bl->write(0);} //Reset BL bit
wim 22:35742ec80c24 1241 }
wim 21:9eb628d9e164 1242
wim 21:9eb628d9e164 1243 }
wim 21:9eb628d9e164 1244
wim 21:9eb628d9e164 1245 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1246 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1247 void TextLCD::_setData(int value) {
wim 21:9eb628d9e164 1248 _d = value & 0x0F; // Write Databits
wim 21:9eb628d9e164 1249 }
wim 22:35742ec80c24 1250
wim 23:d47f226efb24 1251 //----------- End TextLCD ---------------
wim 21:9eb628d9e164 1252
wim 21:9eb628d9e164 1253
wim 23:d47f226efb24 1254 //--------- Start TextLCD_I2C -----------
wim 22:35742ec80c24 1255
wim 26:bd897a001012 1256 /** Create a TextLCD interface using an I2C PC8574 (or PCF8574A) or MCP23008 portexpander
wim 22:35742ec80c24 1257 *
wim 22:35742ec80c24 1258 * @param i2c I2C Bus
wim 26:bd897a001012 1259 * @param deviceAddress I2C slave address (PCF8574, PCF8574A or MCP23008, default = 0x40)
wim 22:35742ec80c24 1260 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1261 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1262 */
wim 21:9eb628d9e164 1263 TextLCD_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1264 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1265 _i2c(i2c){
wim 21:9eb628d9e164 1266
wim 22:35742ec80c24 1267 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1268
wim 28:30fa94f7341c 1269 // Setup the I2C bus
wim 28:30fa94f7341c 1270 // The max bitrate for PCF8574 is 100kbit, the max bitrate for MCP23008 is 400kbit,
wim 28:30fa94f7341c 1271 // _i2c->frequency(100000);
wim 21:9eb628d9e164 1272
wim 26:bd897a001012 1273 #if (MCP23008==1)
wim 26:bd897a001012 1274 // MCP23008 portexpander Init
wim 27:22d5086f6ba6 1275 _write_register(IODIR, 0x00); // All outputs
wim 27:22d5086f6ba6 1276 _write_register(IPOL, 0x00); // No reverse polarity
wim 27:22d5086f6ba6 1277 _write_register(GPINTEN, 0x00); // No interrupt
wim 27:22d5086f6ba6 1278 _write_register(DEFVAL, 0x00); // Default value to compare against for interrupts
wim 27:22d5086f6ba6 1279 _write_register(INTCON, 0x00); // No interrupt on changes
wim 27:22d5086f6ba6 1280 _write_register(IOCON, 0x00); // Interrupt polarity
wim 27:22d5086f6ba6 1281 _write_register(GPPU, 0x00); // No Pullup
wim 27:22d5086f6ba6 1282 _write_register(INTF, 0x00); //
wim 27:22d5086f6ba6 1283 _write_register(INTCAP, 0x00); //
wim 27:22d5086f6ba6 1284 _write_register(GPIO, 0x00); // Output/Input pins
wim 27:22d5086f6ba6 1285 _write_register(OLAT, 0x00); // Output Latch
wim 26:bd897a001012 1286
wim 21:9eb628d9e164 1287 // Init the portexpander bus
wim 21:9eb628d9e164 1288 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1289
wim 21:9eb628d9e164 1290 // write the new data to the portexpander
wim 26:bd897a001012 1291 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1292 #else
wim 26:bd897a001012 1293 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1294
wim 26:bd897a001012 1295 // Init the portexpander bus
wim 26:bd897a001012 1296 _lcd_bus = D_LCD_BUS_DEF;
wim 26:bd897a001012 1297
wim 26:bd897a001012 1298 // write the new data to the portexpander
wim 21:9eb628d9e164 1299 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1300 #endif
wim 21:9eb628d9e164 1301
wim 30:033048611c01 1302 _init();
wim 21:9eb628d9e164 1303 }
wim 21:9eb628d9e164 1304
wim 21:9eb628d9e164 1305 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1306 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1307 void TextLCD_I2C::_setEnable(bool value) {
wim 21:9eb628d9e164 1308
wim 22:35742ec80c24 1309 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1310 if (value) {
wim 22:35742ec80c24 1311 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1312 }
wim 26:bd897a001012 1313 else {
wim 22:35742ec80c24 1314 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1315 }
wim 22:35742ec80c24 1316 }
wim 22:35742ec80c24 1317 else {
wim 26:bd897a001012 1318 if (value) {
wim 22:35742ec80c24 1319 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1320 }
wim 26:bd897a001012 1321 else {
wim 22:35742ec80c24 1322 _lcd_bus &= ~D_LCD_E2; // Reset E2bit
wim 26:bd897a001012 1323 }
wim 26:bd897a001012 1324 }
wim 26:bd897a001012 1325
wim 26:bd897a001012 1326 #if (MCP23008==1)
wim 26:bd897a001012 1327 // MCP23008 portexpander
wim 26:bd897a001012 1328
wim 26:bd897a001012 1329 // write the new data to the portexpander
wim 26:bd897a001012 1330 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1331 #else
wim 26:bd897a001012 1332 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1333
wim 22:35742ec80c24 1334 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1335 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1336 #endif
wim 21:9eb628d9e164 1337 }
wim 21:9eb628d9e164 1338
wim 21:9eb628d9e164 1339 // Set RS pin
wim 21:9eb628d9e164 1340 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1341 void TextLCD_I2C::_setRS(bool value) {
wim 21:9eb628d9e164 1342
wim 26:bd897a001012 1343 if (value) {
wim 22:35742ec80c24 1344 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 26:bd897a001012 1345 }
wim 26:bd897a001012 1346 else {
wim 22:35742ec80c24 1347 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 26:bd897a001012 1348 }
wim 26:bd897a001012 1349
wim 26:bd897a001012 1350 #if (MCP23008==1)
wim 26:bd897a001012 1351 // MCP23008 portexpander
wim 26:bd897a001012 1352
wim 26:bd897a001012 1353 // write the new data to the portexpander
wim 26:bd897a001012 1354 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1355 #else
wim 26:bd897a001012 1356 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1357
wim 22:35742ec80c24 1358 // write the new data to the I2C portexpander
wim 22:35742ec80c24 1359 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1360 #endif
wim 21:9eb628d9e164 1361 }
wim 21:9eb628d9e164 1362
wim 21:9eb628d9e164 1363 // Set BL pin
wim 21:9eb628d9e164 1364 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1365 void TextLCD_I2C::_setBL(bool value) {
wim 21:9eb628d9e164 1366
wim 26:bd897a001012 1367 if (value) {
wim 21:9eb628d9e164 1368 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 26:bd897a001012 1369 }
wim 26:bd897a001012 1370 else {
wim 21:9eb628d9e164 1371 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 26:bd897a001012 1372 }
wim 26:bd897a001012 1373
wim 26:bd897a001012 1374 #if (MCP23008==1)
wim 26:bd897a001012 1375 // MCP23008 portexpander
wim 26:bd897a001012 1376
wim 26:bd897a001012 1377 // write the new data to the portexpander
wim 26:bd897a001012 1378 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1379 #else
wim 26:bd897a001012 1380 // PCF8574 of PCF8574A portexpander
wim 21:9eb628d9e164 1381
wim 21:9eb628d9e164 1382 // write the new data to the I2C portexpander
wim 21:9eb628d9e164 1383 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 30:033048611c01 1384 #endif
wim 21:9eb628d9e164 1385 }
wim 21:9eb628d9e164 1386
wim 21:9eb628d9e164 1387
wim 21:9eb628d9e164 1388 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1389 // Used for mbed pins, I2C bus expander or SPI shifregister
wim 21:9eb628d9e164 1390 void TextLCD_I2C::_setData(int value) {
wim 21:9eb628d9e164 1391 int data;
wim 22:35742ec80c24 1392
wim 22:35742ec80c24 1393 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 21:9eb628d9e164 1394
wim 22:35742ec80c24 1395 data = value & 0x0F;
wim 26:bd897a001012 1396 if (data & 0x01){
wim 22:35742ec80c24 1397 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1398 }
wim 26:bd897a001012 1399 else {
wim 26:bd897a001012 1400 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1401 }
wim 21:9eb628d9e164 1402
wim 26:bd897a001012 1403 if (data & 0x02){
wim 22:35742ec80c24 1404 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1405 }
wim 26:bd897a001012 1406 else {
wim 26:bd897a001012 1407 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1408 }
wim 21:9eb628d9e164 1409
wim 26:bd897a001012 1410 if (data & 0x04) {
wim 22:35742ec80c24 1411 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1412 }
wim 26:bd897a001012 1413 else {
wim 26:bd897a001012 1414 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1415 }
wim 21:9eb628d9e164 1416
wim 26:bd897a001012 1417 if (data & 0x08) {
wim 22:35742ec80c24 1418 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1419 }
wim 26:bd897a001012 1420 else {
wim 26:bd897a001012 1421 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1422 }
wim 21:9eb628d9e164 1423
wim 26:bd897a001012 1424 #if (MCP23008==1)
wim 26:bd897a001012 1425 // MCP23008 portexpander
wim 26:bd897a001012 1426
wim 26:bd897a001012 1427 // write the new data to the portexpander
wim 26:bd897a001012 1428 _write_register(GPIO, _lcd_bus);
wim 26:bd897a001012 1429 #else
wim 26:bd897a001012 1430 // PCF8574 of PCF8574A portexpander
wim 26:bd897a001012 1431
wim 22:35742ec80c24 1432 // write the new data to the I2C portexpander
wim 26:bd897a001012 1433 _i2c->write(_slaveAddress, &_lcd_bus, 1);
wim 26:bd897a001012 1434 #endif
wim 22:35742ec80c24 1435
wim 22:35742ec80c24 1436 }
wim 21:9eb628d9e164 1437
wim 26:bd897a001012 1438 // Write data to MCP23008 I2C portexpander
wim 26:bd897a001012 1439 void TextLCD_I2C::_write_register (int reg, int value) {
wim 26:bd897a001012 1440 char data[] = {reg, value};
wim 26:bd897a001012 1441
wim 30:033048611c01 1442 _i2c->write(_slaveAddress, data, 2);
wim 26:bd897a001012 1443 }
wim 26:bd897a001012 1444
wim 23:d47f226efb24 1445 //---------- End TextLCD_I2C ------------
wim 21:9eb628d9e164 1446
wim 21:9eb628d9e164 1447
wim 28:30fa94f7341c 1448 //--------- Start TextLCD_I2C_N ---------
wim 28:30fa94f7341c 1449
wim 28:30fa94f7341c 1450 /** Create a TextLCD interface using a controller with native I2C interface
wim 28:30fa94f7341c 1451 *
wim 28:30fa94f7341c 1452 * @param i2c I2C Bus
wim 28:30fa94f7341c 1453 * @param deviceAddress I2C slave address (default = 0x7C)
wim 28:30fa94f7341c 1454 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 28:30fa94f7341c 1455 * @param bl Backlight control line (optional, default = NC)
wim 28:30fa94f7341c 1456 * @param ctrl LCD controller (default = ST7032_3V3)
wim 28:30fa94f7341c 1457 */
wim 28:30fa94f7341c 1458 TextLCD_I2C_N::TextLCD_I2C_N(I2C *i2c, char deviceAddress, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 28:30fa94f7341c 1459 TextLCD_Base(type, ctrl),
wim 28:30fa94f7341c 1460 _i2c(i2c){
wim 30:033048611c01 1461
wim 28:30fa94f7341c 1462 _slaveAddress = deviceAddress & 0xFE;
wim 28:30fa94f7341c 1463
wim 28:30fa94f7341c 1464 // Setup the I2C bus
wim 29:a3663151aa65 1465 // The max bitrate for ST7032i is 400kbit, lets stick to default here
wim 29:a3663151aa65 1466 _i2c->frequency(100000);
wim 29:a3663151aa65 1467 // _i2c->frequency(50000);
wim 30:033048611c01 1468
wim 28:30fa94f7341c 1469 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 28:30fa94f7341c 1470 if (bl != NC) {
wim 28:30fa94f7341c 1471 _bl = new DigitalOut(bl); //Construct new pin
wim 28:30fa94f7341c 1472 _bl->write(0); //Deactivate
wim 28:30fa94f7341c 1473 }
wim 28:30fa94f7341c 1474 else {
wim 28:30fa94f7341c 1475 // No Hardware Backlight pin
wim 28:30fa94f7341c 1476 _bl = NULL; //Construct dummy pin
wim 28:30fa94f7341c 1477 }
wim 28:30fa94f7341c 1478
wim 30:033048611c01 1479 //Sanity check
wim 30:033048611c01 1480 if (_ctrl & LCD_C_I2C) {
wim 30:033048611c01 1481 _init();
wim 30:033048611c01 1482 }
wim 30:033048611c01 1483 else {
wim 30:033048611c01 1484 error("Error: LCD Controller type does not support native I2C interface\n\r");
wim 30:033048611c01 1485 }
wim 30:033048611c01 1486
wim 28:30fa94f7341c 1487 }
wim 28:30fa94f7341c 1488
wim 28:30fa94f7341c 1489 TextLCD_I2C_N::~TextLCD_I2C_N() {
wim 28:30fa94f7341c 1490 if (_bl != NULL) {delete _bl;} // BL pin
wim 28:30fa94f7341c 1491 }
wim 28:30fa94f7341c 1492
wim 28:30fa94f7341c 1493 // Not used in this mode
wim 28:30fa94f7341c 1494 void TextLCD_I2C_N::_setEnable(bool value) {
wim 28:30fa94f7341c 1495 }
wim 28:30fa94f7341c 1496
wim 28:30fa94f7341c 1497 // Set RS pin
wim 28:30fa94f7341c 1498 // Used for mbed pins, I2C bus expander or SPI shiftregister and native I2C or SPI
wim 28:30fa94f7341c 1499 void TextLCD_I2C_N::_setRS(bool value) {
wim 30:033048611c01 1500 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1501 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1502 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1503 //
wim 30:033048611c01 1504 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1505 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1506 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1507 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1508 //
wim 30:033048611c01 1509
wim 28:30fa94f7341c 1510 if (value) {
wim 28:30fa94f7341c 1511 _controlbyte = 0x40; // Next byte is data, No more control bytes will follow
wim 28:30fa94f7341c 1512 }
wim 28:30fa94f7341c 1513 else {
wim 28:30fa94f7341c 1514 _controlbyte = 0x00; // Next byte is command, No more control bytes will follow
wim 28:30fa94f7341c 1515 }
wim 28:30fa94f7341c 1516 }
wim 28:30fa94f7341c 1517
wim 28:30fa94f7341c 1518 // Set BL pin
wim 28:30fa94f7341c 1519 void TextLCD_I2C_N::_setBL(bool value) {
wim 28:30fa94f7341c 1520 if (_bl) {
wim 28:30fa94f7341c 1521 _bl->write(value);
wim 28:30fa94f7341c 1522 }
wim 28:30fa94f7341c 1523 }
wim 29:a3663151aa65 1524
wim 29:a3663151aa65 1525 // Not used in this mode
wim 29:a3663151aa65 1526 void TextLCD_I2C_N::_setData(int value) {
wim 29:a3663151aa65 1527 }
wim 29:a3663151aa65 1528
wim 28:30fa94f7341c 1529 // Write a byte using I2C
wim 28:30fa94f7341c 1530 void TextLCD_I2C_N::_writeByte(int value) {
wim 30:033048611c01 1531 // The controlbyte defines the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1532 // Start Slaveaddress+RW b7 b6 b5 b4 b3 b2 b1 b0 b7...........b0 Stop
wim 30:033048611c01 1533 // Co RS RW 0 0 0 0 0 command or data
wim 30:033048611c01 1534 //
wim 30:033048611c01 1535 // C0=1 indicates that another controlbyte will follow after the next data or command byte
wim 30:033048611c01 1536 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1537 // RW=0 means write to controller. RW=1 means that controller will be read from after the next command.
wim 30:033048611c01 1538 // Many native I2C controllers dont support this option and it is not used by this lib.
wim 30:033048611c01 1539 //
wim 28:30fa94f7341c 1540 char data[] = {_controlbyte, value};
wim 28:30fa94f7341c 1541
wim 30:033048611c01 1542 _i2c->write(_slaveAddress, data, 2);
wim 28:30fa94f7341c 1543 }
wim 28:30fa94f7341c 1544
wim 28:30fa94f7341c 1545 //-------- End TextLCD_I2C_N ------------
wim 28:30fa94f7341c 1546
wim 28:30fa94f7341c 1547
wim 23:d47f226efb24 1548 //--------- Start TextLCD_SPI -----------
wim 21:9eb628d9e164 1549
wim 22:35742ec80c24 1550 /** Create a TextLCD interface using an SPI 74595 portexpander
wim 22:35742ec80c24 1551 *
wim 22:35742ec80c24 1552 * @param spi SPI Bus
wim 22:35742ec80c24 1553 * @param cs chip select pin (active low)
wim 22:35742ec80c24 1554 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 22:35742ec80c24 1555 * @param ctrl LCD controller (default = HD44780)
wim 22:35742ec80c24 1556 */
wim 21:9eb628d9e164 1557 TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
wim 21:9eb628d9e164 1558 TextLCD_Base(type, ctrl),
wim 21:9eb628d9e164 1559 _spi(spi),
wim 21:9eb628d9e164 1560 _cs(cs) {
wim 21:9eb628d9e164 1561
wim 21:9eb628d9e164 1562 // Setup the spi for 8 bit data, low steady state clock,
wim 21:9eb628d9e164 1563 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 21:9eb628d9e164 1564 _spi->format(8,0);
wim 21:9eb628d9e164 1565 _spi->frequency(500000);
wim 21:9eb628d9e164 1566 //_spi.frequency(1000000);
wim 21:9eb628d9e164 1567
wim 21:9eb628d9e164 1568 // Init the portexpander bus
wim 21:9eb628d9e164 1569 _lcd_bus = D_LCD_BUS_DEF;
wim 21:9eb628d9e164 1570
wim 21:9eb628d9e164 1571 // write the new data to the portexpander
wim 21:9eb628d9e164 1572 _setCS(false);
wim 21:9eb628d9e164 1573 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1574 _setCS(true);
wim 30:033048611c01 1575
wim 30:033048611c01 1576 _init();
wim 21:9eb628d9e164 1577 }
wim 21:9eb628d9e164 1578
wim 21:9eb628d9e164 1579 // Set E pin (or E2 pin)
wim 21:9eb628d9e164 1580 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1581 void TextLCD_SPI::_setEnable(bool value) {
wim 21:9eb628d9e164 1582
wim 22:35742ec80c24 1583 if(_ctrl_idx==_LCDCtrl_0) {
wim 26:bd897a001012 1584 if (value) {
wim 22:35742ec80c24 1585 _lcd_bus |= D_LCD_E; // Set E bit
wim 26:bd897a001012 1586 }
wim 26:bd897a001012 1587 else {
wim 22:35742ec80c24 1588 _lcd_bus &= ~D_LCD_E; // Reset E bit
wim 26:bd897a001012 1589 }
wim 22:35742ec80c24 1590 }
wim 22:35742ec80c24 1591 else {
wim 26:bd897a001012 1592 if (value) {
wim 22:35742ec80c24 1593 _lcd_bus |= D_LCD_E2; // Set E2 bit
wim 26:bd897a001012 1594 }
wim 26:bd897a001012 1595 else {
wim 22:35742ec80c24 1596 _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
wim 26:bd897a001012 1597 }
wim 22:35742ec80c24 1598 }
wim 21:9eb628d9e164 1599
wim 22:35742ec80c24 1600 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1601 _setCS(false);
wim 22:35742ec80c24 1602 _spi->write(_lcd_bus);
wim 30:033048611c01 1603 _setCS(true);
wim 21:9eb628d9e164 1604 }
wim 21:9eb628d9e164 1605
wim 21:9eb628d9e164 1606 // Set RS pin
wim 21:9eb628d9e164 1607 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1608 void TextLCD_SPI::_setRS(bool value) {
wim 21:9eb628d9e164 1609
wim 22:35742ec80c24 1610 if (value) {
wim 21:9eb628d9e164 1611 _lcd_bus |= D_LCD_RS; // Set RS bit
wim 22:35742ec80c24 1612 }
wim 22:35742ec80c24 1613 else {
wim 21:9eb628d9e164 1614 _lcd_bus &= ~D_LCD_RS; // Reset RS bit
wim 22:35742ec80c24 1615 }
wim 21:9eb628d9e164 1616
wim 21:9eb628d9e164 1617 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1618 _setCS(false);
wim 21:9eb628d9e164 1619 _spi->write(_lcd_bus);
wim 21:9eb628d9e164 1620 _setCS(true);
wim 21:9eb628d9e164 1621 }
wim 21:9eb628d9e164 1622
wim 21:9eb628d9e164 1623 // Set BL pin
wim 21:9eb628d9e164 1624 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1625 void TextLCD_SPI::_setBL(bool value) {
wim 21:9eb628d9e164 1626
wim 22:35742ec80c24 1627 if (value) {
wim 21:9eb628d9e164 1628 _lcd_bus |= D_LCD_BL; // Set BL bit
wim 22:35742ec80c24 1629 }
wim 22:35742ec80c24 1630 else {
wim 21:9eb628d9e164 1631 _lcd_bus &= ~D_LCD_BL; // Reset BL bit
wim 22:35742ec80c24 1632 }
wim 21:9eb628d9e164 1633
wim 21:9eb628d9e164 1634 // write the new data to the SPI portexpander
wim 21:9eb628d9e164 1635 _setCS(false);
wim 21:9eb628d9e164 1636 _spi->write(_lcd_bus);
wim 30:033048611c01 1637 _setCS(true);
wim 21:9eb628d9e164 1638 }
wim 21:9eb628d9e164 1639
wim 21:9eb628d9e164 1640 // Place the 4bit data on the databus
wim 21:9eb628d9e164 1641 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 21:9eb628d9e164 1642 void TextLCD_SPI::_setData(int value) {
wim 21:9eb628d9e164 1643 int data;
wim 21:9eb628d9e164 1644
wim 22:35742ec80c24 1645 // Set bit by bit to support any mapping of expander portpins to LCD pins
wim 22:35742ec80c24 1646
wim 22:35742ec80c24 1647 data = value & 0x0F;
wim 26:bd897a001012 1648 if (data & 0x01) {
wim 22:35742ec80c24 1649 _lcd_bus |= D_LCD_D4; // Set Databit
wim 26:bd897a001012 1650 }
wim 26:bd897a001012 1651 else {
wim 22:35742ec80c24 1652 _lcd_bus &= ~D_LCD_D4; // Reset Databit
wim 26:bd897a001012 1653 }
wim 26:bd897a001012 1654
wim 26:bd897a001012 1655 if (data & 0x02) {
wim 22:35742ec80c24 1656 _lcd_bus |= D_LCD_D5; // Set Databit
wim 26:bd897a001012 1657 }
wim 26:bd897a001012 1658 else {
wim 22:35742ec80c24 1659 _lcd_bus &= ~D_LCD_D5; // Reset Databit
wim 26:bd897a001012 1660 }
wim 26:bd897a001012 1661
wim 26:bd897a001012 1662 if (data & 0x04) {
wim 22:35742ec80c24 1663 _lcd_bus |= D_LCD_D6; // Set Databit
wim 26:bd897a001012 1664 }
wim 26:bd897a001012 1665 else {
wim 22:35742ec80c24 1666 _lcd_bus &= ~D_LCD_D6; // Reset Databit
wim 26:bd897a001012 1667 }
wim 26:bd897a001012 1668
wim 26:bd897a001012 1669 if (data & 0x08) {
wim 22:35742ec80c24 1670 _lcd_bus |= D_LCD_D7; // Set Databit
wim 26:bd897a001012 1671 }
wim 26:bd897a001012 1672 else {
wim 26:bd897a001012 1673 _lcd_bus &= ~D_LCD_D7; // Reset Databit
wim 26:bd897a001012 1674 }
wim 21:9eb628d9e164 1675
wim 22:35742ec80c24 1676 // write the new data to the SPI portexpander
wim 22:35742ec80c24 1677 _setCS(false);
wim 22:35742ec80c24 1678 _spi->write(_lcd_bus);
wim 30:033048611c01 1679 _setCS(true);
wim 21:9eb628d9e164 1680 }
wim 21:9eb628d9e164 1681
wim 21:9eb628d9e164 1682 // Set CS line.
wim 21:9eb628d9e164 1683 // Only used for SPI bus
wim 21:9eb628d9e164 1684 void TextLCD_SPI::_setCS(bool value) {
wim 21:9eb628d9e164 1685
wim 21:9eb628d9e164 1686 if (value) {
wim 21:9eb628d9e164 1687 _cs = 1; // Set CS pin
wim 21:9eb628d9e164 1688 }
wim 22:35742ec80c24 1689 else {
wim 21:9eb628d9e164 1690 _cs = 0; // Reset CS pin
wim 22:35742ec80c24 1691 }
wim 21:9eb628d9e164 1692 }
wim 21:9eb628d9e164 1693
wim 23:d47f226efb24 1694 //---------- End TextLCD_SPI ------------
wim 22:35742ec80c24 1695
wim 22:35742ec80c24 1696
wim 25:6162b31128c9 1697 //--------- Start TextLCD_SPI_N ---------
Sissors 24:fb3399713710 1698
wim 30:033048611c01 1699 /** Create a TextLCD interface using a controller with a native SPI4 interface
Sissors 24:fb3399713710 1700 *
Sissors 24:fb3399713710 1701 * @param spi SPI Bus
Sissors 24:fb3399713710 1702 * @param cs chip select pin (active low)
wim 25:6162b31128c9 1703 * @param rs Instruction/data control line
Sissors 24:fb3399713710 1704 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 25:6162b31128c9 1705 * @param bl Backlight control line (optional, default = NC)
wim 26:bd897a001012 1706 * @param ctrl LCD controller (default = ST7032_3V3)
wim 25:6162b31128c9 1707 */
wim 25:6162b31128c9 1708 TextLCD_SPI_N::TextLCD_SPI_N(SPI *spi, PinName cs, PinName rs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 25:6162b31128c9 1709 TextLCD_Base(type, ctrl),
wim 25:6162b31128c9 1710 _spi(spi),
wim 25:6162b31128c9 1711 _cs(cs),
wim 25:6162b31128c9 1712 _rs(rs) {
Sissors 24:fb3399713710 1713
Sissors 24:fb3399713710 1714 // Setup the spi for 8 bit data, low steady state clock,
Sissors 24:fb3399713710 1715 // rising edge capture, with a 500KHz or 1MHz clock rate
Sissors 24:fb3399713710 1716 _spi->format(8,0);
Sissors 24:fb3399713710 1717 _spi->frequency(1000000);
Sissors 24:fb3399713710 1718
Sissors 24:fb3399713710 1719 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
Sissors 24:fb3399713710 1720 if (bl != NC) {
Sissors 24:fb3399713710 1721 _bl = new DigitalOut(bl); //Construct new pin
Sissors 24:fb3399713710 1722 _bl->write(0); //Deactivate
Sissors 24:fb3399713710 1723 }
Sissors 24:fb3399713710 1724 else {
Sissors 24:fb3399713710 1725 // No Hardware Backlight pin
Sissors 24:fb3399713710 1726 _bl = NULL; //Construct dummy pin
Sissors 24:fb3399713710 1727 }
wim 30:033048611c01 1728
wim 30:033048611c01 1729 //Sanity check
wim 30:033048611c01 1730 if (_ctrl & LCD_C_SPI4) {
wim 30:033048611c01 1731 _init();
wim 30:033048611c01 1732 }
wim 30:033048611c01 1733 else {
wim 30:033048611c01 1734 error("Error: LCD Controller type does not support native SPI4 interface\n\r");
wim 30:033048611c01 1735 }
Sissors 24:fb3399713710 1736 }
Sissors 24:fb3399713710 1737
wim 25:6162b31128c9 1738 TextLCD_SPI_N::~TextLCD_SPI_N() {
Sissors 24:fb3399713710 1739 if (_bl != NULL) {delete _bl;} // BL pin
Sissors 24:fb3399713710 1740 }
Sissors 24:fb3399713710 1741
Sissors 24:fb3399713710 1742 // Not used in this mode
wim 25:6162b31128c9 1743 void TextLCD_SPI_N::_setEnable(bool value) {
Sissors 24:fb3399713710 1744 }
Sissors 24:fb3399713710 1745
Sissors 24:fb3399713710 1746 // Set RS pin
Sissors 24:fb3399713710 1747 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 25:6162b31128c9 1748 void TextLCD_SPI_N::_setRS(bool value) {
Sissors 24:fb3399713710 1749 _rs = value;
Sissors 24:fb3399713710 1750 }
Sissors 24:fb3399713710 1751
Sissors 24:fb3399713710 1752 // Set BL pin
wim 25:6162b31128c9 1753 void TextLCD_SPI_N::_setBL(bool value) {
wim 26:bd897a001012 1754 if (_bl) {
Sissors 24:fb3399713710 1755 _bl->write(value);
wim 26:bd897a001012 1756 }
Sissors 24:fb3399713710 1757 }
Sissors 24:fb3399713710 1758
wim 29:a3663151aa65 1759 // Not used in this mode
wim 29:a3663151aa65 1760 void TextLCD_SPI_N::_setData(int value) {
wim 29:a3663151aa65 1761 }
wim 29:a3663151aa65 1762
Sissors 24:fb3399713710 1763 // Write a byte using SPI
wim 25:6162b31128c9 1764 void TextLCD_SPI_N::_writeByte(int value) {
Sissors 24:fb3399713710 1765 _cs = 0;
Sissors 24:fb3399713710 1766 wait_us(1);
Sissors 24:fb3399713710 1767 _spi->write(value);
Sissors 24:fb3399713710 1768 wait_us(1);
Sissors 24:fb3399713710 1769 _cs = 1;
Sissors 24:fb3399713710 1770 }
wim 30:033048611c01 1771
wim 25:6162b31128c9 1772 //-------- End TextLCD_SPI_N ------------
wim 21:9eb628d9e164 1773
wim 21:9eb628d9e164 1774
wim 21:9eb628d9e164 1775
wim 30:033048611c01 1776 #if(0)
wim 30:033048611c01 1777 //Code checked out on logic analyser. Not yet tested on hardware..
wim 30:033048611c01 1778
wim 30:033048611c01 1779 //-------- Start TextLCD_SPI_N_3_9 --------
wim 30:033048611c01 1780
wim 30:033048611c01 1781 /** Create a TextLCD interface using a controller with a native SPI3 9 bits interface
wim 30:033048611c01 1782 *
wim 30:033048611c01 1783 * @param spi SPI Bus
wim 30:033048611c01 1784 * @param cs chip select pin (active low)
wim 30:033048611c01 1785 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 1786 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 1787 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 1788 */
wim 30:033048611c01 1789 TextLCD_SPI_N_3_9::TextLCD_SPI_N_3_9(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 1790 TextLCD_Base(type, ctrl),
wim 30:033048611c01 1791 _spi(spi),
wim 30:033048611c01 1792 _cs(cs) {
wim 30:033048611c01 1793
wim 30:033048611c01 1794 // Setup the spi for 9 bit data, low steady state clock,
wim 30:033048611c01 1795 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 30:033048611c01 1796 _spi->format(9,0);
wim 30:033048611c01 1797 _spi->frequency(1000000);
wim 30:033048611c01 1798
wim 30:033048611c01 1799 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 1800 if (bl != NC) {
wim 30:033048611c01 1801 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 1802 _bl->write(0); //Deactivate
wim 30:033048611c01 1803 }
wim 30:033048611c01 1804 else {
wim 30:033048611c01 1805 // No Hardware Backlight pin
wim 30:033048611c01 1806 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 1807 }
wim 30:033048611c01 1808
wim 30:033048611c01 1809 //Sanity check
wim 30:033048611c01 1810 if (_ctrl & LCD_C_SPI3_9) {
wim 30:033048611c01 1811 _init();
wim 30:033048611c01 1812 }
wim 30:033048611c01 1813 else {
wim 30:033048611c01 1814 error("Error: LCD Controller type does not support native SPI3 9 bits interface\n\r");
wim 30:033048611c01 1815 }
wim 30:033048611c01 1816 }
wim 30:033048611c01 1817
wim 30:033048611c01 1818 TextLCD_SPI_N_3_9::~TextLCD_SPI_N_3_9() {
wim 30:033048611c01 1819 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 1820 }
wim 30:033048611c01 1821
wim 30:033048611c01 1822 // Not used in this mode
wim 30:033048611c01 1823 void TextLCD_SPI_N_3_9::_setEnable(bool value) {
wim 30:033048611c01 1824 }
wim 30:033048611c01 1825
wim 30:033048611c01 1826 // Set RS pin
wim 30:033048611c01 1827 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 1828 void TextLCD_SPI_N_3_9::_setRS(bool value) {
wim 30:033048611c01 1829 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1830 // b8 b7...........b0
wim 30:033048611c01 1831 // RS command or data
wim 30:033048611c01 1832 //
wim 30:033048611c01 1833 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1834 //
wim 30:033048611c01 1835
wim 30:033048611c01 1836 if (value) {
wim 30:033048611c01 1837 _controlbyte = 0x01; // Next byte is data
wim 30:033048611c01 1838 }
wim 30:033048611c01 1839 else {
wim 30:033048611c01 1840 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 1841 }
wim 30:033048611c01 1842
wim 30:033048611c01 1843 }
wim 30:033048611c01 1844
wim 30:033048611c01 1845 // Set BL pin
wim 30:033048611c01 1846 void TextLCD_SPI_N_3_9::_setBL(bool value) {
wim 30:033048611c01 1847 if (_bl) {
wim 30:033048611c01 1848 _bl->write(value);
wim 30:033048611c01 1849 }
wim 30:033048611c01 1850 }
wim 30:033048611c01 1851
wim 30:033048611c01 1852 // Not used in this mode
wim 30:033048611c01 1853 void TextLCD_SPI_N_3_9::_setData(int value) {
wim 30:033048611c01 1854 }
wim 30:033048611c01 1855
wim 30:033048611c01 1856 // Write a byte using SPI3 9 bits mode
wim 30:033048611c01 1857 void TextLCD_SPI_N_3_9::_writeByte(int value) {
wim 30:033048611c01 1858 _cs = 0;
wim 30:033048611c01 1859 wait_us(1);
wim 30:033048611c01 1860 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 1861 wait_us(1);
wim 30:033048611c01 1862 _cs = 1;
wim 30:033048611c01 1863 }
wim 30:033048611c01 1864
wim 30:033048611c01 1865 //------- End TextLCD_SPI_N_3_9 -----------
wim 30:033048611c01 1866 #endif
wim 21:9eb628d9e164 1867
wim 21:9eb628d9e164 1868
wim 30:033048611c01 1869 #if(0)
wim 30:033048611c01 1870 //Code checked out on logic analyser. Not yet tested on hardware..
wim 30:033048611c01 1871
wim 30:033048611c01 1872 //------- Start TextLCD_SPI_N_3_10 --------
wim 30:033048611c01 1873
wim 30:033048611c01 1874 /** Create a TextLCD interface using a controller with a native SPI3 10 bits interface
wim 30:033048611c01 1875 *
wim 30:033048611c01 1876 * @param spi SPI Bus
wim 30:033048611c01 1877 * @param cs chip select pin (active low)
wim 30:033048611c01 1878 * @param type Sets the panel size/addressing mode (default = LCD16x2)
wim 30:033048611c01 1879 * @param bl Backlight control line (optional, default = NC)
wim 30:033048611c01 1880 * @param ctrl LCD controller (default = AIP31068)
wim 30:033048611c01 1881 */
wim 30:033048611c01 1882 TextLCD_SPI_N_3_10::TextLCD_SPI_N_3_10(SPI *spi, PinName cs, LCDType type, PinName bl, LCDCtrl ctrl) :
wim 30:033048611c01 1883 TextLCD_Base(type, ctrl),
wim 30:033048611c01 1884 _spi(spi),
wim 30:033048611c01 1885 _cs(cs) {
wim 30:033048611c01 1886
wim 30:033048611c01 1887 // Setup the spi for 10 bit data, low steady state clock,
wim 30:033048611c01 1888 // rising edge capture, with a 500KHz or 1MHz clock rate
wim 30:033048611c01 1889 _spi->format(10,0);
wim 30:033048611c01 1890 _spi->frequency(1000000);
wim 30:033048611c01 1891
wim 30:033048611c01 1892 // The hardware Backlight pin is optional. Test and make sure whether it exists or not to prevent illegal access.
wim 30:033048611c01 1893 if (bl != NC) {
wim 30:033048611c01 1894 _bl = new DigitalOut(bl); //Construct new pin
wim 30:033048611c01 1895 _bl->write(0); //Deactivate
wim 30:033048611c01 1896 }
wim 30:033048611c01 1897 else {
wim 30:033048611c01 1898 // No Hardware Backlight pin
wim 30:033048611c01 1899 _bl = NULL; //Construct dummy pin
wim 30:033048611c01 1900 }
wim 30:033048611c01 1901
wim 30:033048611c01 1902 //Sanity check
wim 30:033048611c01 1903 if (_ctrl & LCD_C_SPI3_10) {
wim 30:033048611c01 1904 _init();
wim 30:033048611c01 1905 }
wim 30:033048611c01 1906 else {
wim 30:033048611c01 1907 error("Error: LCD Controller type does not support native SPI3 10 bits interface\n\r");
wim 30:033048611c01 1908 }
wim 30:033048611c01 1909 }
wim 30:033048611c01 1910
wim 30:033048611c01 1911 TextLCD_SPI_N_3_10::~TextLCD_SPI_N_3_10() {
wim 30:033048611c01 1912 if (_bl != NULL) {delete _bl;} // BL pin
wim 30:033048611c01 1913 }
wim 30:033048611c01 1914
wim 30:033048611c01 1915 // Not used in this mode
wim 30:033048611c01 1916 void TextLCD_SPI_N_3_10::_setEnable(bool value) {
wim 30:033048611c01 1917 }
wim 30:033048611c01 1918
wim 30:033048611c01 1919 // Set RS pin
wim 30:033048611c01 1920 // Used for mbed pins, I2C bus expander or SPI shiftregister
wim 30:033048611c01 1921 void TextLCD_SPI_N_3_10::_setRS(bool value) {
wim 30:033048611c01 1922 // The controlbits define the meaning of the next byte. This next byte can either be data or command.
wim 30:033048611c01 1923 // b9 b8 b7...........b0
wim 30:033048611c01 1924 // RS RW command or data
wim 30:033048611c01 1925 //
wim 30:033048611c01 1926 // RS=1 means that next byte is data, RS=0 means that next byte is command
wim 30:033048611c01 1927 // RW=0 means that next byte is writen, RW=1 means that next byte is read (not used in this lib)
wim 30:033048611c01 1928 //
wim 30:033048611c01 1929
wim 30:033048611c01 1930 if (value) {
wim 30:033048611c01 1931 _controlbyte = 0x02; // Next byte is data
wim 30:033048611c01 1932 }
wim 30:033048611c01 1933 else {
wim 30:033048611c01 1934 _controlbyte = 0x00; // Next byte is command
wim 30:033048611c01 1935 }
wim 30:033048611c01 1936
wim 30:033048611c01 1937 }
wim 30:033048611c01 1938
wim 30:033048611c01 1939 // Set BL pin
wim 30:033048611c01 1940 void TextLCD_SPI_N_3_10::_setBL(bool value) {
wim 30:033048611c01 1941 if (_bl) {
wim 30:033048611c01 1942 _bl->write(value);
wim 30:033048611c01 1943 }
wim 30:033048611c01 1944 }
wim 30:033048611c01 1945
wim 30:033048611c01 1946 // Not used in this mode
wim 30:033048611c01 1947 void TextLCD_SPI_N_3_10::_setData(int value) {
wim 30:033048611c01 1948 }
wim 30:033048611c01 1949
wim 30:033048611c01 1950 // Write a byte using SPI3 10 bits mode
wim 30:033048611c01 1951 void TextLCD_SPI_N_3_10::_writeByte(int value) {
wim 30:033048611c01 1952 _cs = 0;
wim 30:033048611c01 1953 wait_us(1);
wim 30:033048611c01 1954 _spi->write( (_controlbyte << 8) | (value & 0xFF));
wim 30:033048611c01 1955 wait_us(1);
wim 30:033048611c01 1956 _cs = 1;
wim 30:033048611c01 1957 }
wim 30:033048611c01 1958
wim 30:033048611c01 1959 //------- End TextLCD_SPI_N_3_10 ----------
wim 30:033048611c01 1960 #endif