247 lines
8.1 KiB
C++
247 lines
8.1 KiB
C++
/*!
|
|
* @file Adafruit_SSD1331.cpp
|
|
*
|
|
* @mainpage Adafruit SSD1331 Arduino Library
|
|
*
|
|
* @section intro_sec Introduction
|
|
*
|
|
* This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip
|
|
*
|
|
* Pick one up today in the adafruit shop!
|
|
* ------> http://www.adafruit.com/products/684
|
|
*
|
|
* These displays use SPI to communicate, 4 or 5 pins are required to
|
|
* interface
|
|
* Adafruit invests time and resources providing this open source code,
|
|
* please support Adafruit and open-source hardware by purchasing
|
|
* products from Adafruit!
|
|
*
|
|
* @section author Author
|
|
*
|
|
* Written by Limor Fried/Ladyada for Adafruit Industries.
|
|
*
|
|
* @section license License
|
|
*
|
|
* BSD license, all text above must be included in any redistribution
|
|
*/
|
|
|
|
#include "Adafruit_SSD1331.h"
|
|
|
|
/***********************************/
|
|
|
|
#define ssd1331_swap(a, b) \
|
|
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
|
|
|
|
/*!
|
|
@brief SPI displays set an address window rectangle for blitting pixels
|
|
@param x Top left corner x coordinate
|
|
@param y Top left corner x coordinate
|
|
@param w Width of window
|
|
@param h Height of window
|
|
*/
|
|
void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w,
|
|
uint16_t h) {
|
|
uint8_t x1 = x;
|
|
uint8_t y1 = y;
|
|
if (x1 > _width - 1)
|
|
x1 = _width - 1;
|
|
if (y1 > _height - 1)
|
|
y1 = _height - 1;
|
|
|
|
uint8_t x2 = (x + w - 1);
|
|
uint8_t y2 = (y + h - 1);
|
|
if (x2 > _width - 1)
|
|
x2 = _width - 1;
|
|
if (y2 > _height - 1)
|
|
y2 = _height - 1;
|
|
|
|
if (x1 > x2) {
|
|
ssd1331_swap(x1, x2);
|
|
}
|
|
if (y1 > y2) {
|
|
ssd1331_swap(y1, y2);
|
|
}
|
|
|
|
if (rotation & 1) { // Vertical address increment mode
|
|
ssd1331_swap(x1, y1);
|
|
ssd1331_swap(x2, y2);
|
|
}
|
|
|
|
SPI_DC_LOW(); // Command mode
|
|
|
|
spiWrite(SSD1331_CMD_SETCOLUMN); // Column addr set
|
|
spiWrite(x1);
|
|
spiWrite(x2);
|
|
|
|
spiWrite(SSD1331_CMD_SETROW); // Row addr set
|
|
spiWrite(y1);
|
|
spiWrite(y2);
|
|
SPI_DC_HIGH(); // Exit Command mode
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Initialize SSD1331 chip
|
|
Connects to the SSD1331 over SPI and sends initialization procedure commands
|
|
@param freq Desired SPI clock frequency
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_SSD1331::begin(uint32_t freq) {
|
|
initSPI(freq);
|
|
|
|
// Initialization Sequence
|
|
sendCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
|
|
sendCommand(SSD1331_CMD_SETREMAP); // 0xA0
|
|
sendCommand(SSD1331_CMD_STARTLINE); // 0xA1
|
|
sendCommand(0x0);
|
|
sendCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2
|
|
sendCommand(0x0);
|
|
sendCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4
|
|
sendCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8
|
|
sendCommand(0x3F); // 0x3F 1/64 duty
|
|
sendCommand(SSD1331_CMD_SETMASTER); // 0xAD
|
|
sendCommand(0x8E);
|
|
sendCommand(SSD1331_CMD_POWERMODE); // 0xB0
|
|
sendCommand(0x0B);
|
|
sendCommand(SSD1331_CMD_PRECHARGE); // 0xB1
|
|
sendCommand(0x31);
|
|
sendCommand(SSD1331_CMD_CLOCKDIV); // 0xB3
|
|
sendCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio
|
|
// (A[3:0]+1 = 1..16)
|
|
sendCommand(SSD1331_CMD_PRECHARGEA); // 0x8A
|
|
sendCommand(0x64);
|
|
sendCommand(SSD1331_CMD_PRECHARGEB); // 0x8B
|
|
sendCommand(0x78);
|
|
sendCommand(SSD1331_CMD_PRECHARGEC); // 0x8C
|
|
sendCommand(0x64);
|
|
sendCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB
|
|
sendCommand(0x3A);
|
|
sendCommand(SSD1331_CMD_VCOMH); // 0xBE
|
|
sendCommand(0x3E);
|
|
sendCommand(SSD1331_CMD_MASTERCURRENT); // 0x87
|
|
sendCommand(0x06);
|
|
sendCommand(SSD1331_CMD_CONTRASTA); // 0x81
|
|
sendCommand(0x91);
|
|
sendCommand(SSD1331_CMD_CONTRASTB); // 0x82
|
|
sendCommand(0x50);
|
|
sendCommand(SSD1331_CMD_CONTRASTC); // 0x83
|
|
sendCommand(0x7D);
|
|
sendCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
|
|
_width = TFTWIDTH;
|
|
_height = TFTHEIGHT;
|
|
setRotation(0);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Instantiate Adafruit SSD1331 driver with software SPI
|
|
@param cs Chip select pin #
|
|
@param dc Data/Command pin #
|
|
@param mosi SPI MOSI pin #
|
|
@param sclk SPI Clock pin #
|
|
@param rst Reset pin # (optional, pass -1 if unused)
|
|
*/
|
|
/**************************************************************************/
|
|
Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi,
|
|
int8_t sclk, int8_t rst)
|
|
: Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Instantiate Adafruit SSD1331 driver with hardware SPI
|
|
@param cs Chip select pin #
|
|
@param dc Data/Command pin #
|
|
@param rst Reset pin # (optional, pass -1 if unused)
|
|
*/
|
|
/**************************************************************************/
|
|
Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst)
|
|
: Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Instantiate Adafruit SSD1331 driver with hardware SPI
|
|
@param spi Pointer to an existing SPIClass instance (e.g. &SPI, the
|
|
microcontroller's primary SPI bus).
|
|
@param cs Chip select pin #
|
|
@param dc Data/Command pin #
|
|
@param rst Reset pin # (optional, pass -1 if unused)
|
|
*/
|
|
/**************************************************************************/
|
|
Adafruit_SSD1331::Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc,
|
|
int8_t rst)
|
|
:
|
|
#if defined(ESP8266)
|
|
Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {
|
|
#else
|
|
Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, spi, cs, dc, rst) {
|
|
#endif
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Change whether display is on or off
|
|
@param enable True if you want the display ON, false OFF
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_SSD1331::enableDisplay(boolean enable) {
|
|
sendCommand(enable ? SSD1331_CMD_DISPLAYON : SSD1331_CMD_DISPLAYOFF);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/*!
|
|
@brief Set origin of (0,0) and orientation of OLED display
|
|
@param r
|
|
The index for rotation, from 0-3 inclusive
|
|
@return None (void).
|
|
@note SSD1331 works differently than most (all?) other SPITFT
|
|
displays. With certain rotation changes the screen contents
|
|
may change immediately into a peculiar format (mirrored, not
|
|
necessarily rotated) (other displays, this only affects new
|
|
drawing -- rotation combinations can apply to different
|
|
areas). Therefore, it's recommend to clear the screen
|
|
(fillScreen(0)) before changing rotation.
|
|
*/
|
|
/**************************************************************************/
|
|
void Adafruit_SSD1331::setRotation(uint8_t r) {
|
|
// madctl bits:
|
|
// 6,7 Color depth (01 = 64K)
|
|
// 5 Odd/even split COM (0: disable, 1: enable)
|
|
// 4 Scan direction (0: top-down, 1: bottom-up)
|
|
// 3 Left-Right swapping on COM (0: disable, 1: enable)
|
|
// 2 Color remap (0: A->B->C, 1: C->B->A)
|
|
// 1 Column remap (0: 0-95, 1: 95-0)
|
|
// 0 Address increment (0: horizontal, 1: vertical)
|
|
|
|
#if defined SSD1331_COLORORDER_RGB
|
|
uint8_t madctl = 0b01100000; // 64K, enable split, ABC
|
|
#else
|
|
uint8_t madctl = 0b01100100; // 64K, enable split, CBA
|
|
#endif
|
|
rotation = r & 3; // Clip input to valid range
|
|
|
|
switch (rotation) {
|
|
case 0:
|
|
madctl |= 0b00010010; // Scan bottom-up, column remap 95-0
|
|
_width = WIDTH;
|
|
_height = HEIGHT;
|
|
break;
|
|
case 1:
|
|
madctl |= 0b00000011; // column remap 95-0, vertical
|
|
_width = HEIGHT;
|
|
_height = WIDTH;
|
|
break;
|
|
case 2:
|
|
madctl |= 0b00000000; // None
|
|
_width = WIDTH;
|
|
_height = HEIGHT;
|
|
break;
|
|
case 3:
|
|
madctl |= 0b00010001; // Scan bottom-up, Vertical
|
|
_width = HEIGHT;
|
|
_height = WIDTH;
|
|
break;
|
|
}
|
|
|
|
sendCommand(SSD1331_CMD_SETREMAP);
|
|
sendCommand(madctl);
|
|
}
|