Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of TextLCD by
Diff: TextLCD.cpp
- Revision:
- 38:cbe275b0b647
- Parent:
- 37:ce348c002929
- Child:
- 39:e9c2319de9c5
--- a/TextLCD.cpp Sun Mar 29 13:08:03 2015 +0000 +++ b/TextLCD.cpp Sat Apr 18 11:33:02 2015 +0000 @@ -18,6 +18,8 @@ * 2014, v15: WH, Added AC780 support, added I2C expander modules, fixed setBacklight() for inverted logic modules. Fixed bug in LCD_SPI_N define * 2014, v16: WH, Added ST7070 and KS0073 support, added setIcon(), clrIcon() and setInvert() method for supported devices * 2015, v17: WH, Clean up low-level _writeCommand() and _writeData(), Added support for alternative fonttables (eg PCF21XX), Added ST7066_ACM controller for ACM1602 module + * 2015, v18: WH, Performance improvement I2C portexpander + * 2015, v19: WH, Fixed Adafruit I2C/SPI portexpander pinmappings, fixed SYDZ Backlight * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -69,6 +71,8 @@ * @return none */ void TextLCD_Base::_init(_LCDDatalength dl) { + + wait_ms(100); // Wait 100ms to ensure powered up // Select and configure second LCD controller when needed if(_type==LCD40x4) { @@ -101,8 +105,6 @@ int _lines=0; // Set lines (Ext Instr Set), temporary variable. this->_setRS(false); // command mode - - wait_ms(20); // Wait 20ms to ensure powered up if (dl == _LCD_DL_4) { // The Controller could be in 8 bit mode (power-on reset) or in 4 bit mode (warm reboot) at this point. @@ -110,18 +112,18 @@ // between the uP and the LCD can only write the 4 most significant bits (Most Significant Nibble, MSN). // In 4 bit mode the LCD expects the MSN first, followed by the LSN. // - // Current state: 8 bit mode | 4 bit mode, MSN is next | 4 bit mode, LSN is next + // Current state: 8 bit mode | 4 bit mode, MSN is next | 4 bit mode, LSN is next //------------------------------------------------------------------------------------------------- - _writeNibble(0x3); // set 8 bit mode (MSN) and dummy LSN, | set 8 bit mode (MSN), | set dummy LSN, - // remains in 8 bit mode | change to 8 bit mode | remains in 4 bit mode + _writeNibble(0x3); // set 8 bit mode (MSN) and dummy LSN, | set 8 bit mode (MSN), | set dummy LSN, + // remains in 8 bit mode | remains in 4 bit mode | remains in 4 bit mode wait_ms(15); // - _writeNibble(0x3); // set 8 bit mode and dummy LSN, | set 8 bit mode and dummy LSN, | set 8bit mode (MSN), - // remains in 8 bit mode | remains in 8 bit mode | remains in 4 bit mode + _writeNibble(0x3); // set 8 bit mode (MSN) and dummy LSN, | set dummy LSN, | set 8bit mode (MSN), + // remains in 8 bit mode | change to 8 bit mode | remains in 4 bit mode wait_ms(15); // - _writeNibble(0x3); // set 8 bit mode and dummy LSN, | set 8 bit mode and dummy LSN, | set dummy LSN, - // remains in 8 bit mode | remains in 8 bit mode | change to 8 bit mode + _writeNibble(0x3); // set 8 bit mode (MSN) and dummy LSN, | set 8 bit mode (MSN) and dummy LSN, | set dummy LSN, + // remains in 8 bit mode | remains in 8 bit mode | change to 8 bit mode wait_ms(15); // // Controller is now in 8 bit mode @@ -132,6 +134,10 @@ // Controller is now in 4-bit mode // Note: 4/8 bit mode is ignored for most native SPI and I2C devices. They dont use the parallel bus. // However, _writeNibble() method is void anyway for native SPI and I2C devices. + } + else { + // Reset in 8 bit mode, final Function set will follow + _writeCommand(0x30); // Function set 0 0 1 DL=1 N F x x } // Device specific initialisations: DC/DC converter to generate VLCD or VLED, number of lines etc @@ -1422,7 +1428,7 @@ // Enable is Low this->_setEnable(true); - this->_setData(value); // Low nibble + this->_setData(value); // Low nibble of value on D4..D7 wait_us(1); // Data setup time this->_setEnable(false); wait_us(1); // Datahold time @@ -2676,8 +2682,8 @@ // No Hardware Enable pin _e2 = NULL; //Construct dummy pin } - - _init(_LCD_DL_4); // Set Datalength to 4 bit for mbed bus interfaces + + _init(_LCD_DL_4); // Set Datalength to 4 bit for mbed bus interfaces } /** Destruct a TextLCD interface for using regular mbed pins @@ -2791,7 +2797,7 @@ // _writeRegister(OLAT, 0x00); // Output Latch // Init the portexpander bus - _lcd_bus = D_LCD_BUS_DEF; + _lcd_bus = LCD_BUS_I2C_DEF; // write the new data to the portexpander _writeRegister(GPIO, _lcd_bus); @@ -2799,7 +2805,7 @@ // PCF8574 of PCF8574A portexpander // Init the portexpander bus - _lcd_bus = D_LCD_BUS_DEF; + _lcd_bus = LCD_BUS_I2C_DEF; // write the new data to the portexpander _i2c->write(_slaveAddress, &_lcd_bus, 1); @@ -2814,18 +2820,18 @@ if(_ctrl_idx==_LCDCtrl_0) { if (value) { - _lcd_bus |= D_LCD_E; // Set E bit + _lcd_bus |= LCD_BUS_I2C_E; // Set E bit } else { - _lcd_bus &= ~D_LCD_E; // Reset E bit + _lcd_bus &= ~LCD_BUS_I2C_E; // Reset E bit } } else { if (value) { - _lcd_bus |= D_LCD_E2; // Set E2 bit + _lcd_bus |= LCD_BUS_I2C_E2; // Set E2 bit } else { - _lcd_bus &= ~D_LCD_E2; // Reset E2bit + _lcd_bus &= ~LCD_BUS_I2C_E2; // Reset E2bit } } } @@ -2856,10 +2862,10 @@ void TextLCD_I2C::_setRS(bool value) { if (value) { - _lcd_bus |= D_LCD_RS; // Set RS bit + _lcd_bus |= LCD_BUS_I2C_RS; // Set RS bit } else { - _lcd_bus &= ~D_LCD_RS; // Reset RS bit + _lcd_bus &= ~LCD_BUS_I2C_RS; // Reset RS bit } #if (MCP23008==1) @@ -2880,10 +2886,10 @@ void TextLCD_I2C::_setBL(bool value) { if (value) { - _lcd_bus |= D_LCD_BL; // Set BL bit + _lcd_bus |= LCD_BUS_I2C_BL; // Set BL bit } else { - _lcd_bus &= ~D_LCD_BL; // Reset BL bit + _lcd_bus &= ~LCD_BUS_I2C_BL; // Reset BL bit } #if (MCP23008==1) @@ -2899,40 +2905,76 @@ #endif } - +#if(0) +// New optimized v018 +// Test faster _writeByte 0.11s vs 0.27s for a 20x4 fillscreen (PCF8574), same as v018 +// Place the 4bit data in the databus shadowvalue +// Used for mbed I2C bus expander +const char _LCD_DATA_BITS[16] = { + 0x00, + ( LCD_BUS_I2C_D4), + ( LCD_BUS_I2C_D5 ), + ( LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4), + ( LCD_BUS_I2C_D6 ), + ( LCD_BUS_I2C_D6 | LCD_BUS_I2C_D4), + ( LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 ), + ( LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4), + (LCD_BUS_I2C_D7 ), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D4), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D5 ), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 ), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D4), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 ), + (LCD_BUS_I2C_D7 | LCD_BUS_I2C_D6 | LCD_BUS_I2C_D5 | LCD_BUS_I2C_D4) + }; +void TextLCD_I2C::_setDataBits(int value) { + + //Clear all databits + _lcd_bus &= ~LCD_BUS_I2C_MSK; + + // Set bit by bit to support any mapping of expander portpins to LCD pins + _lcd_bus |= _LCD_DATA_BITS[value & 0x0F]; +} + +#else +//orig v017 +// Test faster _writeByte 0.11s vs 0.27s for a 20x4 fillscreen (PCF8574) // Place the 4bit data in the databus shadowvalue // Used for mbed I2C bus expander void TextLCD_I2C::_setDataBits(int value) { // Set bit by bit to support any mapping of expander portpins to LCD pins if (value & 0x01){ - _lcd_bus |= D_LCD_D4; // Set Databit + _lcd_bus |= LCD_BUS_I2C_D4; // Set Databit } else { - _lcd_bus &= ~D_LCD_D4; // Reset Databit + _lcd_bus &= ~LCD_BUS_I2C_D4; // Reset Databit } if (value & 0x02){ - _lcd_bus |= D_LCD_D5; // Set Databit + _lcd_bus |= LCD_BUS_I2C_D5; // Set Databit } else { - _lcd_bus &= ~D_LCD_D5; // Reset Databit + _lcd_bus &= ~LCD_BUS_I2C_D5; // Reset Databit } if (value & 0x04) { - _lcd_bus |= D_LCD_D6; // Set Databit + _lcd_bus |= LCD_BUS_I2C_D6; // Set Databit } else { - _lcd_bus &= ~D_LCD_D6; // Reset Databit + _lcd_bus &= ~LCD_BUS_I2C_D6; // Reset Databit } if (value & 0x08) { - _lcd_bus |= D_LCD_D7; // Set Databit + _lcd_bus |= LCD_BUS_I2C_D7; // Set Databit } else { - _lcd_bus &= ~D_LCD_D7; // Reset Databit + _lcd_bus &= ~LCD_BUS_I2C_D7; // Reset Databit } } +#endif + // Place the 4bit data on the databus // Used for mbed pins, I2C bus expander or SPI shifregister @@ -3032,8 +3074,7 @@ TextLCD_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) : TextLCD_Base(type, ctrl), _spi(spi), - _cs(cs) { - + _cs(cs) { // Init cs _cs = 1; @@ -3043,8 +3084,10 @@ _spi->frequency(500000); //_spi.frequency(1000000); + wait_ms(100); // Wait 100ms to ensure LCD powered up + // Init the portexpander bus - _lcd_bus = D_LCD_BUS_DEF; + _lcd_bus = LCD_BUS_SPI_DEF; // write the new data to the portexpander _cs = 0; @@ -3060,18 +3103,18 @@ if(_ctrl_idx==_LCDCtrl_0) { if (value) { - _lcd_bus |= D_LCD_E; // Set E bit + _lcd_bus |= LCD_BUS_SPI_E; // Set E bit } else { - _lcd_bus &= ~D_LCD_E; // Reset E bit + _lcd_bus &= ~LCD_BUS_SPI_E; // Reset E bit } } else { if (value) { - _lcd_bus |= D_LCD_E2; // Set E2 bit + _lcd_bus |= LCD_BUS_SPI_E2; // Set E2 bit } else { - _lcd_bus &= ~D_LCD_E2; // Reset E2 bit + _lcd_bus &= ~LCD_BUS_SPI_E2; // Reset E2 bit } } @@ -3086,10 +3129,10 @@ void TextLCD_SPI::_setRS(bool value) { if (value) { - _lcd_bus |= D_LCD_RS; // Set RS bit + _lcd_bus |= LCD_BUS_SPI_RS; // Set RS bit } else { - _lcd_bus &= ~D_LCD_RS; // Reset RS bit + _lcd_bus &= ~LCD_BUS_SPI_RS; // Reset RS bit } // write the new data to the SPI portexpander @@ -3103,10 +3146,10 @@ void TextLCD_SPI::_setBL(bool value) { if (value) { - _lcd_bus |= D_LCD_BL; // Set BL bit + _lcd_bus |= LCD_BUS_SPI_BL; // Set BL bit } else { - _lcd_bus &= ~D_LCD_BL; // Reset BL bit + _lcd_bus &= ~LCD_BUS_SPI_BL; // Reset BL bit } // write the new data to the SPI portexpander @@ -3121,31 +3164,31 @@ // Set bit by bit to support any mapping of expander portpins to LCD pins if (value & 0x01) { - _lcd_bus |= D_LCD_D4; // Set Databit + _lcd_bus |= LCD_BUS_SPI_D4; // Set Databit } else { - _lcd_bus &= ~D_LCD_D4; // Reset Databit + _lcd_bus &= ~LCD_BUS_SPI_D4; // Reset Databit } if (value & 0x02) { - _lcd_bus |= D_LCD_D5; // Set Databit + _lcd_bus |= LCD_BUS_SPI_D5; // Set Databit } else { - _lcd_bus &= ~D_LCD_D5; // Reset Databit + _lcd_bus &= ~LCD_BUS_SPI_D5; // Reset Databit } if (value & 0x04) { - _lcd_bus |= D_LCD_D6; // Set Databit + _lcd_bus |= LCD_BUS_SPI_D6; // Set Databit } else { - _lcd_bus &= ~D_LCD_D6; // Reset Databit + _lcd_bus &= ~LCD_BUS_SPI_D6; // Reset Databit } if (value & 0x08) { - _lcd_bus |= D_LCD_D7; // Set Databit + _lcd_bus |= LCD_BUS_SPI_D7; // Set Databit } else { - _lcd_bus &= ~D_LCD_D7; // Reset Databit + _lcd_bus &= ~LCD_BUS_SPI_D7; // Reset Databit } // write the new data to the SPI portexpander