Adafruit SSD1331 library for Mbed, specifically tested on NRF51822
Dependents: Pmod_OLEDrgb_ALS1_K64F McLab10_OLEDrgb_L432KC_tk2 Pmod_OLEDrgb_ALS1_L432KC
Revision 0:e8e869596683, committed 2017-12-13
- 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 |
diff -r 000000000000 -r e8e869596683 Adafruit_SSD1331.cpp --- /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
diff -r 000000000000 -r e8e869596683 Adafruit_SSD1331.h --- /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