made some changes in config header file to make this library work with 1602A display and PCF8574AT I2C-bus interface
Fork of TextLCD by
Revision 21:9eb628d9e164, committed 2014-04-01
- Comitter:
- wim
- Date:
- Tue Apr 01 21:30:25 2014 +0000
- Parent:
- 20:e0da005a777f
- Child:
- 22:35742ec80c24
- Commit message:
- Refactored in Abstract Base class and Derived classes for Bus interface, I2C portexpander interface and SPI shiftregister interface.; This was needed to solve problem with recent mbed lib and DigitalOut pins that are default defined as 'NC'.
Changed in this revision
| TextLCD.cpp | Show annotated file Show diff for this revision Revisions of this file |
| TextLCD.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/TextLCD.cpp Mon May 13 19:29:13 2013 +0000
+++ b/TextLCD.cpp Tue Apr 01 21:30:25 2014 +0000
@@ -7,6 +7,7 @@
* 2013, v05: WH, Added support for 8x2B, added some UDCs
* 2013, v06: WH, Added support for devices that use internal DC/DC converters
* 2013, v07: WH, Added support for backlight and include portdefinitions for LCD2004 Module from DFROBOT
+ * 2014, v08: WH, Refactored in Base in Derived Classes to deal with mbed lib change regarding 'NC' defined pins
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,105 +31,23 @@
#include "TextLCD.h"
#include "mbed.h"
-
-/* 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 bl Backlight control line (optional, default = NC)
- * @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 bl, PinName e2, LCDCtrl ctrl) : _rs(rs), _e(e), _bl(bl), _e2(e2),
- _d(d4, d5, d6, d7),
- _cs(NC),
- _type(type),
- _ctrl(ctrl) {
-
- _busType = _PinBus;
-
- _init();
-
-}
-
-/* Create a TextLCD interface using an I2C PC8574 portexpander
- *
- * @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, LCDCtrl ctrl) :
- _rs(NC), _e(NC), _bl(NC), _e2(NC),
- _d(NC),
- _i2c(i2c),
- _cs(NC),
- _type(type),
- _ctrl(ctrl) {
-
- _slaveAddress = deviceAddress;
- _busType = _I2CBus;
-
-
- // Init the portexpander bus
- _lcd_bus = D_LCD_BUS_DEF;
-
- // write the new data to the portexpander
- _i2c->write(_slaveAddress, &_lcd_bus, 1);
-
- _init();
-
-}
-
- /* Create a TextLCD interface using an SPI 74595 portexpander
+/** Create a TextLCD_Base interface
*
- * @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)
+ * @param type Sets the panel size/addressing mode (default = LCD16x2)
+ * @param ctrl LCD controller (default = HD44780)
*/
-TextLCD::TextLCD(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
- _rs(NC), _e(NC), _bl(NC), _e2(NC),
- _d(NC),
- _spi(spi),
- _cs(cs),
- _type(type),
- _ctrl(ctrl) {
-
- _busType = _SPIBus;
-
- // Setup the spi for 8 bit data, low steady state clock,
- // rising edge capture, with a 500KHz or 1MHz clock rate
- _spi->format(8,0);
- _spi->frequency(500000);
- //_spi.frequency(1000000);
-
-
- // Init the portexpander bus
- _lcd_bus = D_LCD_BUS_DEF;
-
- // write the new data to the portexpander
- _setCS(false);
- _spi->write(_lcd_bus);
- _setCS(true);
-
- _init();
-
+TextLCD_Base::TextLCD_Base(LCDType type, LCDCtrl ctrl) : _type(type), _ctrl(ctrl) {
}
-/* Init the LCD Controller(s)
- * Clear display
- */
-void TextLCD::_init() {
+/** Init the LCD Controller(s)
+ * Clear display
+ */
+void TextLCD_Base::_init() {
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- _ctrl_idx=TextLCD::_LCDCtrl_1; // Select 2nd controller
+ _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
_initCtrl(); // Init 2nd controller
@@ -140,7 +59,7 @@
}
// Select and configure primary LCD controller
- _ctrl_idx=TextLCD::_LCDCtrl_0; // Select primary controller
+ _ctrl_idx=_LCDCtrl_0; // Select primary controller
_initCtrl(); // Init primary controller
@@ -152,13 +71,13 @@
}
-/* Init the LCD controller
- * 4-bit mode, number of lines, fonttype, no cursor etc
- *
- */
-void TextLCD::_initCtrl() {
+/** Init the LCD controller
+ * 4-bit mode, number of lines, fonttype, no cursor etc
+ *
+ */
+void TextLCD_Base::_initCtrl() {
- _setRS(false); // command mode
+ this->_setRS(false); // command mode
wait_ms(20); // Wait 20ms to ensure powered up
@@ -275,20 +194,21 @@
// _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
// // Display On, Cursor Off, Blink Off
- setCursor(TextLCD::CurOff_BlkOff);
- setMode(TextLCD::DispOn);
+ setCursor(CurOff_BlkOff);
+ setMode(DispOn);
}
-// Clear the screen, Cursor home.
-void TextLCD::cls() {
+/** Clear the screen, Cursor home.
+ */
+void TextLCD_Base::cls() {
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- _ctrl_idx=TextLCD::_LCDCtrl_1; // Select 2nd controller
+ _ctrl_idx=_LCDCtrl_1; // Select 2nd controller
// Second LCD controller Cursor always Off
- _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+ _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
// Second LCD controller Clearscreen
_writeCommand(0x01); // cls, and set cursor to 0
@@ -297,7 +217,7 @@
// Since we are not using the Busy flag, Lets be safe and take 10 ms
- _ctrl_idx=TextLCD::_LCDCtrl_0; // Select primary controller
+ _ctrl_idx=_LCDCtrl_0; // Select primary controller
}
// Primary LCD controller Clearscreen
@@ -315,8 +235,9 @@
_column=0;
}
-// Move cursor to selected row and column
-void TextLCD::locate(int column, int row) {
+/** Move cursor to selected row and column
+ */
+void TextLCD_Base::locate(int column, int row) {
// setAddress() does all the heavy lifting:
// check column and row sanity,
@@ -328,8 +249,9 @@
}
-// Write a single character (Stream implementation)
-int TextLCD::_putc(int value) {
+/** Write a single character (Stream implementation)
+ */
+int TextLCD_Base::_putc(int value) {
int addr;
if (value == '\n') {
@@ -366,250 +288,19 @@
// get a single character (Stream implementation)
-int TextLCD::_getc() {
+int TextLCD_Base::_getc() {
return -1;
}
-// Set E pin (or E2 pin)
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_setEnable(bool value) {
-
- switch(_busType) {
- case _PinBus :
- if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
- if (value)
- _e = 1; // Set E bit
- else
- _e = 0; // Reset E bit
- }
- else {
- if (value)
- _e2 = 1; // Set E2 bit
- else
- _e2 = 0; // Reset E2 bit
- }
-
- break;
-
- case _I2CBus :
-
- if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
- if (value)
- _lcd_bus |= D_LCD_E; // Set E bit
- else
- _lcd_bus &= ~D_LCD_E; // Reset E bit
- }
- else {
- if (value)
- _lcd_bus |= D_LCD_E2; // Set E2 bit
- else
- _lcd_bus &= ~D_LCD_E2; // Reset E2bit
- }
-
- // write the new data to the I2C portexpander
- _i2c->write(_slaveAddress, &_lcd_bus, 1);
-
- break;
-
- case _SPIBus :
- if(_ctrl_idx==TextLCD::_LCDCtrl_0) {
- if (value)
- _lcd_bus |= D_LCD_E; // Set E bit
- else
- _lcd_bus &= ~D_LCD_E; // Reset E bit
- }
- else {
- if (value)
- _lcd_bus |= D_LCD_E2; // Set E2 bit
- else
- _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
- }
-
- // write the new data to the SPI portexpander
- _setCS(false);
- _spi->write(_lcd_bus);
- _setCS(true);
-
- break;
- }
-}
-
-// Set RS pin
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_setRS(bool value) {
-
- switch(_busType) {
- case _PinBus :
- if (value)
- _rs = 1; // Set RS bit
- else
- _rs = 0; // Reset RS bit
-
- break;
-
- case _I2CBus :
- if (value)
- _lcd_bus |= D_LCD_RS; // Set RS bit
- else
- _lcd_bus &= ~D_LCD_RS; // Reset RS bit
-
- // write the new data to the I2C portexpander
- _i2c->write(_slaveAddress, &_lcd_bus, 1);
-
- break;
-
- case _SPIBus :
- if (value)
- _lcd_bus |= D_LCD_RS; // Set RS bit
- else
- _lcd_bus &= ~D_LCD_RS; // Reset RS bit
-
- // write the new data to the SPI portexpander
- _setCS(false);
- _spi->write(_lcd_bus);
- _setCS(true);
-
- break;
- }
-
-}
-
-// Set BL pin
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_setBL(bool value) {
-
- switch(_busType) {
- case _PinBus :
- if (value)
- _bl = 1; // Set BL bit
- else
- _bl = 0; // Reset BL bit
-
- break;
-
- case _I2CBus :
- if (value)
- _lcd_bus |= D_LCD_BL; // Set BL bit
- else
- _lcd_bus &= ~D_LCD_BL; // Reset BL bit
-
- // write the new data to the I2C portexpander
- _i2c->write(_slaveAddress, &_lcd_bus, 1);
-
- break;
-
- case _SPIBus :
- if (value)
- _lcd_bus |= D_LCD_BL; // Set BL bit
- else
- _lcd_bus &= ~D_LCD_BL; // Reset BL bit
-
- // write the new data to the SPI portexpander
- _setCS(false);
- _spi->write(_lcd_bus);
- _setCS(true);
-
- break;
- }
-
-}
-
-
-
-// Place the 4bit data on the databus
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_setData(int value) {
- int data;
-
- switch(_busType) {
- case _PinBus :
- _d = value & 0x0F; // Write Databits
-
- break;
-
- case _I2CBus :
- data = value & 0x0F;
- if (data & 0x01)
- _lcd_bus |= D_LCD_D4; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D4; // Reset Databit
-
- if (data & 0x02)
- _lcd_bus |= D_LCD_D5; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D5; // Reset Databit
-
- if (data & 0x04)
- _lcd_bus |= D_LCD_D6; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D6; // Reset Databit
-
- if (data & 0x08)
- _lcd_bus |= D_LCD_D7; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D7; // Reset Databit
-
- // write the new data to the I2C portexpander
- _i2c->write(_slaveAddress, &_lcd_bus, 1);
-
- break;
-
- case _SPIBus :
-
- data = value & 0x0F;
- if (data & 0x01)
- _lcd_bus |= D_LCD_D4; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D4; // Reset Databit
-
- if (data & 0x02)
- _lcd_bus |= D_LCD_D5; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D5; // Reset Databit
-
- if (data & 0x04)
- _lcd_bus |= D_LCD_D6; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D6; // Reset Databit
-
- if (data & 0x08)
- _lcd_bus |= D_LCD_D7; // Set Databit
- else
- _lcd_bus &= ~D_LCD_D7; // Reset Databit
-
- // write the new data to the SPI portexpander
- _setCS(false);
- _spi->write(_lcd_bus);
- _setCS(true);
-
- break;
- }
-
-}
-
-
-// Set CS line.
-// Only used for SPI bus
-void TextLCD::_setCS(bool value) {
-
- if (value) {
- _cs = 1; // Set CS pin
- }
- else
- _cs = 0; // Reset CS pin
-
-}
-
// Write a nibble using the 4-bit interface
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_writeNibble(int value) {
+void TextLCD_Base::_writeNibble(int value) {
// Enable is Low
- _setEnable(true);
- _setData(value & 0x0F); // Low nibble
+ this->_setEnable(true);
+ this->_setData(value & 0x0F); // Low nibble
wait_us(1); // Data setup time
- _setEnable(false);
+ this->_setEnable(false);
wait_us(1); // Datahold time
// Enable is Low
@@ -618,41 +309,42 @@
// Write a byte using the 4-bit interface
-// Used for mbed pins, I2C bus expander or SPI shifregister
-void TextLCD::_writeByte(int value) {
+void TextLCD_Base::_writeByte(int value) {
// Enable is Low
- _setEnable(true);
- _setData(value >> 4); // High nibble
+ this->_setEnable(true);
+ this->_setData(value >> 4); // High nibble
wait_us(1); // Data setup time
- _setEnable(false);
+ this->_setEnable(false);
wait_us(1); // Data hold time
- _setEnable(true);
- _setData(value >> 0); // Low nibble
+ this->_setEnable(true);
+ this->_setData(value >> 0); // Low nibble
wait_us(1); // Data setup time
- _setEnable(false);
+ this->_setEnable(false);
wait_us(1); // Datahold time
// Enable is Low
}
-void TextLCD::_writeCommand(int command) {
+// Write a command byte to the LCD controller
+void TextLCD_Base::_writeCommand(int command) {
- _setRS(false);
+ this->_setRS(false);
wait_us(1); // Data setup time for RS
- _writeByte(command);
+ this->_writeByte(command);
wait_us(40); // most instructions take 40us
}
-void TextLCD::_writeData(int data) {
+// Write a data byte to the LCD controller
+void TextLCD_Base::_writeData(int data) {
- _setRS(true);
+ this->_setRS(true);
wait_us(1); // Data setup time for RS
- _writeByte(data);
+ this->_writeByte(data);
wait_us(40); // data writes take 40us
}
@@ -662,7 +354,7 @@
// It is confusing since it returns the memoryaddress or-ed with the set memorycommand 0x80.
// Left it in here for compatibility with older code. New applications should use getAddress() instead.
//
-int TextLCD::_address(int column, int row) {
+int TextLCD_Base::_address(int column, int row) {
switch (_type) {
case LCD20x4:
switch (row) {
@@ -688,13 +380,13 @@
// This replaces the original _address() method.
// Left it in here for compatibility with older code. New applications should use getAddress() instead.
-int TextLCD::_address(int column, int row) {
+int TextLCD_Base::_address(int column, int row) {
return 0x80 | getAddress(column, row);
}
// This is new method to return the memory address based on row, column and displaytype.
//
-int TextLCD::getAddress(int column, int row) {
+int TextLCD_Base::getAddress(int column, int row) {
switch (_type) {
case LCD8x1:
@@ -784,7 +476,7 @@
if (_ctrl_idx != _LCDCtrl_0) {
// Second LCD controller Cursor Off
- _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+ _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
// Select primary controller
_ctrl_idx = _LCDCtrl_0;
@@ -800,7 +492,7 @@
// Test to see if we need to switch between controllers
if (_ctrl_idx != _LCDCtrl_1) {
// Primary LCD controller Cursor Off
- _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+ _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
// Select secondary controller
_ctrl_idx = _LCDCtrl_1;
@@ -821,7 +513,7 @@
// Set row, column and update memoryaddress.
//
-void TextLCD::setAddress(int column, int row) {
+void TextLCD_Base::setAddress(int column, int row) {
// Sanity Check column
if (column < 0) {
@@ -848,7 +540,7 @@
_writeCommand(0x80 | addr);
}
-int TextLCD::columns() {
+int TextLCD_Base::columns() {
switch (_type) {
case LCD8x1:
case LCD8x2:
@@ -883,7 +575,7 @@
}
}
-int TextLCD::rows() {
+int TextLCD_Base::rows() {
switch (_type) {
case LCD8x1:
case LCD16x1:
@@ -914,7 +606,7 @@
// Set the Cursor Mode (Cursor Off & Blink Off, Cursor On & Blink Off, Cursor Off & Blink On, Cursor On & Blink On
-void TextLCD::setCursor(TextLCD::LCDCursor cursorMode) {
+void TextLCD_Base::setCursor(LCDCursor cursorMode) {
// Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
_currentCursor = cursorMode;
@@ -925,35 +617,35 @@
}
// Set the Displaymode (On/Off)
-void TextLCD::setMode(TextLCD::LCDMode displayMode) {
+void TextLCD_Base::setMode(LCDMode displayMode) {
// Save new displayMode, needed when 2 controllers are in use or when cursor is changed
_currentMode = displayMode;
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
- if (_ctrl_idx==TextLCD::_LCDCtrl_0) {
+ if (_ctrl_idx==_LCDCtrl_0) {
// Configure primary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
// Select 2nd controller
- _ctrl_idx=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=_LCDCtrl_1;
// Configure secondary LCD controller
- _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+ _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
// Restore current controller
- _ctrl_idx=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=_LCDCtrl_0;
}
else {
// Select primary controller
- _ctrl_idx=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=_LCDCtrl_0;
// Configure primary LCD controller
- _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+ _setCursorAndDisplayMode(_currentMode, CurOff_BlkOff);
// Restore current controller
- _ctrl_idx=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=_LCDCtrl_1;
// Configure secondary LCD controller
_setCursorAndDisplayMode(_currentMode, _currentCursor);
@@ -969,38 +661,38 @@
// Set the Displaymode (On/Off) and Cursortype for current controller
-void TextLCD::_setCursorAndDisplayMode(TextLCD::LCDMode displayMode, TextLCD::LCDCursor cursorType) {
+void TextLCD_Base::_setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType) {
// Configure current LCD controller
_writeCommand(0x08 | displayMode | cursorType);
}
// Set the Backlight mode (Off/On)
-void TextLCD::setBacklight(TextLCD::LCDBacklight backlightMode) {
+void TextLCD_Base::setBacklight(LCDBacklight backlightMode) {
if (backlightMode == LightOn) {
- _setBL(true);
+ this->_setBL(true);
}
else {
- _setBL(false);
+ this->_setBL(false);
}
}
-void TextLCD::setUDC(unsigned char c, char *udc_data) {
+void TextLCD_Base::setUDC(unsigned char c, char *udc_data) {
// Select and configure second LCD controller when needed
if(_type==LCD40x4) {
_LCDCtrl_Idx current_ctrl_idx = _ctrl_idx; // Temp save current controller
// Select primary controller
- _ctrl_idx=TextLCD::_LCDCtrl_0;
+ _ctrl_idx=_LCDCtrl_0;
// Configure primary LCD controller
_setUDC(c, udc_data);
// Select 2nd controller
- _ctrl_idx=TextLCD::_LCDCtrl_1;
+ _ctrl_idx=_LCDCtrl_1;
// Configure secondary LCD controller
_setUDC(c, udc_data);
@@ -1015,7 +707,7 @@
}
-void TextLCD::_setUDC(unsigned char c, char *udc_data) {
+void TextLCD_Base::_setUDC(unsigned char c, char *udc_data) {
// Select CG RAM for current LCD controller
_writeCommand(0x40 + ((c & 0x07) << 3)); //Set CG-RAM address,
@@ -1030,3 +722,350 @@
_writeCommand(0x80 | addr);
}
+
+
+///-------------------------------------------------------------------
+
+
+/* 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 bl Backlight control line (optional, default = NC)
+ * @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 bl, PinName e2, LCDCtrl ctrl) :
+ TextLCD_Base(type, ctrl),
+ _rs(rs), _e(e), _bl(bl), _e2(e2),
+ _d(d4, d5, d6, d7) {
+
+ _init();
+
+}
+
+// Set E pin (or E2 pin)
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD::_setEnable(bool value) {
+
+ if(_ctrl_idx==_LCDCtrl_0) {
+ if (value)
+ _e = 1; // Set E bit
+ else
+ _e = 0; // Reset E bit
+ }
+ else {
+ if (value)
+ _e2 = 1; // Set E2 bit
+ else
+ _e2 = 0; // Reset E2 bit
+ }
+
+}
+
+// Set RS pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD::_setRS(bool value) {
+
+ if (value)
+ _rs = 1; // Set RS bit
+ else
+ _rs = 0; // Reset RS bit
+
+}
+
+// Set BL pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD::_setBL(bool value) {
+
+ if (value)
+ _bl = 1; // Set BL bit
+ else
+ _bl = 0; // Reset BL bit
+
+}
+
+
+
+// Place the 4bit data on the databus
+// Used for mbed pins, I2C bus expander or SPI shifregister
+void TextLCD::_setData(int value) {
+ _d = value & 0x0F; // Write Databits
+}
+
+
+
+
+///----------------------------------------------------------------------------------------
+
+
+/* Create a TextLCD interface using an I2C PC8574 portexpander
+ *
+ * @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_I2C::TextLCD_I2C(I2C *i2c, char deviceAddress, LCDType type, LCDCtrl ctrl) :
+ TextLCD_Base(type, ctrl),
+ _i2c(i2c){
+
+ _slaveAddress = deviceAddress;
+
+ // Init the portexpander bus
+ _lcd_bus = D_LCD_BUS_DEF;
+
+ // write the new data to the portexpander
+ _i2c->write(_slaveAddress, &_lcd_bus, 1);
+
+ _init();
+
+}
+
+// Set E pin (or E2 pin)
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_I2C::_setEnable(bool value) {
+
+ if(_ctrl_idx==_LCDCtrl_0) {
+ if (value)
+ _lcd_bus |= D_LCD_E; // Set E bit
+ else
+ _lcd_bus &= ~D_LCD_E; // Reset E bit
+ }
+ else {
+ if (value)
+ _lcd_bus |= D_LCD_E2; // Set E2 bit
+ else
+ _lcd_bus &= ~D_LCD_E2; // Reset E2bit
+ }
+
+ // write the new data to the I2C portexpander
+ _i2c->write(_slaveAddress, &_lcd_bus, 1);
+
+}
+
+// Set RS pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_I2C::_setRS(bool value) {
+
+ if (value)
+ _lcd_bus |= D_LCD_RS; // Set RS bit
+ else
+ _lcd_bus &= ~D_LCD_RS; // Reset RS bit
+
+ // write the new data to the I2C portexpander
+ _i2c->write(_slaveAddress, &_lcd_bus, 1);
+
+}
+
+// Set BL pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_I2C::_setBL(bool value) {
+
+ if (value)
+ _lcd_bus |= D_LCD_BL; // Set BL bit
+ else
+ _lcd_bus &= ~D_LCD_BL; // Reset BL bit
+
+ // write the new data to the I2C portexpander
+ _i2c->write(_slaveAddress, &_lcd_bus, 1);
+
+}
+
+
+
+// Place the 4bit data on the databus
+// Used for mbed pins, I2C bus expander or SPI shifregister
+void TextLCD_I2C::_setData(int value) {
+ int data;
+
+ data = value & 0x0F;
+ if (data & 0x01)
+ _lcd_bus |= D_LCD_D4; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D4; // Reset Databit
+
+ if (data & 0x02)
+ _lcd_bus |= D_LCD_D5; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D5; // Reset Databit
+
+ if (data & 0x04)
+ _lcd_bus |= D_LCD_D6; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D6; // Reset Databit
+
+ if (data & 0x08)
+ _lcd_bus |= D_LCD_D7; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D7; // Reset Databit
+
+ // write the new data to the I2C portexpander
+ _i2c->write(_slaveAddress, &_lcd_bus, 1);
+
+
+}
+
+
+
+
+
+///------------------------------------------------------------------------------------
+
+
+
+
+
+
+// TextLCD_SPI Implementation
+
+
+ /* Create a TextLCD interface using an SPI 74595 portexpander
+ *
+ * @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_SPI::TextLCD_SPI(SPI *spi, PinName cs, LCDType type, LCDCtrl ctrl) :
+ TextLCD_Base(type, ctrl),
+ _spi(spi),
+ _cs(cs) {
+
+ // Setup the spi for 8 bit data, low steady state clock,
+ // rising edge capture, with a 500KHz or 1MHz clock rate
+ _spi->format(8,0);
+ _spi->frequency(500000);
+ //_spi.frequency(1000000);
+
+
+ // Init the portexpander bus
+ _lcd_bus = D_LCD_BUS_DEF;
+
+ // write the new data to the portexpander
+ _setCS(false);
+ _spi->write(_lcd_bus);
+ _setCS(true);
+
+ _init();
+
+}
+
+// Set E pin (or E2 pin)
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_SPI::_setEnable(bool value) {
+
+ if(_ctrl_idx==_LCDCtrl_0) {
+ if (value)
+ _lcd_bus |= D_LCD_E; // Set E bit
+ else
+ _lcd_bus &= ~D_LCD_E; // Reset E bit
+ }
+ else {
+ if (value)
+ _lcd_bus |= D_LCD_E2; // Set E2 bit
+ else
+ _lcd_bus &= ~D_LCD_E2; // Reset E2 bit
+ }
+
+ // write the new data to the SPI portexpander
+ _setCS(false);
+ _spi->write(_lcd_bus);
+ _setCS(true);
+
+}
+
+// Set RS pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_SPI::_setRS(bool value) {
+
+ if (value)
+ _lcd_bus |= D_LCD_RS; // Set RS bit
+ else
+ _lcd_bus &= ~D_LCD_RS; // Reset RS bit
+
+ // write the new data to the SPI portexpander
+ _setCS(false);
+ _spi->write(_lcd_bus);
+ _setCS(true);
+
+}
+
+// Set BL pin
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_SPI::_setBL(bool value) {
+
+ if (value)
+ _lcd_bus |= D_LCD_BL; // Set BL bit
+ else
+ _lcd_bus &= ~D_LCD_BL; // Reset BL bit
+
+ // write the new data to the SPI portexpander
+ _setCS(false);
+ _spi->write(_lcd_bus);
+ _setCS(true);
+
+}
+
+
+
+// Place the 4bit data on the databus
+// Used for mbed pins, I2C bus expander or SPI shiftregister
+void TextLCD_SPI::_setData(int value) {
+ int data;
+
+ data = value & 0x0F;
+ if (data & 0x01)
+ _lcd_bus |= D_LCD_D4; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D4; // Reset Databit
+
+ if (data & 0x02)
+ _lcd_bus |= D_LCD_D5; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D5; // Reset Databit
+
+ if (data & 0x04)
+ _lcd_bus |= D_LCD_D6; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D6; // Reset Databit
+
+ if (data & 0x08)
+ _lcd_bus |= D_LCD_D7; // Set Databit
+ else
+ _lcd_bus &= ~D_LCD_D7; // Reset Databit
+
+ // write the new data to the SPI portexpander
+ _setCS(false);
+ _spi->write(_lcd_bus);
+ _setCS(true);
+
+}
+
+
+// Set CS line.
+// Only used for SPI bus
+void TextLCD_SPI::_setCS(bool value) {
+
+ if (value) {
+ _cs = 1; // Set CS pin
+ }
+ else
+ _cs = 0; // Reset CS pin
+
+}
+
+
+
+
+
+
+
+
+
+
+
--- a/TextLCD.h Mon May 13 19:29:13 2013 +0000
+++ b/TextLCD.h Tue Apr 01 21:30:25 2014 +0000
@@ -7,6 +7,7 @@
* 2013, v05: WH, Added support for 8x2B, added some UDCs
* 2013, v06: WH, Added support for devices that use internal DC/DC converters
* 2013, v07: WH, Added support for backlight and include portdefinitions for LCD2004 Module from DFROBOT
+ * 2014, v08: WH, Refactored in Base and Derived Classes to deal with mbed lib change regarding 'NC' defined DigitalOut pins
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -50,9 +51,9 @@
* 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 lcd(&spi_lcd, p8, TextLCD::LCD40x4); // SPI bus, CS pin, LCD Type
- * //TextLCD lcd(&i2c_lcd, 0x42, TextLCD::LCD20x4); // I2C bus, PCF8574 Slaveaddress, LCD Type
- * //TextLCD lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C bus, PCF8574 Slaveaddress, LCD Type, Device Type
+ * //TextLCD_SPI lcd(&spi_lcd, p8, TextLCD::LCD40x4); // SPI bus, 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
*
* int main() {
* lcd.printf("Hello World!\n");
@@ -163,7 +164,7 @@
* Currently supports 8x1, 8x2, 12x2, 12x4, 16x1, 16x2, 16x4, 20x2, 20x4, 24x2, 24x4, 40x2 and 40x4 panels
*
*/
-class TextLCD : public Stream {
+class TextLCD_Base : public Stream {
public:
/** LCD panel format */
@@ -193,6 +194,8 @@
};
+
+
/** LCD Cursor control */
enum LCDCursor {
CurOff_BlkOff = 0x00, /**< Cursor Off, Blinking Char Off */
@@ -214,37 +217,6 @@
LightOn /**< Backlight On */
};
- /** 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 bl Backlight control line (optional, default = NC)
- * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
- * @param ctrl LCD controller (default = HD44780)
- */
- TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type = LCD16x2, PinName bl = NC, PinName e2 = NC, LCDCtrl ctrl = HD44780);
-
- /** Create a TextLCD interface using an I2C PC8574 portexpander
- *
- * @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(I2C *i2c, char deviceAddress, LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
-
-
- /** Create a TextLCD interface using an SPI 74595 portexpander
- *
- * @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(SPI *spi, PinName cs, LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
-
#if DOXYGEN_ONLY
/** Write a character to the LCD
@@ -312,13 +284,13 @@
*
* @param displayMode The Display mode (DispOff, DispOn)
*/
- void setMode(TextLCD::LCDMode displayMode);
+ void setMode(LCDMode displayMode);
/** Set the Backlight mode
*
- * @param backlightMode The Backlight mode (LightOff, LightOn)
+ * @param backlightMode The Backlight mode (LightOff, LightOn)
*/
- void setBacklight(TextLCD::LCDBacklight backlightMode);
+ void setBacklight(LCDBacklight backlightMode);
/** Set User Defined Characters
@@ -330,70 +302,55 @@
protected:
- /* LCD Bus control */
- enum _LCDBus {
- _PinBus, /*< Regular mbed pins */
- _I2CBus, /*< I2C PCF8574 Portexpander */
- _SPIBus /*< SPI 74595 Shiftregister */
- };
- /* LCD controller select, mainly used for LCD40x4 */
+ /** LCD controller select, mainly used for LCD40x4
+ */
enum _LCDCtrl_Idx {
_LCDCtrl_0, /*< Primary */
_LCDCtrl_1, /*< Secondary */
};
+
+ /** Create a TextLCD_Base interface
+ * @brief Base class, can not be instantiated
+ *
+ * @param type Sets the panel size/addressing mode (default = LCD16x2)
+ * @param ctrl LCD controller (default = HD44780)
+ */
+ TextLCD_Base(LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
+
// Stream implementation functions
virtual int _putc(int value);
virtual int _getc();
-//Low level methods for LCD controller
+/** Low level methods for LCD controller
+ */
void _init();
void _initCtrl();
int _address(int column, int row);
- void _setCursor(TextLCD::LCDCursor show);
+ void _setCursor(LCDCursor show);
void _setUDC(unsigned char c, char *udc_data);
- void _setCursorAndDisplayMode(TextLCD::LCDMode displayMode, TextLCD::LCDCursor cursorType);
+ void _setCursorAndDisplayMode(LCDMode displayMode, LCDCursor cursorType);
-//Low level write operations to LCD controller
+/** Low level write operations to LCD controller
+ */
void _writeNibble(int value);
void _writeByte(int value);
void _writeCommand(int command);
void _writeData(int data);
-//Low level writes to LCD Bus (serial or parallel)
- void _setEnable(bool value);
- void _setRS(bool value);
- void _setBL(bool value);
- void _setData(int value);
- void _setCS(bool value);
-
-//Low level writes to LCD serial bus only
- void _writeBus();
+/** Pure Virtual Low level writes to LCD Bus (serial or parallel)
+ */
+ virtual void _setEnable(bool value) = 0;
+ virtual void _setRS(bool value) = 0;
+ virtual void _setBL(bool value) = 0;
+ virtual void _setData(int value) = 0;
-
-// Regular mbed pins bus
- DigitalOut _rs, _e, _bl, _e2;
- BusOut _d;
-
-// I2C bus
- I2C *_i2c;
- unsigned char _slaveAddress;
-
-// SPI bus
- SPI *_spi;
- DigitalOut _cs;
-
-//Bus Interface type
- _LCDBus _busType;
-
-// Internal bus mirror value for serial bus only
- char _lcd_bus;
//Display type
LCDType _type;
-//Display type
+//Display mode
LCDMode _currentMode;
//Controller type
@@ -408,4 +365,104 @@
LCDCursor _currentCursor;
};
+
+/** Create a TextLCD interface for using regular mbed pins
+ *
+ */
+class TextLCD : public TextLCD_Base {
+public:
+ /** 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 bl Backlight control line (optional, default = NC)
+ * @param e2 Enable2 line (clock for second controller, LCD40x4 only)
+ * @param ctrl LCD controller (default = HD44780)
+ */
+ TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type = LCD16x2, PinName bl = NC, PinName e2 = NC, LCDCtrl ctrl = HD44780);
+
+private:
+//Low level writes to LCD Bus (serial or parallel)
+ virtual void _setEnable(bool value);
+ virtual void _setRS(bool value);
+ virtual void _setBL(bool value);
+ virtual void _setData(int value);
+
+// Regular mbed pins bus
+ DigitalOut _rs, _e, _bl, _e2;
+ BusOut _d;
+};
+
+
+
+/** Create a TextLCD interface using an I2C PC8574 portexpander
+ *
+ */
+class TextLCD_I2C : public TextLCD_Base {
+public:
+ /** Create a TextLCD interface using an I2C PC8574 portexpander
+ *
+ * @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_I2C(I2C *i2c, char deviceAddress, LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
+
+private:
+//Low level writes to LCD Bus (serial or parallel)
+ virtual void _setEnable(bool value);
+ virtual void _setRS(bool value);
+ virtual void _setBL(bool value);
+ virtual void _setData(int value);
+
+//I2C bus
+ I2C *_i2c;
+ char _slaveAddress;
+
+// Internal bus mirror value for serial bus only
+ char _lcd_bus;
+
+};
+
+
+
+/** Create a TextLCD interface using an SPI 74595 portexpander
+ *
+ */
+class TextLCD_SPI : public TextLCD_Base {
+public:
+ /** Create a TextLCD interface using an SPI 74595 portexpander
+ *
+ * @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_SPI(SPI *spi, PinName cs, LCDType type = LCD16x2, LCDCtrl ctrl = HD44780);
+
+
+private:
+//Low level writes to LCD Bus (serial or parallel)
+ virtual void _setEnable(bool value);
+ virtual void _setRS(bool value);
+ virtual void _setBL(bool value);
+ virtual void _setData(int value);
+ virtual void _setCS(bool value);
+
+//Low level writes to LCD serial bus only
+ void _writeBus();
+
+// SPI bus
+ SPI *_spi;
+ DigitalOut _cs;
+
+// Internal bus mirror value for serial bus only
+ char _lcd_bus;
+
+};
+
+
#endif
