Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Adafruit_GFX by
mx_ssd1306.h
00001 /********************************************************************* 00002 This is a library for our Monochrome OLEDs based on SSD1306 drivers 00003 00004 Pick one up today in the adafruit shop! 00005 ------> http://www.adafruit.com/category/63_98 00006 00007 These displays use SPI to communicate, 4 or 5 pins are required to 00008 interface 00009 00010 Adafruit invests time and resources providing this open source code, 00011 please support Adafruit and open-source hardware by purchasing 00012 products from Adafruit! 00013 00014 Written by Limor Fried/Ladyada for Adafruit Industries. 00015 BSD license, check license.txt for more information 00016 All text above, and the splash screen must be included in any redistribution 00017 *********************************************************************/ 00018 00019 /* 00020 * Modified by Neal Horman 7/14/2012 for use in mbed 00021 */ 00022 00023 #ifndef _ADAFRUIT_SSD1306_H_ 00024 #define _ADAFRUIT_SSD1306_H_ 00025 #include "im4oled_default_config.h" 00026 #include "mx_gfx.h" 00027 00028 #if (OLED_USE_VECTOR==1) 00029 #include <vector> 00030 #endif 00031 #include <algorithm> 00032 00033 #define OLED_HAS_RESET 0 00034 00035 // A DigitalOut sub-class that provides a constructed default state 00036 class DigitalOut2 : public DigitalOut 00037 { 00038 public: 00039 DigitalOut2(PinName pin, bool active = false) : DigitalOut(pin) { write(active); }; 00040 DigitalOut2& operator= (int value) { write(value); return *this; }; 00041 DigitalOut2& operator= (DigitalOut2& rhs) { write(rhs.read()); return *this; }; 00042 operator int() { return read(); }; 00043 }; 00044 00045 #define SSD1306_EXTERNALVCC 0x1 00046 #define SSD1306_SWITCHCAPVCC 0x2 00047 00048 /** The pure base class for the SSD1306 display driver. 00049 * 00050 * You should derive from this for a new transport interface type, 00051 * such as the SPI and I2C drivers. 00052 */ 00053 class MxSSD1306 : public MxGfx 00054 { 00055 public: 00056 #if (OLED_HAS_RESET==1) 00057 MxSSD1306(PinName RST, uint8_t rawHeight = 32, uint8_t rawWidth = 128) 00058 : MxGfx(rawWidth,rawHeight) 00059 , colBlock(0) 00060 , rowBlock(0) 00061 , rst(RST,false) 00062 #else 00063 MxSSD1306(uint8_t rawHeight = 32, uint8_t rawWidth = 128) 00064 : MxGfx(rawWidth,rawHeight) 00065 , colBlock(0) 00066 , rowBlock(0) 00067 #endif 00068 { 00069 //Initialize as all dirty 00070 memset(&dirty[0], 0xff, sizeof(dirty)); 00071 00072 #if (OLED_USE_VECTOR==0) 00073 memset(&buffer[0], 0, sizeof(buffer)); 00074 #else 00075 buffer.resize(rawHeight * rawWidth / 8); 00076 #endif 00077 }; 00078 00079 /** Initialize 00080 * @return 0 if success, else I2C or SPI error code 00081 */ 00082 uint8_t begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC); 00083 00084 // These must be implemented in the derived transport driver 00085 virtual uint8_t command(uint8_t c) = 0; 00086 virtual uint8_t data(uint8_t c) = 0; 00087 virtual void drawPixel(int16_t x, int16_t y, uint16_t color); 00088 00089 /** 00090 * Clear the display buffer. Requires a display() call at some point afterwards. 00091 * NOTE that this function will make the WHOLE display as dirty! The next display() call will update the 00092 * entire display! This can be prevented by just clearing the required part of the display using fillRect()! 00093 */ 00094 void clearDisplay(void); 00095 00096 /** Set display contrast 00097 * @return 0 if success, else I2C or SPI error code 00098 */ 00099 virtual uint8_t setContrast(uint8_t contrast); 00100 00101 /** Turn display on or off 00102 * @return 0 if success, else I2C or SPI error code 00103 */ 00104 virtual uint8_t displayOn(bool on); 00105 00106 /** Invert Display 00107 * @return 0 if success, else I2C or SPI error code 00108 */ 00109 virtual uint8_t invertDisplay(bool i); 00110 00111 /** Cause the display to be updated with the buffer content. 00112 * @return 0 if success, else I2C or SPI error code 00113 */ 00114 uint8_t display(); 00115 00116 // Fill the buffer with the AdaFruit splash screen. 00117 virtual void splash(); 00118 00119 protected: 00120 /** Write contents of display buffer to OLED display. 00121 * @return 0 if success, else I2C or SPI error code 00122 */ 00123 virtual uint8_t sendDisplayBuffer() = 0; 00124 00125 /** Write a block of display data. The 128x64 pixels are divided into: 00126 * - 8 RowBlocks, each with 8 rows. This is 1 page of the SSD1206 00127 * - 8 ColBlocks, each with 16 columns. 00128 * 00129 * @param rowBlock Value 0-7 indicating what block of 8 rows to write. 0=0-7, 00130 * 1=8-15, ...., 7=56-63 00131 * @param colBlock Value 0-7 indicating what block of 16 columns to write. 0=0-15, 00132 * 1=16-31, ...., 7=112-127 00133 * @return 0 if success, else I2C or SPI error code 00134 */ 00135 virtual uint8_t sendDisplayBuffer(uint8_t rowBlock, uint8_t colBlock) = 0; 00136 00137 public: 00138 // Set whole display as being dirty 00139 virtual void setAllDirty(); 00140 00141 // Protected Data 00142 protected: 00143 uint8_t colBlock, rowBlock; 00144 00145 #if (OLED_WIDTH <= 128 ) 00146 uint8_t dirty[OLED_HEIGHT/8]; //Each bit marks block of "8 Rows x 16 Columns". So, a single byte is enough for up to 128col. One byte for each 8 rows. 00147 #elif (OLED_WIDTH <= 256 ) 00148 uint16_t dirty[OLED_HEIGHT/8]; //Each bit marks block of "8 Rows x 16 Columns". One UINT16 = 16x16 = 256 columns. 00149 #endif 00150 00151 #if (OLED_HAS_RESET==1) 00152 DigitalOut2 rst; 00153 #endif 00154 00155 // the memory buffer for the LCD 00156 #if (OLED_USE_VECTOR==1) 00157 std::vector<uint8_t> buffer; 00158 #else 00159 uint8_t buffer[OLED_HEIGHT * OLED_WIDTH / 8]; 00160 #endif 00161 }; 00162 00163 00164 /** This is the SPI SSD1306 display driver transport class 00165 * 00166 */ 00167 class MxSSD1306_SPI : public MxSSD1306 00168 { 00169 public: 00170 /** Create a SSD1306 SPI transport display driver instance with the specified DC, RST, and CS pins, as well as the display dimentions 00171 * 00172 * Required parameters 00173 * @param spi - a reference to an initialized SPI object 00174 * @param DC (Data/Command) pin name 00175 * @param RST (Reset) pin name 00176 * @param CS (Chip Select) pin name 00177 * 00178 * Optional parameters 00179 * @param rawHeight - the vertical number of pixels for the display, defaults to 32 00180 * @param rawWidth - the horizonal number of pixels for the display, defaults to 128 00181 */ 00182 #if (OLED_HAS_RESET==1) 00183 MxSSD1306_SPI(SPI &spi, PinName DC, PinName RST, PinName CS, uint8_t rawHieght = 32, uint8_t rawWidth = 128) 00184 : MxSSD1306(RST, rawHieght, rawWidth) 00185 #else 00186 MxSSD1306_SPI(SPI &spi, PinName DC, PinName CS, uint8_t rawHieght = 32, uint8_t rawWidth = 128) 00187 : MxSSD1306(rawHieght, rawWidth) 00188 #endif 00189 , cs(CS,true) 00190 , dc(DC,false) 00191 , mspi(spi) 00192 { 00193 begin(); 00194 splash(); 00195 display(); 00196 }; 00197 00198 /** Send command via SPI 00199 * @param c The command to send 00200 * @return 0 if success, else SPI error 00201 */ 00202 virtual uint8_t command(uint8_t c) 00203 { 00204 cs = 1; 00205 dc = 0; 00206 cs = 0; 00207 mspi.write(c); 00208 cs = 1; 00209 return 0; 00210 }; 00211 00212 /** Send Data via SPI 00213 * @param c The data to send 00214 * @return 0 if success, else SPI error 00215 */ 00216 virtual uint8_t data(uint8_t c) 00217 { 00218 cs = 1; 00219 dc = 1; 00220 cs = 0; 00221 mspi.write(c); 00222 cs = 1; 00223 return 0; 00224 }; 00225 00226 protected: 00227 virtual uint8_t sendDisplayBuffer() 00228 { 00229 uint8_t retVal; 00230 cs = 1; 00231 dc = 1; 00232 cs = 0; 00233 00234 #if (OLED_USE_VECTOR==0) 00235 for(uint16_t i=0, q=sizeof(buffer); i<q; i++) { 00236 #else 00237 for(uint16_t i=0, q=buffer.size(); i<q; i++) { 00238 #endif 00239 if((retVal=mspi.write(buffer[i])) != 0) { 00240 cs = 1; 00241 return retVal; 00242 } 00243 } 00244 00245 if(height() == 32) 00246 { 00247 #if (OLED_USE_VECTOR==0) 00248 for(uint16_t i=0, q=sizeof(buffer); i<q; i++) { 00249 #else 00250 for(uint16_t i=0, q=buffer.size(); i<q; i++) { 00251 #endif 00252 if((retVal=mspi.write(0)) != 0) { 00253 cs = 1; 00254 return retVal; 00255 } 00256 } 00257 } 00258 00259 cs = 1; 00260 return 0; 00261 }; 00262 00263 DigitalOut2 cs, dc; 00264 SPI &mspi; 00265 }; 00266 00267 /** This is the I2C SSD1306 display driver transport class 00268 * 00269 */ 00270 class MxSSD1306_I2C : public MxSSD1306 00271 { 00272 public: 00273 #define SSD_I2C_ADDRESS 0x78 00274 /** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions 00275 * 00276 * Required parameters 00277 * @param i2c - A reference to an initialized I2C object 00278 * @param RST - The Reset pin name 00279 * 00280 * Optional parameters 00281 * @param i2cAddress - The i2c address of the display 00282 * @param rawHeight - The vertical number of pixels for the display, defaults to 32 00283 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128 00284 */ 00285 #if (OLED_HAS_RESET==1) 00286 Adafruit_SSD1306_I2c(I2C &i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128) 00287 : MxSSD1306(RST, rawHeight, rawWidth) 00288 #else 00289 MxSSD1306_I2C(I2C &i2c, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128) 00290 : MxSSD1306(rawHeight, rawWidth) 00291 #endif 00292 , mi2c(i2c) 00293 , mi2cAddress(i2cAddress) 00294 { 00295 begin(); 00296 splash(); 00297 display(); 00298 }; 00299 00300 00301 /**Constructor without doing any initialization requiring I2C object. Use this constructor if the I2C object must still be 00302 * initialized, or used after startup delay. 00303 * !!!!! IMPORTANT !!!!! 00304 * This constructor must be followed by calling the init() function BEFORE using any other functions! 00305 * 00306 * Required parameters 00307 * @param i2cAddress - The i2c address of the display 00308 * @param i2c - A reference to an initialized I2C object 00309 * 00310 * Optional parameters 00311 * @param rawHeight - The vertical number of pixels for the display, defaults to 32 00312 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128 00313 */ 00314 MxSSD1306_I2C(uint8_t i2cAddress, I2C &i2c, uint8_t rawHeight = 32, uint8_t rawWidth = 128) 00315 : MxSSD1306(rawHeight, rawWidth), mi2c(i2c), mi2cAddress(i2cAddress) 00316 { 00317 }; 00318 00319 00320 /** 00321 * Initialize with given I2C bus. 00322 * !!!!! IMPORTANT !!!!! 00323 * This function must be called after the Adafruit_SSD1306_I2c(rawHeight, rawWidth) constructor! 00324 * 00325 * @param i2c I2C Bus to use 00326 * @return 0 if OK, else error code 00327 */ 00328 uint8_t init() 00329 { 00330 uint8_t retVal; 00331 if((retVal=begin()) != 0) { 00332 return retVal; //Return error code 00333 } 00334 00335 //splash(); 00336 if((retVal=display()) != 0) { 00337 return retVal; //Return error code 00338 } 00339 return 0; 00340 } 00341 00342 /** Send command via I2C 00343 * @param c The command to send 00344 * @return 0 if success, else I2C error 00345 */ 00346 virtual uint8_t command(uint8_t c) 00347 { 00348 char buff[2]; 00349 buff[0] = 0; // Command Mode 00350 buff[1] = c; 00351 return mi2c.write(mi2cAddress, buff, sizeof(buff)); 00352 } 00353 00354 /** Send Data via I2C 00355 * @param c The data to send 00356 * @return 0 if success, else I2C error 00357 */ 00358 virtual uint8_t data(uint8_t c) 00359 { 00360 char buff[2]; 00361 buff[0] = 0x40; // Data Mode 00362 buff[1] = c; 00363 return mi2c.write(mi2cAddress, buff, sizeof(buff)); 00364 }; 00365 00366 protected: 00367 virtual uint8_t sendDisplayBuffer() 00368 { 00369 char buff[17]; 00370 buff[0] = 0x40; // Data Mode 00371 00372 // send display buffer in 16 byte chunks 00373 #if (OLED_USE_VECTOR==0) 00374 for(uint16_t i=0, q=sizeof(buffer); i<q; i+=16 ) { 00375 #else 00376 for(uint16_t i=0, q=buffer.size(); i<q; i+=16 ) { 00377 #endif 00378 uint8_t retVal; 00379 uint8_t x; 00380 00381 for(x=1; x<sizeof(buff); x++) { 00382 buff[x] = buffer[i+x-1]; 00383 } 00384 00385 if((retVal=mi2c.write(mi2cAddress, buff, sizeof(buff))) != 0) { 00386 return retVal; //Return error code 00387 } 00388 } 00389 return 0; 00390 }; 00391 00392 /** Write a block of display data. The 128x64 pixels are divided into: 00393 * - 8 RowBlocks, each with 8 rows. This is 1 page of the SSD1206 00394 * - 8 ColBlocks, each with 16 columns. 00395 * 00396 * @param rowBlock Value 0-7 indicating what block of 8 rows to write. 0=0-7, 00397 * 1=8-15, ...., 7=56-63 00398 * @param colBlock Value 0-7 indicating what block of 16 columns to write. 0=0-15, 00399 * 1=16-31, ...., 7=112-127 00400 * @return 0 if success, else I2C or SPI error code 00401 */ 00402 uint8_t sendDisplayBuffer(uint8_t rowBlock, uint8_t colBlock) { 00403 uint8_t retVal; 00404 int idxBuffer; 00405 char buff[17]; 00406 00407 buff[0] = 0x40; // Data Mode 00408 00409 //Each byte of buffer contains 8pixels for single column, and 8 rows. For example: 00410 //buffer[0] contains row 0-7 for column 0 00411 //buffer[1] contains row 0-7 for column 1 00412 idxBuffer = (rowBlock*128) + (colBlock*16); 00413 00414 // Copy requested "row block" and "column block" 00415 for(uint16_t i=0; i<16; i++) { 00416 buff[i+1] = buffer[idxBuffer+i]; 00417 } 00418 00419 //Write all display data 00420 if((retVal=mi2c.write(mi2cAddress, buff, 17)) != 0) { 00421 return retVal; //Return error code 00422 } 00423 00424 return 0; 00425 } 00426 00427 I2C &mi2c; 00428 uint8_t mi2cAddress; 00429 }; 00430 00431 #endif
Generated on Tue Jul 12 2022 19:44:12 by
1.7.2
