A fork with some I2C optimizations that speed up the display.

Fork of SSD1308_128x64_I2C by Wim Huiskamp

Committer:
ruevs
Date:
Tue Jun 12 08:22:06 2018 +0000
Revision:
5:b6fbc7614a98
Parent:
4:df92b0c0cb92
MPU9250 and BMP180 support for the "Xadow - IMU 10DOF" board.

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