Adafruit_SH110x/Adafruit_SH1107.cpp

195 lines
8 KiB
C++

/*!
* @file Adafruit_SH1107.cpp
*
*/
#include "Adafruit_SH110X.h"
#include "splash.h"
// CONSTRUCTORS, DESTRUCTOR ------------------------------------------------
/*!
@brief Constructor for I2C-interfaced SH1107 displays.
@param w
Display width in pixels
@param h
Display height in pixels
@param twi
Pointer to an existing TwoWire instance (e.g. &Wire, the
microcontroller's primary I2C bus).
@param rst_pin
Reset pin (using Arduino pin numbering), or -1 if not used
(some displays might be wired to share the microcontroller's
reset pin).
@param clkDuring
Speed (in Hz) for Wire transmissions in SH110X library calls.
Defaults to 400000 (400 KHz), a known 'safe' value for most
microcontrollers, and meets the SH110X datasheet spec.
Some systems can operate I2C faster (800 KHz for ESP32, 1 MHz
for many other 32-bit MCUs), and some (perhaps not all)
SH110X's can work with this -- so it's optionally be specified
here and is not a default behavior. (Ignored if using pre-1.5.7
Arduino software, which operates I2C at a fixed 100 KHz.)
@param clkAfter
Speed (in Hz) for Wire transmissions following SH110X library
calls. Defaults to 100000 (100 KHz), the default Arduino Wire
speed. This is done rather than leaving it at the 'during' speed
because other devices on the I2C bus might not be compatible
with the faster rate. (Ignored if using pre-1.5.7 Arduino
software, which operates I2C at a fixed 100 KHz.)
@note Call the object's begin() function before use -- buffer
allocation is performed there!
*/
Adafruit_SH1107::Adafruit_SH1107(uint16_t w, uint16_t h, TwoWire *twi,
int16_t rst_pin, uint32_t clkDuring,
uint32_t clkAfter)
: Adafruit_SH110X(w, h, twi, rst_pin, clkDuring, clkAfter) {}
/*!
@brief Constructor for SPI SH1107 displays, using software (bitbang)
SPI.
@param w
Display width in pixels
@param h
Display height in pixels
@param mosi_pin
MOSI (master out, slave in) pin (using Arduino pin numbering).
This transfers serial data from microcontroller to display.
@param sclk_pin
SCLK (serial clock) pin (using Arduino pin numbering).
This clocks each bit from MOSI.
@param dc_pin
Data/command pin (using Arduino pin numbering), selects whether
display is receiving commands (low) or data (high).
@param rst_pin
Reset pin (using Arduino pin numbering), or -1 if not used
(some displays might be wired to share the microcontroller's
reset pin).
@param cs_pin
Chip-select pin (using Arduino pin numbering) for sharing the
bus with other devices. Active low.
@note Call the object's begin() function before use -- buffer
allocation is performed there!
*/
Adafruit_SH1107::Adafruit_SH1107(uint16_t w, uint16_t h, int16_t mosi_pin,
int16_t sclk_pin, int16_t dc_pin,
int16_t rst_pin, int16_t cs_pin)
: Adafruit_SH110X(w, h, mosi_pin, sclk_pin, dc_pin, rst_pin, cs_pin) {}
/*!
@brief Constructor for SPI SH1107 displays, using native hardware SPI.
@param w
Display width in pixels
@param h
Display height in pixels
@param spi
Pointer to an existing SPIClass instance (e.g. &SPI, the
microcontroller's primary SPI bus).
@param dc_pin
Data/command pin (using Arduino pin numbering), selects whether
display is receiving commands (low) or data (high).
@param rst_pin
Reset pin (using Arduino pin numbering), or -1 if not used
(some displays might be wired to share the microcontroller's
reset pin).
@param cs_pin
Chip-select pin (using Arduino pin numbering) for sharing the
bus with other devices. Active low.
@param bitrate
SPI clock rate for transfers to this display. Default if
unspecified is 8000000UL (8 MHz).
@note Call the object's begin() function before use -- buffer
allocation is performed there!
*/
Adafruit_SH1107::Adafruit_SH1107(uint16_t w, uint16_t h, SPIClass *spi,
int16_t dc_pin, int16_t rst_pin,
int16_t cs_pin, uint32_t bitrate)
: Adafruit_SH110X(w, h, spi, dc_pin, rst_pin, cs_pin, bitrate) {}
/*!
@brief Destructor for Adafruit_SH1107 object.
*/
Adafruit_SH1107::~Adafruit_SH1107(void) {}
/*!
@brief Allocate RAM for image buffer, initialize peripherals and pins.
@param addr
I2C address of corresponding SH110X display (or pass 0 to use
default of 0x3C for 128x32 display, 0x3D for all others).
SPI displays (hardware or software) do not use addresses, but
this argument is still required (pass 0 or any value really,
it will simply be ignored). Default if unspecified is 0.
@param reset
If true, and if the reset pin passed to the constructor is
valid, a hard reset will be performed before initializing the
display. If using multiple SH110X displays on the same bus, and
if they all share the same reset pin, you should only pass true
on the first display being initialized, false on all others,
else the already-initialized displays would be reset. Default if
unspecified is true.
@return true on successful allocation/init, false otherwise.
Well-behaved code should check the return value before
proceeding.
@note MUST call this function before any drawing or updates!
*/
bool Adafruit_SH1107::begin(uint8_t addr, bool reset) {
Adafruit_GrayOLED::_init(addr, reset);
setContrast(0x2F);
#ifndef SH110X_NO_SPLASH
// the featherwing with 128x64 oled is 'rotated' so to make the splash right,
// rotate!
if (WIDTH == 64 && HEIGHT == 128) {
setRotation(1);
drawBitmap((HEIGHT - splash2_width) / 2, (WIDTH - splash2_height) / 2,
splash2_data, splash2_width, splash2_height, 1);
setRotation(0);
}
if (WIDTH == 128 && HEIGHT == 128) {
drawBitmap((HEIGHT - splash2_width) / 2, (WIDTH - splash2_height) / 2,
splash2_data, splash2_width, splash2_height, 1);
}
#endif
// Init sequence, make sure its under 32 bytes, or split into multiples!
// clang-format off
static const uint8_t init[] = {
SH110X_DISPLAYOFF, // 0xAE
SH110X_SETDISPLAYCLOCKDIV, 0x51, // 0xd5, 0x51,
SH110X_MEMORYMODE, // 0x20
SH110X_SETCONTRAST, 0x4F, // 0x81, 0x4F
SH110X_DCDC, 0x8A, // 0xAD, 0x8A
SH110X_SEGREMAP, // 0xA0
SH110X_COMSCANINC, // 0xC0
SH110X_SETDISPSTARTLINE, 0x0, // 0xDC 0x00
SH110X_SETDISPLAYOFFSET, 0x60, // 0xd3, 0x60,
SH110X_SETPRECHARGE, 0x22, // 0xd9, 0x22,
SH110X_SETVCOMDETECT, 0x35, // 0xdb, 0x35,
SH110X_SETMULTIPLEX, 0x3F, // 0xa8, 0x3f,
// SH110X_SETPAGEADDR, // 0xb0
// SH110X_SETCOMPINS, 0x12, // 0xda, 0x12,
SH110X_DISPLAYALLON_RESUME, // 0xa4
SH110X_NORMALDISPLAY, // 0xa6
};
// clang-format on
if (!oled_commandList(init, sizeof(init))) {
return false;
}
if (WIDTH == 128 && HEIGHT == 128) {
static const uint8_t init_128x128[] = {
SH110X_SETDISPLAYOFFSET, 0x00, SH110X_SETMULTIPLEX, 0x7F, // 0xa8, 0x3f,
};
if (!oled_commandList(init_128x128, sizeof(init_128x128))) {
return false;
}
}
delay(100); // 100ms delay recommended
oled_command(SH110X_DISPLAYON); // 0xaf
return true; // Success
}