SSD1308 128x64 OLED Driver with I2C interface
Dependents: sense xadow_m0_ada_gps xadow_m0_SD_Hello sense-DHT11 ... more
See http://mbed.org/users/wim/notebook/oled-display-with-ssd1308-driver/#c6729
Revision 4:df92b0c0cb92, committed 2015-01-01
- Comitter:
- wim
- Date:
- Thu Jan 01 17:53:40 2015 +0000
- Parent:
- 3:fa18169dd7e6
- Child:
- 5:e564cde8e03e
- Commit message:
- Added option to select optimisation using low level I2C methods. Used for testing on F401 and LPC1768.
Changed in this revision
| SSD1308.cpp | Show annotated file Show diff for this revision Revisions of this file |
| SSD1308.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/SSD1308.cpp Mon Jul 23 20:24:11 2012 +0000
+++ b/SSD1308.cpp Thu Jan 01 17:53:40 2015 +0000
@@ -12,12 +12,14 @@
// Changelog:
// 2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
// 2012-06-19 - Ported to mbed and optimised (WH)
+// 2013-07-12 - Minor comment fix and placeholder for SSD1306 (WH)
+// 2015-01-01 - Switch for optimised I2C calls to test on F401 (WH)
//
-/*
+/*
================================================================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Andrew Schamp
-Copyright (c) 2012 WH (mbed port)
+Copyright (c) 2012,2013 WH (mbed port)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -49,6 +51,12 @@
//#include "font_16x20.h"
#include "font_16x24.h"
+#if defined(TARGET_LPC1768)
+#define I2C_OPTIMIZE 1
+#else
+#define I2C_OPTIMIZE 0
+#endif
+
/**
*@brief Constructor
*@param I2C &i2c reference to i2c
@@ -77,7 +85,7 @@
/** @brief clear the display
*/
-#if(0)
+#if (I2C_OPTIMIZE == 0)
// Standard version
void SSD1308::clearDisplay() {
@@ -120,24 +128,31 @@
/** @brief fill the display
* @param uint8_t pattern fillpattern vertical patch or 8 bits
+ * @param uint8_t start_page begin page (0..MAX_PAGE)
+ * @param uint8_t end_page end page (start_page..MAX_PAGE)
+ * @param uint8_t start_col begin column (0..MAX_COL)
+ * @param uint8_t end_col end column (start_col..MAX_COL)
*/
-#if(0)
+#if (I2C_OPTIMIZE == 0)
//Standard version
-void SSD1308::fillDisplay(uint8_t pattern) {
-
- //setDisplayOff();
+
+void SSD1308::fillDisplay(uint8_t pattern,
+ uint8_t start_page, uint8_t end_page,
+ uint8_t start_col, uint8_t end_col) {
- setPageAddress(0, MAX_PAGE); // all pages
- setColumnAddress(0, MAX_COL); // all columns
+ int count = (end_page - start_page + 1) * (end_col - start_col + 1);
+
+ //setDisplayOff();
+ setPageAddress(start_page, end_page); // set page window
+ setColumnAddress(start_col, end_col); // set column window
+
+ for (int i=0; i<count; i++) {
+ _sendData(pattern); // Write Data
+ }
- for (uint8_t page = 0; page < PAGES; page++) {
- for (uint8_t col = 0; col < COLUMNS; col++) {
- _sendData(pattern);
- }
- }
-
- //setDisplayOn();
+ //setDisplayOn();
}
+
#else
//Optimised version
@@ -175,26 +190,26 @@
* @param uint8_t start_col begin column (0..MAX_COL)
* @param uint8_t end_col end column (start_col..MAX_COL)
*/
-#if(0)
+#if (I2C_OPTIMIZE == 0)
//Standard version
-void SSD1308::writeBitmap(int len, uint8_t* data) {
+void SSD1308::writeBitmap(uint8_t* data,
+ uint8_t start_page, uint8_t end_page,
+ uint8_t start_col, uint8_t end_col){
+
+ int count = (end_page - start_page + 1) * (end_col - start_col + 1);
//setDisplayOff();
- setPageAddress(0, MAX_PAGE); // all pages
- setColumnAddress(0, MAX_COL); // all columns
+ setPageAddress(start_page, end_page); // set page window
+ setColumnAddress(start_col, end_col); // set column window
- _i2c.start();
- _i2c.write(_writeOpcode);
- _i2c.write(DATA_MODE);
- for (int i=0; i<len; i++) {
- _i2c.write(data[i]); // Write Data
+ for (int i=0; i<count; i++) {
+ _sendData(data[i]); // Write Data
}
- _i2c.stop();
//setDisplayOn();
}
+
#else
-
//Optimised version
// Save lots of I2C S,P, address and datacommands:
// Send S, address, DATA_MODE, data, data, data,...., P
@@ -219,6 +234,7 @@
//setDisplayOn();
}
+
#endif
@@ -234,7 +250,7 @@
//#define PRG_ACTIVE 0xBD
#define PRG_NOT_ACTIVE 0x81
-#if(0)
+#if (I2C_OPTIMIZE == 0)
//Standard version
void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
uint8_t scale_value;
@@ -319,6 +335,40 @@
* @param uint8_t col begin column (0..MAX_COL)
* @param int percentage value (0..100)
*/
+#if (I2C_OPTIMIZE == 0)
+void SSD1308::writeLevelBar(uint8_t page, uint8_t col, int percentage) {
+ uint8_t scale_value;
+
+ if (percentage <= 0) {
+ scale_value = 0;
+ } else if (percentage >= 100) {
+ scale_value = PRG_MAX_SCALE - 1;
+ }
+ else {
+ scale_value = (percentage * PRG_MAX_SCALE) / 100;
+ }
+
+ //setDisplayOff();
+ setPageAddress(page, page);
+ setColumnAddress(col, MAX_COL);
+
+ _sendData(PRG_LEFT_EDGE);
+
+ for (uint8_t col = 0; col < scale_value; col++) {
+ _sendData(PRG_NOT_ACTIVE); // Write Data
+ }
+
+ _sendData(PRG_ACTIVE); // Write Data at active meterlevel
+
+ for (uint8_t col = scale_value+1; col < PRG_MAX_SCALE; col++) {
+ _sendData(PRG_NOT_ACTIVE);
+ }
+
+ _sendData(PRG_RIGHT_EDGE);
+
+ //setDisplayOn();
+}
+#else
//Optimised version
// Save lots of I2C S,P, address and datacommands:
// Send S, address, DATA_MODE, data, data, data,...., P
@@ -361,6 +411,7 @@
//setDisplayOn();
}
+#endif
/** @brief Write single character to the display using the 8x8 fontable
* @brief Start at current cursor location
@@ -386,7 +437,6 @@
* @brief Start at selected cursor location, text will wrap around until it is done
* @param uint8_t row row number (0...ROWS/FONT_HEIGHT)
* @param uint8_t col column number (0...COLUMNS/FONT_WIDTH)
- * @param uint16_t len number of chars in text
* @param const char * text pointer to text
*/
void SSD1308::writeString(uint8_t row, uint8_t col, const char * text) {
@@ -442,14 +492,14 @@
void SSD1308::_sendCommand(uint8_t command) {
// I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command);
-#if(0)
+#if (I2C_OPTIMIZE == 0)
char databytes[2];
databytes[0] = COMMAND_MODE;
databytes[1] = command;
_i2c.write(_writeOpcode, databytes, 2); // Write command
-#endif
-
+#else
+
_i2c.start();
_i2c.write(_writeOpcode);
@@ -457,7 +507,7 @@
_i2c.write(command); // Write Command
_i2c.stop();
-
+#endif
}
/** @brief Write command that has one parameter
@@ -466,6 +516,15 @@
// Note continuationbit is set, so COMMAND_MODE must be
// repeated before each databyte that serves as parameter!
+#if (I2C_OPTIMIZE == 0)
+ char databytes[4];
+
+ databytes[0] = COMMAND_MODE;
+ databytes[1] = command;
+ databytes[2] = COMMAND_MODE;
+ databytes[3] = param1;
+ _i2c.write(_writeOpcode, databytes, 4); // Write command
+#else
_i2c.start();
_i2c.write(_writeOpcode);
@@ -476,7 +535,7 @@
_i2c.write(param1); // Write Param1
_i2c.stop();
-
+#endif
}
/** @brief Write command that has two parameters
@@ -485,7 +544,17 @@
// Note continuationbit is set, so COMMAND_MODE must be
// repeated before each databyte that serves as parameter!
-
+#if (I2C_OPTIMIZE == 0)
+ char databytes[6];
+
+ databytes[0] = COMMAND_MODE;
+ databytes[1] = command;
+ databytes[2] = COMMAND_MODE;
+ databytes[3] = param1;
+ databytes[4] = COMMAND_MODE;
+ databytes[5] = param2;
+ _i2c.write(_writeOpcode, databytes, 6); // Write command
+#else
_i2c.start();
_i2c.write(_writeOpcode);
@@ -497,7 +566,7 @@
_i2c.write(param2); // Write Param2
_i2c.stop();
-
+ #endif
}
/** @brief Write command that has five parameters
@@ -508,7 +577,23 @@
// Note continuationbit is set, so COMMAND_MODE must be
// repeated before each databyte that serves as parameter!
-
+#if (I2C_OPTIMIZE == 0)
+ char databytes[12];
+
+ databytes[0] = COMMAND_MODE;
+ databytes[1] = command;
+ databytes[2] = COMMAND_MODE;
+ databytes[3] = param1;
+ databytes[4] = COMMAND_MODE;
+ databytes[5] = param2;
+ databytes[6] = COMMAND_MODE;
+ databytes[7] = param3;
+ databytes[8] = COMMAND_MODE;
+ databytes[9] = param4;
+ databytes[10] = COMMAND_MODE;
+ databytes[11] = param5;
+ _i2c.write(_writeOpcode, databytes, 12); // Write command
+#else
_i2c.start();
_i2c.write(_writeOpcode);
@@ -526,7 +611,7 @@
_i2c.write(param5); // Write Param5
_i2c.stop();
-
+#endif
}
@@ -538,7 +623,25 @@
// Note continuationbit is set, so COMMAND_MODE must be
// repeated before each databyte that serves as parameter!
-
+#if (I2C_OPTIMIZE == 0)
+ char databytes[14];
+
+ databytes[0] = COMMAND_MODE;
+ databytes[1] = command;
+ databytes[2] = COMMAND_MODE;
+ databytes[3] = param1;
+ databytes[4] = COMMAND_MODE;
+ databytes[5] = param2;
+ databytes[6] = COMMAND_MODE;
+ databytes[7] = param3;
+ databytes[8] = COMMAND_MODE;
+ databytes[9] = param4;
+ databytes[10] = COMMAND_MODE;
+ databytes[11] = param5;
+ databytes[12] = COMMAND_MODE;
+ databytes[13] = param6;
+ _i2c.write(_writeOpcode, databytes, 14); // Write command
+#else
_i2c.start();
_i2c.write(_writeOpcode);
@@ -558,7 +661,7 @@
_i2c.write(param6); // Write Param6
_i2c.stop();
-
+#endif
}
@@ -588,14 +691,25 @@
* @param uint8_t data databyte to write
*/
void SSD1308::_sendData(uint8_t data){
-// I2Cdev::writeByte(m_devAddr, DATA_MODE, data);
+#if (I2C_OPTIMIZE == 0)
+//I2C Blockwrite versions dont seem to work ?
+//That may be related to fact that the SSD1308/SSD1306 does NOT return an acknowledge: blockwrite may abort the operation
+//Noted for mbed lib v63 on 20/7/13
char databytes[2];
databytes[0] = DATA_MODE;
databytes[1] = data;
_i2c.write(_writeOpcode, databytes, 2); // Write Data
-
+
+#else
+ _i2c.start();
+ _i2c.write(_writeOpcode);
+ _i2c.write(DATA_MODE);
+ _i2c.write(data);
+ _i2c.stop();
+#endif
+
}
/** @brief Write len bytes from buffer data to display,
@@ -605,7 +719,11 @@
*/
void SSD1308::_sendData(uint8_t len, uint8_t* data) {
// I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
-
+#if (I2C_OPTIMIZE == 0)
+ for (int i=0; i<len ; i++) {
+ _sendData(data[i]); // Write Data
+ }
+#else
_i2c.start();
_i2c.write(_writeOpcode);
_i2c.write(DATA_MODE);
@@ -613,7 +731,7 @@
_i2c.write(data[i]); // Write Data
}
_i2c.stop();
-
+#endif
}
--- a/SSD1308.h Mon Jul 23 20:24:11 2012 +0000
+++ b/SSD1308.h Thu Jan 01 17:53:40 2015 +0000
@@ -12,11 +12,14 @@
// Changelog:
// 2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
// 2012-06-19 - Ported to mbed and optimised (WH)
+// 2013-07-12 - Minor comment fix and placeholder for SSD1306 (WH)
+// 2015-01-01 - Switch for optimised I2C calls to test on F401 (WH)
//
-/* ============================================
+/*
+================================================================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Andrew Schamp
-Copyright (c) 2012 WH (mbed port)
+Copyright (c) 2012,2013 WH (mbed port)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -35,7 +38,7 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-===============================================
+================================================================================
*/
#ifndef SSD1308_H
@@ -236,6 +239,10 @@
/** @brief fill the display
* @param uint8_t pattern fillpattern vertical patch or 8 bits
+ * @param uint8_t start_page begin page (0..MAX_PAGE)
+ * @param uint8_t end_page end page (start_page..MAX_PAGE)
+ * @param uint8_t start_col begin column (0..MAX_COL)
+ * @param uint8_t end_col end column (start_col..MAX_COL)
*/
void fillDisplay(uint8_t pattern = 0x00,
uint8_t start_page=0, uint8_t end_page=MAX_PAGE,
@@ -290,10 +297,8 @@
* @brief Start at selected cursor location, text will wrap around until it is done
* @param uint8_t row row number (0...ROWS/FONT_HEIGHT)
* @param uint8_t col column number (0...COLUMNS/FONT_WIDTH)
- * @param uint16_t len number of chars in text
* @param const char * text pointer to text
*/
-// void writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt);
void writeString(uint8_t row, uint8_t col, const char* txt);
// Stream implementation - provides printf() interface
SSD1308 OLED 128x64