ThingPulse OLED SSD1306

Dependents:   Turtle_RadioShuttle mbed-os5-F303-18650-Manager-tp4056 Kretanje_kroz_izbornike_OLED128x64_4tipke

Committer:
Helmut64
Date:
Wed Apr 10 14:15:31 2019 +0000
Revision:
0:56dd5df33ab4
Child:
1:9270c15c6aea
initial mbed library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut64 0:56dd5df33ab4 1 /**
Helmut64 0:56dd5df33ab4 2 * The MIT License (MIT)
Helmut64 0:56dd5df33ab4 3 *
Helmut64 0:56dd5df33ab4 4 * Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
Helmut64 0:56dd5df33ab4 5 *
Helmut64 0:56dd5df33ab4 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
Helmut64 0:56dd5df33ab4 7 * of this software and associated documentation files (the "Software"), to deal
Helmut64 0:56dd5df33ab4 8 * in the Software without restriction, including without limitation the rights
Helmut64 0:56dd5df33ab4 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Helmut64 0:56dd5df33ab4 10 * copies of the Software, and to permit persons to whom the Software is
Helmut64 0:56dd5df33ab4 11 * furnished to do so, subject to the following conditions:
Helmut64 0:56dd5df33ab4 12 *
Helmut64 0:56dd5df33ab4 13 * The above copyright notice and this permission notice shall be included in all
Helmut64 0:56dd5df33ab4 14 * copies or substantial portions of the Software.
Helmut64 0:56dd5df33ab4 15 *
Helmut64 0:56dd5df33ab4 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Helmut64 0:56dd5df33ab4 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Helmut64 0:56dd5df33ab4 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Helmut64 0:56dd5df33ab4 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Helmut64 0:56dd5df33ab4 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Helmut64 0:56dd5df33ab4 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Helmut64 0:56dd5df33ab4 22 * SOFTWARE.
Helmut64 0:56dd5df33ab4 23 *
Helmut64 0:56dd5df33ab4 24 * ThingPulse invests considerable time and money to develop these open source libraries.
Helmut64 0:56dd5df33ab4 25 * Please support us by buying our products (and not the clones) from
Helmut64 0:56dd5df33ab4 26 * https://thingpulse.com
Helmut64 0:56dd5df33ab4 27 *
Helmut64 0:56dd5df33ab4 28 */
Helmut64 0:56dd5df33ab4 29
Helmut64 0:56dd5df33ab4 30 #ifndef SSD1306I2C_h
Helmut64 0:56dd5df33ab4 31 #define SSD1306I2C_h
Helmut64 0:56dd5df33ab4 32
Helmut64 0:56dd5df33ab4 33
Helmut64 0:56dd5df33ab4 34 #ifdef __MBED__
Helmut64 0:56dd5df33ab4 35
Helmut64 0:56dd5df33ab4 36 #include "OLEDDisplay.h"
Helmut64 0:56dd5df33ab4 37 #include <mbed.h>
Helmut64 0:56dd5df33ab4 38
Helmut64 0:56dd5df33ab4 39 #ifndef UINT8_MAX
Helmut64 0:56dd5df33ab4 40 #define UINT8_MAX 0xff
Helmut64 0:56dd5df33ab4 41 #endif
Helmut64 0:56dd5df33ab4 42
Helmut64 0:56dd5df33ab4 43 class SSD1306I2C : public OLEDDisplay {
Helmut64 0:56dd5df33ab4 44 public:
Helmut64 0:56dd5df33ab4 45 SSD1306I2C(uint8_t _address, PinName _sda, PinName _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
Helmut64 0:56dd5df33ab4 46 setGeometry(g);
Helmut64 0:56dd5df33ab4 47
Helmut64 0:56dd5df33ab4 48 this->_address = _address << 1; // convert from 7 to 8 bit for mbed.
Helmut64 0:56dd5df33ab4 49 this->_sda = _sda;
Helmut64 0:56dd5df33ab4 50 this->_scl = _scl;
Helmut64 0:56dd5df33ab4 51 _i2c = new I2C(_sda, _scl);
Helmut64 0:56dd5df33ab4 52 }
Helmut64 0:56dd5df33ab4 53
Helmut64 0:56dd5df33ab4 54 bool connect() {
Helmut64 0:56dd5df33ab4 55 // mbed supports 100k and 400k some device maybe 1000k
Helmut64 0:56dd5df33ab4 56 #ifdef TARGET_STM32L4
Helmut64 0:56dd5df33ab4 57 _i2c->frequency(1000000);
Helmut64 0:56dd5df33ab4 58 #else
Helmut64 0:56dd5df33ab4 59 _i2c->frequency(400000);
Helmut64 0:56dd5df33ab4 60 #endif
Helmut64 0:56dd5df33ab4 61 return true;
Helmut64 0:56dd5df33ab4 62 }
Helmut64 0:56dd5df33ab4 63
Helmut64 0:56dd5df33ab4 64 void display(void) {
Helmut64 0:56dd5df33ab4 65 const int x_offset = (128 - this->width()) / 2;
Helmut64 0:56dd5df33ab4 66 #ifdef OLEDDISPLAY_DOUBLE_BUFFER
Helmut64 0:56dd5df33ab4 67 uint8_t minBoundY = UINT8_MAX;
Helmut64 0:56dd5df33ab4 68 uint8_t maxBoundY = 0;
Helmut64 0:56dd5df33ab4 69
Helmut64 0:56dd5df33ab4 70 uint8_t minBoundX = UINT8_MAX;
Helmut64 0:56dd5df33ab4 71 uint8_t maxBoundX = 0;
Helmut64 0:56dd5df33ab4 72 uint8_t x, y;
Helmut64 0:56dd5df33ab4 73
Helmut64 0:56dd5df33ab4 74 // Calculate the Y bounding box of changes
Helmut64 0:56dd5df33ab4 75 // and copy buffer[pos] to buffer_back[pos];
Helmut64 0:56dd5df33ab4 76 for (y = 0; y < (this->height() / 8); y++) {
Helmut64 0:56dd5df33ab4 77 for (x = 0; x < this->width(); x++) {
Helmut64 0:56dd5df33ab4 78 uint16_t pos = x + y * this->width();
Helmut64 0:56dd5df33ab4 79 if (buffer[pos] != buffer_back[pos]) {
Helmut64 0:56dd5df33ab4 80 minBoundY = std::min(minBoundY, y);
Helmut64 0:56dd5df33ab4 81 maxBoundY = std::max(maxBoundY, y);
Helmut64 0:56dd5df33ab4 82 minBoundX = std::min(minBoundX, x);
Helmut64 0:56dd5df33ab4 83 maxBoundX = std::max(maxBoundX, x);
Helmut64 0:56dd5df33ab4 84 }
Helmut64 0:56dd5df33ab4 85 buffer_back[pos] = buffer[pos];
Helmut64 0:56dd5df33ab4 86 }
Helmut64 0:56dd5df33ab4 87 yield();
Helmut64 0:56dd5df33ab4 88 }
Helmut64 0:56dd5df33ab4 89
Helmut64 0:56dd5df33ab4 90 // If the minBoundY wasn't updated
Helmut64 0:56dd5df33ab4 91 // we can savely assume that buffer_back[pos] == buffer[pos]
Helmut64 0:56dd5df33ab4 92 // holdes true for all values of pos
Helmut64 0:56dd5df33ab4 93
Helmut64 0:56dd5df33ab4 94 if (minBoundY == UINT8_MAX) return;
Helmut64 0:56dd5df33ab4 95
Helmut64 0:56dd5df33ab4 96 sendCommand(COLUMNADDR);
Helmut64 0:56dd5df33ab4 97 sendCommand(x_offset + minBoundX); // column start address (0 = reset)
Helmut64 0:56dd5df33ab4 98 sendCommand(x_offset + maxBoundX); // column end address (127 = reset)
Helmut64 0:56dd5df33ab4 99
Helmut64 0:56dd5df33ab4 100 sendCommand(PAGEADDR);
Helmut64 0:56dd5df33ab4 101 sendCommand(minBoundY); // page start address
Helmut64 0:56dd5df33ab4 102 sendCommand(maxBoundY); // page end address
Helmut64 0:56dd5df33ab4 103
Helmut64 0:56dd5df33ab4 104 for (y = minBoundY; y <= maxBoundY; y++) {
Helmut64 0:56dd5df33ab4 105 uint8_t *start = &buffer[(minBoundX + y * this->width())-1];
Helmut64 0:56dd5df33ab4 106 uint8_t save = *start;
Helmut64 0:56dd5df33ab4 107
Helmut64 0:56dd5df33ab4 108 *start = 0x40; // control
Helmut64 0:56dd5df33ab4 109 _i2c->write(_address, (char *)start, (maxBoundX-minBoundX) + 1 + 1);
Helmut64 0:56dd5df33ab4 110 *start = save;
Helmut64 0:56dd5df33ab4 111 }
Helmut64 0:56dd5df33ab4 112 #else
Helmut64 0:56dd5df33ab4 113
Helmut64 0:56dd5df33ab4 114 sendCommand(COLUMNADDR);
Helmut64 0:56dd5df33ab4 115 sendCommand(x_offset); // column start address (0 = reset)
Helmut64 0:56dd5df33ab4 116 sendCommand(x_offset + (this->width() - 1));// column end address (127 = reset)
Helmut64 0:56dd5df33ab4 117
Helmut64 0:56dd5df33ab4 118 sendCommand(PAGEADDR);
Helmut64 0:56dd5df33ab4 119 sendCommand(0x0); // page start address (0 = reset)
Helmut64 0:56dd5df33ab4 120 sendCommand((this->height() / 8) - 1); // page end address 7
Helmut64 0:56dd5df33ab4 121
Helmut64 0:56dd5df33ab4 122 if (geometry == GEOMETRY_128_64) {
Helmut64 0:56dd5df33ab4 123 sendCommand(0x7);
Helmut64 0:56dd5df33ab4 124 } else if (geometry == GEOMETRY_128_32) {
Helmut64 0:56dd5df33ab4 125 sendCommand(0x3);
Helmut64 0:56dd5df33ab4 126 }
Helmut64 0:56dd5df33ab4 127
Helmut64 0:56dd5df33ab4 128 buffer[-1] = 0x40; // control
Helmut64 0:56dd5df33ab4 129 _i2c->write(_address, (char *)&buffer[-1], displayBufferSize + 1);
Helmut64 0:56dd5df33ab4 130 #endif
Helmut64 0:56dd5df33ab4 131 }
Helmut64 0:56dd5df33ab4 132
Helmut64 0:56dd5df33ab4 133 private:
Helmut64 0:56dd5df33ab4 134 int getBufferOffset(void) {
Helmut64 0:56dd5df33ab4 135 return 0;
Helmut64 0:56dd5df33ab4 136 }
Helmut64 0:56dd5df33ab4 137
Helmut64 0:56dd5df33ab4 138 inline void sendCommand(uint8_t command) __attribute__((always_inline)) {
Helmut64 0:56dd5df33ab4 139 char _data[2];
Helmut64 0:56dd5df33ab4 140 _data[0] = 0x80; // control
Helmut64 0:56dd5df33ab4 141 _data[1] = command;
Helmut64 0:56dd5df33ab4 142 _i2c->write(_address, _data, sizeof(_data));
Helmut64 0:56dd5df33ab4 143 }
Helmut64 0:56dd5df33ab4 144
Helmut64 0:56dd5df33ab4 145 uint8_t _address;
Helmut64 0:56dd5df33ab4 146 PinName _sda;
Helmut64 0:56dd5df33ab4 147 PinName _scl;
Helmut64 0:56dd5df33ab4 148 I2C *_i2c;
Helmut64 0:56dd5df33ab4 149 };
Helmut64 0:56dd5df33ab4 150
Helmut64 0:56dd5df33ab4 151 #endif
Helmut64 0:56dd5df33ab4 152
Helmut64 0:56dd5df33ab4 153 #endif
Helmut64 0:56dd5df33ab4 154