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

Files at this revision

API Documentation at this revision

Comitter:
lionello
Date:
Wed Apr 22 02:14:36 2015 +0000
Parent:
16:7fb1d4d3525d
Commit message:
Added SSD1351 support

Changed in this revision

Adafruit_GFX.h Show annotated file Show diff for this revision Revisions of this file
Adafruit_GFX_Config.h Show annotated file Show diff for this revision Revisions of this file
Adafruit_SSD1351.cpp Show annotated file Show diff for this revision Revisions of this file
Adafruit_SSD1351.h Show annotated file Show diff for this revision Revisions of this file
--- a/Adafruit_GFX.h	Tue Nov 11 22:08:20 2014 +0000
+++ b/Adafruit_GFX.h	Wed Apr 22 02:14:36 2015 +0000
@@ -171,7 +171,7 @@
     inline uint8_t getRotation(void) { rotation %= 4; return rotation; };
 
 protected:
-    int16_t  _rawWidth, _rawHeight;   // this is the 'raw' display w/h - never changes
+    const int16_t _rawWidth, _rawHeight;   // this is the 'raw' display w/h - never changes
     int16_t  _width, _height; // dependent on rotation
     int16_t  cursor_x, cursor_y;
     uint16_t textcolor, textbgcolor;
--- a/Adafruit_GFX_Config.h	Tue Nov 11 22:08:20 2014 +0000
+++ b/Adafruit_GFX_Config.h	Wed Apr 22 02:14:36 2015 +0000
@@ -2,7 +2,7 @@
 #define _ADAFRUIT_GFX_CONFIG_H_
 
 // Uncomment this to turn off the builtin splash
-//#define NO_SPLASH_ADAFRUIT
+#define NO_SPLASH_ADAFRUIT
 
 // Uncomment this to enable all functionality
 //#define GFX_WANT_ABSTRACTS
--- /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);
+   }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_SSD1351.h	Wed Apr 22 02:14:36 2015 +0000
@@ -0,0 +1,117 @@
+/*************************************************** 
+  This is a library for the 1.5" & 1.27" 16-bit Color OLEDs 
+  with SSD1331 driver chip
+
+  Pick one up today in the adafruit shop!
+  ------> http://www.adafruit.com/products/1431
+  ------> http://www.adafruit.com/products/1673
+
+  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!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+#pragma once
+
+#include <mbed.h>
+
+#include "Adafruit_GFX.h"
+
+#define swap(a, b) { uint16_t t = a; a = b; b = t; }
+
+#define SSD1351WIDTH 128
+#define SSD1351HEIGHT 128  // SET THIS TO 96 FOR 1.27"!
+
+// Select one of these defines to set the pixel color order
+#define SSD1351_COLORORDER_RGB
+// #define SSD1351_COLORORDER_BGR
+
+#if defined SSD1351_COLORORDER_RGB && defined SSD1351_COLORORDER_BGR
+  #error "RGB and BGR can not both be defined for SSD1351_COLORODER."
+#endif
+
+// Timing Delays
+#define SSD1351_DELAYS_HWFILL       (3)
+#define SSD1351_DELAYS_HWLINE       (1)
+
+// SSD1351 Commands
+#define SSD1351_CMD_SETCOLUMN       0x15
+#define SSD1351_CMD_SETROW          0x75
+#define SSD1351_CMD_WRITERAM        0x5C
+#define SSD1351_CMD_READRAM         0x5D
+#define SSD1351_CMD_SETREMAP        0xA0
+#define SSD1351_CMD_STARTLINE       0xA1
+#define SSD1351_CMD_DISPLAYOFFSET   0xA2
+#define SSD1351_CMD_DISPLAYALLOFF   0xA4
+#define SSD1351_CMD_DISPLAYALLON    0xA5
+#define SSD1351_CMD_NORMALDISPLAY   0xA6
+#define SSD1351_CMD_INVERTDISPLAY   0xA7
+#define SSD1351_CMD_FUNCTIONSELECT  0xAB
+#define SSD1351_CMD_DISPLAYOFF      0xAE
+#define SSD1351_CMD_DISPLAYON       0xAF
+#define SSD1351_CMD_PRECHARGE       0xB1
+#define SSD1351_CMD_DISPLAYENHANCE  0xB2
+#define SSD1351_CMD_CLOCKDIV        0xB3
+#define SSD1351_CMD_SETVSL      0xB4
+#define SSD1351_CMD_SETGPIO         0xB5
+#define SSD1351_CMD_PRECHARGE2      0xB6
+#define SSD1351_CMD_SETGRAY         0xB8
+#define SSD1351_CMD_USELUT      0xB9
+#define SSD1351_CMD_PRECHARGELEVEL  0xBB
+#define SSD1351_CMD_VCOMH       0xBE
+#define SSD1351_CMD_CONTRASTABC     0xC1
+#define SSD1351_CMD_CONTRASTMASTER  0xC7
+#define SSD1351_CMD_MUXRATIO            0xCA
+#define SSD1351_CMD_COMMANDLOCK         0xFD
+#define SSD1351_CMD_HORIZSCROLL         0x96
+#define SSD1351_CMD_STOPSCROLL          0x9E
+#define SSD1351_CMD_STARTSCROLL         0x9F
+
+
+class Adafruit_SSD1351 : public virtual Adafruit_GFX
+{
+ public:
+  Adafruit_SSD1351(PinName cs, PinName rs, PinName dc, PinName clk, PinName data);
+
+  void on();
+  void off();
+  
+  uint16_t Color565(uint8_t r, uint8_t g, uint8_t b);
+
+  // drawing primitives!
+  virtual void drawPixel(int16_t x, int16_t y, uint16_t color);
+  void fillRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);
+  void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
+  void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
+  void fillScreen(uint16_t fillcolor);
+
+  void invert(bool);
+  // commands
+  void begin(void);
+  void goTo(int x, int y);
+
+  void reset(void);
+
+  /* low level */
+
+  void writeData(uint8_t d);
+  void writeCommand(uint8_t c);
+
+
+  void writeData_unsafe(uint16_t d);
+
+  void setWriteDir(void);
+  void write8(uint8_t d);
+
+ private:
+  SPI _spi;
+  DigitalOut _cs, _dc, _reset;
+
+  void rawFillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor);
+  void rawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
+  void rawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
+};