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

Committer:
wim
Date:
Wed Jul 18 14:10:57 2012 +0000
Revision:
0:300d08d9b058
Child:
1:b7e8f5139026
First release of SSD1308 OLED driver (128x64, I2C interface)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:300d08d9b058 1 // SSD1308 I2C device class file
wim 0:300d08d9b058 2 // Based on Solomon Systech SSD1308 datasheet, rev. 1, 10/2008
wim 0:300d08d9b058 3 // The SSD1308 is used for example in the Seeed 128x64 OLED Display
wim 0:300d08d9b058 4 // http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167
wim 0:300d08d9b058 5 //
wim 0:300d08d9b058 6 // The original code by Andrew Schamp is using (and has been submitted as a part of) Jeff Rowberg's I2Cdevlib library,
wim 0:300d08d9b058 7 // which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
wim 0:300d08d9b058 8 // Some parts also mashed up from Graphic Library for driving monochrome displays based on the PCD8544,
wim 0:300d08d9b058 9 // Copyright (c) 2011, Wim De Roeve, who in turn did partial port of code found on
wim 0:300d08d9b058 10 // http://serdisplib.sourceforge.net/ser/pcd8544.html#links and by Petras Saduikis <petras@petras.co.uk>
wim 0:300d08d9b058 11 //
wim 0:300d08d9b058 12 // Changelog:
wim 0:300d08d9b058 13 // 2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
wim 0:300d08d9b058 14 // 2012-06-19 - Ported to mbed and optimised (WH)
wim 0:300d08d9b058 15 //
wim 0:300d08d9b058 16 /* ============================================
wim 0:300d08d9b058 17 I2Cdev device library code is placed under the MIT license
wim 0:300d08d9b058 18 Copyright (c) 2011 Andrew Schamp
wim 0:300d08d9b058 19 Copyright (c) 2012 WH (mbed port)
wim 0:300d08d9b058 20
wim 0:300d08d9b058 21 Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:300d08d9b058 22 of this software and associated documentation files (the "Software"), to deal
wim 0:300d08d9b058 23 in the Software without restriction, including without limitation the rights
wim 0:300d08d9b058 24 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:300d08d9b058 25 copies of the Software, and to permit persons to whom the Software is
wim 0:300d08d9b058 26 furnished to do so, subject to the following conditions:
wim 0:300d08d9b058 27
wim 0:300d08d9b058 28 The above copyright notice and this permission notice shall be included in
wim 0:300d08d9b058 29 all copies or substantial portions of the Software.
wim 0:300d08d9b058 30
wim 0:300d08d9b058 31 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:300d08d9b058 32 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:300d08d9b058 33 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:300d08d9b058 34 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:300d08d9b058 35 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:300d08d9b058 36 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:300d08d9b058 37 THE SOFTWARE.
wim 0:300d08d9b058 38 ===============================================
wim 0:300d08d9b058 39 */
wim 0:300d08d9b058 40 #include "mbed.h"
wim 0:300d08d9b058 41 #include "SSD1308.h"
wim 0:300d08d9b058 42
wim 0:300d08d9b058 43 //#define SSD1308_USE_FONT
wim 0:300d08d9b058 44 //#ifdef SSD1308_USE_FONT
wim 0:300d08d9b058 45
wim 0:300d08d9b058 46 //#include "font_3x5.h"
wim 0:300d08d9b058 47 //#include "font_5x7.h"
wim 0:300d08d9b058 48 //#include "font_6x8.h"
wim 0:300d08d9b058 49 #include "font_8x8.h"
wim 0:300d08d9b058 50 //#include "font_8x12.h"
wim 0:300d08d9b058 51 //#include "font_16x20.h"
wim 0:300d08d9b058 52 #include "font_16x24.h"
wim 0:300d08d9b058 53 //#endif
wim 0:300d08d9b058 54
wim 0:300d08d9b058 55 //@brief Constructor
wim 0:300d08d9b058 56 //@param I2C &i2c reference to i2c
wim 0:300d08d9b058 57 //@param uint8_t deviceAddress slaveaddress
wim 0:300d08d9b058 58 //
wim 0:300d08d9b058 59 SSD1308::SSD1308(I2C &i2c, uint8_t deviceAddress) : _i2c(i2c) {
wim 0:300d08d9b058 60 // m_devAddr = deviceAddress;
wim 0:300d08d9b058 61
wim 0:300d08d9b058 62 _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
wim 0:300d08d9b058 63 _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read
wim 0:300d08d9b058 64
wim 0:300d08d9b058 65 initialize();
wim 0:300d08d9b058 66 }
wim 0:300d08d9b058 67
wim 0:300d08d9b058 68 // @brief High level Init, most settings remain at Power-On reset value
wim 0:300d08d9b058 69 //
wim 0:300d08d9b058 70 void SSD1308::initialize() {
wim 0:300d08d9b058 71 setHorizontalAddressingMode();
wim 0:300d08d9b058 72
wim 0:300d08d9b058 73 clearDisplay();
wim 0:300d08d9b058 74
wim 0:300d08d9b058 75 setInverted(false);
wim 0:300d08d9b058 76
wim 0:300d08d9b058 77 setDisplayOn();
wim 0:300d08d9b058 78 }
wim 0:300d08d9b058 79
wim 0:300d08d9b058 80
wim 0:300d08d9b058 81 // @brief clear the display
wim 0:300d08d9b058 82 //
wim 0:300d08d9b058 83 #if(0)
wim 0:300d08d9b058 84 // Standard version
wim 0:300d08d9b058 85 void SSD1308::clearDisplay() {
wim 0:300d08d9b058 86
wim 0:300d08d9b058 87 //setDisplayOff();
wim 0:300d08d9b058 88 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 89 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 90
wim 0:300d08d9b058 91 for (uint8_t page = 0; page < PAGES; page++) {
wim 0:300d08d9b058 92 for (uint8_t col = 0; col < COLUMNS; col++) {
wim 0:300d08d9b058 93 _sendData(0x00);
wim 0:300d08d9b058 94 }
wim 0:300d08d9b058 95 }
wim 0:300d08d9b058 96
wim 0:300d08d9b058 97 //setDisplayOn();
wim 0:300d08d9b058 98 }
wim 0:300d08d9b058 99 #else
wim 0:300d08d9b058 100 //Optimised version
wim 0:300d08d9b058 101 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 102 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 103 //
wim 0:300d08d9b058 104 void SSD1308::clearDisplay() {
wim 0:300d08d9b058 105
wim 0:300d08d9b058 106 //setDisplayOff();
wim 0:300d08d9b058 107
wim 0:300d08d9b058 108 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 109 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 110
wim 0:300d08d9b058 111 _i2c.start();
wim 0:300d08d9b058 112 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 113 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 114 for (int i=0; i<(PAGES * COLUMNS); i++) {
wim 0:300d08d9b058 115 _i2c.write(0x00); // Write Data
wim 0:300d08d9b058 116 }
wim 0:300d08d9b058 117 _i2c.stop();
wim 0:300d08d9b058 118
wim 0:300d08d9b058 119 //setDisplayOn();
wim 0:300d08d9b058 120 }
wim 0:300d08d9b058 121 #endif
wim 0:300d08d9b058 122
wim 0:300d08d9b058 123
wim 0:300d08d9b058 124 // @brief fill the display
wim 0:300d08d9b058 125 // @param uint8_t pattern fillpattern vertical patch or 8 bits
wim 0:300d08d9b058 126 //
wim 0:300d08d9b058 127 #if(0)
wim 0:300d08d9b058 128 //Standard version
wim 0:300d08d9b058 129 void SSD1308::fillDisplay(uint8_t pattern) {
wim 0:300d08d9b058 130
wim 0:300d08d9b058 131 //setDisplayOff();
wim 0:300d08d9b058 132
wim 0:300d08d9b058 133 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 134 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 135
wim 0:300d08d9b058 136 for (uint8_t page = 0; page < PAGES; page++) {
wim 0:300d08d9b058 137 for (uint8_t col = 0; col < COLUMNS; col++) {
wim 0:300d08d9b058 138 _sendData(pattern);
wim 0:300d08d9b058 139 }
wim 0:300d08d9b058 140 }
wim 0:300d08d9b058 141
wim 0:300d08d9b058 142 //setDisplayOn();
wim 0:300d08d9b058 143 }
wim 0:300d08d9b058 144 #else
wim 0:300d08d9b058 145
wim 0:300d08d9b058 146 //Optimised version
wim 0:300d08d9b058 147 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 148 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 149 //
wim 0:300d08d9b058 150 void SSD1308::fillDisplay(uint8_t pattern,
wim 0:300d08d9b058 151 uint8_t start_page, uint8_t end_page,
wim 0:300d08d9b058 152 uint8_t start_col, uint8_t end_col) {
wim 0:300d08d9b058 153
wim 0:300d08d9b058 154 int count = (end_page - start_page + 1) * (end_col - start_col + 1);
wim 0:300d08d9b058 155
wim 0:300d08d9b058 156 //setDisplayOff();
wim 0:300d08d9b058 157 setPageAddress(start_page, end_page); // set page window
wim 0:300d08d9b058 158 setColumnAddress(start_col, end_col); // set column window
wim 0:300d08d9b058 159
wim 0:300d08d9b058 160 _i2c.start();
wim 0:300d08d9b058 161 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 162 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 163 for (int i=0; i<count; i++) {
wim 0:300d08d9b058 164 _i2c.write(pattern); // Write Data
wim 0:300d08d9b058 165 }
wim 0:300d08d9b058 166 _i2c.stop();
wim 0:300d08d9b058 167
wim 0:300d08d9b058 168 //setDisplayOn();
wim 0:300d08d9b058 169 }
wim 0:300d08d9b058 170
wim 0:300d08d9b058 171 #endif
wim 0:300d08d9b058 172
wim 0:300d08d9b058 173
wim 0:300d08d9b058 174 // @brief write a bitmap to the display
wim 0:300d08d9b058 175 // @param uint8_t* data pointer to bitmap
wim 0:300d08d9b058 176 // @param uint8_t start_page begin page (0..MAX_PAGE)
wim 0:300d08d9b058 177 // @param uint8_t end_page end page (start_page..MAX_PAGE)
wim 0:300d08d9b058 178 // @param uint8_t start_col begin column (0..MAX_COL)
wim 0:300d08d9b058 179 // @param uint8_t end_col end column (start_col..MAX_COL)
wim 0:300d08d9b058 180 //
wim 0:300d08d9b058 181 #if(0)
wim 0:300d08d9b058 182 //Standard version
wim 0:300d08d9b058 183 void SSD1308::writeBitmap(int len, uint8_t* data) {
wim 0:300d08d9b058 184
wim 0:300d08d9b058 185 //setDisplayOff();
wim 0:300d08d9b058 186 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 187 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 188
wim 0:300d08d9b058 189 _i2c.start();
wim 0:300d08d9b058 190 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 191 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 192 for (int i=0; i<len; i++) {
wim 0:300d08d9b058 193 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 194 }
wim 0:300d08d9b058 195 _i2c.stop();
wim 0:300d08d9b058 196
wim 0:300d08d9b058 197 //setDisplayOn();
wim 0:300d08d9b058 198 }
wim 0:300d08d9b058 199 #else
wim 0:300d08d9b058 200
wim 0:300d08d9b058 201 //Optimised version
wim 0:300d08d9b058 202 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 203 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 204 //
wim 0:300d08d9b058 205 void SSD1308::writeBitmap(uint8_t* data,
wim 0:300d08d9b058 206 uint8_t start_page, uint8_t end_page,
wim 0:300d08d9b058 207 uint8_t start_col, uint8_t end_col){
wim 0:300d08d9b058 208
wim 0:300d08d9b058 209 int count = (end_page - start_page + 1) * (end_col - start_col + 1);
wim 0:300d08d9b058 210
wim 0:300d08d9b058 211 //setDisplayOff();
wim 0:300d08d9b058 212 setPageAddress(start_page, end_page); // set page window
wim 0:300d08d9b058 213 setColumnAddress(start_col, end_col); // set column window
wim 0:300d08d9b058 214
wim 0:300d08d9b058 215 _i2c.start();
wim 0:300d08d9b058 216 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 217 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 218 for (int i=0; i<count; i++) {
wim 0:300d08d9b058 219 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 220 }
wim 0:300d08d9b058 221 _i2c.stop();
wim 0:300d08d9b058 222
wim 0:300d08d9b058 223 //setDisplayOn();
wim 0:300d08d9b058 224 }
wim 0:300d08d9b058 225 #endif
wim 0:300d08d9b058 226
wim 0:300d08d9b058 227
wim 0:300d08d9b058 228 // @brief Write single character to the display using the 8x8 fontable
wim 0:300d08d9b058 229 // @brief Start at current cursor location
wim 0:300d08d9b058 230 // @param char chr character to write
wim 0:300d08d9b058 231 //
wim 0:300d08d9b058 232 void SSD1308::writeChar(char chr) {
wim 0:300d08d9b058 233
wim 0:300d08d9b058 234 const uint8_t char_index = chr - 0x20;
wim 0:300d08d9b058 235
wim 0:300d08d9b058 236 for (uint8_t i = 0; i < 8; i++) {
wim 0:300d08d9b058 237 if (_inverted) {
wim 0:300d08d9b058 238 _sendData( ~font_8x8[char_index][i] );
wim 0:300d08d9b058 239 }
wim 0:300d08d9b058 240 else {
wim 0:300d08d9b058 241 _sendData( font_8x8[char_index][i] );
wim 0:300d08d9b058 242 }
wim 0:300d08d9b058 243 }
wim 0:300d08d9b058 244
wim 0:300d08d9b058 245 }
wim 0:300d08d9b058 246
wim 0:300d08d9b058 247
wim 0:300d08d9b058 248 // @brief Write a string to the display using the 8x8 font
wim 0:300d08d9b058 249 // @brief Start at selected cursor location
wim 0:300d08d9b058 250 // @param uint8_t row row number (0...ROWS/FONT_HEIGHT)
wim 0:300d08d9b058 251 // @param uint8_t col column number (0...COLUMNS/FONT_WIDTH)
wim 0:300d08d9b058 252 // @param uint16_t len number of chars in text
wim 0:300d08d9b058 253 // @param const char * text pointer to text
wim 0:300d08d9b058 254 //
wim 0:300d08d9b058 255 void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text) {
wim 0:300d08d9b058 256 uint16_t index = 0;
wim 0:300d08d9b058 257 setPageAddress(row, MAX_PAGE);
wim 0:300d08d9b058 258 const uint8_t col_addr = FONT8x8_WIDTH*col;
wim 0:300d08d9b058 259 setColumnAddress(col_addr, MAX_COL);
wim 0:300d08d9b058 260
wim 0:300d08d9b058 261 while ((col+index) < CHARS && (index < len)) {
wim 0:300d08d9b058 262 // write first line, starting at given position
wim 0:300d08d9b058 263 writeChar(text[index++]);
wim 0:300d08d9b058 264 }
wim 0:300d08d9b058 265
wim 0:300d08d9b058 266 // write remaining lines
wim 0:300d08d9b058 267 // write until the end of memory
wim 0:300d08d9b058 268 // then wrap around again from the top.
wim 0:300d08d9b058 269 if (index + 1 < len) {
wim 0:300d08d9b058 270 setPageAddress(row + 1, MAX_PAGE);
wim 0:300d08d9b058 271 setColumnAddress(0, MAX_COL);
wim 0:300d08d9b058 272 bool wrapEntireScreen = false;
wim 0:300d08d9b058 273 while (index + 1 < len) {
wim 0:300d08d9b058 274 writeChar(text[index++]);
wim 0:300d08d9b058 275 // if we've written the last character space on the screen,
wim 0:300d08d9b058 276 // reset the page and column address so that it wraps around from the top again
wim 0:300d08d9b058 277 if (!wrapEntireScreen && (row*CHARS + col + index) > 127) {
wim 0:300d08d9b058 278 setPageAddress(0, MAX_PAGE);
wim 0:300d08d9b058 279 setColumnAddress(0, MAX_COL);
wim 0:300d08d9b058 280 wrapEntireScreen = true;
wim 0:300d08d9b058 281 }
wim 0:300d08d9b058 282 }
wim 0:300d08d9b058 283 }
wim 0:300d08d9b058 284 }
wim 0:300d08d9b058 285
wim 0:300d08d9b058 286
wim 0:300d08d9b058 287
wim 0:300d08d9b058 288 // @brief Write large character (16x24 font)
wim 0:300d08d9b058 289 // @param uint8_t row row number (0...MAX_ROW)
wim 0:300d08d9b058 290 // @param uint8_t col column number (0...MAX_COL)
wim 0:300d08d9b058 291 // @param char chr Used for displaying numbers 0 - 9 and '+', '-', '.'
wim 0:300d08d9b058 292 //
wim 0:300d08d9b058 293 void SSD1308::writeBigChar(uint8_t row, uint8_t col, char chr) {
wim 0:300d08d9b058 294
wim 0:300d08d9b058 295 writeBitmap((uint8_t*) font_16x24[int(chr) - FONT16x24_START],
wim 0:300d08d9b058 296 row, (row + FONT16x24_BYTES - 1),
wim 0:300d08d9b058 297 col, (col + FONT16x24_WIDTH - 1));
wim 0:300d08d9b058 298 }
wim 0:300d08d9b058 299
wim 0:300d08d9b058 300
wim 0:300d08d9b058 301 // @brief Write command that has no parameters
wim 0:300d08d9b058 302 //
wim 0:300d08d9b058 303 void SSD1308::_sendCommand(uint8_t command) {
wim 0:300d08d9b058 304 // I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command);
wim 0:300d08d9b058 305
wim 0:300d08d9b058 306 #if(0)
wim 0:300d08d9b058 307 char databytes[2];
wim 0:300d08d9b058 308
wim 0:300d08d9b058 309 databytes[0] = COMMAND_MODE;
wim 0:300d08d9b058 310 databytes[1] = command;
wim 0:300d08d9b058 311 _i2c.write(_writeOpcode, databytes, 2); // Write command
wim 0:300d08d9b058 312 #endif
wim 0:300d08d9b058 313
wim 0:300d08d9b058 314 _i2c.start();
wim 0:300d08d9b058 315 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 316
wim 0:300d08d9b058 317 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 318 _i2c.write(command); // Write Command
wim 0:300d08d9b058 319
wim 0:300d08d9b058 320 _i2c.stop();
wim 0:300d08d9b058 321
wim 0:300d08d9b058 322 }
wim 0:300d08d9b058 323
wim 0:300d08d9b058 324 // @brief Write command that has one parameter
wim 0:300d08d9b058 325 //
wim 0:300d08d9b058 326 void SSD1308::_sendCommand(uint8_t command, uint8_t param1) {
wim 0:300d08d9b058 327
wim 0:300d08d9b058 328 // Note continuationbit is set, so COMMAND_MODE must be
wim 0:300d08d9b058 329 // repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 330
wim 0:300d08d9b058 331 _i2c.start();
wim 0:300d08d9b058 332 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 333
wim 0:300d08d9b058 334 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 335 _i2c.write(command); // Write Command
wim 0:300d08d9b058 336 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 337 _i2c.write(param1); // Write Param1
wim 0:300d08d9b058 338
wim 0:300d08d9b058 339 _i2c.stop();
wim 0:300d08d9b058 340
wim 0:300d08d9b058 341 }
wim 0:300d08d9b058 342
wim 0:300d08d9b058 343 // @brief Write command that has two parameters
wim 0:300d08d9b058 344 //
wim 0:300d08d9b058 345 void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2) {
wim 0:300d08d9b058 346
wim 0:300d08d9b058 347 // Note continuationbit is set, so COMMAND_MODE must be
wim 0:300d08d9b058 348 // repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 349
wim 0:300d08d9b058 350 _i2c.start();
wim 0:300d08d9b058 351 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 352
wim 0:300d08d9b058 353 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 354 _i2c.write(command); // Write Command
wim 0:300d08d9b058 355 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 356 _i2c.write(param1); // Write Param1
wim 0:300d08d9b058 357 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 358 _i2c.write(param2); // Write Param2
wim 0:300d08d9b058 359
wim 0:300d08d9b058 360 _i2c.stop();
wim 0:300d08d9b058 361
wim 0:300d08d9b058 362 }
wim 0:300d08d9b058 363
wim 0:300d08d9b058 364 #if(0)
wim 0:300d08d9b058 365 // @brief Write command that has multiple parameters
wim 0:300d08d9b058 366 //
wim 0:300d08d9b058 367 void SSD1308::_sendCommands(uint8_t len, uint8_t* commands) {
wim 0:300d08d9b058 368
wim 0:300d08d9b058 369 // I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
wim 0:300d08d9b058 370 // Note this original code is not correct, continuationbit is set,
wim 0:300d08d9b058 371 // so COMMAND_MODE must be repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 372
wim 0:300d08d9b058 373 _i2c.start();
wim 0:300d08d9b058 374 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 375
wim 0:300d08d9b058 376 for (int i=0; i<len ; i++) {
wim 0:300d08d9b058 377 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 378 _i2c.write(commands[i]); // Write Commands
wim 0:300d08d9b058 379 }
wim 0:300d08d9b058 380 _i2c.stop();
wim 0:300d08d9b058 381
wim 0:300d08d9b058 382 }
wim 0:300d08d9b058 383 #endif
wim 0:300d08d9b058 384
wim 0:300d08d9b058 385 // @brief Write databyte to display
wim 0:300d08d9b058 386 // @brief Start at current cursor location
wim 0:300d08d9b058 387 // @param uint8_t data databyte to write
wim 0:300d08d9b058 388 //
wim 0:300d08d9b058 389 void SSD1308::_sendData(uint8_t data){
wim 0:300d08d9b058 390 // I2Cdev::writeByte(m_devAddr, DATA_MODE, data);
wim 0:300d08d9b058 391
wim 0:300d08d9b058 392 char databytes[2];
wim 0:300d08d9b058 393
wim 0:300d08d9b058 394 databytes[0] = DATA_MODE;
wim 0:300d08d9b058 395 databytes[1] = data;
wim 0:300d08d9b058 396 _i2c.write(_writeOpcode, databytes, 2); // Write Data
wim 0:300d08d9b058 397
wim 0:300d08d9b058 398 }
wim 0:300d08d9b058 399
wim 0:300d08d9b058 400 // @brief Write len bytes from buffer data to display,
wim 0:300d08d9b058 401 // @brief Start at current cursor location
wim 0:300d08d9b058 402 // @param uint8_t len number of bytes to write
wim 0:300d08d9b058 403 // @param uint8_t* data pointer to data
wim 0:300d08d9b058 404 //
wim 0:300d08d9b058 405 void SSD1308::_sendData(uint8_t len, uint8_t* data) {
wim 0:300d08d9b058 406 // I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
wim 0:300d08d9b058 407
wim 0:300d08d9b058 408 _i2c.start();
wim 0:300d08d9b058 409 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 410 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 411 for (int i=0; i<len ; i++) {
wim 0:300d08d9b058 412 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 413 }
wim 0:300d08d9b058 414 _i2c.stop();
wim 0:300d08d9b058 415
wim 0:300d08d9b058 416 }
wim 0:300d08d9b058 417
wim 0:300d08d9b058 418
wim 0:300d08d9b058 419
wim 0:300d08d9b058 420 void SSD1308::setHorizontalAddressingMode(){
wim 0:300d08d9b058 421 setMemoryAddressingMode(HORIZONTAL_ADDRESSING_MODE);
wim 0:300d08d9b058 422 }
wim 0:300d08d9b058 423
wim 0:300d08d9b058 424 void SSD1308::setVerticalAddressingMode() {
wim 0:300d08d9b058 425 setMemoryAddressingMode(VERTICAL_ADDRESSING_MODE);
wim 0:300d08d9b058 426 }
wim 0:300d08d9b058 427
wim 0:300d08d9b058 428 void SSD1308::setPageAddressingMode(){
wim 0:300d08d9b058 429 setMemoryAddressingMode(PAGE_ADDRESSING_MODE);
wim 0:300d08d9b058 430 }
wim 0:300d08d9b058 431
wim 0:300d08d9b058 432 void SSD1308::setMemoryAddressingMode(uint8_t mode){
wim 0:300d08d9b058 433
wim 0:300d08d9b058 434 _sendCommand(SET_MEMORY_ADDRESSING_MODE, mode);
wim 0:300d08d9b058 435 }
wim 0:300d08d9b058 436
wim 0:300d08d9b058 437
wim 0:300d08d9b058 438 // @param uint8_t start startpage (valid range 0..MAX_PAGE)
wim 0:300d08d9b058 439 // @param uint8_t end endpage (valid range start..MAX_PAGE)
wim 0:300d08d9b058 440 //
wim 0:300d08d9b058 441 void SSD1308::setPageAddress(uint8_t start, uint8_t end) {
wim 0:300d08d9b058 442
wim 0:300d08d9b058 443 _sendCommand(SET_PAGE_ADDRESS, start, end);
wim 0:300d08d9b058 444 }
wim 0:300d08d9b058 445
wim 0:300d08d9b058 446
wim 0:300d08d9b058 447 // @param uint8_t start startcolumn (valid range 0..MAX_COL)
wim 0:300d08d9b058 448 // @param uint8_t end endcolumn (valid range start..MAX_COL)
wim 0:300d08d9b058 449 //
wim 0:300d08d9b058 450 void SSD1308::setColumnAddress(uint8_t start, uint8_t end) {
wim 0:300d08d9b058 451
wim 0:300d08d9b058 452 _sendCommand(SET_COLUMN_ADDRESS, start, end);
wim 0:300d08d9b058 453 }
wim 0:300d08d9b058 454
wim 0:300d08d9b058 455 // @brief Set Contrast
wim 0:300d08d9b058 456 // @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
wim 0:300d08d9b058 457 void SSD1308::setContrastControl(uint8_t contrast) {
wim 0:300d08d9b058 458
wim 0:300d08d9b058 459 _sendCommand(SET_CONTRAST, contrast);
wim 0:300d08d9b058 460 }
wim 0:300d08d9b058 461
wim 0:300d08d9b058 462 // @brief Enable Display
wim 0:300d08d9b058 463 //
wim 0:300d08d9b058 464 void SSD1308::setDisplayOn() {
wim 0:300d08d9b058 465 _sendCommand(SET_DISPLAY_POWER_ON);
wim 0:300d08d9b058 466 }
wim 0:300d08d9b058 467
wim 0:300d08d9b058 468 // @brief Disable Display
wim 0:300d08d9b058 469 //
wim 0:300d08d9b058 470 void SSD1308::setDisplayOff() {
wim 0:300d08d9b058 471 _sendCommand(SET_DISPLAY_POWER_OFF);
wim 0:300d08d9b058 472 }
wim 0:300d08d9b058 473
wim 0:300d08d9b058 474 // @brief Enable or Disable Display
wim 0:300d08d9b058 475 // @param bool on
wim 0:300d08d9b058 476 void SSD1308::setDisplayPower(bool on) {
wim 0:300d08d9b058 477 if (on) {
wim 0:300d08d9b058 478 setDisplayOn();
wim 0:300d08d9b058 479 } else {
wim 0:300d08d9b058 480 setDisplayOff();
wim 0:300d08d9b058 481 }
wim 0:300d08d9b058 482 }
wim 0:300d08d9b058 483
wim 0:300d08d9b058 484 // @brief White pixels on Black background
wim 0:300d08d9b058 485 //
wim 0:300d08d9b058 486 void SSD1308::setDisplayNormal() {
wim 0:300d08d9b058 487 _sendCommand(SET_NORMAL_DISPLAY);
wim 0:300d08d9b058 488 }
wim 0:300d08d9b058 489
wim 0:300d08d9b058 490 // @brief Black pixels on White background
wim 0:300d08d9b058 491 //
wim 0:300d08d9b058 492 void SSD1308::setDisplayInverse() {
wim 0:300d08d9b058 493 _sendCommand(SET_INVERSE_DISPLAY);
wim 0:300d08d9b058 494 }
wim 0:300d08d9b058 495
wim 0:300d08d9b058 496 // @brief Blink display by fading in and out over a set number of frames
wim 0:300d08d9b058 497 // @param bool on
wim 0:300d08d9b058 498 //
wim 0:300d08d9b058 499 void SSD1308::setDisplayBlink(bool on){
wim 0:300d08d9b058 500 if (on) {
wim 0:300d08d9b058 501 _sendCommand(SET_FADE_BLINK, (BLINK_ENABLE | FADE_INTERVAL_128_FRAMES));
wim 0:300d08d9b058 502 }
wim 0:300d08d9b058 503 else {
wim 0:300d08d9b058 504 _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
wim 0:300d08d9b058 505 }
wim 0:300d08d9b058 506 }
wim 0:300d08d9b058 507
wim 0:300d08d9b058 508
wim 0:300d08d9b058 509 // @brief Fade out display in set number of frames
wim 0:300d08d9b058 510 // @param bool on
wim 0:300d08d9b058 511 //
wim 0:300d08d9b058 512 void SSD1308::setDisplayFade(bool on) {
wim 0:300d08d9b058 513 if (on) {
wim 0:300d08d9b058 514 _sendCommand(SET_FADE_BLINK, (FADE_OUT_ENABLE | FADE_INTERVAL_128_FRAMES));
wim 0:300d08d9b058 515 }
wim 0:300d08d9b058 516 else {
wim 0:300d08d9b058 517 _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
wim 0:300d08d9b058 518 }
wim 0:300d08d9b058 519 }
wim 0:300d08d9b058 520
wim 0:300d08d9b058 521 // @brief Display Flip (Left/Right, Up/Down)
wim 0:300d08d9b058 522 // @param bool left flip Left/Right
wim 0:300d08d9b058 523 // @param bool down flip Up/Down
wim 0:300d08d9b058 524 //
wim 0:300d08d9b058 525 void SSD1308::setDisplayFlip(bool left, bool down) {
wim 0:300d08d9b058 526 if (left) {
wim 0:300d08d9b058 527 // column address 0 is mapped to SEG0 (Reset)
wim 0:300d08d9b058 528 _sendCommand(SET_SEGMENT_REMAP_0);
wim 0:300d08d9b058 529 }
wim 0:300d08d9b058 530 else {
wim 0:300d08d9b058 531 // column address 127 is mapped to SEG0
wim 0:300d08d9b058 532 _sendCommand(SET_SEGMENT_REMAP_127);
wim 0:300d08d9b058 533 }
wim 0:300d08d9b058 534
wim 0:300d08d9b058 535 if (down) {
wim 0:300d08d9b058 536 // Reset mode
wim 0:300d08d9b058 537 _sendCommand(SET_COMMON_REMAP_0);
wim 0:300d08d9b058 538 }
wim 0:300d08d9b058 539 else {
wim 0:300d08d9b058 540 // Flip Up/Down (Need to rewrite display before H effect shows)
wim 0:300d08d9b058 541 _sendCommand(SET_COMMON_REMAP_63);
wim 0:300d08d9b058 542 }
wim 0:300d08d9b058 543
wim 0:300d08d9b058 544 }
wim 0:300d08d9b058 545
wim 0:300d08d9b058 546 // @brief Sets Internal Iref
wim 0:300d08d9b058 547 //
wim 0:300d08d9b058 548 void SSD1308::setInternalIref() {
wim 0:300d08d9b058 549 // uint8_t cmds[2] = {SET_IREF_SELECTION, INTERNAL_IREF};
wim 0:300d08d9b058 550 // _sendCommands(2, cmds);
wim 0:300d08d9b058 551
wim 0:300d08d9b058 552 _sendCommand(SET_IREF_SELECTION, INTERNAL_IREF);
wim 0:300d08d9b058 553 }
wim 0:300d08d9b058 554
wim 0:300d08d9b058 555 // @brief Sets External Iref (default)
wim 0:300d08d9b058 556 //
wim 0:300d08d9b058 557 void SSD1308::setExternalIref() {
wim 0:300d08d9b058 558 // uint8_t cmds[2] = {SET_IREF_SELECTION, EXTERNAL_IREF};
wim 0:300d08d9b058 559 // _sendCommands(2, cmds);
wim 0:300d08d9b058 560 _sendCommand(SET_IREF_SELECTION, EXTERNAL_IREF);
wim 0:300d08d9b058 561 }
wim 0:300d08d9b058 562
wim 0:300d08d9b058 563
wim 0:300d08d9b058 564 // @brief Low level Init
wim 0:300d08d9b058 565 // @brief Init the configuration registers in accordance with the datasheet
wim 0:300d08d9b058 566 //
wim 0:300d08d9b058 567 void SSD1308::_init() {
wim 0:300d08d9b058 568
wim 0:300d08d9b058 569 //not complete yet
wim 0:300d08d9b058 570 _sendCommand(SET_DISPLAY_POWER_OFF);
wim 0:300d08d9b058 571
wim 0:300d08d9b058 572 // column address 0 is mapped to SEG0 (Reset)
wim 0:300d08d9b058 573 // row address 0 is mapped to COMM0 (Reset)
wim 0:300d08d9b058 574 _sendCommand(SET_SEGMENT_REMAP_0);
wim 0:300d08d9b058 575 _sendCommand(SET_COMMON_REMAP_0);
wim 0:300d08d9b058 576
wim 0:300d08d9b058 577 _sendCommand(SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL);
wim 0:300d08d9b058 578
wim 0:300d08d9b058 579 setHorizontalAddressingMode(); // (Non-Reset)
wim 0:300d08d9b058 580
wim 0:300d08d9b058 581 setExternalIref(); // (Reset)
wim 0:300d08d9b058 582
wim 0:300d08d9b058 583 _sendCommand(SET_CONTRAST, 0x7F); // (Reset)
wim 0:300d08d9b058 584
wim 0:300d08d9b058 585 _sendCommand(SET_NORMAL_DISPLAY);
wim 0:300d08d9b058 586
wim 0:300d08d9b058 587 clearDisplay();
wim 0:300d08d9b058 588
wim 0:300d08d9b058 589 _sendCommand(SET_DISPLAY_POWER_ON);
wim 0:300d08d9b058 590 }
wim 0:300d08d9b058 591