Forked from Neal Horman: Adafruit_GFX, a derived version of the BSD licensed Adafrut GFX library for the SSD1306 controller for an OLED 128x32 or 128x64 display using SPI or I2C. Now it is adopted also for the SH1106 I2C 128x64 display as well...

Dependents:   Lab06_oled_i2c Lab06_BME280_oled Lab06_oled_clock I2C_SSD1306andSH1106_nucleo_F446RE

Committer:
cspista
Date:
Wed Feb 02 17:55:38 2022 +0000
Revision:
20:da33cca77ce5
Parent:
19:1b773847a04b
SH1106 initialization was added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nkhorman 0:c3dcd4c4983a 1 /*********************************************************************
nkhorman 0:c3dcd4c4983a 2 This is a library for our Monochrome OLEDs based on SSD1306 drivers
nkhorman 0:c3dcd4c4983a 3
nkhorman 0:c3dcd4c4983a 4 Pick one up today in the adafruit shop!
nkhorman 0:c3dcd4c4983a 5 ------> http://www.adafruit.com/category/63_98
nkhorman 0:c3dcd4c4983a 6
cspista 17:00a1379bd18a 7 These displays use SPI to communicate, 4 or 5 pins are required to
nkhorman 0:c3dcd4c4983a 8 interface
nkhorman 0:c3dcd4c4983a 9
cspista 17:00a1379bd18a 10 Adafruit invests time and resources providing this open source code,
cspista 17:00a1379bd18a 11 please support Adafruit and open-source hardware by purchasing
nkhorman 0:c3dcd4c4983a 12 products from Adafruit!
nkhorman 0:c3dcd4c4983a 13
cspista 17:00a1379bd18a 14 Written by Limor Fried/Ladyada for Adafruit Industries.
nkhorman 0:c3dcd4c4983a 15 BSD license, check license.txt for more information
nkhorman 0:c3dcd4c4983a 16 All text above, and the splash screen must be included in any redistribution
nkhorman 0:c3dcd4c4983a 17 *********************************************************************/
nkhorman 0:c3dcd4c4983a 18
nkhorman 0:c3dcd4c4983a 19 /*
nkhorman 9:ddb97c9850a2 20 * Modified by Neal Horman 7/14/2012 for use in mbed
cspista 20:da33cca77ce5 21 *
cspista 19:1b773847a04b 22 * Further modified by Istvan Cserny, January 31, 2022
cspista 19:1b773847a04b 23 * so that it could be used for the SH1106 I2C display as well
cspista 19:1b773847a04b 24 * The memory mode for the SSD1306 I2C display was changed to
cspista 20:da33cca77ce5 25 * Page addressing mode (0x10) and the virtual void sendDisplayBuffer()
cspista 19:1b773847a04b 26 * function has been rewritten accordingly.
cspista 19:1b773847a04b 27 *
cspista 19:1b773847a04b 28 *
cspista 20:da33cca77ce5 29 *
nkhorman 0:c3dcd4c4983a 30 */
nkhorman 0:c3dcd4c4983a 31
nkhorman 0:c3dcd4c4983a 32 #ifndef _ADAFRUIT_SSD1306_H_
nkhorman 0:c3dcd4c4983a 33 #define _ADAFRUIT_SSD1306_H_
nkhorman 0:c3dcd4c4983a 34
nkhorman 0:c3dcd4c4983a 35 #include "mbed.h"
nkhorman 0:c3dcd4c4983a 36 #include "Adafruit_GFX.h"
nkhorman 0:c3dcd4c4983a 37
nkhorman 9:ddb97c9850a2 38 #include <vector>
nkhorman 9:ddb97c9850a2 39 #include <algorithm>
nkhorman 0:c3dcd4c4983a 40
nkhorman 9:ddb97c9850a2 41 // A DigitalOut sub-class that provides a constructed default state
nkhorman 9:ddb97c9850a2 42 class DigitalOut2 : public DigitalOut
nkhorman 9:ddb97c9850a2 43 {
nkhorman 9:ddb97c9850a2 44 public:
cspista 17:00a1379bd18a 45 DigitalOut2(PinName pin, bool active = false) : DigitalOut(pin)
cspista 17:00a1379bd18a 46 {
cspista 17:00a1379bd18a 47 write(active);
cspista 17:00a1379bd18a 48 };
cspista 17:00a1379bd18a 49 DigitalOut2& operator= (int value)
cspista 17:00a1379bd18a 50 {
cspista 17:00a1379bd18a 51 write(value);
cspista 17:00a1379bd18a 52 return *this;
cspista 17:00a1379bd18a 53 };
cspista 17:00a1379bd18a 54 DigitalOut2& operator= (DigitalOut2& rhs)
cspista 17:00a1379bd18a 55 {
cspista 17:00a1379bd18a 56 write(rhs.read());
cspista 17:00a1379bd18a 57 return *this;
cspista 17:00a1379bd18a 58 };
cspista 17:00a1379bd18a 59 operator int()
cspista 17:00a1379bd18a 60 {
cspista 17:00a1379bd18a 61 return read();
cspista 17:00a1379bd18a 62 };
nkhorman 9:ddb97c9850a2 63 };
Neal Horman 6:1be3e3b46eb7 64
nkhorman 0:c3dcd4c4983a 65 #define SSD1306_EXTERNALVCC 0x1
nkhorman 0:c3dcd4c4983a 66 #define SSD1306_SWITCHCAPVCC 0x2
nkhorman 0:c3dcd4c4983a 67
nkhorman 11:86909e6db3c8 68 /** The pure base class for the SSD1306 display driver.
nkhorman 11:86909e6db3c8 69 *
nkhorman 11:86909e6db3c8 70 * You should derive from this for a new transport interface type,
nkhorman 11:86909e6db3c8 71 * such as the SPI and I2C drivers.
nkhorman 11:86909e6db3c8 72 */
nkhorman 0:c3dcd4c4983a 73 class Adafruit_SSD1306 : public Adafruit_GFX
nkhorman 0:c3dcd4c4983a 74 {
nkhorman 9:ddb97c9850a2 75 public:
cspista 17:00a1379bd18a 76 Adafruit_SSD1306(PinName RST, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
cspista 17:00a1379bd18a 77 : Adafruit_GFX(rawWidth,rawHeight)
cspista 17:00a1379bd18a 78 , rst(RST,false)
cspista 17:00a1379bd18a 79 {
cspista 17:00a1379bd18a 80 buffer.resize(rawHeight * rawWidth / 8);
cspista 17:00a1379bd18a 81 };
nkhorman 9:ddb97c9850a2 82
cspista 17:00a1379bd18a 83 void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC);
cspista 17:00a1379bd18a 84
cspista 17:00a1379bd18a 85 // These must be implemented in the derived transport driver
cspista 17:00a1379bd18a 86 virtual void command(uint8_t c) = 0;
cspista 17:00a1379bd18a 87 virtual void data(uint8_t c) = 0;
cspista 17:00a1379bd18a 88 virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
nkhorman 11:86909e6db3c8 89
cspista 17:00a1379bd18a 90 /// Clear the display buffer
cspista 17:00a1379bd18a 91 void clearDisplay(void);
cspista 17:00a1379bd18a 92 virtual void invertDisplay(bool i);
nkhorman 11:86909e6db3c8 93
cspista 17:00a1379bd18a 94 /// Cause the display to be updated with the buffer content.
cspista 17:00a1379bd18a 95 void display();
cspista 17:00a1379bd18a 96 /// Fill the buffer with the AdaFruit splash screen.
cspista 17:00a1379bd18a 97 virtual void splash();
cspista 17:00a1379bd18a 98
nkhorman 9:ddb97c9850a2 99 protected:
cspista 17:00a1379bd18a 100 virtual void sendDisplayBuffer() = 0;
cspista 17:00a1379bd18a 101 DigitalOut2 rst;
nkhorman 9:ddb97c9850a2 102
cspista 17:00a1379bd18a 103 // the memory buffer for the LCD
cspista 17:00a1379bd18a 104 std::vector<uint8_t> buffer;
nkhorman 9:ddb97c9850a2 105 };
nkhorman 9:ddb97c9850a2 106
nkhorman 11:86909e6db3c8 107
nkhorman 11:86909e6db3c8 108 /** This is the SPI SSD1306 display driver transport class
nkhorman 11:86909e6db3c8 109 *
nkhorman 11:86909e6db3c8 110 */
nkhorman 9:ddb97c9850a2 111 class Adafruit_SSD1306_Spi : public Adafruit_SSD1306
nkhorman 9:ddb97c9850a2 112 {
nkhorman 9:ddb97c9850a2 113 public:
cspista 17:00a1379bd18a 114 /** Create a SSD1306 SPI transport display driver instance with the specified DC, RST, and CS pins, as well as the display dimentions
cspista 17:00a1379bd18a 115 *
cspista 17:00a1379bd18a 116 * Required parameters
cspista 17:00a1379bd18a 117 * @param spi - a reference to an initialized SPI object
cspista 17:00a1379bd18a 118 * @param DC (Data/Command) pin name
cspista 17:00a1379bd18a 119 * @param RST (Reset) pin name
cspista 17:00a1379bd18a 120 * @param CS (Chip Select) pin name
cspista 17:00a1379bd18a 121 *
cspista 17:00a1379bd18a 122 * Optional parameters
cspista 17:00a1379bd18a 123 * @param rawHeight - the vertical number of pixels for the display, defaults to 32
cspista 17:00a1379bd18a 124 * @param rawWidth - the horizonal number of pixels for the display, defaults to 128
cspista 17:00a1379bd18a 125 */
cspista 17:00a1379bd18a 126 Adafruit_SSD1306_Spi(SPI &spi, PinName DC, PinName RST, PinName CS, uint8_t rawHieght = 32, uint8_t rawWidth = 128)
cspista 17:00a1379bd18a 127 : Adafruit_SSD1306(RST, rawHieght, rawWidth)
cspista 17:00a1379bd18a 128 , cs(CS,true)
cspista 17:00a1379bd18a 129 , dc(DC,false)
cspista 17:00a1379bd18a 130 , mspi(spi)
cspista 17:00a1379bd18a 131 {
cspista 17:00a1379bd18a 132 begin();
cspista 17:00a1379bd18a 133 splash();
cspista 17:00a1379bd18a 134 display();
cspista 17:00a1379bd18a 135 };
nkhorman 9:ddb97c9850a2 136
cspista 17:00a1379bd18a 137 virtual void command(uint8_t c)
cspista 17:00a1379bd18a 138 {
cspista 17:00a1379bd18a 139 cs = 1;
cspista 17:00a1379bd18a 140 dc = 0;
cspista 17:00a1379bd18a 141 cs = 0;
cspista 17:00a1379bd18a 142 mspi.write(c);
cspista 17:00a1379bd18a 143 cs = 1;
cspista 17:00a1379bd18a 144 };
nkhorman 9:ddb97c9850a2 145
cspista 17:00a1379bd18a 146 virtual void data(uint8_t c)
cspista 17:00a1379bd18a 147 {
cspista 17:00a1379bd18a 148 cs = 1;
cspista 17:00a1379bd18a 149 dc = 1;
cspista 17:00a1379bd18a 150 cs = 0;
cspista 17:00a1379bd18a 151 mspi.write(c);
cspista 17:00a1379bd18a 152 cs = 1;
cspista 17:00a1379bd18a 153 };
nkhorman 9:ddb97c9850a2 154
nkhorman 9:ddb97c9850a2 155 protected:
cspista 17:00a1379bd18a 156 virtual void sendDisplayBuffer()
cspista 17:00a1379bd18a 157 {
cspista 17:00a1379bd18a 158 cs = 1;
cspista 17:00a1379bd18a 159 dc = 1;
cspista 17:00a1379bd18a 160 cs = 0;
nkhorman 9:ddb97c9850a2 161
cspista 17:00a1379bd18a 162 for(uint16_t i=0, q=buffer.size(); i<q; i++)
cspista 17:00a1379bd18a 163 mspi.write(buffer[i]);
nkhorman 9:ddb97c9850a2 164
cspista 17:00a1379bd18a 165 if(height() == 32) {
cspista 17:00a1379bd18a 166 for(uint16_t i=0, q=buffer.size(); i<q; i++)
cspista 17:00a1379bd18a 167 mspi.write(0);
cspista 17:00a1379bd18a 168 }
nkhorman 11:86909e6db3c8 169
cspista 17:00a1379bd18a 170 cs = 1;
cspista 17:00a1379bd18a 171 };
nkhorman 9:ddb97c9850a2 172
cspista 17:00a1379bd18a 173 DigitalOut2 cs, dc;
cspista 17:00a1379bd18a 174 SPI &mspi;
nkhorman 9:ddb97c9850a2 175 };
nkhorman 9:ddb97c9850a2 176
nkhorman 11:86909e6db3c8 177 /** This is the I2C SSD1306 display driver transport class
nkhorman 11:86909e6db3c8 178 *
nkhorman 11:86909e6db3c8 179 */
nkhorman 9:ddb97c9850a2 180 class Adafruit_SSD1306_I2c : public Adafruit_SSD1306
nkhorman 9:ddb97c9850a2 181 {
nkhorman 9:ddb97c9850a2 182 public:
cspista 17:00a1379bd18a 183 #define SSD_I2C_ADDRESS 0x78
cspista 17:00a1379bd18a 184 /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions
cspista 17:00a1379bd18a 185 *
cspista 17:00a1379bd18a 186 * Required parameters
cspista 17:00a1379bd18a 187 * @param i2c - A reference to an initialized I2C object
cspista 17:00a1379bd18a 188 * @param RST - The Reset pin name
cspista 17:00a1379bd18a 189 *
cspista 17:00a1379bd18a 190 * Optional parameters
cspista 17:00a1379bd18a 191 * @param i2cAddress - The i2c address of the display
cspista 17:00a1379bd18a 192 * @param rawHeight - The vertical number of pixels for the display, defaults to 32
cspista 17:00a1379bd18a 193 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128
cspista 17:00a1379bd18a 194 */
cspista 17:00a1379bd18a 195 Adafruit_SSD1306_I2c(I2C &i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
cspista 17:00a1379bd18a 196 : Adafruit_SSD1306(RST, rawHeight, rawWidth)
cspista 17:00a1379bd18a 197 , mi2c(i2c)
cspista 17:00a1379bd18a 198 , mi2cAddress(i2cAddress)
cspista 17:00a1379bd18a 199 {
cspista 17:00a1379bd18a 200 begin();
cspista 20:da33cca77ce5 201 command(0x20); // SSD1306_MEMORYMODE
cspista 20:da33cca77ce5 202 command(0x10); // Page addressing mode (compatible with SG1106)
cspista 17:00a1379bd18a 203 splash();
cspista 17:00a1379bd18a 204 display();
cspista 17:00a1379bd18a 205 };
nkhorman 9:ddb97c9850a2 206
cspista 17:00a1379bd18a 207 virtual void command(uint8_t c)
cspista 17:00a1379bd18a 208 {
cspista 17:00a1379bd18a 209 char buff[2];
cspista 17:00a1379bd18a 210 buff[0] = 0; // Command Mode
cspista 17:00a1379bd18a 211 buff[1] = c;
cspista 17:00a1379bd18a 212 mi2c.write(mi2cAddress, buff, sizeof(buff));
cspista 17:00a1379bd18a 213 }
nkhorman 9:ddb97c9850a2 214
cspista 17:00a1379bd18a 215 virtual void data(uint8_t c)
cspista 17:00a1379bd18a 216 {
cspista 17:00a1379bd18a 217 char buff[2];
cspista 17:00a1379bd18a 218 buff[0] = 0x40; // Data Mode
cspista 17:00a1379bd18a 219 buff[1] = c;
cspista 17:00a1379bd18a 220 mi2c.write(mi2cAddress, buff, sizeof(buff));
cspista 17:00a1379bd18a 221 };
nkhorman 9:ddb97c9850a2 222
nkhorman 9:ddb97c9850a2 223 protected:
cspista 17:00a1379bd18a 224 virtual void sendDisplayBuffer()
cspista 17:00a1379bd18a 225 {
nkhorman 9:ddb97c9850a2 226
cspista 17:00a1379bd18a 227 char buff[256];
cspista 17:00a1379bd18a 228 char cmd[4] = {0, 0xB0, 0x00, 0x10};
cspista 19:1b773847a04b 229 for (uint8_t m = 0; m < _rawHeight/8; m++) {
cspista 17:00a1379bd18a 230 buff[0] = 0x40;
cspista 17:00a1379bd18a 231 cmd[1] = 0xB0 + m;
cspista 17:00a1379bd18a 232 for(int i=0; i<128; i++) {
cspista 17:00a1379bd18a 233 buff[i+1]= buffer[m*128+i];
cspista 17:00a1379bd18a 234 }
cspista 17:00a1379bd18a 235 mi2c.write(mi2cAddress, cmd, 4);
cspista 17:00a1379bd18a 236 mi2c.write(mi2cAddress, buff, 129);
cspista 17:00a1379bd18a 237 }
cspista 17:00a1379bd18a 238 };
nkhorman 9:ddb97c9850a2 239
cspista 17:00a1379bd18a 240 I2C &mi2c;
cspista 17:00a1379bd18a 241 uint8_t mi2cAddress;
nkhorman 0:c3dcd4c4983a 242 };
nkhorman 0:c3dcd4c4983a 243
cspista 17:00a1379bd18a 244 /** This is the I2C SH1106 display driver transport class
cspista 17:00a1379bd18a 245 *
cspista 17:00a1379bd18a 246 */
cspista 17:00a1379bd18a 247 class Adafruit_SH1106_I2c : public Adafruit_SSD1306
cspista 17:00a1379bd18a 248 {
cspista 17:00a1379bd18a 249 public:
cspista 17:00a1379bd18a 250 #define SSD_I2C_ADDRESS 0x78
cspista 17:00a1379bd18a 251 /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions
cspista 17:00a1379bd18a 252 *
cspista 17:00a1379bd18a 253 * Required parameters
cspista 17:00a1379bd18a 254 * @param i2c - A reference to an initialized I2C object
cspista 17:00a1379bd18a 255 * @param RST - The Reset pin name
cspista 17:00a1379bd18a 256 *
cspista 17:00a1379bd18a 257 * Optional parameters
cspista 17:00a1379bd18a 258 * @param i2cAddress - The i2c address of the display
cspista 17:00a1379bd18a 259 * @param rawHeight - The vertical number of pixels for the display, defaults to 32
cspista 17:00a1379bd18a 260 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128
cspista 17:00a1379bd18a 261 */
cspista 17:00a1379bd18a 262 Adafruit_SH1106_I2c(I2C &i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 64, uint8_t rawWidth = 128)
cspista 17:00a1379bd18a 263 : Adafruit_SSD1306(RST, rawHeight, rawWidth)
cspista 17:00a1379bd18a 264 , mi2c(i2c)
cspista 17:00a1379bd18a 265 , mi2cAddress(i2cAddress)
cspista 17:00a1379bd18a 266 {
cspista 20:da33cca77ce5 267 begin2();
cspista 17:00a1379bd18a 268 splash();
cspista 17:00a1379bd18a 269 display();
cspista 17:00a1379bd18a 270 };
cspista 17:00a1379bd18a 271
cspista 17:00a1379bd18a 272 virtual void command(uint8_t c)
cspista 17:00a1379bd18a 273 {
cspista 17:00a1379bd18a 274 char buff[2];
cspista 17:00a1379bd18a 275 buff[0] = 0; // Command Mode
cspista 17:00a1379bd18a 276 buff[1] = c;
cspista 17:00a1379bd18a 277 mi2c.write(mi2cAddress, buff, sizeof(buff));
cspista 17:00a1379bd18a 278 }
cspista 17:00a1379bd18a 279
cspista 17:00a1379bd18a 280 virtual void data(uint8_t c)
cspista 17:00a1379bd18a 281 {
cspista 17:00a1379bd18a 282 char buff[2];
cspista 17:00a1379bd18a 283 buff[0] = 0x40; // Data Mode
cspista 17:00a1379bd18a 284 buff[1] = c;
cspista 17:00a1379bd18a 285 mi2c.write(mi2cAddress, buff, sizeof(buff));
cspista 17:00a1379bd18a 286 };
cspista 17:00a1379bd18a 287
cspista 17:00a1379bd18a 288 protected:
cspista 20:da33cca77ce5 289 void begin2(void)
cspista 20:da33cca77ce5 290 {
cspista 20:da33cca77ce5 291 command(0xAE); //--display off
cspista 20:da33cca77ce5 292 command(0xA1); //--set segment re-map 127 to 0
cspista 20:da33cca77ce5 293 command(0xC8); //--Set COM Out Scan Dir 63 to 0
cspista 20:da33cca77ce5 294 command(0x32); //--set pump voltage value to 8.0V (SH1106 only)
cspista 20:da33cca77ce5 295 command(0x40); //--set start line address
cspista 20:da33cca77ce5 296 command(0x81); //--set contrast control register
cspista 20:da33cca77ce5 297 command(0x80); // POR value = 80
cspista 20:da33cca77ce5 298 command(0xA4); //--set normal mode (A5: test mode)
cspista 20:da33cca77ce5 299 command(0xA6); //--set normal display (i.e non-inverted mode)
cspista 20:da33cca77ce5 300 command(0xA8); //--set multiplex ratio(1 to 64)
cspista 20:da33cca77ce5 301 command(0x3F); //
cspista 20:da33cca77ce5 302 command(0xAD); //--set DC-DC mode
cspista 20:da33cca77ce5 303 command(0x8B); // DC-DC converter ON
cspista 20:da33cca77ce5 304 command(0xD3); //--set display offset
cspista 20:da33cca77ce5 305 command(0x00); // no offset
cspista 20:da33cca77ce5 306 command(0xD5); //--set display clock divide ratio/oscillator frequency
cspista 20:da33cca77ce5 307 command(0x50); // set frequency and divide ratio
cspista 20:da33cca77ce5 308 command(0xD9); //--set dis-charge/pre-charge period
cspista 20:da33cca77ce5 309 command(0x22); //
cspista 20:da33cca77ce5 310 command(0xDA); //--set com pins hardware configuration
cspista 20:da33cca77ce5 311 command(0x12);
cspista 20:da33cca77ce5 312 command(0xDB); //--set vcomh
cspista 20:da33cca77ce5 313 command(0x35); // SH1106: 0x35, SSD1306: 0x20 0.77xVcc
cspista 20:da33cca77ce5 314 command(0xAF); //--turn on SSD1306 panel
cspista 20:da33cca77ce5 315 };
cspista 20:da33cca77ce5 316
cspista 17:00a1379bd18a 317 virtual void sendDisplayBuffer()
cspista 17:00a1379bd18a 318 {
cspista 17:00a1379bd18a 319
cspista 17:00a1379bd18a 320 char buff[256];
cspista 17:00a1379bd18a 321 char cmd[4] = {0, 0xB0, 0x02, 0x10};
cspista 19:1b773847a04b 322 for (uint8_t m = 0; m < _rawHeight/8; m++) {
cspista 17:00a1379bd18a 323 buff[0] = 0x40;
cspista 17:00a1379bd18a 324 cmd[1] = 0xB0 + m;
cspista 17:00a1379bd18a 325 for(int i=0; i<128; i++) {
cspista 17:00a1379bd18a 326 buff[i+1]= buffer[m*128+i];
cspista 17:00a1379bd18a 327 }
cspista 17:00a1379bd18a 328 mi2c.write(mi2cAddress, cmd, 4);
cspista 17:00a1379bd18a 329 mi2c.write(mi2cAddress, buff, 129);
cspista 17:00a1379bd18a 330 }
cspista 17:00a1379bd18a 331 };
cspista 17:00a1379bd18a 332
cspista 17:00a1379bd18a 333 I2C &mi2c;
cspista 17:00a1379bd18a 334 uint8_t mi2cAddress;
cspista 17:00a1379bd18a 335 };
cspista 17:00a1379bd18a 336
cspista 17:00a1379bd18a 337
cspista 17:00a1379bd18a 338
nkhorman 0:c3dcd4c4983a 339 #endif