arduinoprojects

git clone https://git.tarina.org/arduinoprojects
Log | Files | Refs

Adafruit_SSD1306.cpp (42599B)


      1 /*!
      2  * @file Adafruit_SSD1306.cpp
      3  *
      4  * @mainpage Arduino library for monochrome OLEDs based on SSD1306 drivers.
      5  *
      6  * @section intro_sec Introduction
      7  *
      8  * This is documentation for Adafruit's SSD1306 library for monochrome
      9  * OLED displays: http://www.adafruit.com/category/63_98
     10  *
     11  * These displays use I2C or SPI to communicate. I2C requires 2 pins
     12  * (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
     13  * select, data/command) and optionally a reset pin. Hardware SPI or
     14  * 'bitbang' software SPI are both supported.
     15  *
     16  * Adafruit invests time and resources providing this open source code,
     17  * please support Adafruit and open-source hardware by purchasing
     18  * products from Adafruit!
     19  *
     20  * @section dependencies Dependencies
     21  *
     22  * This library depends on <a
     23  * href="https://github.com/adafruit/Adafruit-GFX-Library"> Adafruit_GFX</a>
     24  * being present on your system. Please make sure you have installed the latest
     25  * version before using this library.
     26  *
     27  * @section author Author
     28  *
     29  * Written by Limor Fried/Ladyada for Adafruit Industries, with
     30  * contributions from the open source community.
     31  *
     32  * @section license License
     33  *
     34  * BSD license, all text above, and the splash screen included below,
     35  * must be included in any redistribution.
     36  *
     37  */
     38 
     39 #ifdef __AVR__
     40 #include <avr/pgmspace.h>
     41 #elif defined(ESP8266) || defined(ESP32)
     42 #include <pgmspace.h>
     43 #else
     44 #define pgm_read_byte(addr)                                                    \
     45   (*(const unsigned char *)(addr)) ///< PROGMEM workaround for non-AVR
     46 #endif
     47 
     48 #if !defined(__ARM_ARCH) && !defined(ENERGIA) && !defined(ESP8266) &&          \
     49     !defined(ESP32) && !defined(__arc__)
     50 #include <util/delay.h>
     51 #endif
     52 
     53 #include "Adafruit_SSD1306.h"
     54 #include "splash.h"
     55 #include <Adafruit_GFX.h>
     56 
     57 // SOME DEFINES AND STATIC VARIABLES USED INTERNALLY -----------------------
     58 
     59 #if defined(I2C_BUFFER_LENGTH)
     60 #define WIRE_MAX min(256, I2C_BUFFER_LENGTH) ///< Particle or similar Wire lib
     61 #elif defined(BUFFER_LENGTH)
     62 #define WIRE_MAX min(256, BUFFER_LENGTH) ///< AVR or similar Wire lib
     63 #elif defined(SERIAL_BUFFER_SIZE)
     64 #define WIRE_MAX                                                               \
     65   min(255, SERIAL_BUFFER_SIZE - 1) ///< Newer Wire uses RingBuffer
     66 #else
     67 #define WIRE_MAX 32 ///< Use common Arduino core default
     68 #endif
     69 
     70 #define ssd1306_swap(a, b)                                                     \
     71   (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
     72 
     73 #if ARDUINO >= 100
     74 #define WIRE_WRITE wire->write ///< Wire write function in recent Arduino lib
     75 #else
     76 #define WIRE_WRITE wire->send ///< Wire write function in older Arduino lib
     77 #endif
     78 
     79 #ifdef HAVE_PORTREG
     80 #define SSD1306_SELECT *csPort &= ~csPinMask;       ///< Device select
     81 #define SSD1306_DESELECT *csPort |= csPinMask;      ///< Device deselect
     82 #define SSD1306_MODE_COMMAND *dcPort &= ~dcPinMask; ///< Command mode
     83 #define SSD1306_MODE_DATA *dcPort |= dcPinMask;     ///< Data mode
     84 #else
     85 #define SSD1306_SELECT digitalWrite(csPin, LOW);       ///< Device select
     86 #define SSD1306_DESELECT digitalWrite(csPin, HIGH);    ///< Device deselect
     87 #define SSD1306_MODE_COMMAND digitalWrite(dcPin, LOW); ///< Command mode
     88 #define SSD1306_MODE_DATA digitalWrite(dcPin, HIGH);   ///< Data mode
     89 #endif
     90 
     91 #if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER)
     92 #define SETWIRECLOCK wire->setClock(wireClk)    ///< Set before I2C transfer
     93 #define RESWIRECLOCK wire->setClock(restoreClk) ///< Restore after I2C xfer
     94 #else // setClock() is not present in older Arduino Wire lib (or WICED)
     95 #define SETWIRECLOCK ///< Dummy stand-in define
     96 #define RESWIRECLOCK ///< keeps compiler happy
     97 #endif
     98 
     99 #if defined(SPI_HAS_TRANSACTION)
    100 #define SPI_TRANSACTION_START spi->beginTransaction(spiSettings) ///< Pre-SPI
    101 #define SPI_TRANSACTION_END spi->endTransaction()                ///< Post-SPI
    102 #else // SPI transactions likewise not present in older Arduino SPI lib
    103 #define SPI_TRANSACTION_START ///< Dummy stand-in define
    104 #define SPI_TRANSACTION_END   ///< keeps compiler happy
    105 #endif
    106 
    107 // The definition of 'transaction' is broadened a bit in the context of
    108 // this library -- referring not just to SPI transactions (if supported
    109 // in the version of the SPI library being used), but also chip select
    110 // (if SPI is being used, whether hardware or soft), and also to the
    111 // beginning and end of I2C transfers (the Wire clock may be sped up before
    112 // issuing data to the display, then restored to the default rate afterward
    113 // so other I2C device types still work).  All of these are encapsulated
    114 // in the TRANSACTION_* macros.
    115 
    116 // Check first if Wire, then hardware SPI, then soft SPI:
    117 #define TRANSACTION_START                                                      \
    118   if (wire) {                                                                  \
    119     SETWIRECLOCK;                                                              \
    120   } else {                                                                     \
    121     if (spi) {                                                                 \
    122       SPI_TRANSACTION_START;                                                   \
    123     }                                                                          \
    124     SSD1306_SELECT;                                                            \
    125   } ///< Wire, SPI or bitbang transfer setup
    126 #define TRANSACTION_END                                                        \
    127   if (wire) {                                                                  \
    128     RESWIRECLOCK;                                                              \
    129   } else {                                                                     \
    130     SSD1306_DESELECT;                                                          \
    131     if (spi) {                                                                 \
    132       SPI_TRANSACTION_END;                                                     \
    133     }                                                                          \
    134   } ///< Wire, SPI or bitbang transfer end
    135 
    136 // CONSTRUCTORS, DESTRUCTOR ------------------------------------------------
    137 
    138 /*!
    139     @brief  Constructor for I2C-interfaced SSD1306 displays.
    140     @param  w
    141             Display width in pixels
    142     @param  h
    143             Display height in pixels
    144     @param  twi
    145             Pointer to an existing TwoWire instance (e.g. &Wire, the
    146             microcontroller's primary I2C bus).
    147     @param  rst_pin
    148             Reset pin (using Arduino pin numbering), or -1 if not used
    149             (some displays might be wired to share the microcontroller's
    150             reset pin).
    151     @param  clkDuring
    152             Speed (in Hz) for Wire transmissions in SSD1306 library calls.
    153             Defaults to 400000 (400 KHz), a known 'safe' value for most
    154             microcontrollers, and meets the SSD1306 datasheet spec.
    155             Some systems can operate I2C faster (800 KHz for ESP32, 1 MHz
    156             for many other 32-bit MCUs), and some (perhaps not all)
    157             SSD1306's can work with this -- so it's optionally be specified
    158             here and is not a default behavior. (Ignored if using pre-1.5.7
    159             Arduino software, which operates I2C at a fixed 100 KHz.)
    160     @param  clkAfter
    161             Speed (in Hz) for Wire transmissions following SSD1306 library
    162             calls. Defaults to 100000 (100 KHz), the default Arduino Wire
    163             speed. This is done rather than leaving it at the 'during' speed
    164             because other devices on the I2C bus might not be compatible
    165             with the faster rate. (Ignored if using pre-1.5.7 Arduino
    166             software, which operates I2C at a fixed 100 KHz.)
    167     @return Adafruit_SSD1306 object.
    168     @note   Call the object's begin() function before use -- buffer
    169             allocation is performed there!
    170 */
    171 Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi,
    172                                    int8_t rst_pin, uint32_t clkDuring,
    173                                    uint32_t clkAfter)
    174     : Adafruit_GFX(w, h), spi(NULL), wire(twi ? twi : &Wire), buffer(NULL),
    175       mosiPin(-1), clkPin(-1), dcPin(-1), csPin(-1), rstPin(rst_pin)
    176 #if ARDUINO >= 157
    177       ,
    178       wireClk(clkDuring), restoreClk(clkAfter)
    179 #endif
    180 {
    181 }
    182 
    183 /*!
    184     @brief  Constructor for SPI SSD1306 displays, using software (bitbang)
    185             SPI.
    186     @param  w
    187             Display width in pixels
    188     @param  h
    189             Display height in pixels
    190     @param  mosi_pin
    191             MOSI (master out, slave in) pin (using Arduino pin numbering).
    192             This transfers serial data from microcontroller to display.
    193     @param  sclk_pin
    194             SCLK (serial clock) pin (using Arduino pin numbering).
    195             This clocks each bit from MOSI.
    196     @param  dc_pin
    197             Data/command pin (using Arduino pin numbering), selects whether
    198             display is receiving commands (low) or data (high).
    199     @param  rst_pin
    200             Reset pin (using Arduino pin numbering), or -1 if not used
    201             (some displays might be wired to share the microcontroller's
    202             reset pin).
    203     @param  cs_pin
    204             Chip-select pin (using Arduino pin numbering) for sharing the
    205             bus with other devices. Active low.
    206     @return Adafruit_SSD1306 object.
    207     @note   Call the object's begin() function before use -- buffer
    208             allocation is performed there!
    209 */
    210 Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, int8_t mosi_pin,
    211                                    int8_t sclk_pin, int8_t dc_pin,
    212                                    int8_t rst_pin, int8_t cs_pin)
    213     : Adafruit_GFX(w, h), spi(NULL), wire(NULL), buffer(NULL),
    214       mosiPin(mosi_pin), clkPin(sclk_pin), dcPin(dc_pin), csPin(cs_pin),
    215       rstPin(rst_pin) {}
    216 
    217 /*!
    218     @brief  Constructor for SPI SSD1306 displays, using native hardware SPI.
    219     @param  w
    220             Display width in pixels
    221     @param  h
    222             Display height in pixels
    223     @param  spi
    224             Pointer to an existing SPIClass instance (e.g. &SPI, the
    225             microcontroller's primary SPI bus).
    226     @param  dc_pin
    227             Data/command pin (using Arduino pin numbering), selects whether
    228             display is receiving commands (low) or data (high).
    229     @param  rst_pin
    230             Reset pin (using Arduino pin numbering), or -1 if not used
    231             (some displays might be wired to share the microcontroller's
    232             reset pin).
    233     @param  cs_pin
    234             Chip-select pin (using Arduino pin numbering) for sharing the
    235             bus with other devices. Active low.
    236     @param  bitrate
    237             SPI clock rate for transfers to this display. Default if
    238             unspecified is 8000000UL (8 MHz).
    239     @return Adafruit_SSD1306 object.
    240     @note   Call the object's begin() function before use -- buffer
    241             allocation is performed there!
    242 */
    243 Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, SPIClass *spi,
    244                                    int8_t dc_pin, int8_t rst_pin, int8_t cs_pin,
    245                                    uint32_t bitrate)
    246     : Adafruit_GFX(w, h), spi(spi ? spi : &SPI), wire(NULL), buffer(NULL),
    247       mosiPin(-1), clkPin(-1), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin) {
    248 #ifdef SPI_HAS_TRANSACTION
    249   spiSettings = SPISettings(bitrate, MSBFIRST, SPI_MODE0);
    250 #endif
    251 }
    252 
    253 /*!
    254     @brief  DEPRECATED constructor for SPI SSD1306 displays, using software
    255             (bitbang) SPI. Provided for older code to maintain compatibility
    256             with the current library. Screen size is determined by enabling
    257             one of the SSD1306_* size defines in Adafruit_SSD1306.h. New
    258             code should NOT use this.
    259     @param  mosi_pin
    260             MOSI (master out, slave in) pin (using Arduino pin numbering).
    261             This transfers serial data from microcontroller to display.
    262     @param  sclk_pin
    263             SCLK (serial clock) pin (using Arduino pin numbering).
    264             This clocks each bit from MOSI.
    265     @param  dc_pin
    266             Data/command pin (using Arduino pin numbering), selects whether
    267             display is receiving commands (low) or data (high).
    268     @param  rst_pin
    269             Reset pin (using Arduino pin numbering), or -1 if not used
    270             (some displays might be wired to share the microcontroller's
    271             reset pin).
    272     @param  cs_pin
    273             Chip-select pin (using Arduino pin numbering) for sharing the
    274             bus with other devices. Active low.
    275     @return Adafruit_SSD1306 object.
    276     @note   Call the object's begin() function before use -- buffer
    277             allocation is performed there!
    278 */
    279 Adafruit_SSD1306::Adafruit_SSD1306(int8_t mosi_pin, int8_t sclk_pin,
    280                                    int8_t dc_pin, int8_t rst_pin, int8_t cs_pin)
    281     : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT), spi(NULL), wire(NULL),
    282       buffer(NULL), mosiPin(mosi_pin), clkPin(sclk_pin), dcPin(dc_pin),
    283       csPin(cs_pin), rstPin(rst_pin) {}
    284 
    285 /*!
    286     @brief  DEPRECATED constructor for SPI SSD1306 displays, using native
    287             hardware SPI. Provided for older code to maintain compatibility
    288             with the current library. Screen size is determined by enabling
    289             one of the SSD1306_* size defines in Adafruit_SSD1306.h. New
    290             code should NOT use this. Only the primary SPI bus is supported,
    291             and bitrate is fixed at 8 MHz.
    292     @param  dc_pin
    293             Data/command pin (using Arduino pin numbering), selects whether
    294             display is receiving commands (low) or data (high).
    295     @param  rst_pin
    296             Reset pin (using Arduino pin numbering), or -1 if not used
    297             (some displays might be wired to share the microcontroller's
    298             reset pin).
    299     @param  cs_pin
    300             Chip-select pin (using Arduino pin numbering) for sharing the
    301             bus with other devices. Active low.
    302     @return Adafruit_SSD1306 object.
    303     @note   Call the object's begin() function before use -- buffer
    304             allocation is performed there!
    305 */
    306 Adafruit_SSD1306::Adafruit_SSD1306(int8_t dc_pin, int8_t rst_pin, int8_t cs_pin)
    307     : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT), spi(&SPI), wire(NULL),
    308       buffer(NULL), mosiPin(-1), clkPin(-1), dcPin(dc_pin), csPin(cs_pin),
    309       rstPin(rst_pin) {
    310 #ifdef SPI_HAS_TRANSACTION
    311   spiSettings = SPISettings(8000000, MSBFIRST, SPI_MODE0);
    312 #endif
    313 }
    314 
    315 /*!
    316     @brief  DEPRECATED constructor for I2C SSD1306 displays. Provided for
    317             older code to maintain compatibility with the current library.
    318             Screen size is determined by enabling one of the SSD1306_* size
    319             defines in Adafruit_SSD1306.h. New code should NOT use this.
    320             Only the primary I2C bus is supported.
    321     @param  rst_pin
    322             Reset pin (using Arduino pin numbering), or -1 if not used
    323             (some displays might be wired to share the microcontroller's
    324             reset pin).
    325     @return Adafruit_SSD1306 object.
    326     @note   Call the object's begin() function before use -- buffer
    327             allocation is performed there!
    328 */
    329 Adafruit_SSD1306::Adafruit_SSD1306(int8_t rst_pin)
    330     : Adafruit_GFX(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT), spi(NULL), wire(&Wire),
    331       buffer(NULL), mosiPin(-1), clkPin(-1), dcPin(-1), csPin(-1),
    332       rstPin(rst_pin) {}
    333 
    334 /*!
    335     @brief  Destructor for Adafruit_SSD1306 object.
    336 */
    337 Adafruit_SSD1306::~Adafruit_SSD1306(void) {
    338   if (buffer) {
    339     free(buffer);
    340     buffer = NULL;
    341   }
    342 }
    343 
    344 // LOW-LEVEL UTILS ---------------------------------------------------------
    345 
    346 // Issue single byte out SPI, either soft or hardware as appropriate.
    347 // SPI transaction/selection must be performed in calling function.
    348 inline void Adafruit_SSD1306::SPIwrite(uint8_t d) {
    349   if (spi) {
    350     (void)spi->transfer(d);
    351   } else {
    352     for (uint8_t bit = 0x80; bit; bit >>= 1) {
    353 #ifdef HAVE_PORTREG
    354       if (d & bit)
    355         *mosiPort |= mosiPinMask;
    356       else
    357         *mosiPort &= ~mosiPinMask;
    358       *clkPort |= clkPinMask;  // Clock high
    359       *clkPort &= ~clkPinMask; // Clock low
    360 #else
    361       digitalWrite(mosiPin, d & bit);
    362       digitalWrite(clkPin, HIGH);
    363       digitalWrite(clkPin, LOW);
    364 #endif
    365     }
    366   }
    367 }
    368 
    369 // Issue single command to SSD1306, using I2C or hard/soft SPI as needed.
    370 // Because command calls are often grouped, SPI transaction and selection
    371 // must be started/ended in calling function for efficiency.
    372 // This is a private function, not exposed (see ssd1306_command() instead).
    373 void Adafruit_SSD1306::ssd1306_command1(uint8_t c) {
    374   if (wire) { // I2C
    375     wire->beginTransmission(i2caddr);
    376     WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
    377     WIRE_WRITE(c);
    378     wire->endTransmission();
    379   } else { // SPI (hw or soft) -- transaction started in calling function
    380     SSD1306_MODE_COMMAND
    381     SPIwrite(c);
    382   }
    383 }
    384 
    385 // Issue list of commands to SSD1306, same rules as above re: transactions.
    386 // This is a private function, not exposed.
    387 void Adafruit_SSD1306::ssd1306_commandList(const uint8_t *c, uint8_t n) {
    388   if (wire) { // I2C
    389     wire->beginTransmission(i2caddr);
    390     WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
    391     uint16_t bytesOut = 1;
    392     while (n--) {
    393       if (bytesOut >= WIRE_MAX) {
    394         wire->endTransmission();
    395         wire->beginTransmission(i2caddr);
    396         WIRE_WRITE((uint8_t)0x00); // Co = 0, D/C = 0
    397         bytesOut = 1;
    398       }
    399       WIRE_WRITE(pgm_read_byte(c++));
    400       bytesOut++;
    401     }
    402     wire->endTransmission();
    403   } else { // SPI -- transaction started in calling function
    404     SSD1306_MODE_COMMAND
    405     while (n--)
    406       SPIwrite(pgm_read_byte(c++));
    407   }
    408 }
    409 
    410 // A public version of ssd1306_command1(), for existing user code that
    411 // might rely on that function. This encapsulates the command transfer
    412 // in a transaction start/end, similar to old library's handling of it.
    413 /*!
    414     @brief  Issue a single low-level command directly to the SSD1306
    415             display, bypassing the library.
    416     @param  c
    417             Command to issue (0x00 to 0xFF, see datasheet).
    418     @return None (void).
    419 */
    420 void Adafruit_SSD1306::ssd1306_command(uint8_t c) {
    421   TRANSACTION_START
    422   ssd1306_command1(c);
    423   TRANSACTION_END
    424 }
    425 
    426 // ALLOCATE & INIT DISPLAY -------------------------------------------------
    427 
    428 /*!
    429     @brief  Allocate RAM for image buffer, initialize peripherals and pins.
    430     @param  vcs
    431             VCC selection. Pass SSD1306_SWITCHCAPVCC to generate the display
    432             voltage (step up) from the 3.3V source, or SSD1306_EXTERNALVCC
    433             otherwise. Most situations with Adafruit SSD1306 breakouts will
    434             want SSD1306_SWITCHCAPVCC.
    435     @param  addr
    436             I2C address of corresponding SSD1306 display (or pass 0 to use
    437             default of 0x3C for 128x32 display, 0x3D for all others).
    438             SPI displays (hardware or software) do not use addresses, but
    439             this argument is still required (pass 0 or any value really,
    440             it will simply be ignored). Default if unspecified is 0.
    441     @param  reset
    442             If true, and if the reset pin passed to the constructor is
    443             valid, a hard reset will be performed before initializing the
    444             display. If using multiple SSD1306 displays on the same bus, and
    445             if they all share the same reset pin, you should only pass true
    446             on the first display being initialized, false on all others,
    447             else the already-initialized displays would be reset. Default if
    448             unspecified is true.
    449     @param  periphBegin
    450             If true, and if a hardware peripheral is being used (I2C or SPI,
    451             but not software SPI), call that peripheral's begin() function,
    452             else (false) it has already been done in one's sketch code.
    453             Cases where false might be used include multiple displays or
    454             other devices sharing a common bus, or situations on some
    455             platforms where a nonstandard begin() function is available
    456             (e.g. a TwoWire interface on non-default pins, as can be done
    457             on the ESP8266 and perhaps others).
    458     @return true on successful allocation/init, false otherwise.
    459             Well-behaved code should check the return value before
    460             proceeding.
    461     @note   MUST call this function before any drawing or updates!
    462 */
    463 bool Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, bool reset,
    464                              bool periphBegin) {
    465 
    466   if ((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
    467     return false;
    468 
    469   clearDisplay();
    470   if (HEIGHT > 32) {
    471     drawBitmap((WIDTH - splash1_width) / 2, (HEIGHT - splash1_height) / 2,
    472                splash1_data, splash1_width, splash1_height, 1);
    473   } else {
    474     drawBitmap((WIDTH - splash2_width) / 2, (HEIGHT - splash2_height) / 2,
    475                splash2_data, splash2_width, splash2_height, 1);
    476   }
    477 
    478   vccstate = vcs;
    479 
    480   // Setup pin directions
    481   if (wire) { // Using I2C
    482     // If I2C address is unspecified, use default
    483     // (0x3C for 32-pixel-tall displays, 0x3D for all others).
    484     i2caddr = addr ? addr : ((HEIGHT == 32) ? 0x3C : 0x3D);
    485     // TwoWire begin() function might be already performed by the calling
    486     // function if it has unusual circumstances (e.g. TWI variants that
    487     // can accept different SDA/SCL pins, or if two SSD1306 instances
    488     // with different addresses -- only a single begin() is needed).
    489     if (periphBegin)
    490       wire->begin();
    491   } else { // Using one of the SPI modes, either soft or hardware
    492     pinMode(dcPin, OUTPUT); // Set data/command pin as output
    493     pinMode(csPin, OUTPUT); // Same for chip select
    494 #ifdef HAVE_PORTREG
    495     dcPort = (PortReg *)portOutputRegister(digitalPinToPort(dcPin));
    496     dcPinMask = digitalPinToBitMask(dcPin);
    497     csPort = (PortReg *)portOutputRegister(digitalPinToPort(csPin));
    498     csPinMask = digitalPinToBitMask(csPin);
    499 #endif
    500     SSD1306_DESELECT
    501     if (spi) { // Hardware SPI
    502       // SPI peripheral begin same as wire check above.
    503       if (periphBegin)
    504         spi->begin();
    505     } else {                    // Soft SPI
    506       pinMode(mosiPin, OUTPUT); // MOSI and SCLK outputs
    507       pinMode(clkPin, OUTPUT);
    508 #ifdef HAVE_PORTREG
    509       mosiPort = (PortReg *)portOutputRegister(digitalPinToPort(mosiPin));
    510       mosiPinMask = digitalPinToBitMask(mosiPin);
    511       clkPort = (PortReg *)portOutputRegister(digitalPinToPort(clkPin));
    512       clkPinMask = digitalPinToBitMask(clkPin);
    513       *clkPort &= ~clkPinMask; // Clock low
    514 #else
    515       digitalWrite(clkPin, LOW); // Clock low
    516 #endif
    517     }
    518   }
    519 
    520   // Reset SSD1306 if requested and reset pin specified in constructor
    521   if (reset && (rstPin >= 0)) {
    522     pinMode(rstPin, OUTPUT);
    523     digitalWrite(rstPin, HIGH);
    524     delay(1);                   // VDD goes high at start, pause for 1 ms
    525     digitalWrite(rstPin, LOW);  // Bring reset low
    526     delay(10);                  // Wait 10 ms
    527     digitalWrite(rstPin, HIGH); // Bring out of reset
    528   }
    529 
    530   TRANSACTION_START
    531 
    532   // Init sequence
    533   static const uint8_t PROGMEM init1[] = {SSD1306_DISPLAYOFF,         // 0xAE
    534                                           SSD1306_SETDISPLAYCLOCKDIV, // 0xD5
    535                                           0x80, // the suggested ratio 0x80
    536                                           SSD1306_SETMULTIPLEX}; // 0xA8
    537   ssd1306_commandList(init1, sizeof(init1));
    538   ssd1306_command1(HEIGHT - 1);
    539 
    540   static const uint8_t PROGMEM init2[] = {SSD1306_SETDISPLAYOFFSET, // 0xD3
    541                                           0x0,                      // no offset
    542                                           SSD1306_SETSTARTLINE | 0x0, // line #0
    543                                           SSD1306_CHARGEPUMP};        // 0x8D
    544   ssd1306_commandList(init2, sizeof(init2));
    545 
    546   ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);
    547 
    548   static const uint8_t PROGMEM init3[] = {SSD1306_MEMORYMODE, // 0x20
    549                                           0x00, // 0x0 act like ks0108
    550                                           SSD1306_SEGREMAP | 0x1,
    551                                           SSD1306_COMSCANDEC};
    552   ssd1306_commandList(init3, sizeof(init3));
    553 
    554   uint8_t comPins = 0x02;
    555   contrast = 0x8F;
    556 
    557   if ((WIDTH == 128) && (HEIGHT == 32)) {
    558     comPins = 0x02;
    559     contrast = 0x8F;
    560   } else if ((WIDTH == 128) && (HEIGHT == 64)) {
    561     comPins = 0x12;
    562     contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF;
    563   } else if ((WIDTH == 96) && (HEIGHT == 16)) {
    564     comPins = 0x2; // ada x12
    565     contrast = (vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0xAF;
    566   } else {
    567     // Other screen varieties -- TBD
    568   }
    569 
    570   ssd1306_command1(SSD1306_SETCOMPINS);
    571   ssd1306_command1(comPins);
    572   ssd1306_command1(SSD1306_SETCONTRAST);
    573   ssd1306_command1(contrast);
    574 
    575   ssd1306_command1(SSD1306_SETPRECHARGE); // 0xd9
    576   ssd1306_command1((vccstate == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1);
    577   static const uint8_t PROGMEM init5[] = {
    578       SSD1306_SETVCOMDETECT, // 0xDB
    579       0x40,
    580       SSD1306_DISPLAYALLON_RESUME, // 0xA4
    581       SSD1306_NORMALDISPLAY,       // 0xA6
    582       SSD1306_DEACTIVATE_SCROLL,
    583       SSD1306_DISPLAYON}; // Main screen turn on
    584   ssd1306_commandList(init5, sizeof(init5));
    585 
    586   TRANSACTION_END
    587 
    588   return true; // Success
    589 }
    590 
    591 // DRAWING FUNCTIONS -------------------------------------------------------
    592 
    593 /*!
    594     @brief  Set/clear/invert a single pixel. This is also invoked by the
    595             Adafruit_GFX library in generating many higher-level graphics
    596             primitives.
    597     @param  x
    598             Column of display -- 0 at left to (screen width - 1) at right.
    599     @param  y
    600             Row of display -- 0 at top to (screen height -1) at bottom.
    601     @param  color
    602             Pixel color, one of: SSD1306_BLACK, SSD1306_WHITE or SSD1306_INVERT.
    603     @return None (void).
    604     @note   Changes buffer contents only, no immediate effect on display.
    605             Follow up with a call to display(), or with other graphics
    606             commands as needed by one's own application.
    607 */
    608 void Adafruit_SSD1306::drawPixel(int16_t x, int16_t y, uint16_t color) {
    609   if ((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
    610     // Pixel is in-bounds. Rotate coordinates if needed.
    611     switch (getRotation()) {
    612     case 1:
    613       ssd1306_swap(x, y);
    614       x = WIDTH - x - 1;
    615       break;
    616     case 2:
    617       x = WIDTH - x - 1;
    618       y = HEIGHT - y - 1;
    619       break;
    620     case 3:
    621       ssd1306_swap(x, y);
    622       y = HEIGHT - y - 1;
    623       break;
    624     }
    625     switch (color) {
    626     case SSD1306_WHITE:
    627       buffer[x + (y / 8) * WIDTH] |= (1 << (y & 7));
    628       break;
    629     case SSD1306_BLACK:
    630       buffer[x + (y / 8) * WIDTH] &= ~(1 << (y & 7));
    631       break;
    632     case SSD1306_INVERSE:
    633       buffer[x + (y / 8) * WIDTH] ^= (1 << (y & 7));
    634       break;
    635     }
    636   }
    637 }
    638 
    639 /*!
    640     @brief  Clear contents of display buffer (set all pixels to off).
    641     @return None (void).
    642     @note   Changes buffer contents only, no immediate effect on display.
    643             Follow up with a call to display(), or with other graphics
    644             commands as needed by one's own application.
    645 */
    646 void Adafruit_SSD1306::clearDisplay(void) {
    647   memset(buffer, 0, WIDTH * ((HEIGHT + 7) / 8));
    648 }
    649 
    650 /*!
    651     @brief  Draw a horizontal line. This is also invoked by the Adafruit_GFX
    652             library in generating many higher-level graphics primitives.
    653     @param  x
    654             Leftmost column -- 0 at left to (screen width - 1) at right.
    655     @param  y
    656             Row of display -- 0 at top to (screen height -1) at bottom.
    657     @param  w
    658             Width of line, in pixels.
    659     @param  color
    660             Line color, one of: SSD1306_BLACK, SSD1306_WHITE or SSD1306_INVERT.
    661     @return None (void).
    662     @note   Changes buffer contents only, no immediate effect on display.
    663             Follow up with a call to display(), or with other graphics
    664             commands as needed by one's own application.
    665 */
    666 void Adafruit_SSD1306::drawFastHLine(int16_t x, int16_t y, int16_t w,
    667                                      uint16_t color) {
    668   bool bSwap = false;
    669   switch (rotation) {
    670   case 1:
    671     // 90 degree rotation, swap x & y for rotation, then invert x
    672     bSwap = true;
    673     ssd1306_swap(x, y);
    674     x = WIDTH - x - 1;
    675     break;
    676   case 2:
    677     // 180 degree rotation, invert x and y, then shift y around for height.
    678     x = WIDTH - x - 1;
    679     y = HEIGHT - y - 1;
    680     x -= (w - 1);
    681     break;
    682   case 3:
    683     // 270 degree rotation, swap x & y for rotation,
    684     // then invert y and adjust y for w (not to become h)
    685     bSwap = true;
    686     ssd1306_swap(x, y);
    687     y = HEIGHT - y - 1;
    688     y -= (w - 1);
    689     break;
    690   }
    691 
    692   if (bSwap)
    693     drawFastVLineInternal(x, y, w, color);
    694   else
    695     drawFastHLineInternal(x, y, w, color);
    696 }
    697 
    698 void Adafruit_SSD1306::drawFastHLineInternal(int16_t x, int16_t y, int16_t w,
    699                                              uint16_t color) {
    700 
    701   if ((y >= 0) && (y < HEIGHT)) { // Y coord in bounds?
    702     if (x < 0) {                  // Clip left
    703       w += x;
    704       x = 0;
    705     }
    706     if ((x + w) > WIDTH) { // Clip right
    707       w = (WIDTH - x);
    708     }
    709     if (w > 0) { // Proceed only if width is positive
    710       uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x], mask = 1 << (y & 7);
    711       switch (color) {
    712       case SSD1306_WHITE:
    713         while (w--) {
    714           *pBuf++ |= mask;
    715         };
    716         break;
    717       case SSD1306_BLACK:
    718         mask = ~mask;
    719         while (w--) {
    720           *pBuf++ &= mask;
    721         };
    722         break;
    723       case SSD1306_INVERSE:
    724         while (w--) {
    725           *pBuf++ ^= mask;
    726         };
    727         break;
    728       }
    729     }
    730   }
    731 }
    732 
    733 /*!
    734     @brief  Draw a vertical line. This is also invoked by the Adafruit_GFX
    735             library in generating many higher-level graphics primitives.
    736     @param  x
    737             Column of display -- 0 at left to (screen width -1) at right.
    738     @param  y
    739             Topmost row -- 0 at top to (screen height - 1) at bottom.
    740     @param  h
    741             Height of line, in pixels.
    742     @param  color
    743             Line color, one of: SSD1306_BLACK, SSD1306_WHITE or SSD1306_INVERT.
    744     @return None (void).
    745     @note   Changes buffer contents only, no immediate effect on display.
    746             Follow up with a call to display(), or with other graphics
    747             commands as needed by one's own application.
    748 */
    749 void Adafruit_SSD1306::drawFastVLine(int16_t x, int16_t y, int16_t h,
    750                                      uint16_t color) {
    751   bool bSwap = false;
    752   switch (rotation) {
    753   case 1:
    754     // 90 degree rotation, swap x & y for rotation,
    755     // then invert x and adjust x for h (now to become w)
    756     bSwap = true;
    757     ssd1306_swap(x, y);
    758     x = WIDTH - x - 1;
    759     x -= (h - 1);
    760     break;
    761   case 2:
    762     // 180 degree rotation, invert x and y, then shift y around for height.
    763     x = WIDTH - x - 1;
    764     y = HEIGHT - y - 1;
    765     y -= (h - 1);
    766     break;
    767   case 3:
    768     // 270 degree rotation, swap x & y for rotation, then invert y
    769     bSwap = true;
    770     ssd1306_swap(x, y);
    771     y = HEIGHT - y - 1;
    772     break;
    773   }
    774 
    775   if (bSwap)
    776     drawFastHLineInternal(x, y, h, color);
    777   else
    778     drawFastVLineInternal(x, y, h, color);
    779 }
    780 
    781 void Adafruit_SSD1306::drawFastVLineInternal(int16_t x, int16_t __y,
    782                                              int16_t __h, uint16_t color) {
    783 
    784   if ((x >= 0) && (x < WIDTH)) { // X coord in bounds?
    785     if (__y < 0) {               // Clip top
    786       __h += __y;
    787       __y = 0;
    788     }
    789     if ((__y + __h) > HEIGHT) { // Clip bottom
    790       __h = (HEIGHT - __y);
    791     }
    792     if (__h > 0) { // Proceed only if height is now positive
    793       // this display doesn't need ints for coordinates,
    794       // use local byte registers for faster juggling
    795       uint8_t y = __y, h = __h;
    796       uint8_t *pBuf = &buffer[(y / 8) * WIDTH + x];
    797 
    798       // do the first partial byte, if necessary - this requires some masking
    799       uint8_t mod = (y & 7);
    800       if (mod) {
    801         // mask off the high n bits we want to set
    802         mod = 8 - mod;
    803         // note - lookup table results in a nearly 10% performance
    804         // improvement in fill* functions
    805         // uint8_t mask = ~(0xFF >> mod);
    806         static const uint8_t PROGMEM premask[8] = {0x00, 0x80, 0xC0, 0xE0,
    807                                                    0xF0, 0xF8, 0xFC, 0xFE};
    808         uint8_t mask = pgm_read_byte(&premask[mod]);
    809         // adjust the mask if we're not going to reach the end of this byte
    810         if (h < mod)
    811           mask &= (0XFF >> (mod - h));
    812 
    813         switch (color) {
    814         case SSD1306_WHITE:
    815           *pBuf |= mask;
    816           break;
    817         case SSD1306_BLACK:
    818           *pBuf &= ~mask;
    819           break;
    820         case SSD1306_INVERSE:
    821           *pBuf ^= mask;
    822           break;
    823         }
    824         pBuf += WIDTH;
    825       }
    826 
    827       if (h >= mod) { // More to go?
    828         h -= mod;
    829         // Write solid bytes while we can - effectively 8 rows at a time
    830         if (h >= 8) {
    831           if (color == SSD1306_INVERSE) {
    832             // separate copy of the code so we don't impact performance of
    833             // black/white write version with an extra comparison per loop
    834             do {
    835               *pBuf ^= 0xFF; // Invert byte
    836               pBuf += WIDTH; // Advance pointer 8 rows
    837               h -= 8;        // Subtract 8 rows from height
    838             } while (h >= 8);
    839           } else {
    840             // store a local value to work with
    841             uint8_t val = (color != SSD1306_BLACK) ? 255 : 0;
    842             do {
    843               *pBuf = val;   // Set byte
    844               pBuf += WIDTH; // Advance pointer 8 rows
    845               h -= 8;        // Subtract 8 rows from height
    846             } while (h >= 8);
    847           }
    848         }
    849 
    850         if (h) { // Do the final partial byte, if necessary
    851           mod = h & 7;
    852           // this time we want to mask the low bits of the byte,
    853           // vs the high bits we did above
    854           // uint8_t mask = (1 << mod) - 1;
    855           // note - lookup table results in a nearly 10% performance
    856           // improvement in fill* functions
    857           static const uint8_t PROGMEM postmask[8] = {0x00, 0x01, 0x03, 0x07,
    858                                                       0x0F, 0x1F, 0x3F, 0x7F};
    859           uint8_t mask = pgm_read_byte(&postmask[mod]);
    860           switch (color) {
    861           case SSD1306_WHITE:
    862             *pBuf |= mask;
    863             break;
    864           case SSD1306_BLACK:
    865             *pBuf &= ~mask;
    866             break;
    867           case SSD1306_INVERSE:
    868             *pBuf ^= mask;
    869             break;
    870           }
    871         }
    872       }
    873     } // endif positive height
    874   }   // endif x in bounds
    875 }
    876 
    877 /*!
    878     @brief  Return color of a single pixel in display buffer.
    879     @param  x
    880             Column of display -- 0 at left to (screen width - 1) at right.
    881     @param  y
    882             Row of display -- 0 at top to (screen height -1) at bottom.
    883     @return true if pixel is set (usually SSD1306_WHITE, unless display invert
    884    mode is enabled), false if clear (SSD1306_BLACK).
    885     @note   Reads from buffer contents; may not reflect current contents of
    886             screen if display() has not been called.
    887 */
    888 bool Adafruit_SSD1306::getPixel(int16_t x, int16_t y) {
    889   if ((x >= 0) && (x < width()) && (y >= 0) && (y < height())) {
    890     // Pixel is in-bounds. Rotate coordinates if needed.
    891     switch (getRotation()) {
    892     case 1:
    893       ssd1306_swap(x, y);
    894       x = WIDTH - x - 1;
    895       break;
    896     case 2:
    897       x = WIDTH - x - 1;
    898       y = HEIGHT - y - 1;
    899       break;
    900     case 3:
    901       ssd1306_swap(x, y);
    902       y = HEIGHT - y - 1;
    903       break;
    904     }
    905     return (buffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
    906   }
    907   return false; // Pixel out of bounds
    908 }
    909 
    910 /*!
    911     @brief  Get base address of display buffer for direct reading or writing.
    912     @return Pointer to an unsigned 8-bit array, column-major, columns padded
    913             to full byte boundary if needed.
    914 */
    915 uint8_t *Adafruit_SSD1306::getBuffer(void) { return buffer; }
    916 
    917 // REFRESH DISPLAY ---------------------------------------------------------
    918 
    919 /*!
    920     @brief  Push data currently in RAM to SSD1306 display.
    921     @return None (void).
    922     @note   Drawing operations are not visible until this function is
    923             called. Call after each graphics command, or after a whole set
    924             of graphics commands, as best needed by one's own application.
    925 */
    926 void Adafruit_SSD1306::display(void) {
    927   TRANSACTION_START
    928   static const uint8_t PROGMEM dlist1[] = {
    929       SSD1306_PAGEADDR,
    930       0,                      // Page start address
    931       0xFF,                   // Page end (not really, but works here)
    932       SSD1306_COLUMNADDR, 0}; // Column start address
    933   ssd1306_commandList(dlist1, sizeof(dlist1));
    934   ssd1306_command1(WIDTH - 1); // Column end address
    935 
    936 #if defined(ESP8266)
    937   // ESP8266 needs a periodic yield() call to avoid watchdog reset.
    938   // With the limited size of SSD1306 displays, and the fast bitrate
    939   // being used (1 MHz or more), I think one yield() immediately before
    940   // a screen write and one immediately after should cover it.  But if
    941   // not, if this becomes a problem, yields() might be added in the
    942   // 32-byte transfer condition below.
    943   yield();
    944 #endif
    945   uint16_t count = WIDTH * ((HEIGHT + 7) / 8);
    946   uint8_t *ptr = buffer;
    947   if (wire) { // I2C
    948     wire->beginTransmission(i2caddr);
    949     WIRE_WRITE((uint8_t)0x40);
    950     uint16_t bytesOut = 1;
    951     while (count--) {
    952       if (bytesOut >= WIRE_MAX) {
    953         wire->endTransmission();
    954         wire->beginTransmission(i2caddr);
    955         WIRE_WRITE((uint8_t)0x40);
    956         bytesOut = 1;
    957       }
    958       WIRE_WRITE(*ptr++);
    959       bytesOut++;
    960     }
    961     wire->endTransmission();
    962   } else { // SPI
    963     SSD1306_MODE_DATA
    964     while (count--)
    965       SPIwrite(*ptr++);
    966   }
    967   TRANSACTION_END
    968 #if defined(ESP8266)
    969   yield();
    970 #endif
    971 }
    972 
    973 // SCROLLING FUNCTIONS -----------------------------------------------------
    974 
    975 /*!
    976     @brief  Activate a right-handed scroll for all or part of the display.
    977     @param  start
    978             First row.
    979     @param  stop
    980             Last row.
    981     @return None (void).
    982 */
    983 // To scroll the whole display, run: display.startscrollright(0x00, 0x0F)
    984 void Adafruit_SSD1306::startscrollright(uint8_t start, uint8_t stop) {
    985   TRANSACTION_START
    986   static const uint8_t PROGMEM scrollList1a[] = {
    987       SSD1306_RIGHT_HORIZONTAL_SCROLL, 0X00};
    988   ssd1306_commandList(scrollList1a, sizeof(scrollList1a));
    989   ssd1306_command1(start);
    990   ssd1306_command1(0X00);
    991   ssd1306_command1(stop);
    992   static const uint8_t PROGMEM scrollList1b[] = {0X00, 0XFF,
    993                                                  SSD1306_ACTIVATE_SCROLL};
    994   ssd1306_commandList(scrollList1b, sizeof(scrollList1b));
    995   TRANSACTION_END
    996 }
    997 
    998 /*!
    999     @brief  Activate a left-handed scroll for all or part of the display.
   1000     @param  start
   1001             First row.
   1002     @param  stop
   1003             Last row.
   1004     @return None (void).
   1005 */
   1006 // To scroll the whole display, run: display.startscrollleft(0x00, 0x0F)
   1007 void Adafruit_SSD1306::startscrollleft(uint8_t start, uint8_t stop) {
   1008   TRANSACTION_START
   1009   static const uint8_t PROGMEM scrollList2a[] = {SSD1306_LEFT_HORIZONTAL_SCROLL,
   1010                                                  0X00};
   1011   ssd1306_commandList(scrollList2a, sizeof(scrollList2a));
   1012   ssd1306_command1(start);
   1013   ssd1306_command1(0X00);
   1014   ssd1306_command1(stop);
   1015   static const uint8_t PROGMEM scrollList2b[] = {0X00, 0XFF,
   1016                                                  SSD1306_ACTIVATE_SCROLL};
   1017   ssd1306_commandList(scrollList2b, sizeof(scrollList2b));
   1018   TRANSACTION_END
   1019 }
   1020 
   1021 /*!
   1022     @brief  Activate a diagonal scroll for all or part of the display.
   1023     @param  start
   1024             First row.
   1025     @param  stop
   1026             Last row.
   1027     @return None (void).
   1028 */
   1029 // display.startscrolldiagright(0x00, 0x0F)
   1030 void Adafruit_SSD1306::startscrolldiagright(uint8_t start, uint8_t stop) {
   1031   TRANSACTION_START
   1032   static const uint8_t PROGMEM scrollList3a[] = {
   1033       SSD1306_SET_VERTICAL_SCROLL_AREA, 0X00};
   1034   ssd1306_commandList(scrollList3a, sizeof(scrollList3a));
   1035   ssd1306_command1(HEIGHT);
   1036   static const uint8_t PROGMEM scrollList3b[] = {
   1037       SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL, 0X00};
   1038   ssd1306_commandList(scrollList3b, sizeof(scrollList3b));
   1039   ssd1306_command1(start);
   1040   ssd1306_command1(0X00);
   1041   ssd1306_command1(stop);
   1042   static const uint8_t PROGMEM scrollList3c[] = {0X01, SSD1306_ACTIVATE_SCROLL};
   1043   ssd1306_commandList(scrollList3c, sizeof(scrollList3c));
   1044   TRANSACTION_END
   1045 }
   1046 
   1047 /*!
   1048     @brief  Activate alternate diagonal scroll for all or part of the display.
   1049     @param  start
   1050             First row.
   1051     @param  stop
   1052             Last row.
   1053     @return None (void).
   1054 */
   1055 // To scroll the whole display, run: display.startscrolldiagleft(0x00, 0x0F)
   1056 void Adafruit_SSD1306::startscrolldiagleft(uint8_t start, uint8_t stop) {
   1057   TRANSACTION_START
   1058   static const uint8_t PROGMEM scrollList4a[] = {
   1059       SSD1306_SET_VERTICAL_SCROLL_AREA, 0X00};
   1060   ssd1306_commandList(scrollList4a, sizeof(scrollList4a));
   1061   ssd1306_command1(HEIGHT);
   1062   static const uint8_t PROGMEM scrollList4b[] = {
   1063       SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL, 0X00};
   1064   ssd1306_commandList(scrollList4b, sizeof(scrollList4b));
   1065   ssd1306_command1(start);
   1066   ssd1306_command1(0X00);
   1067   ssd1306_command1(stop);
   1068   static const uint8_t PROGMEM scrollList4c[] = {0X01, SSD1306_ACTIVATE_SCROLL};
   1069   ssd1306_commandList(scrollList4c, sizeof(scrollList4c));
   1070   TRANSACTION_END
   1071 }
   1072 
   1073 /*!
   1074     @brief  Cease a previously-begun scrolling action.
   1075     @return None (void).
   1076 */
   1077 void Adafruit_SSD1306::stopscroll(void) {
   1078   TRANSACTION_START
   1079   ssd1306_command1(SSD1306_DEACTIVATE_SCROLL);
   1080   TRANSACTION_END
   1081 }
   1082 
   1083 // OTHER HARDWARE SETTINGS -------------------------------------------------
   1084 
   1085 /*!
   1086     @brief  Enable or disable display invert mode (white-on-black vs
   1087             black-on-white).
   1088     @param  i
   1089             If true, switch to invert mode (black-on-white), else normal
   1090             mode (white-on-black).
   1091     @return None (void).
   1092     @note   This has an immediate effect on the display, no need to call the
   1093             display() function -- buffer contents are not changed, rather a
   1094             different pixel mode of the display hardware is used. When
   1095             enabled, drawing SSD1306_BLACK (value 0) pixels will actually draw
   1096    white, SSD1306_WHITE (value 1) will draw black.
   1097 */
   1098 void Adafruit_SSD1306::invertDisplay(bool i) {
   1099   TRANSACTION_START
   1100   ssd1306_command1(i ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
   1101   TRANSACTION_END
   1102 }
   1103 
   1104 /*!
   1105     @brief  Dim the display.
   1106     @param  dim
   1107             true to enable lower brightness mode, false for full brightness.
   1108     @return None (void).
   1109     @note   This has an immediate effect on the display, no need to call the
   1110             display() function -- buffer contents are not changed.
   1111 */
   1112 void Adafruit_SSD1306::dim(bool dim) {
   1113   // the range of contrast to too small to be really useful
   1114   // it is useful to dim the display
   1115   TRANSACTION_START
   1116   ssd1306_command1(SSD1306_SETCONTRAST);
   1117   ssd1306_command1(dim ? 0 : contrast);
   1118   TRANSACTION_END
   1119 }