A derived version of the BSD licensed Adafrut GFX library for the SSD1351 controller for an OLED 128x128 display using SPI.

Fork of Adafruit_GFX by Neal Horman

Revision:
17:0a4bb1070fd5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_SSD1351.cpp	Wed Apr 22 02:14:36 2015 +0000
@@ -0,0 +1,402 @@
+#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);
+   }
+ }