Diff: TextLCD.cpp
- Revision:
- 19:c747b9e2e7b8
- Parent:
- 18:bd65dc10f27f
- Child:
- 20:e0da005a777f
diff -r bd65dc10f27f -r c747b9e2e7b8 TextLCD.cpp
--- a/TextLCD.cpp Sat Mar 09 19:39:53 2013 +0000
+++ b/TextLCD.cpp Fri Apr 19 19:36:37 2013 +0000
@@ -5,6 +5,7 @@
* 2013, v03: WH, Added support for LCD40x4 which uses 2 controllers
* 2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess
* 2013, v05: WH, Added support for 8x2B, added some UDCs
+ * 2013, v06: WH, Added support for devices that use internal DC/DC converters
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -31,18 +32,20 @@
/* Create a TextLCD interface for using regular mbed pins
*
- * @param rs Instruction/data control line
- * @param e Enable line (clock)
- * @param d4-d7 Data lines for using as a 4-bit interface
- * @param type Sets the panel size/addressing mode (default = LCD16x2)
- * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
+ * @param rs Instruction/data control line
+ * @param e Enable line (clock)
+ * @param d4-d7 Data lines for using as a 4-bit interface
+ * @param type Sets the panel size/addressing mode (default = LCD16x2)
+ * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
+ * @param ctrl LCD controller (default = HD44780)
*/
TextLCD::TextLCD(PinName rs, PinName e,
PinName d4, PinName d5, PinName d6, PinName d7,
- LCDType type, PinName e2) : _rs(rs), _e(e), _e2(e2),
- _d(d4, d5, d6, d7),
- _cs(NC),
- _type(type) {
+ LCDType type, PinName e2, LCDCtrl ctrl) : _rs(rs), _e(e), _e2(e2),
+ _d(d4, d5, d6, d7),
+ _cs(NC),
+ _type(type),
+ _ctrl(ctrl) {
_busType = _PinBus;
@@ -55,13 +58,15 @@
* @param i2c I2C Bus
* @param deviceAddress I2C slave address (PCF8574)
* @param type Sets the panel size/addressing mode (default = LCD16x2)
+ * @param ctrl LCD controller (default = HD44780)
*/
-TextLCD::TextLCD(I2C *i2c, char deviceAddress, LCDType type) :
+TextLCD::TextLCD(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
_rs(NC), _e(NC), _e2(NC),
_d(NC),
_i2c(i2c),
_cs(NC),
- _type(type) {
+ _type(type),
+ _ctrl(ctrl) {
_slaveAddress = deviceAddress;
_busType = _I2CBus;
@@ -82,13 +87,15 @@
* @param spi SPI Bus
* @param cs chip select pin (active low)
* @param type Sets the panel size/addressing mode (default = LCD16x2)
+ * @param ctrl LCD controller (default = HD44780)
*/
-TextLCD::TextLCD(SPI *spi, PinName cs, LCDType type) :
+TextLCD::TextLCD(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
_rs(NC), _e(NC), _e2(NC),
_d(NC),
_spi(spi),
_cs(cs),
- _type(type) {
+ _type(type),
+ _ctrl(ctrl) {
_busType = _SPIBus;
@@ -119,9 +126,9 @@
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller
+ _ctrl_idx=TextLCD::_LCDCtrl_1; // Select 2nd controller
- _initCtrl(); // Init 2nd controller
+ _initCtrl(); // Init 2nd controller
// Secondary LCD controller Clearscreen
_writeCommand(0x01); // cls, and set cursor to 0
@@ -131,9 +138,9 @@
}
// Select and configure primary LCD controller
- _ctrl=TextLCD::_LCDCtrl_0; // Select primary controller
+ _ctrl_idx=TextLCD::_LCDCtrl_0; // Select primary controller
- _initCtrl(); // Init primary controller
+ _initCtrl(); // Init primary controller
// Primary LCD controller Clearscreen
_writeCommand(0x01); // cls, and set cursor to 0
@@ -153,7 +160,6 @@
wait_ms(20); // Wait 20ms to ensure powered up
-#if(1)
// send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
for (int i=0; i<3; i++) {
_writeNibble(0x3);
@@ -161,37 +167,52 @@
}
_writeNibble(0x2); // 4-bit mode
wait_us(40); // most instructions take 40us
-#else
-//Original code. Does not comply with specification and causes problems
-//unless used right after power-on.
-
- // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
- for (int i=0; i<3; i++) {
- _writeByte(0x3);
- wait_ms(15); // this command takes 1.64ms, so wait for it
- }
- _writeByte(0x2); // 4-bit mode
- wait_us(40); // most instructions take 40us
-#endif
// Display is now in 4-bit mode
-#if(0)
- // ST7036 controller: Initialise Voltage booster for VLCD. VDD=5V
- // Note: supports 1,2 or 3 lines
- _writeByte( 0x29 ); // 4-bit Databus, 2 Lines, Select Instruction table 1
- wait_us(27); // > 26,3ms
- _writeByte( 0x14 ); // Bias: 1/5, 2-Lines LCD
- wait_us(30); // > 26,3ms
- _writeByte( 0x55 ); // Icon off, Booster on, Set Contrast C5, C4
- wait_us(30); // > 26,3ms
- _writeByte( 0x6d ); // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
- wait_ms(200); // > 200ms!
- _writeByte( 0x78 ); // Set Contrast C3, C2, C1, C0
- wait_us(30); // > 26,3ms
- _writeByte( 0x28 ); // Return to Instruction table 0
- wait_ms(50);
-#endif
+
+ // Device specific initialisations for DC/DC converter to generate VLCD or VLED
+ switch (_ctrl) {
+ case ST7063:
+ // ST7036 controller: Initialise Voltage booster for VLCD. VDD=5V
+ // Note: supports 1,2 or 3 lines
+ _writeByte( 0x29 ); // 4-bit Databus, 2 Lines, Select Instruction table 1
+ wait_us(27); // > 26,3ms
+ _writeByte( 0x14 ); // Bias: 1/5, 2-Lines LCD
+ wait_us(30); // > 26,3ms
+ _writeByte( 0x55 ); // Icon off, Booster on, Set Contrast C5, C4
+ wait_us(30); // > 26,3ms
+ _writeByte( 0x6d ); // Voltagefollower On, Ampl ratio Rab2, Rab1, Rab0
+ wait_ms(200); // > 200ms!
+ _writeByte( 0x78 ); // Set Contrast C3, C2, C1, C0
+ wait_us(30); // > 26,3ms
+ _writeByte( 0x28 ); // Return to Instruction table 0
+ wait_ms(50);
+
+ break;
+
+ case WS0010:
+ // WS0010 OLED controller: Initialise DC/DC Voltage converter for LEDs
+ // Note: supports 1 or 2 lines (and 16x100 graphics)
+ // supports 4 fonts (English/Japanese (default), Western European-I, English/Russian, Western European-II)
+
+ // Cursor/Disp shift set 0001 SC RL 0 0
+ //
+ // Mode en Power set 0001 GC PWR 1 1
+ // GC = 0 (Graph Mode=1, Char Mode=0)
+ // PWR = (DC/DC On/Off)
+
+ //_writeCommand(0x13); // DC/DC off
+
+ _writeCommand(0x17); // DC/DC on
+ wait_ms(10);
+
+ break;
+
+ default:
+ // Devices that do not use DC/DC Voltage converters but external VLCD
+ break;
+ }
// Initialise Display configuration
switch (_type) {
@@ -262,7 +283,7 @@
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller
+ _ctrl_idx=TextLCD::_LCDCtrl_1; // Select 2nd controller
// Second LCD controller Cursor always Off
_setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
@@ -274,7 +295,7 @@
// Since we are not using the Busy flag, Lets be safe and take 10 ms
- _ctrl=TextLCD::_LCDCtrl_0; // Select primary controller
+ _ctrl_idx=TextLCD::_LCDCtrl_0; // Select primary controller
}
// Primary LCD controller Clearscreen
@@ -353,7 +374,7 @@
switch(_busType) {
case _PinBus :
- if(_ctrl==TextLCD::_LCDCtrl_0) {
+ if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
if (value)
_e = 1; // Set E bit
else
@@ -370,7 +391,7 @@
case _I2CBus :
- if(_ctrl==TextLCD::_LCDCtrl_0) {
+ if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
if (value)
_lcd_bus |= D_LCD_E; // Set E bit
else
@@ -389,7 +410,7 @@
break;
case _SPIBus :
- if(_ctrl==TextLCD::_LCDCtrl_0) {
+ if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
if (value)
_lcd_bus |= D_LCD_E; // Set E bit
else
@@ -716,13 +737,13 @@
// Each controller is configured as 40x2
if (row<2) {
// Test to see if we need to switch between controllers
- if (_ctrl != _LCDCtrl_0) {
+ if (_ctrl_idx != _LCDCtrl_0) {
// Second LCD controller Cursor Off
_setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
// Select primary controller
- _ctrl = _LCDCtrl_0;
+ _ctrl_idx = _LCDCtrl_0;
// Restore cursormode on primary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
@@ -733,12 +754,12 @@
else {
// Test to see if we need to switch between controllers
- if (_ctrl != _LCDCtrl_1) {
+ if (_ctrl_idx != _LCDCtrl_1) {
// Primary LCD controller Cursor Off
_setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
// Select secondary controller
- _ctrl = _LCDCtrl_1;
+ _ctrl_idx = _LCDCtrl_1;
// Restore cursormode on secondary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
@@ -867,28 +888,28 @@
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- if (_ctrl==TextLCD::_LCDCtrl_0) {
+ if (_ctrl_idx==TextLCD::_LCDCtrl_0) {
// Configure primary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
// Select 2nd controller
- _ctrl=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=TextLCD::_LCDCtrl_1;
// Configure secondary LCD controller
_setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
// Restore current controller
- _ctrl=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=TextLCD::_LCDCtrl_0;
}
else {
// Select primary controller
- _ctrl=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=TextLCD::_LCDCtrl_0;
// Configure primary LCD controller
_setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
// Restore current controller
- _ctrl=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=TextLCD::_LCDCtrl_1;
// Configure secondary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
@@ -915,22 +936,22 @@
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- _LCDCtrl current_ctrl = _ctrl; // Temp save current controller
+ _LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
// Select primary controller
- _ctrl=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=TextLCD::_LCDCtrl_0;
// Configure primary LCD controller
_setUDC(c, udc_data);
// Select 2nd controller
- _ctrl=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=TextLCD::_LCDCtrl_1;
// Configure secondary LCD controller
_setUDC(c, udc_data);
// Restore current controller
- _ctrl=current_ctrl;
+ _ctrl_idx=current_ctrl_idx;
}
else {
// Configure primary LCD controller