ThingPulse OLED SSD1306
Dependents: Turtle_RadioShuttle mbed-os5-F303-18650-Manager-tp4056 Kretanje_kroz_izbornike_OLED128x64_4tipke
SSD1306I2C.h@0:56dd5df33ab4, 2019-04-10 (annotated)
- 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?
User | Revision | Line number | New 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 |