Adafruit SSD1331 library for Mbed, specifically tested on NRF51822

Dependents:   Pmod_OLEDrgb_ALS1_K64F McLab10_OLEDrgb_L432KC_tk2 Pmod_OLEDrgb_ALS1_L432KC

Files at this revision

API Documentation at this revision

Comitter:
mjromeijn
Date:
Wed Dec 13 20:41:59 2017 +0000
Commit message:
Initial commit

Changed in this revision

Adafruit_SSD1331.cpp Show annotated file Show diff for this revision Revisions of this file
Adafruit_SSD1331.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_SSD1331.cpp	Wed Dec 13 20:41:59 2017 +0000
@@ -0,0 +1,416 @@
+/*************************************************** 
+  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!
+  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+
+#include "Adafruit_GFX.h"
+#include "Adafruit_SSD1331.h"
+
+#include <SPI.h>
+
+/********************************** low level pin interface */
+
+inline void Adafruit_SSD1331::spiwrite(uint8_t c) {
+    
+        spi.write(c);
+        return;
+}
+
+
+void Adafruit_SSD1331::writeCommand(uint8_t c) {
+    DC=0;
+    CS=0;
+    
+    spiwrite(c);
+    
+    CS=1;
+}
+
+
+void Adafruit_SSD1331::writeData(uint8_t c) {
+    DC=1;
+    CS=0;
+    
+    spiwrite(c);
+
+    CS=1;
+} 
+
+/***********************************/
+
+void Adafruit_SSD1331::goHome(void) {
+  goTo(0,0);
+}
+
+void Adafruit_SSD1331::goTo(int x, int y) {
+    if (cursorX==x && cursorY == y) return;
+    cursorX = x;
+    cursorY = y;
+    if ((x >= WIDTH) || (y >= HEIGHT)) return;
+    
+    // set x and y coordinate
+    /*writeCommand(SSD1331_CMD_SETCOLUMN);
+    writeCommand(x);
+    writeCommand(WIDTH-1);
+    
+    writeCommand(SSD1331_CMD_SETROW);
+    writeCommand(y);
+    writeCommand(HEIGHT-1);*/
+    DC=0;
+    CS=0;
+    
+    spiwrite(SSD1331_CMD_SETCOLUMN);
+    spiwrite(x);
+    spiwrite(WIDTH-1);
+    
+    spiwrite(SSD1331_CMD_SETROW);
+    spiwrite(y);
+    spiwrite(HEIGHT-1);
+    
+    CS=1;
+}
+
+uint16_t Adafruit_SSD1331::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;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Draws a filled rectangle using HW acceleration
+*/
+/**************************************************************************/
+/*
+void Adafruit_SSD1331::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor) 
+{
+//Serial.println("fillRect");
+  // check rotation, move rect around if necessary
+  switch (getRotation()) {
+  case 1:
+    swap(x, y);
+    swap(w, h);
+    x = WIDTH - x - 1;
+    break;
+  case 2:
+    x = WIDTH - x - 1;
+    y = HEIGHT - y - 1;
+    break;
+  case 3:
+    swap(x, y);
+    swap(w, h);
+    y = HEIGHT - y - 1;
+    break;
+  }
+  // Bounds check
+  if ((x >= TFTWIDTH) || (y >= TFTHEIGHT))
+    return;
+  // Y bounds check
+  if (y+h > TFTHEIGHT)
+  {
+    h = TFTHEIGHT - y;
+  }
+  // X bounds check
+  if (x+w > TFTWIDTH)
+  {
+    w = TFTWIDTH - x;
+  }
+  
+  // fill!
+  writeCommand(SSD1331_CMD_FILL);
+  writeCommand(0x01);
+  writeCommand(SSD1331_CMD_DRAWRECT);
+  writeCommand(x & 0xFF);                           // Starting column
+  writeCommand(y & 0xFF);                           // Starting row
+  writeCommand((x+w-1) & 0xFF); // End column
+  writeCommand((y+h-1) & 0xFF); // End row
+  
+  // Outline color
+  writeCommand((uint8_t)((fillcolor >> 11) << 1));
+  writeCommand((uint8_t)((fillcolor >> 5) & 0x3F));
+  writeCommand((uint8_t)((fillcolor << 1) & 0x3F));
+  // Fill color
+  writeCommand((uint8_t)((fillcolor >> 11) << 1));
+  writeCommand((uint8_t)((fillcolor >> 5) & 0x3F));
+  writeCommand((uint8_t)((fillcolor << 1) & 0x3F));
+ 
+  // Delay while the fill completes
+  delay(SSD1331_DELAYS_HWFILL); 
+}
+*/
+
+void Adafruit_SSD1331::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {   
+  // check rotation, move pixel around if necessary
+  switch (getRotation()) {
+  case 1:
+    gfx_swap(x0, y0);
+    gfx_swap(x1, y1);
+    x0 = WIDTH - x0 - 1;
+    x1 = WIDTH - x1 - 1;
+    break;
+  case 2:
+    x0 = WIDTH - x0 - 1;
+    y0 = HEIGHT - y0 - 1;
+    x1 = WIDTH - x1 - 1;
+    y1 = HEIGHT - y1 - 1;
+    break;
+  case 3:
+    gfx_swap(x0, y0);
+    gfx_swap(x1, y1);
+    y0 = HEIGHT - y0 - 1;
+    y1 = HEIGHT - y1 - 1;
+    break;
+  }
+
+  // Boundary check
+  if ((y0 >= TFTHEIGHT) && (y1 >= TFTHEIGHT))
+    return;
+  if ((x0 >= TFTWIDTH) && (x1 >= TFTWIDTH))
+    return; 
+  if (x0 >= TFTWIDTH)
+    x0 = TFTWIDTH - 1;
+  if (y0 >= TFTHEIGHT)
+    y0 = TFTHEIGHT - 1;
+  if (x1 >= TFTWIDTH)
+    x1 = TFTWIDTH - 1;
+  if (y1 >= TFTHEIGHT)
+    y1 = TFTHEIGHT - 1;
+  
+  writeCommand(SSD1331_CMD_DRAWLINE);
+  writeCommand(x0);
+  writeCommand(y0);
+  writeCommand(x1);
+  writeCommand(y1);
+  //wait_ms(SSD1331_DELAYS_HWLINE);  
+  writeCommand((uint8_t)((color >> 11) << 1));
+  writeCommand((uint8_t)((color >> 5) & 0x3F));
+  writeCommand((uint8_t)((color << 1) & 0x3F));
+  //wait_ms(SSD1331_DELAYS_HWLINE);  
+}
+
+void Adafruit_SSD1331::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
+    switch (getRotation()) {
+  case 1:
+    gfx_swap(x, y);
+    gfx_swap(w, h);
+    x = WIDTH - x - 1;
+    w = -w;
+    break;
+  case 2:
+    x = WIDTH - x - 1;
+    y = HEIGHT - y - 1;
+    w = -w;
+    h = -h;
+    break;
+  case 3:
+    gfx_swap(x, y);
+    gfx_swap(w, h);
+    y = HEIGHT - y - 1;
+    h = -h;
+    break;
+  }
+
+  writeCommand(SSD1331_CMD_DRAWRECT);
+  writeCommand(x);
+  writeCommand(y);
+  writeCommand(x+w-1);
+  writeCommand(y+h-1);
+  writeCommand((uint8_t)((color >> 11) << 1));
+  writeCommand((uint8_t)((color >> 5) & 0x3F));
+  writeCommand((uint8_t)((color << 1) & 0x3F));
+  writeCommand((uint8_t)((color >> 11) << 1));
+  writeCommand((uint8_t)((color >> 5) & 0x3F));
+  writeCommand((uint8_t)((color << 1) & 0x3F));
+    
+}
+
+void Adafruit_SSD1331::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
+    writeCommand(SSD1331_CMD_FILL);
+    writeCommand(0xFF);
+    drawRect(x,y,w,h,color);
+    wait_ms(SSD1331_DELAYS_HWFILL);
+    writeCommand(SSD1331_CMD_FILL);
+    writeCommand(0x00);
+}
+
+void Adafruit_SSD1331::clearArea(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {   
+  // check rotation, move pixel around if necessary
+  switch (getRotation()) {
+  case 1:
+    gfx_swap(x0, y0);
+    gfx_swap(x1, y1);
+    x0 = WIDTH - x0 - 1;
+    x1 = WIDTH - x1 - 1;
+    break;
+  case 2:
+    x0 = WIDTH - x0 - 1;
+    y0 = HEIGHT - y0 - 1;
+    x1 = WIDTH - x1 - 1;
+    y1 = HEIGHT - y1 - 1;
+    break;
+  case 3:
+    gfx_swap(x0, y0);
+    gfx_swap(x1, y1);
+    y0 = HEIGHT - y0 - 1;
+    y1 = HEIGHT - y1 - 1;
+    break;
+  }
+
+  // Boundary check
+  if ((y0 >= TFTHEIGHT) && (y1 >= TFTHEIGHT))
+    return;
+  if ((x0 >= TFTWIDTH) && (x1 >= TFTWIDTH))
+    return; 
+  if (x0 >= TFTWIDTH)
+    x0 = TFTWIDTH - 1;
+  if (y0 >= TFTHEIGHT)
+    y0 = TFTHEIGHT - 1;
+  if (x1 >= TFTWIDTH)
+    x1 = TFTWIDTH - 1;
+  if (y1 >= TFTHEIGHT)
+    y1 = TFTHEIGHT - 1;
+  
+  writeCommand(SSD1331_CMD_CLEAR);
+  writeCommand(x0);
+  writeCommand(y0);
+  writeCommand(x1);
+  writeCommand(y1);
+  wait_ms(SSD1331_DELAYS_HWCLEAR);
+}
+
+void Adafruit_SSD1331::clearScreen() {
+    clearArea(0,0,WIDTH,HEIGHT);
+}
+
+void Adafruit_SSD1331::drawPixel(int16_t x, int16_t y, uint16_t color)
+{
+  if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) return;
+
+  // check rotation, move pixel around if necessary
+  switch (getRotation()) {
+  case 1:
+    gfx_swap(x, y);
+    x = WIDTH - x - 1;
+    break;
+  case 2:
+    x = WIDTH - x - 1;
+    y = HEIGHT - y - 1;
+    break;
+  case 3:
+    gfx_swap(x, y);
+    y = HEIGHT - y - 1;
+    break;
+  }
+
+  goTo(x, y);
+  
+  // setup for data
+  /**rsportreg |= rspin;
+  *csportreg &= ~ cspin;*/
+  DC=1;
+  CS=0;
+  spiwrite(color >> 8);    
+  spiwrite(color);
+  CS=1;
+  cursorX++;
+  //*csportreg |= cspin;  
+}
+
+void Adafruit_SSD1331::pushColor(uint16_t color) {
+  // setup for data
+  //*rsportreg |= rspin;
+  //*csportreg &= ~ cspin;
+  DC=1;
+  CS=0;
+  spiwrite(color >> 8);    
+  spiwrite(color);
+  CS=1;
+  //*csportreg |= cspin; 
+}
+
+
+void Adafruit_SSD1331::begin(void) {
+    // set pin directions
+    //pinMode(_rs, OUTPUT);
+    
+    spi.format(8,3); //8bit frame and POL=1 /PHA=1(UpEdge Sampled)
+    spi.frequency(4000000); // modify later
+    
+    // Toggle RST low to reset; CS low so it'll listen to us
+    CS=0;
+    
+    RES=1;
+    wait_ms(200);
+    RES=0;
+    wait_ms(200);
+    RES=1;
+    wait_ms(200);
+        
+    // Initialization Sequence
+    writeCommand(SSD1331_CMD_DISPLAYOFF);   // 0xAE
+    writeCommand(SSD1331_CMD_SETREMAP);     // 0xA0
+#if defined SSD1331_COLORORDER_RGB
+    writeCommand(0x72);             // RGB Color
+#else
+    writeCommand(0x76);             // BGR Color
+#endif
+    writeCommand(SSD1331_CMD_STARTLINE);    // 0xA1
+    writeCommand(0x0);
+    writeCommand(SSD1331_CMD_DISPLAYOFFSET);    // 0xA2
+    writeCommand(0x0);
+    writeCommand(SSD1331_CMD_NORMALDISPLAY);    // 0xA4
+    writeCommand(SSD1331_CMD_SETMULTIPLEX);     // 0xA8
+    writeCommand(0x3F);             // 0x3F 1/64 duty
+    writeCommand(SSD1331_CMD_SETMASTER);    // 0xAD
+    writeCommand(0x8E);
+    writeCommand(SSD1331_CMD_POWERMODE);    // 0xB0
+    writeCommand(0x0B);
+    writeCommand(SSD1331_CMD_PRECHARGE);    // 0xB1
+    writeCommand(0x31);
+    writeCommand(SSD1331_CMD_CLOCKDIV);     // 0xB3
+    writeCommand(0xF0);  // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio (A[3:0]+1 = 1..16)
+    writeCommand(SSD1331_CMD_PRECHARGEA);   // 0x8A
+    writeCommand(0x64);
+    writeCommand(SSD1331_CMD_PRECHARGEB);   // 0x8B
+    writeCommand(0x78);
+    writeCommand(SSD1331_CMD_PRECHARGEA);   // 0x8C
+    writeCommand(0x64);
+    writeCommand(SSD1331_CMD_PRECHARGELEVEL);   // 0xBB
+    writeCommand(0x3A);
+    writeCommand(SSD1331_CMD_VCOMH);        // 0xBE
+    writeCommand(0x3E);
+    writeCommand(SSD1331_CMD_MASTERCURRENT);    // 0x87
+    writeCommand(0x06);
+    writeCommand(SSD1331_CMD_CONTRASTA);    // 0x81
+    writeCommand(0x91);
+    writeCommand(SSD1331_CMD_CONTRASTB);    // 0x82
+    writeCommand(0x50);
+    writeCommand(SSD1331_CMD_CONTRASTC);    // 0x83
+    writeCommand(0x7D);
+    writeCommand(SSD1331_CMD_DISPLAYON);    //--turn on oled panel    
+}
+
+/********************************* low level pin initialization */
+
+Adafruit_SSD1331::Adafruit_SSD1331(PinName cs, PinName rs, PinName dc, PinName mosi, PinName miso, PinName sclk)
+: Adafruit_GFX(TFTWIDTH,
+TFTHEIGHT),
+CS(cs),
+RES(rs),
+DC(dc),
+spi(mosi, miso, sclk) {
+    begin();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_SSD1331.h	Wed Dec 13 20:41:59 2017 +0000
@@ -0,0 +1,118 @@
+/*************************************************** 
+  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!
+  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+ 
+#include <stddef.h>
+#include "mbed.h"
+#include "Adafruit_GFX.h"
+
+#define gfx_swap(a, b) { uint16_t t = a; a = b; b = t; }
+
+#ifdef __SAM3X8E__
+typedef volatile RwReg PortReg;
+typedef uint32_t PortMask;
+#define _BV(b) (1<<(b))
+#else
+typedef volatile uint8_t PortReg;
+typedef uint8_t PortMask;
+#endif
+
+// Select one of these defines to set the pixel color order
+#define SSD1331_COLORORDER_RGB
+// #define SSD1331_COLORORDER_BGR
+
+#if defined SSD1331_COLORORDER_RGB && defined SSD1331_COLORORDER_BGR
+  #error "RGB and BGR can not both be defined for SSD1331_COLORODER."
+#endif
+
+// Timing Delays
+#define SSD1331_DELAYS_HWFILL       (1)
+#define SSD1331_DELAYS_HWLINE       (0)
+#define SSD1331_DELAYS_HWCLEAR      (1)
+
+// SSD1331 Commands
+#define SSD1331_CMD_DRAWLINE        0x21
+#define SSD1331_CMD_DRAWRECT        0x22
+#define SSD1331_CMD_FILL            0x26
+#define SSD1331_CMD_SETCOLUMN       0x15
+#define SSD1331_CMD_SETROW          0x75
+#define SSD1331_CMD_CONTRASTA       0x81
+#define SSD1331_CMD_CONTRASTB       0x82
+#define SSD1331_CMD_CONTRASTC       0x83
+#define SSD1331_CMD_MASTERCURRENT   0x87
+#define SSD1331_CMD_SETREMAP        0xA0
+#define SSD1331_CMD_STARTLINE       0xA1
+#define SSD1331_CMD_DISPLAYOFFSET   0xA2
+#define SSD1331_CMD_NORMALDISPLAY   0xA4
+#define SSD1331_CMD_DISPLAYALLON    0xA5
+#define SSD1331_CMD_DISPLAYALLOFF   0xA6
+#define SSD1331_CMD_INVERTDISPLAY   0xA7
+#define SSD1331_CMD_SETMULTIPLEX    0xA8
+#define SSD1331_CMD_SETMASTER       0xAD
+#define SSD1331_CMD_DISPLAYOFF      0xAE
+#define SSD1331_CMD_DISPLAYON       0xAF
+#define SSD1331_CMD_POWERMODE       0xB0
+#define SSD1331_CMD_PRECHARGE       0xB1
+#define SSD1331_CMD_CLOCKDIV        0xB3
+#define SSD1331_CMD_PRECHARGEA      0x8A
+#define SSD1331_CMD_PRECHARGEB      0x8B
+#define SSD1331_CMD_PRECHARGEC      0x8C
+#define SSD1331_CMD_PRECHARGELEVEL  0xBB
+#define SSD1331_CMD_VCOMH           0xBE
+#define WIDTH                       96
+#define HEIGHT                      64
+
+#define SSD1331_CMD_CLEAR           0x25
+
+class Adafruit_SSD1331 : public Adafruit_GFX {
+ public:
+  Adafruit_SSD1331(PinName cs, PinName rs, PinName dc, PinName mosi, PinName miso, PinName sclk);
+
+  uint16_t Color565(uint8_t r, uint8_t g, uint8_t b);
+
+  // drawing primitives!
+  void drawPixel(int16_t x, int16_t y, uint16_t color);
+  void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
+  void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
+  void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t fillcolor);
+  void clearScreen();
+  void clearArea(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
+  void pushColor(uint16_t c);
+
+  // commands
+  void begin(void);
+  void goHome(void);
+  void goTo(int x, int y);
+
+  void reset(void);
+
+  /* low level */
+
+  void writeData(uint8_t d);
+  void writeCommand(uint8_t c);
+
+  static const int16_t TFTWIDTH = 96;
+  static const int16_t TFTHEIGHT = 64;
+  
+  uint8_t cursorX, cursorY;
+
+  void writeData_unsafe(uint16_t d);
+
+  void setWriteDir(void);
+  void write8(uint8_t d);
+
+ private:
+  void spiwrite(uint8_t);
+
+  DigitalOut  CS,  RES,  DC;
+  SPI spi; // mosi, miso, sclk
+};
\ No newline at end of file