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:
Mon Jul 23 20:03:18 2012 +0000
Revision:
2:16c84a134393
Parent:
1:b7e8f5139026
Child:
4:df92b0c0cb92
Updated methods

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 1:b7e8f5139026 1 /** @file SSD1308 I2C device class file
wim 1:b7e8f5139026 2 * Based on Solomon Systech SSD1308 datasheet, rev. 1, 10/2008
wim 1:b7e8f5139026 3 * The SSD1308 is used for example in the Seeed 128x64 OLED Display
wim 1:b7e8f5139026 4 * http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167
wim 1:b7e8f5139026 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 1:b7e8f5139026 16 /*
wim 1:b7e8f5139026 17 ================================================================================
wim 0:300d08d9b058 18 I2Cdev device library code is placed under the MIT license
wim 0:300d08d9b058 19 Copyright (c) 2011 Andrew Schamp
wim 0:300d08d9b058 20 Copyright (c) 2012 WH (mbed port)
wim 0:300d08d9b058 21
wim 0:300d08d9b058 22 Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:300d08d9b058 23 of this software and associated documentation files (the "Software"), to deal
wim 0:300d08d9b058 24 in the Software without restriction, including without limitation the rights
wim 0:300d08d9b058 25 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:300d08d9b058 26 copies of the Software, and to permit persons to whom the Software is
wim 0:300d08d9b058 27 furnished to do so, subject to the following conditions:
wim 0:300d08d9b058 28
wim 0:300d08d9b058 29 The above copyright notice and this permission notice shall be included in
wim 0:300d08d9b058 30 all copies or substantial portions of the Software.
wim 0:300d08d9b058 31
wim 0:300d08d9b058 32 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:300d08d9b058 33 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:300d08d9b058 34 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:300d08d9b058 35 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:300d08d9b058 36 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:300d08d9b058 37 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:300d08d9b058 38 THE SOFTWARE.
wim 1:b7e8f5139026 39 ================================================================================
wim 0:300d08d9b058 40 */
wim 0:300d08d9b058 41 #include "mbed.h"
wim 0:300d08d9b058 42 #include "SSD1308.h"
wim 0:300d08d9b058 43
wim 0:300d08d9b058 44 //#include "font_3x5.h"
wim 0:300d08d9b058 45 //#include "font_5x7.h"
wim 0:300d08d9b058 46 //#include "font_6x8.h"
wim 0:300d08d9b058 47 #include "font_8x8.h"
wim 0:300d08d9b058 48 //#include "font_8x12.h"
wim 0:300d08d9b058 49 //#include "font_16x20.h"
wim 0:300d08d9b058 50 #include "font_16x24.h"
wim 0:300d08d9b058 51
wim 1:b7e8f5139026 52 /**
wim 1:b7e8f5139026 53 *@brief Constructor
wim 1:b7e8f5139026 54 *@param I2C &i2c reference to i2c
wim 1:b7e8f5139026 55 *@param uint8_t deviceAddress slaveaddress
wim 1:b7e8f5139026 56 */
wim 0:300d08d9b058 57 SSD1308::SSD1308(I2C &i2c, uint8_t deviceAddress) : _i2c(i2c) {
wim 0:300d08d9b058 58
wim 0:300d08d9b058 59 _writeOpcode = deviceAddress & 0xFE; // low order bit = 0 for write
wim 0:300d08d9b058 60 _readOpcode = deviceAddress | 0x01; // low order bit = 1 for read
wim 0:300d08d9b058 61
wim 0:300d08d9b058 62 initialize();
wim 0:300d08d9b058 63 }
wim 0:300d08d9b058 64
wim 1:b7e8f5139026 65 /** @brief High level Init, most settings remain at Power-On reset value
wim 1:b7e8f5139026 66 */
wim 0:300d08d9b058 67 void SSD1308::initialize() {
wim 0:300d08d9b058 68 setHorizontalAddressingMode();
wim 0:300d08d9b058 69
wim 0:300d08d9b058 70 clearDisplay();
wim 0:300d08d9b058 71
wim 0:300d08d9b058 72 setInverted(false);
wim 0:300d08d9b058 73
wim 0:300d08d9b058 74 setDisplayOn();
wim 0:300d08d9b058 75 }
wim 0:300d08d9b058 76
wim 0:300d08d9b058 77
wim 1:b7e8f5139026 78 /** @brief clear the display
wim 1:b7e8f5139026 79 */
wim 0:300d08d9b058 80 #if(0)
wim 0:300d08d9b058 81 // Standard version
wim 0:300d08d9b058 82 void SSD1308::clearDisplay() {
wim 0:300d08d9b058 83
wim 0:300d08d9b058 84 //setDisplayOff();
wim 0:300d08d9b058 85 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 86 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 87
wim 0:300d08d9b058 88 for (uint8_t page = 0; page < PAGES; page++) {
wim 0:300d08d9b058 89 for (uint8_t col = 0; col < COLUMNS; col++) {
wim 0:300d08d9b058 90 _sendData(0x00);
wim 0:300d08d9b058 91 }
wim 0:300d08d9b058 92 }
wim 0:300d08d9b058 93
wim 0:300d08d9b058 94 //setDisplayOn();
wim 0:300d08d9b058 95 }
wim 0:300d08d9b058 96 #else
wim 0:300d08d9b058 97 //Optimised version
wim 0:300d08d9b058 98 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 99 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 100 //
wim 0:300d08d9b058 101 void SSD1308::clearDisplay() {
wim 0:300d08d9b058 102
wim 0:300d08d9b058 103 //setDisplayOff();
wim 0:300d08d9b058 104
wim 0:300d08d9b058 105 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 106 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 107
wim 0:300d08d9b058 108 _i2c.start();
wim 0:300d08d9b058 109 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 110 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 111 for (int i=0; i<(PAGES * COLUMNS); i++) {
wim 0:300d08d9b058 112 _i2c.write(0x00); // Write Data
wim 0:300d08d9b058 113 }
wim 0:300d08d9b058 114 _i2c.stop();
wim 0:300d08d9b058 115
wim 0:300d08d9b058 116 //setDisplayOn();
wim 0:300d08d9b058 117 }
wim 0:300d08d9b058 118 #endif
wim 0:300d08d9b058 119
wim 0:300d08d9b058 120
wim 1:b7e8f5139026 121 /** @brief fill the display
wim 1:b7e8f5139026 122 * @param uint8_t pattern fillpattern vertical patch or 8 bits
wim 1:b7e8f5139026 123 */
wim 0:300d08d9b058 124 #if(0)
wim 0:300d08d9b058 125 //Standard version
wim 0:300d08d9b058 126 void SSD1308::fillDisplay(uint8_t pattern) {
wim 0:300d08d9b058 127
wim 0:300d08d9b058 128 //setDisplayOff();
wim 0:300d08d9b058 129
wim 0:300d08d9b058 130 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 131 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 132
wim 0:300d08d9b058 133 for (uint8_t page = 0; page < PAGES; page++) {
wim 0:300d08d9b058 134 for (uint8_t col = 0; col < COLUMNS; col++) {
wim 0:300d08d9b058 135 _sendData(pattern);
wim 0:300d08d9b058 136 }
wim 0:300d08d9b058 137 }
wim 0:300d08d9b058 138
wim 0:300d08d9b058 139 //setDisplayOn();
wim 0:300d08d9b058 140 }
wim 0:300d08d9b058 141 #else
wim 0:300d08d9b058 142
wim 0:300d08d9b058 143 //Optimised version
wim 0:300d08d9b058 144 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 145 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 146 //
wim 0:300d08d9b058 147 void SSD1308::fillDisplay(uint8_t pattern,
wim 0:300d08d9b058 148 uint8_t start_page, uint8_t end_page,
wim 0:300d08d9b058 149 uint8_t start_col, uint8_t end_col) {
wim 0:300d08d9b058 150
wim 0:300d08d9b058 151 int count = (end_page - start_page + 1) * (end_col - start_col + 1);
wim 0:300d08d9b058 152
wim 0:300d08d9b058 153 //setDisplayOff();
wim 0:300d08d9b058 154 setPageAddress(start_page, end_page); // set page window
wim 0:300d08d9b058 155 setColumnAddress(start_col, end_col); // set column window
wim 0:300d08d9b058 156
wim 0:300d08d9b058 157 _i2c.start();
wim 0:300d08d9b058 158 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 159 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 160 for (int i=0; i<count; i++) {
wim 0:300d08d9b058 161 _i2c.write(pattern); // Write Data
wim 0:300d08d9b058 162 }
wim 0:300d08d9b058 163 _i2c.stop();
wim 0:300d08d9b058 164
wim 0:300d08d9b058 165 //setDisplayOn();
wim 0:300d08d9b058 166 }
wim 0:300d08d9b058 167
wim 0:300d08d9b058 168 #endif
wim 0:300d08d9b058 169
wim 0:300d08d9b058 170
wim 1:b7e8f5139026 171 /** @brief write a bitmap to the display
wim 1:b7e8f5139026 172 * @param uint8_t* data pointer to bitmap
wim 1:b7e8f5139026 173 * @param uint8_t start_page begin page (0..MAX_PAGE)
wim 1:b7e8f5139026 174 * @param uint8_t end_page end page (start_page..MAX_PAGE)
wim 1:b7e8f5139026 175 * @param uint8_t start_col begin column (0..MAX_COL)
wim 1:b7e8f5139026 176 * @param uint8_t end_col end column (start_col..MAX_COL)
wim 1:b7e8f5139026 177 */
wim 0:300d08d9b058 178 #if(0)
wim 0:300d08d9b058 179 //Standard version
wim 0:300d08d9b058 180 void SSD1308::writeBitmap(int len, uint8_t* data) {
wim 0:300d08d9b058 181
wim 0:300d08d9b058 182 //setDisplayOff();
wim 0:300d08d9b058 183 setPageAddress(0, MAX_PAGE); // all pages
wim 0:300d08d9b058 184 setColumnAddress(0, MAX_COL); // all columns
wim 0:300d08d9b058 185
wim 0:300d08d9b058 186 _i2c.start();
wim 0:300d08d9b058 187 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 188 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 189 for (int i=0; i<len; i++) {
wim 0:300d08d9b058 190 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 191 }
wim 0:300d08d9b058 192 _i2c.stop();
wim 0:300d08d9b058 193
wim 0:300d08d9b058 194 //setDisplayOn();
wim 0:300d08d9b058 195 }
wim 0:300d08d9b058 196 #else
wim 0:300d08d9b058 197
wim 0:300d08d9b058 198 //Optimised version
wim 0:300d08d9b058 199 // Save lots of I2C S,P, address and datacommands:
wim 0:300d08d9b058 200 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 201 //
wim 0:300d08d9b058 202 void SSD1308::writeBitmap(uint8_t* data,
wim 0:300d08d9b058 203 uint8_t start_page, uint8_t end_page,
wim 0:300d08d9b058 204 uint8_t start_col, uint8_t end_col){
wim 0:300d08d9b058 205
wim 0:300d08d9b058 206 int count = (end_page - start_page + 1) * (end_col - start_col + 1);
wim 0:300d08d9b058 207
wim 0:300d08d9b058 208 //setDisplayOff();
wim 0:300d08d9b058 209 setPageAddress(start_page, end_page); // set page window
wim 0:300d08d9b058 210 setColumnAddress(start_col, end_col); // set column window
wim 0:300d08d9b058 211
wim 0:300d08d9b058 212 _i2c.start();
wim 0:300d08d9b058 213 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 214 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 215 for (int i=0; i<count; i++) {
wim 0:300d08d9b058 216 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 217 }
wim 0:300d08d9b058 218 _i2c.stop();
wim 0:300d08d9b058 219
wim 0:300d08d9b058 220 //setDisplayOn();
wim 0:300d08d9b058 221 }
wim 0:300d08d9b058 222 #endif
wim 0:300d08d9b058 223
wim 0:300d08d9b058 224
wim 2:16c84a134393 225 /** @brief write a progressbar to the display, Width is (PRG_MAX_SCALE + 2) pixels
wim 1:b7e8f5139026 226 * @param uint8_t page begin page (0..MAX_PAGE)
wim 1:b7e8f5139026 227 * @param uint8_t col begin column (0..MAX_COL)
wim 1:b7e8f5139026 228 * @param int percentage value (0..100)
wim 1:b7e8f5139026 229 */
wim 1:b7e8f5139026 230 #define PRG_MAX_SCALE 50
wim 1:b7e8f5139026 231 #define PRG_LEFT_EDGE 0xFF
wim 1:b7e8f5139026 232 #define PRG_RIGHT_EDGE 0xFF
wim 1:b7e8f5139026 233 #define PRG_ACTIVE 0xFF
wim 2:16c84a134393 234 //#define PRG_ACTIVE 0xBD
wim 1:b7e8f5139026 235 #define PRG_NOT_ACTIVE 0x81
wim 1:b7e8f5139026 236
wim 1:b7e8f5139026 237 #if(0)
wim 1:b7e8f5139026 238 //Standard version
wim 1:b7e8f5139026 239 void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
wim 1:b7e8f5139026 240 uint8_t scale_value;
wim 1:b7e8f5139026 241
wim 2:16c84a134393 242 if (percentage <= 0) {
wim 1:b7e8f5139026 243 scale_value = 0;
wim 2:16c84a134393 244 } else if (percentage >= 100) {
wim 2:16c84a134393 245 scale_value = PRG_MAX_SCALE - 1;
wim 1:b7e8f5139026 246 }
wim 1:b7e8f5139026 247 else {
wim 1:b7e8f5139026 248 scale_value = (percentage * PRG_MAX_SCALE) / 100;
wim 1:b7e8f5139026 249 }
wim 1:b7e8f5139026 250
wim 1:b7e8f5139026 251 //setDisplayOff();
wim 1:b7e8f5139026 252 setPageAddress(page, page);
wim 1:b7e8f5139026 253 setColumnAddress(col, MAX_COL);
wim 1:b7e8f5139026 254
wim 1:b7e8f5139026 255 _sendData(PRG_LEFT_EDGE);
wim 1:b7e8f5139026 256
wim 1:b7e8f5139026 257 for (uint8_t col = 0; col < scale_value; col++) {
wim 1:b7e8f5139026 258 _sendData(PRG_ACTIVE);
wim 1:b7e8f5139026 259 }
wim 2:16c84a134393 260
wim 2:16c84a134393 261 _sendData(PRG_ACTIVE);
wim 2:16c84a134393 262
wim 2:16c84a134393 263 for (uint8_t col = (scale_value+1); col < PRG_MAX_SCALE; col++) {
wim 1:b7e8f5139026 264 _sendData(PRG_NOT_ACTIVE);
wim 1:b7e8f5139026 265 }
wim 1:b7e8f5139026 266
wim 1:b7e8f5139026 267 _sendData(PRG_RIGHT_EDGE);
wim 1:b7e8f5139026 268
wim 1:b7e8f5139026 269 //setDisplayOn();
wim 1:b7e8f5139026 270 }
wim 1:b7e8f5139026 271 #else
wim 1:b7e8f5139026 272
wim 1:b7e8f5139026 273 //Optimised version
wim 1:b7e8f5139026 274 // Save lots of I2C S,P, address and datacommands:
wim 1:b7e8f5139026 275 // Send S, address, DATA_MODE, data, data, data,...., P
wim 0:300d08d9b058 276 //
wim 1:b7e8f5139026 277 void SSD1308::writeProgressBar(uint8_t page, uint8_t col, int percentage) {
wim 1:b7e8f5139026 278 uint8_t scale_value;
wim 1:b7e8f5139026 279
wim 2:16c84a134393 280 if (percentage <= 0) {
wim 1:b7e8f5139026 281 scale_value = 0;
wim 2:16c84a134393 282 } else if (percentage >= 100) {
wim 2:16c84a134393 283 scale_value = PRG_MAX_SCALE - 1 ;
wim 1:b7e8f5139026 284 }
wim 1:b7e8f5139026 285 else {
wim 1:b7e8f5139026 286 scale_value = (percentage * PRG_MAX_SCALE) / 100;
wim 1:b7e8f5139026 287 }
wim 1:b7e8f5139026 288
wim 1:b7e8f5139026 289 //setDisplayOff();
wim 1:b7e8f5139026 290 setPageAddress(page, page);
wim 1:b7e8f5139026 291 setColumnAddress(col, MAX_COL);
wim 1:b7e8f5139026 292
wim 1:b7e8f5139026 293 _i2c.start();
wim 1:b7e8f5139026 294 _i2c.write(_writeOpcode);
wim 1:b7e8f5139026 295 _i2c.write(DATA_MODE);
wim 1:b7e8f5139026 296
wim 1:b7e8f5139026 297 _i2c.write(PRG_LEFT_EDGE); // Write Data
wim 1:b7e8f5139026 298
wim 1:b7e8f5139026 299 for (uint8_t col = 0; col < scale_value; col++) {
wim 1:b7e8f5139026 300 _i2c.write(PRG_ACTIVE); // Write Data
wim 1:b7e8f5139026 301 }
wim 1:b7e8f5139026 302
wim 2:16c84a134393 303 _i2c.write(PRG_ACTIVE); // Write Data
wim 2:16c84a134393 304
wim 2:16c84a134393 305 for (uint8_t col = (scale_value+1); col < PRG_MAX_SCALE; col++) {
wim 1:b7e8f5139026 306 _i2c.write(PRG_NOT_ACTIVE); // Write Data
wim 1:b7e8f5139026 307 }
wim 1:b7e8f5139026 308
wim 1:b7e8f5139026 309 _i2c.write(PRG_RIGHT_EDGE); // Write Data
wim 1:b7e8f5139026 310
wim 1:b7e8f5139026 311 _i2c.stop();
wim 1:b7e8f5139026 312
wim 1:b7e8f5139026 313 //setDisplayOn();
wim 1:b7e8f5139026 314 }
wim 1:b7e8f5139026 315 #endif
wim 1:b7e8f5139026 316
wim 2:16c84a134393 317 /** @brief write a level meter to the display, Width is (PRG_MAX_SCALE + 2) pixels
wim 2:16c84a134393 318 * @param uint8_t page begin page (0..MAX_PAGE)
wim 2:16c84a134393 319 * @param uint8_t col begin column (0..MAX_COL)
wim 2:16c84a134393 320 * @param int percentage value (0..100)
wim 2:16c84a134393 321 */
wim 2:16c84a134393 322 //Optimised version
wim 2:16c84a134393 323 // Save lots of I2C S,P, address and datacommands:
wim 2:16c84a134393 324 // Send S, address, DATA_MODE, data, data, data,...., P
wim 2:16c84a134393 325 //
wim 2:16c84a134393 326 void SSD1308::writeLevelBar(uint8_t page, uint8_t col, int percentage) {
wim 2:16c84a134393 327 uint8_t scale_value;
wim 2:16c84a134393 328
wim 2:16c84a134393 329 if (percentage <= 0) {
wim 2:16c84a134393 330 scale_value = 0;
wim 2:16c84a134393 331 } else if (percentage >= 100) {
wim 2:16c84a134393 332 scale_value = PRG_MAX_SCALE - 1;
wim 2:16c84a134393 333 }
wim 2:16c84a134393 334 else {
wim 2:16c84a134393 335 scale_value = (percentage * PRG_MAX_SCALE) / 100;
wim 2:16c84a134393 336 }
wim 2:16c84a134393 337
wim 2:16c84a134393 338 //setDisplayOff();
wim 2:16c84a134393 339 setPageAddress(page, page);
wim 2:16c84a134393 340 setColumnAddress(col, MAX_COL);
wim 1:b7e8f5139026 341
wim 2:16c84a134393 342 _i2c.start();
wim 2:16c84a134393 343 _i2c.write(_writeOpcode);
wim 2:16c84a134393 344 _i2c.write(DATA_MODE);
wim 1:b7e8f5139026 345
wim 2:16c84a134393 346 _i2c.write(PRG_LEFT_EDGE); // Write Data
wim 2:16c84a134393 347
wim 2:16c84a134393 348 for (uint8_t col = 0; col < scale_value; col++) {
wim 2:16c84a134393 349 _i2c.write(PRG_NOT_ACTIVE); // Write Data
wim 2:16c84a134393 350 }
wim 2:16c84a134393 351
wim 2:16c84a134393 352 _i2c.write(PRG_ACTIVE); // Write Data at active meterlevel
wim 2:16c84a134393 353
wim 2:16c84a134393 354 for (uint8_t col = scale_value+1; col < PRG_MAX_SCALE; col++) {
wim 2:16c84a134393 355 _i2c.write(PRG_NOT_ACTIVE); // Write Data
wim 2:16c84a134393 356 }
wim 2:16c84a134393 357
wim 2:16c84a134393 358 _i2c.write(PRG_RIGHT_EDGE); // Write Data
wim 2:16c84a134393 359
wim 2:16c84a134393 360 _i2c.stop();
wim 2:16c84a134393 361
wim 2:16c84a134393 362 //setDisplayOn();
wim 2:16c84a134393 363 }
wim 1:b7e8f5139026 364
wim 1:b7e8f5139026 365 /** @brief Write single character to the display using the 8x8 fontable
wim 1:b7e8f5139026 366 * @brief Start at current cursor location
wim 1:b7e8f5139026 367 * @param char chr character to write
wim 1:b7e8f5139026 368 */
wim 0:300d08d9b058 369 void SSD1308::writeChar(char chr) {
wim 0:300d08d9b058 370
wim 0:300d08d9b058 371 const uint8_t char_index = chr - 0x20;
wim 0:300d08d9b058 372
wim 0:300d08d9b058 373 for (uint8_t i = 0; i < 8; i++) {
wim 0:300d08d9b058 374 if (_inverted) {
wim 0:300d08d9b058 375 _sendData( ~font_8x8[char_index][i] );
wim 0:300d08d9b058 376 }
wim 0:300d08d9b058 377 else {
wim 0:300d08d9b058 378 _sendData( font_8x8[char_index][i] );
wim 0:300d08d9b058 379 }
wim 0:300d08d9b058 380 }
wim 0:300d08d9b058 381
wim 0:300d08d9b058 382 }
wim 0:300d08d9b058 383
wim 0:300d08d9b058 384
wim 1:b7e8f5139026 385 /** @brief Write a string to the display using the 8x8 font
wim 2:16c84a134393 386 * @brief Start at selected cursor location, text will wrap around until it is done
wim 1:b7e8f5139026 387 * @param uint8_t row row number (0...ROWS/FONT_HEIGHT)
wim 1:b7e8f5139026 388 * @param uint8_t col column number (0...COLUMNS/FONT_WIDTH)
wim 1:b7e8f5139026 389 * @param uint16_t len number of chars in text
wim 1:b7e8f5139026 390 * @param const char * text pointer to text
wim 1:b7e8f5139026 391 */
wim 2:16c84a134393 392 void SSD1308::writeString(uint8_t row, uint8_t col, const char * text) {
wim 0:300d08d9b058 393 uint16_t index = 0;
wim 2:16c84a134393 394 uint16_t len = strlen(text);
wim 2:16c84a134393 395
wim 0:300d08d9b058 396 setPageAddress(row, MAX_PAGE);
wim 0:300d08d9b058 397 const uint8_t col_addr = FONT8x8_WIDTH*col;
wim 0:300d08d9b058 398 setColumnAddress(col_addr, MAX_COL);
wim 0:300d08d9b058 399
wim 0:300d08d9b058 400 while ((col+index) < CHARS && (index < len)) {
wim 0:300d08d9b058 401 // write first line, starting at given position
wim 0:300d08d9b058 402 writeChar(text[index++]);
wim 0:300d08d9b058 403 }
wim 0:300d08d9b058 404
wim 0:300d08d9b058 405 // write remaining lines
wim 0:300d08d9b058 406 // write until the end of memory
wim 0:300d08d9b058 407 // then wrap around again from the top.
wim 0:300d08d9b058 408 if (index + 1 < len) {
wim 0:300d08d9b058 409 setPageAddress(row + 1, MAX_PAGE);
wim 0:300d08d9b058 410 setColumnAddress(0, MAX_COL);
wim 0:300d08d9b058 411 bool wrapEntireScreen = false;
wim 0:300d08d9b058 412 while (index + 1 < len) {
wim 0:300d08d9b058 413 writeChar(text[index++]);
wim 0:300d08d9b058 414 // if we've written the last character space on the screen,
wim 0:300d08d9b058 415 // reset the page and column address so that it wraps around from the top again
wim 0:300d08d9b058 416 if (!wrapEntireScreen && (row*CHARS + col + index) > 127) {
wim 0:300d08d9b058 417 setPageAddress(0, MAX_PAGE);
wim 0:300d08d9b058 418 setColumnAddress(0, MAX_COL);
wim 0:300d08d9b058 419 wrapEntireScreen = true;
wim 0:300d08d9b058 420 }
wim 0:300d08d9b058 421 }
wim 0:300d08d9b058 422 }
wim 0:300d08d9b058 423 }
wim 0:300d08d9b058 424
wim 0:300d08d9b058 425
wim 0:300d08d9b058 426
wim 1:b7e8f5139026 427 /** @brief Write large character (16x24 font)
wim 1:b7e8f5139026 428 * @param uint8_t row row number (0...MAX_ROW)
wim 1:b7e8f5139026 429 * @param uint8_t col column number (0...MAX_COL)
wim 1:b7e8f5139026 430 * @param char chr Used for displaying numbers 0 - 9 and '+', '-', '.'
wim 1:b7e8f5139026 431 */
wim 0:300d08d9b058 432 void SSD1308::writeBigChar(uint8_t row, uint8_t col, char chr) {
wim 0:300d08d9b058 433
wim 0:300d08d9b058 434 writeBitmap((uint8_t*) font_16x24[int(chr) - FONT16x24_START],
wim 0:300d08d9b058 435 row, (row + FONT16x24_BYTES - 1),
wim 0:300d08d9b058 436 col, (col + FONT16x24_WIDTH - 1));
wim 0:300d08d9b058 437 }
wim 0:300d08d9b058 438
wim 0:300d08d9b058 439
wim 1:b7e8f5139026 440 /** @brief Write command that has no parameters
wim 1:b7e8f5139026 441 */
wim 0:300d08d9b058 442 void SSD1308::_sendCommand(uint8_t command) {
wim 0:300d08d9b058 443 // I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command);
wim 0:300d08d9b058 444
wim 0:300d08d9b058 445 #if(0)
wim 0:300d08d9b058 446 char databytes[2];
wim 0:300d08d9b058 447
wim 0:300d08d9b058 448 databytes[0] = COMMAND_MODE;
wim 0:300d08d9b058 449 databytes[1] = command;
wim 0:300d08d9b058 450 _i2c.write(_writeOpcode, databytes, 2); // Write command
wim 0:300d08d9b058 451 #endif
wim 0:300d08d9b058 452
wim 0:300d08d9b058 453 _i2c.start();
wim 0:300d08d9b058 454 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 455
wim 0:300d08d9b058 456 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 457 _i2c.write(command); // Write Command
wim 0:300d08d9b058 458
wim 0:300d08d9b058 459 _i2c.stop();
wim 0:300d08d9b058 460
wim 0:300d08d9b058 461 }
wim 0:300d08d9b058 462
wim 1:b7e8f5139026 463 /** @brief Write command that has one parameter
wim 1:b7e8f5139026 464 */
wim 0:300d08d9b058 465 void SSD1308::_sendCommand(uint8_t command, uint8_t param1) {
wim 0:300d08d9b058 466
wim 0:300d08d9b058 467 // Note continuationbit is set, so COMMAND_MODE must be
wim 0:300d08d9b058 468 // repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 469
wim 0:300d08d9b058 470 _i2c.start();
wim 0:300d08d9b058 471 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 472
wim 0:300d08d9b058 473 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 474 _i2c.write(command); // Write Command
wim 0:300d08d9b058 475 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 476 _i2c.write(param1); // Write Param1
wim 0:300d08d9b058 477
wim 0:300d08d9b058 478 _i2c.stop();
wim 0:300d08d9b058 479
wim 0:300d08d9b058 480 }
wim 0:300d08d9b058 481
wim 1:b7e8f5139026 482 /** @brief Write command that has two parameters
wim 1:b7e8f5139026 483 */
wim 0:300d08d9b058 484 void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2) {
wim 0:300d08d9b058 485
wim 0:300d08d9b058 486 // Note continuationbit is set, so COMMAND_MODE must be
wim 0:300d08d9b058 487 // repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 488
wim 0:300d08d9b058 489 _i2c.start();
wim 0:300d08d9b058 490 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 491
wim 0:300d08d9b058 492 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 493 _i2c.write(command); // Write Command
wim 0:300d08d9b058 494 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 495 _i2c.write(param1); // Write Param1
wim 0:300d08d9b058 496 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 497 _i2c.write(param2); // Write Param2
wim 0:300d08d9b058 498
wim 0:300d08d9b058 499 _i2c.stop();
wim 0:300d08d9b058 500
wim 0:300d08d9b058 501 }
wim 0:300d08d9b058 502
wim 2:16c84a134393 503 /** @brief Write command that has five parameters
wim 2:16c84a134393 504 */
wim 2:16c84a134393 505 void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
wim 2:16c84a134393 506 uint8_t param3, uint8_t param4,
wim 2:16c84a134393 507 uint8_t param5) {
wim 2:16c84a134393 508
wim 2:16c84a134393 509 // Note continuationbit is set, so COMMAND_MODE must be
wim 2:16c84a134393 510 // repeated before each databyte that serves as parameter!
wim 2:16c84a134393 511
wim 2:16c84a134393 512 _i2c.start();
wim 2:16c84a134393 513 _i2c.write(_writeOpcode);
wim 2:16c84a134393 514
wim 2:16c84a134393 515 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 516 _i2c.write(command); // Write Command
wim 2:16c84a134393 517 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 518 _i2c.write(param1); // Write Param1
wim 2:16c84a134393 519 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 520 _i2c.write(param2); // Write Param2
wim 2:16c84a134393 521 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 522 _i2c.write(param3); // Write Param3
wim 2:16c84a134393 523 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 524 _i2c.write(param4); // Write Param4
wim 2:16c84a134393 525 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 526 _i2c.write(param5); // Write Param5
wim 2:16c84a134393 527
wim 2:16c84a134393 528 _i2c.stop();
wim 2:16c84a134393 529
wim 2:16c84a134393 530 }
wim 2:16c84a134393 531
wim 2:16c84a134393 532
wim 2:16c84a134393 533 /** @brief Write command that has six parameters
wim 2:16c84a134393 534 */
wim 2:16c84a134393 535 void SSD1308::_sendCommand(uint8_t command, uint8_t param1, uint8_t param2,
wim 2:16c84a134393 536 uint8_t param3, uint8_t param4,
wim 2:16c84a134393 537 uint8_t param5, uint8_t param6) {
wim 2:16c84a134393 538
wim 2:16c84a134393 539 // Note continuationbit is set, so COMMAND_MODE must be
wim 2:16c84a134393 540 // repeated before each databyte that serves as parameter!
wim 2:16c84a134393 541
wim 2:16c84a134393 542 _i2c.start();
wim 2:16c84a134393 543 _i2c.write(_writeOpcode);
wim 2:16c84a134393 544
wim 2:16c84a134393 545 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 546 _i2c.write(command); // Write Command
wim 2:16c84a134393 547 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 548 _i2c.write(param1); // Write Param1
wim 2:16c84a134393 549 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 550 _i2c.write(param2); // Write Param2
wim 2:16c84a134393 551 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 552 _i2c.write(param3); // Write Param3
wim 2:16c84a134393 553 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 554 _i2c.write(param4); // Write Param4
wim 2:16c84a134393 555 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 556 _i2c.write(param5); // Write Param5
wim 2:16c84a134393 557 _i2c.write(COMMAND_MODE);
wim 2:16c84a134393 558 _i2c.write(param6); // Write Param6
wim 2:16c84a134393 559
wim 2:16c84a134393 560 _i2c.stop();
wim 2:16c84a134393 561
wim 2:16c84a134393 562 }
wim 2:16c84a134393 563
wim 2:16c84a134393 564
wim 0:300d08d9b058 565 #if(0)
wim 1:b7e8f5139026 566 /** @brief Write command that has multiple parameters
wim 1:b7e8f5139026 567 */
wim 0:300d08d9b058 568 void SSD1308::_sendCommands(uint8_t len, uint8_t* commands) {
wim 0:300d08d9b058 569
wim 0:300d08d9b058 570 // I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
wim 0:300d08d9b058 571 // Note this original code is not correct, continuationbit is set,
wim 0:300d08d9b058 572 // so COMMAND_MODE must be repeated before each databyte that serves as parameter!
wim 0:300d08d9b058 573
wim 0:300d08d9b058 574 _i2c.start();
wim 0:300d08d9b058 575 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 576
wim 0:300d08d9b058 577 for (int i=0; i<len ; i++) {
wim 0:300d08d9b058 578 _i2c.write(COMMAND_MODE);
wim 0:300d08d9b058 579 _i2c.write(commands[i]); // Write Commands
wim 0:300d08d9b058 580 }
wim 0:300d08d9b058 581 _i2c.stop();
wim 0:300d08d9b058 582
wim 0:300d08d9b058 583 }
wim 0:300d08d9b058 584 #endif
wim 0:300d08d9b058 585
wim 1:b7e8f5139026 586 /** @brief Write databyte to display
wim 1:b7e8f5139026 587 * @brief Start at current cursor location
wim 1:b7e8f5139026 588 * @param uint8_t data databyte to write
wim 1:b7e8f5139026 589 */
wim 0:300d08d9b058 590 void SSD1308::_sendData(uint8_t data){
wim 0:300d08d9b058 591 // I2Cdev::writeByte(m_devAddr, DATA_MODE, data);
wim 0:300d08d9b058 592
wim 0:300d08d9b058 593 char databytes[2];
wim 0:300d08d9b058 594
wim 0:300d08d9b058 595 databytes[0] = DATA_MODE;
wim 0:300d08d9b058 596 databytes[1] = data;
wim 0:300d08d9b058 597 _i2c.write(_writeOpcode, databytes, 2); // Write Data
wim 0:300d08d9b058 598
wim 0:300d08d9b058 599 }
wim 0:300d08d9b058 600
wim 1:b7e8f5139026 601 /** @brief Write len bytes from buffer data to display,
wim 1:b7e8f5139026 602 * @brief Start at current cursor location
wim 1:b7e8f5139026 603 * @param uint8_t len number of bytes to write
wim 1:b7e8f5139026 604 * @param uint8_t* data pointer to data
wim 1:b7e8f5139026 605 */
wim 0:300d08d9b058 606 void SSD1308::_sendData(uint8_t len, uint8_t* data) {
wim 0:300d08d9b058 607 // I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
wim 0:300d08d9b058 608
wim 0:300d08d9b058 609 _i2c.start();
wim 0:300d08d9b058 610 _i2c.write(_writeOpcode);
wim 0:300d08d9b058 611 _i2c.write(DATA_MODE);
wim 0:300d08d9b058 612 for (int i=0; i<len ; i++) {
wim 0:300d08d9b058 613 _i2c.write(data[i]); // Write Data
wim 0:300d08d9b058 614 }
wim 0:300d08d9b058 615 _i2c.stop();
wim 0:300d08d9b058 616
wim 0:300d08d9b058 617 }
wim 0:300d08d9b058 618
wim 0:300d08d9b058 619
wim 2:16c84a134393 620 /** @brief Set Horizontal Addressing Mode (cursor incr left-to-right, top-to-bottom)
wim 2:16c84a134393 621 *
wim 2:16c84a134393 622 */
wim 0:300d08d9b058 623 void SSD1308::setHorizontalAddressingMode(){
wim 0:300d08d9b058 624 setMemoryAddressingMode(HORIZONTAL_ADDRESSING_MODE);
wim 0:300d08d9b058 625 }
wim 0:300d08d9b058 626
wim 2:16c84a134393 627 /** @brief Set Vertical Addressing Mode (cursor incr top-to-bottom, left-to-right)
wim 2:16c84a134393 628 *
wim 2:16c84a134393 629 */
wim 0:300d08d9b058 630 void SSD1308::setVerticalAddressingMode() {
wim 0:300d08d9b058 631 setMemoryAddressingMode(VERTICAL_ADDRESSING_MODE);
wim 0:300d08d9b058 632 }
wim 0:300d08d9b058 633
wim 2:16c84a134393 634 /** @brief Set Page Addressing Mode (cursor incr left-to-right)
wim 2:16c84a134393 635 *
wim 2:16c84a134393 636 */
wim 0:300d08d9b058 637 void SSD1308::setPageAddressingMode(){
wim 0:300d08d9b058 638 setMemoryAddressingMode(PAGE_ADDRESSING_MODE);
wim 0:300d08d9b058 639 }
wim 0:300d08d9b058 640
wim 2:16c84a134393 641 /** @brief Set Addressing Mode
wim 2:16c84a134393 642 * @param uint8_t mode
wim 2:16c84a134393 643 */
wim 0:300d08d9b058 644 void SSD1308::setMemoryAddressingMode(uint8_t mode){
wim 0:300d08d9b058 645
wim 0:300d08d9b058 646 _sendCommand(SET_MEMORY_ADDRESSING_MODE, mode);
wim 0:300d08d9b058 647 }
wim 0:300d08d9b058 648
wim 0:300d08d9b058 649
wim 1:b7e8f5139026 650 /** @param uint8_t start startpage (valid range 0..MAX_PAGE)
wim 1:b7e8f5139026 651 * @param uint8_t end endpage (valid range start..MAX_PAGE)
wim 1:b7e8f5139026 652 */
wim 0:300d08d9b058 653 void SSD1308::setPageAddress(uint8_t start, uint8_t end) {
wim 0:300d08d9b058 654
wim 0:300d08d9b058 655 _sendCommand(SET_PAGE_ADDRESS, start, end);
wim 0:300d08d9b058 656 }
wim 0:300d08d9b058 657
wim 0:300d08d9b058 658
wim 1:b7e8f5139026 659 /** @param uint8_t start startcolumn (valid range 0..MAX_COL)
wim 1:b7e8f5139026 660 * @param uint8_t end endcolumn (valid range start..MAX_COL)
wim 1:b7e8f5139026 661 */
wim 0:300d08d9b058 662 void SSD1308::setColumnAddress(uint8_t start, uint8_t end) {
wim 0:300d08d9b058 663
wim 0:300d08d9b058 664 _sendCommand(SET_COLUMN_ADDRESS, start, end);
wim 0:300d08d9b058 665 }
wim 0:300d08d9b058 666
wim 2:16c84a134393 667 /**
wim 2:16c84a134393 668 * @brief Set Display StartLine, takes one byte, 0x00-0x3F
wim 2:16c84a134393 669 * @param uint8_t line startline (valid range 0..MAX_ROWS)
wim 2:16c84a134393 670 */
wim 2:16c84a134393 671 void SSD1308::setDisplayStartLine(uint8_t line) {
wim 2:16c84a134393 672
wim 2:16c84a134393 673 line = line & MAX_ROW;
wim 2:16c84a134393 674
wim 2:16c84a134393 675 _sendCommand(SET_DISPLAY_START_LINE | line);
wim 2:16c84a134393 676 }
wim 2:16c84a134393 677
wim 2:16c84a134393 678
wim 2:16c84a134393 679 /**
wim 2:16c84a134393 680 * @brief Set Column Start (for Page Addressing Mode only)
wim 2:16c84a134393 681 * @param uint8_t column column start (valid range 0..MAX_COL)
wim 2:16c84a134393 682 */
wim 2:16c84a134393 683 void SSD1308::setColumnStartForPageAddressingMode(uint8_t column) {
wim 2:16c84a134393 684
wim 2:16c84a134393 685 column = column & MAX_COL;
wim 2:16c84a134393 686
wim 2:16c84a134393 687 _sendCommand(SET_LOWER_COLUMN | ( column & 0x0F)); // lower nibble
wim 2:16c84a134393 688 _sendCommand(SET_HIGHER_COLUMN | ((column>>4) & 0x0F)); // higher nibble
wim 2:16c84a134393 689 }
wim 2:16c84a134393 690
wim 2:16c84a134393 691
wim 2:16c84a134393 692 /**
wim 2:16c84a134393 693 * @brief Set Page Start (for Page Addressing Mode only)
wim 2:16c84a134393 694 * @param uint8_t page page start (valid range PAGE0 - PAGE7)
wim 2:16c84a134393 695 */
wim 2:16c84a134393 696 void SSD1308::setPageStartForPageAddressingMode(uint8_t page) {
wim 2:16c84a134393 697
wim 2:16c84a134393 698 page = page & MAX_PAGE;
wim 2:16c84a134393 699
wim 2:16c84a134393 700 _sendCommand(SET_PAGE_START_ADDRESS | page);
wim 2:16c84a134393 701
wim 2:16c84a134393 702 }
wim 2:16c84a134393 703
wim 2:16c84a134393 704
wim 1:b7e8f5139026 705 /** @brief Set Contrast
wim 1:b7e8f5139026 706 * @param uint8_t contrast (valid range 0x00 (lowest) - 0xFF (highest))
wim 1:b7e8f5139026 707 */
wim 0:300d08d9b058 708 void SSD1308::setContrastControl(uint8_t contrast) {
wim 0:300d08d9b058 709
wim 0:300d08d9b058 710 _sendCommand(SET_CONTRAST, contrast);
wim 0:300d08d9b058 711 }
wim 0:300d08d9b058 712
wim 1:b7e8f5139026 713 /** @brief Enable Display
wim 1:b7e8f5139026 714 */
wim 0:300d08d9b058 715 void SSD1308::setDisplayOn() {
wim 0:300d08d9b058 716 _sendCommand(SET_DISPLAY_POWER_ON);
wim 0:300d08d9b058 717 }
wim 0:300d08d9b058 718
wim 1:b7e8f5139026 719 /** @brief Disable Display
wim 1:b7e8f5139026 720 */
wim 0:300d08d9b058 721 void SSD1308::setDisplayOff() {
wim 0:300d08d9b058 722 _sendCommand(SET_DISPLAY_POWER_OFF);
wim 0:300d08d9b058 723 }
wim 0:300d08d9b058 724
wim 1:b7e8f5139026 725 /** @brief Enable or Disable Display
wim 1:b7e8f5139026 726 * @param bool on
wim 1:b7e8f5139026 727 */
wim 0:300d08d9b058 728 void SSD1308::setDisplayPower(bool on) {
wim 0:300d08d9b058 729 if (on) {
wim 0:300d08d9b058 730 setDisplayOn();
wim 0:300d08d9b058 731 } else {
wim 0:300d08d9b058 732 setDisplayOff();
wim 0:300d08d9b058 733 }
wim 0:300d08d9b058 734 }
wim 0:300d08d9b058 735
wim 1:b7e8f5139026 736 /** @brief Show White pixels on Black background
wim 1:b7e8f5139026 737 */
wim 0:300d08d9b058 738 void SSD1308::setDisplayNormal() {
wim 0:300d08d9b058 739 _sendCommand(SET_NORMAL_DISPLAY);
wim 0:300d08d9b058 740 }
wim 0:300d08d9b058 741
wim 1:b7e8f5139026 742 /** @brief Show Black pixels on White background
wim 1:b7e8f5139026 743 */
wim 0:300d08d9b058 744 void SSD1308::setDisplayInverse() {
wim 0:300d08d9b058 745 _sendCommand(SET_INVERSE_DISPLAY);
wim 0:300d08d9b058 746 }
wim 0:300d08d9b058 747
wim 1:b7e8f5139026 748 /** @brief Blink display by fading in and out over a set number of frames
wim 1:b7e8f5139026 749 * @param bool on
wim 1:b7e8f5139026 750 */
wim 0:300d08d9b058 751 void SSD1308::setDisplayBlink(bool on){
wim 0:300d08d9b058 752 if (on) {
wim 0:300d08d9b058 753 _sendCommand(SET_FADE_BLINK, (BLINK_ENABLE | FADE_INTERVAL_128_FRAMES));
wim 0:300d08d9b058 754 }
wim 0:300d08d9b058 755 else {
wim 0:300d08d9b058 756 _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
wim 0:300d08d9b058 757 }
wim 0:300d08d9b058 758 }
wim 0:300d08d9b058 759
wim 0:300d08d9b058 760
wim 1:b7e8f5139026 761 /** @brief Fade out display in set number of frames
wim 1:b7e8f5139026 762 * @param bool on
wim 1:b7e8f5139026 763 */
wim 0:300d08d9b058 764 void SSD1308::setDisplayFade(bool on) {
wim 0:300d08d9b058 765 if (on) {
wim 0:300d08d9b058 766 _sendCommand(SET_FADE_BLINK, (FADE_OUT_ENABLE | FADE_INTERVAL_128_FRAMES));
wim 0:300d08d9b058 767 }
wim 0:300d08d9b058 768 else {
wim 0:300d08d9b058 769 _sendCommand(SET_FADE_BLINK, FADE_BLINK_DISABLE);
wim 0:300d08d9b058 770 }
wim 0:300d08d9b058 771 }
wim 0:300d08d9b058 772
wim 1:b7e8f5139026 773 /** @brief Display Flip (Left/Right, Up/Down)
wim 1:b7e8f5139026 774 * @param bool left flip Left/Right
wim 1:b7e8f5139026 775 * @param bool down flip Up/Down
wim 1:b7e8f5139026 776 */
wim 0:300d08d9b058 777 void SSD1308::setDisplayFlip(bool left, bool down) {
wim 0:300d08d9b058 778 if (left) {
wim 0:300d08d9b058 779 // column address 0 is mapped to SEG0 (Reset)
wim 0:300d08d9b058 780 _sendCommand(SET_SEGMENT_REMAP_0);
wim 0:300d08d9b058 781 }
wim 0:300d08d9b058 782 else {
wim 0:300d08d9b058 783 // column address 127 is mapped to SEG0
wim 0:300d08d9b058 784 _sendCommand(SET_SEGMENT_REMAP_127);
wim 0:300d08d9b058 785 }
wim 0:300d08d9b058 786
wim 0:300d08d9b058 787 if (down) {
wim 0:300d08d9b058 788 // Reset mode
wim 0:300d08d9b058 789 _sendCommand(SET_COMMON_REMAP_0);
wim 0:300d08d9b058 790 }
wim 0:300d08d9b058 791 else {
wim 0:300d08d9b058 792 // Flip Up/Down (Need to rewrite display before H effect shows)
wim 0:300d08d9b058 793 _sendCommand(SET_COMMON_REMAP_63);
wim 0:300d08d9b058 794 }
wim 0:300d08d9b058 795
wim 0:300d08d9b058 796 }
wim 0:300d08d9b058 797
wim 1:b7e8f5139026 798 /** @brief Sets Internal Iref
wim 1:b7e8f5139026 799 */
wim 0:300d08d9b058 800 void SSD1308::setInternalIref() {
wim 0:300d08d9b058 801 // uint8_t cmds[2] = {SET_IREF_SELECTION, INTERNAL_IREF};
wim 0:300d08d9b058 802 // _sendCommands(2, cmds);
wim 0:300d08d9b058 803
wim 0:300d08d9b058 804 _sendCommand(SET_IREF_SELECTION, INTERNAL_IREF);
wim 0:300d08d9b058 805 }
wim 0:300d08d9b058 806
wim 1:b7e8f5139026 807 /** @brief Sets External Iref (default)
wim 1:b7e8f5139026 808 */
wim 0:300d08d9b058 809 void SSD1308::setExternalIref() {
wim 0:300d08d9b058 810 // uint8_t cmds[2] = {SET_IREF_SELECTION, EXTERNAL_IREF};
wim 0:300d08d9b058 811 // _sendCommands(2, cmds);
wim 0:300d08d9b058 812 _sendCommand(SET_IREF_SELECTION, EXTERNAL_IREF);
wim 0:300d08d9b058 813 }
wim 0:300d08d9b058 814
wim 0:300d08d9b058 815
wim 2:16c84a134393 816 /** @brief Shows All Pixels On
wim 2:16c84a134393 817 */
wim 2:16c84a134393 818 void SSD1308::setEntireDisplayOn(){
wim 2:16c84a134393 819 _sendCommand(SET_ENTIRE_DISPLAY_ON);
wim 2:16c84a134393 820 }
wim 2:16c84a134393 821
wim 2:16c84a134393 822 /** @brief Shows Pixels as RAM content
wim 2:16c84a134393 823 */
wim 2:16c84a134393 824 void SSD1308::setEntireDisplayRAM(){
wim 2:16c84a134393 825 _sendCommand(SET_DISPLAY_GDDRAM);
wim 2:16c84a134393 826 }
wim 2:16c84a134393 827
wim 2:16c84a134393 828 /** @brief Shows Pixels On or as RAM content
wim 2:16c84a134393 829 * @param bool on (true is All on, false is RAM content)
wim 2:16c84a134393 830 */
wim 2:16c84a134393 831 void SSD1308::setEntireDisplay(bool on){
wim 2:16c84a134393 832 if (on) {
wim 2:16c84a134393 833 setEntireDisplayOn(); // All Pixels on
wim 2:16c84a134393 834 }
wim 2:16c84a134393 835 else {
wim 2:16c84a134393 836 setEntireDisplayRAM(); // Pixels are RAM content
wim 2:16c84a134393 837 }
wim 2:16c84a134393 838 }
wim 2:16c84a134393 839
wim 2:16c84a134393 840
wim 2:16c84a134393 841 /** @brief Horizontal scroll by one column per interval
wim 2:16c84a134393 842 * @param bool left select Left/Right scroll
wim 2:16c84a134393 843 * @param uint8_t start_page begin page (0..MAX_PAGE)
wim 2:16c84a134393 844 * @param uint8_t end_page end page (start_page..MAX_PAGE)
wim 2:16c84a134393 845 * @param uint8_t interval scroll interval in frames (see codes above)
wim 2:16c84a134393 846 */
wim 2:16c84a134393 847 void SSD1308::setContinuousHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page, uint8_t interval) {
wim 2:16c84a134393 848 if (left) {
wim 2:16c84a134393 849 _sendCommand(SET_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF); // Scroll Left
wim 2:16c84a134393 850 }
wim 2:16c84a134393 851 else {
wim 2:16c84a134393 852 _sendCommand(SET_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, 0x00, 0xFF); // Scroll Right
wim 2:16c84a134393 853 }
wim 2:16c84a134393 854
wim 2:16c84a134393 855 }
wim 2:16c84a134393 856
wim 2:16c84a134393 857
wim 2:16c84a134393 858 /** @brief Horizontal and Vertical scroll by one column per interval
wim 2:16c84a134393 859 * @param bool left select Left/Right scroll
wim 2:16c84a134393 860 * @param uint8_t start_page begin page (0..MAX_PAGE)
wim 2:16c84a134393 861 * @param uint8_t end_page end page (start_page..MAX_PAGE)
wim 2:16c84a134393 862 * @param uint8_t offset vert offset (0x01..0x63)
wim 2:16c84a134393 863 * @param uint8_t interval scroll interval in frames (see codes above)
wim 2:16c84a134393 864 */
wim 2:16c84a134393 865 void SSD1308::setContinuousVerticalAndHorizontalScroll(bool left, uint8_t start_page, uint8_t end_page,
wim 2:16c84a134393 866 uint8_t offset, uint8_t interval) {
wim 2:16c84a134393 867 if (left) {
wim 2:16c84a134393 868 _sendCommand(SET_VERT_LEFT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset); // Scroll Left
wim 2:16c84a134393 869 }
wim 2:16c84a134393 870 else {
wim 2:16c84a134393 871 _sendCommand(SET_VERT_RIGHT_HOR_SCROLL, 0x00, start_page, interval, end_page, offset); // Scroll Right
wim 2:16c84a134393 872 }
wim 2:16c84a134393 873
wim 2:16c84a134393 874 }
wim 2:16c84a134393 875
wim 2:16c84a134393 876 /** @brief Set Vertical scroll area
wim 2:16c84a134393 877 * @param uint8_t topRowsFixed fixed rows (0..MAX_ROW)
wim 2:16c84a134393 878 * @param uint8_t scrollRowsoffset scroll rows (topRowsFixed..ROWS)
wim 2:16c84a134393 879 */
wim 2:16c84a134393 880 void SSD1308::setVerticalScrollArea(uint8_t topRowsFixed, uint8_t scrollRows) {
wim 2:16c84a134393 881
wim 2:16c84a134393 882 if ((topRowsFixed + scrollRows) > ROWS) {
wim 2:16c84a134393 883 scrollRows = ROWS - topRowsFixed;
wim 2:16c84a134393 884 };
wim 2:16c84a134393 885
wim 2:16c84a134393 886 _sendCommand(SET_VERTICAL_SCROLL_AREA, topRowsFixed, scrollRows);
wim 2:16c84a134393 887 }
wim 2:16c84a134393 888
wim 2:16c84a134393 889 /** @brief Activate or Deactivate Horizontal and Vertical scroll
wim 2:16c84a134393 890 * @brief Note: after deactivating scrolling, the RAM data needs to be rewritten
wim 2:16c84a134393 891 * @param bool on activate scroll
wim 2:16c84a134393 892 */
wim 2:16c84a134393 893 void SSD1308::setDisplayScroll(bool on) {
wim 2:16c84a134393 894 if (on) {
wim 2:16c84a134393 895 _sendCommand(SET_ACTIVATE_SCROLL); // Scroll on
wim 2:16c84a134393 896 }
wim 2:16c84a134393 897 else {
wim 2:16c84a134393 898 _sendCommand(SET_DEACTIVATE_SCROLL); // Scroll off
wim 2:16c84a134393 899 }
wim 2:16c84a134393 900 }
wim 2:16c84a134393 901
wim 2:16c84a134393 902
wim 2:16c84a134393 903
wim 1:b7e8f5139026 904 /** @brief Low level Init
wim 1:b7e8f5139026 905 * @brief Init the configuration registers in accordance with the datasheet
wim 1:b7e8f5139026 906 */
wim 0:300d08d9b058 907 void SSD1308::_init() {
wim 0:300d08d9b058 908
wim 2:16c84a134393 909 _sendCommand(SET_DISPLAY_POWER_OFF); // 0xAE
wim 0:300d08d9b058 910
wim 0:300d08d9b058 911 // column address 0 is mapped to SEG0 (Reset)
wim 2:16c84a134393 912 // row address 0 is mapped to COM0 (Reset)
wim 2:16c84a134393 913 _sendCommand(SET_SEGMENT_REMAP_0); // 0xA0 (Reset)
wim 2:16c84a134393 914 _sendCommand(SET_COMMON_REMAP_0); // 0xC0 (Reset)
wim 2:16c84a134393 915
wim 2:16c84a134393 916 setDisplayStartLine(0); // 0x40 (Reset)
wim 0:300d08d9b058 917
wim 2:16c84a134393 918 _sendCommand(SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL); // 0xDA, 0x12 (Reset)
wim 0:300d08d9b058 919
wim 2:16c84a134393 920 // Pagemode or Horizontal mode
wim 2:16c84a134393 921 // setPageAddressingMode(); // 0x20, 0x02 (Reset)
wim 2:16c84a134393 922 // setColumnStartForPageAddressingMode(0); // 0x00, 0x10 (Reset = Column 0)
wim 2:16c84a134393 923 // setPageStartForPageAddressingMode(PAGE_0);// 0xBO (Reset = Page 0)
wim 2:16c84a134393 924 setHorizontalAddressingMode(); // 0x20, 0x00 (Non-Reset)
wim 2:16c84a134393 925 setColumnAddress(0, MAX_COL); // 0x21, 0x00, 0x37 (Reset)
wim 2:16c84a134393 926 setPageAddress(0, MAX_PAGE); // 0x22, 0x00, 0x07 (Reset)
wim 0:300d08d9b058 927
wim 2:16c84a134393 928 setExternalIref(); // 0xAD, 0x10 (Reset)
wim 2:16c84a134393 929
wim 2:16c84a134393 930 _sendCommand(SET_DISPLAY_CLOCK, 0x70); // 0xD5, 0x70 (Reset = 0x80)
wim 2:16c84a134393 931 _sendCommand(SET_PRECHARGE_TIME, 0x21); // 0xD9, 0x21 (Reset = 0x22)
wim 2:16c84a134393 932 _sendCommand(SET_VCOMH_DESELECT_LEVEL, 0x30); // 0xDB, 0x30 (Reset = 0x20)
wim 2:16c84a134393 933 _sendCommand(SET_MULTIPLEX_RATIO, 0x3F); // 0xA8, 0x3F (Reset)
wim 2:16c84a134393 934 _sendCommand(SET_DISPLAY_OFFSET, 0x00); // 0xD3, 0x00 (Reset)
wim 2:16c84a134393 935
wim 2:16c84a134393 936 _sendCommand(SET_CONTRAST, 0x7F); // 0x81, 0x7F (Reset)
wim 0:300d08d9b058 937
wim 2:16c84a134393 938 _sendCommand(SET_NORMAL_DISPLAY); // 0xA6 (Reset)
wim 2:16c84a134393 939
wim 2:16c84a134393 940 setEntireDisplayRAM(); // 0xA4 (Reset)
wim 2:16c84a134393 941 setDisplayScroll(false);
wim 0:300d08d9b058 942
wim 0:300d08d9b058 943 clearDisplay();
wim 0:300d08d9b058 944
wim 2:16c84a134393 945 _sendCommand(SET_DISPLAY_POWER_ON); // 0xAF
wim 0:300d08d9b058 946 }
wim 0:300d08d9b058 947