Compiles against mbed OS 5
Fork of Adafruit_GFX_1351 by
Adafruit_SSD1351.cpp
- Committer:
- lionello
- Date:
- 2015-04-22
- Revision:
- 17:0a4bb1070fd5
- Child:
- 18:8606e2c579f1
File content as of revision 17:0a4bb1070fd5:
#include "Adafruit_SSD1351.h"
#include <stdarg.h>
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
Adafruit_SSD1351::Adafruit_SSD1351(PinName cs, PinName rs, PinName dc, PinName clk, PinName data)
: Adafruit_GFX(SSD1351WIDTH, SSD1351HEIGHT),
_spi(data, NC, clk),
_cs(cs),
_reset(rs),
_dc(dc)
{
}
void Adafruit_SSD1351::writeCommand(uint8_t code)
{
_cs = 1;
_dc = 0;
_cs = 0;
_spi.write(code);
_cs = 1;
}
void Adafruit_SSD1351::writeData(uint8_t value)
{
_cs = 1;
_dc = 1;
_cs = 0;
_spi.write(value);
_cs = 1;
}
void Adafruit_SSD1351::off()
{
writeCommand(0xAE);
}
void Adafruit_SSD1351::on()
{
writeCommand(0xAF);
}
void Adafruit_SSD1351::goTo(int x, int y) {
if ((x >= SSD1351WIDTH) || (y >= SSD1351HEIGHT)) return;
// set x and y coordinate
writeCommand(SSD1351_CMD_SETCOLUMN);
writeData(x);
writeData(SSD1351WIDTH-1);
writeCommand(SSD1351_CMD_SETROW);
writeData(y);
writeData(SSD1351HEIGHT-1);
writeCommand(SSD1351_CMD_WRITERAM);
}
uint16_t Adafruit_SSD1351::Color565(uint8_t r, uint8_t g, uint8_t b) {
uint16_t c;
c = r >> 3;
c <<= 6;
c |= g >> 2;
c <<= 5;
c |= b >> 3;
return c;
}
void Adafruit_SSD1351::fillScreen(uint16_t fillcolor) {
fillRect(0, 0, SSD1351WIDTH, SSD1351HEIGHT, fillcolor);
}
// Draw a filled rectangle with no rotation.
void Adafruit_SSD1351::rawFillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor) {
// Bounds check
if ((x >= SSD1351WIDTH) || (y >= SSD1351HEIGHT))
return;
// Y bounds check
if (y+h > SSD1351HEIGHT)
{
h = SSD1351HEIGHT - y - 1;
}
// X bounds check
if (x+w > SSD1351WIDTH)
{
w = SSD1351WIDTH - x - 1;
}
/*
Serial.print(x); Serial.print(", ");
Serial.print(y); Serial.print(", ");
Serial.print(w); Serial.print(", ");
Serial.print(h); Serial.println(", ");
*/
// set location
writeCommand(SSD1351_CMD_SETCOLUMN);
writeData(x);
writeData(x+w-1);
writeCommand(SSD1351_CMD_SETROW);
writeData(y);
writeData(y+h-1);
// fill!
writeCommand(SSD1351_CMD_WRITERAM);
for (uint16_t i=0; i < w*h; i++) {
writeData(fillcolor >> 8);
writeData(fillcolor);
}
}
/**************************************************************************/
/*!
@brief Draws a filled rectangle using HW acceleration
*/
/**************************************************************************/
void Adafruit_SSD1351::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor) {
// Transform x and y based on current rotation.
switch (getRotation()) {
case 0: // No rotation
rawFillRect(x, y, w, h, fillcolor);
break;
case 1: // Rotated 90 degrees clockwise.
swap(x, y);
x = _rawWidth - x - h;
rawFillRect(x, y, h, w, fillcolor);
break;
case 2: // Rotated 180 degrees clockwise.
x = _rawWidth - x - w;
y = _rawHeight - y - h;
rawFillRect(x, y, w, h, fillcolor);
break;
case 3: // Rotated 270 degrees clockwise.
swap(x, y);
y = _rawHeight - y - w;
rawFillRect(x, y, h, w, fillcolor);
break;
}
}
// Draw a horizontal line ignoring any screen rotation.
void Adafruit_SSD1351::rawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
// Bounds check
if ((x >= SSD1351WIDTH) || (y >= SSD1351HEIGHT))
return;
// X bounds check
if (x+w > SSD1351WIDTH)
{
w = SSD1351WIDTH - x - 1;
}
if (w < 0) return;
// set location
writeCommand(SSD1351_CMD_SETCOLUMN);
writeData(x);
writeData(x+w-1);
writeCommand(SSD1351_CMD_SETROW);
writeData(y);
writeData(y);
// fill!
writeCommand(SSD1351_CMD_WRITERAM);
for (uint16_t i=0; i < w; i++) {
writeData(color >> 8);
writeData(color);
}
}
// Draw a vertical line ignoring any screen rotation.
void Adafruit_SSD1351::rawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
// Bounds check
if ((x >= SSD1351WIDTH) || (y >= SSD1351HEIGHT))
return;
// X bounds check
if (y+h > SSD1351HEIGHT)
{
h = SSD1351HEIGHT - y - 1;
}
if (h < 0) return;
// set location
writeCommand(SSD1351_CMD_SETCOLUMN);
writeData(x);
writeData(x);
writeCommand(SSD1351_CMD_SETROW);
writeData(y);
writeData(y+h-1);
// fill!
writeCommand(SSD1351_CMD_WRITERAM);
for (uint16_t i=0; i < h; i++) {
writeData(color >> 8);
writeData(color);
}
}
void Adafruit_SSD1351::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
// Transform x and y based on current rotation.
switch (getRotation()) {
case 0: // No rotation
rawFastVLine(x, y, h, color);
break;
case 1: // Rotated 90 degrees clockwise.
swap(x, y);
x = _rawWidth - x - h;
rawFastHLine(x, y, h, color);
break;
case 2: // Rotated 180 degrees clockwise.
x = _rawWidth - x - 1;
y = _rawHeight - y - h;
rawFastVLine(x, y, h, color);
break;
case 3: // Rotated 270 degrees clockwise.
swap(x, y);
y = _rawHeight - y - 1;
rawFastHLine(x, y, h, color);
break;
}
}
void Adafruit_SSD1351::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
// Transform x and y based on current rotation.
switch (getRotation()) {
case 0: // No rotation.
rawFastHLine(x, y, w, color);
break;
case 1: // Rotated 90 degrees clockwise.
swap(x, y);
x = _rawWidth - x - 1;
rawFastVLine(x, y, w, color);
break;
case 2: // Rotated 180 degrees clockwise.
x = _rawWidth - x - w;
y = _rawHeight - y - 1;
rawFastHLine(x, y, w, color);
break;
case 3: // Rotated 270 degrees clockwise.
swap(x, y);
y = _rawHeight - y - w;
rawFastVLine(x, y, w, color);
break;
}
}
void Adafruit_SSD1351::drawPixel(int16_t x, int16_t y, uint16_t color)
{
// Transform x and y based on current rotation.
switch (getRotation()) {
// Case 0: No rotation
case 1: // Rotated 90 degrees clockwise.
swap(x, y);
x = _rawWidth - x - 1;
break;
case 2: // Rotated 180 degrees clockwise.
x = _rawWidth - x - 1;
y = _rawHeight - y - 1;
break;
case 3: // Rotated 270 degrees clockwise.
swap(x, y);
y = _rawHeight - y - 1;
break;
}
// Bounds check.
if ((x >= SSD1351WIDTH) || (y >= SSD1351HEIGHT)) return;
if ((x < 0) || (y < 0)) return;
goTo(x, y);
writeData(color >> 8);
writeData(color);
}
void Adafruit_SSD1351::begin(void) {
#if 0
// set pin directions
pinMode(_rs, OUTPUT);
if (_sclk) {
pinMode(_sclk, OUTPUT);
pinMode(_sid, OUTPUT);
} else {
// using the hardware SPI
SPI.begin();
SPI.setDataMode(SPI_MODE3);
}
// Toggle RST low to reset; CS low so it'll listen to us
pinMode(_cs, OUTPUT);
digitalWrite(_cs, LOW);
if (_rst) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(500);
digitalWrite(_rst, LOW);
delay(500);
digitalWrite(_rst, HIGH);
delay(500);
}
#endif
_spi.format(8,3);
//_spi.format(9,3);// no D/C# pin
//_spi.frequency(2000000);
_cs = 0;
_reset = 1;
wait(0.1f);
_reset = 0;
wait(0.1f);
_reset = 1;
wait(0.1f);
// Initialization Sequence
writeCommand(SSD1351_CMD_COMMANDLOCK); // set command lock
writeData(0x12);
writeCommand(SSD1351_CMD_COMMANDLOCK); // set command lock
writeData(0xB1);
writeCommand(SSD1351_CMD_DISPLAYOFF); // 0xAE
writeCommand(SSD1351_CMD_CLOCKDIV); // 0xB3
writeCommand(0xF1); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
writeCommand(SSD1351_CMD_MUXRATIO);
writeData(127);
writeCommand(SSD1351_CMD_SETREMAP);
writeData(0x74);
writeCommand(SSD1351_CMD_SETCOLUMN);
writeData(0x00);
writeData(0x7F);
writeCommand(SSD1351_CMD_SETROW);
writeData(0x00);
writeData(0x7F);
writeCommand(SSD1351_CMD_STARTLINE); // 0xA1
if (SSD1351HEIGHT == 96) {
writeData(96);
} else {
writeData(0);
}
writeCommand(SSD1351_CMD_DISPLAYOFFSET); // 0xA2
writeData(0x0);
writeCommand(SSD1351_CMD_SETGPIO);
writeData(0x00);
writeCommand(SSD1351_CMD_FUNCTIONSELECT);
writeData(0x01); // internal (diode drop)
//writeData(0x01); // external bias
// writeCommand(SSSD1351_CMD_SETPHASELENGTH);
// writeData(0x32);
writeCommand(SSD1351_CMD_PRECHARGE); // 0xB1
writeCommand(0x32);
writeCommand(SSD1351_CMD_VCOMH); // 0xBE
writeCommand(0x05);
writeCommand(SSD1351_CMD_NORMALDISPLAY); // 0xA6
writeCommand(SSD1351_CMD_CONTRASTABC);
writeData(0xC8);
writeData(0x80);
writeData(0xC8);
writeCommand(SSD1351_CMD_CONTRASTMASTER);
writeData(0x0F);
writeCommand(SSD1351_CMD_SETVSL );
writeData(0xA0);
writeData(0xB5);
writeData(0x55);
writeCommand(SSD1351_CMD_PRECHARGE2);
writeData(0x01);
writeCommand(SSD1351_CMD_DISPLAYON); //--turn on oled panel
}
void Adafruit_SSD1351::invert(bool v) {
if (v) {
writeCommand(SSD1351_CMD_INVERTDISPLAY);
} else {
writeCommand(SSD1351_CMD_NORMALDISPLAY);
}
}
