Driver for the Seeedstudio RGB OLED module for the xadow M0

src/SSD1331.cpp

Committer:
messi1
Date:
2015-11-10
Revision:
0:6e810b5b40a3
Child:
2:e033aab5daad

File content as of revision 0:6e810b5b40a3:

/*
* SSD1331.cpp
* A library for RGB OLED module
*
* Copyright (c) 2014 seeed technology inc.
* Copyright (c) 2012, Adafruit Industries.
*
* All rights reserved.
*
* This library is based on Adafruit's SSD1331-OLED-Driver-Library. Thanks to 
* their contribution to the code, we modify it and add more interface to 
* support our Seeed's Xadow RGB OLED 96*64 module.
*
* Below is the introduction of Adafruit's Color OLED module, we add it to here
* to express our thanks to them.
*
* ****************************************************************************
* 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.
*
* 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.
* Modifed by lawliet for Seeed Studio's RGB OLED module.
* BSD license, all text above must be included in any redistribution
* ******************************************************************************
*
* Software License Agreement (BSD License)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "DigitalOut.h"
#include "SPI.h"
#include "SSD1331.h"

SSD1331::SSD1331(PinName cs, PinName dc, PinName mosi, PinName sck)
:SGL(RGB_OLED_WIDTH, RGB_OLED_HEIGHT)
{
    _cs = new mbed::DigitalOut(cs);
    _dc = new mbed::DigitalOut(dc);
    _spiPort = new mbed::SPI(mosi, NC, sck);
    _spiPort->format(8,3); //8bit frame and POL=1 /PHA=1(UpEdge Sampled)
    _spiPort->frequency(25000000); // modify later
};

void SSD1331::_sendCmd(uint8_t c)
{
    _dc->write(LOW);
    _cs->write(LOW);
    _spiPort->write(c);
    _cs->write(HIGH);
}

void SSD1331::init(void)
{
//    pinMode(_dc, OUTPUT);
//    pinMode(_cs, OUTPUT);

//    _spiPort->begin();

    _sendCmd(CMD_DISPLAY_OFF);          //Display Off
    _sendCmd(CMD_SET_CONTRAST_A);       //Set contrast for color A
    _sendCmd(0x91);                     //145
    _sendCmd(CMD_SET_CONTRAST_B);       //Set contrast for color B
    _sendCmd(0x50);                     //80
    _sendCmd(CMD_SET_CONTRAST_C);       //Set contrast for color C
    _sendCmd(0x7D);                     //125
    _sendCmd(CMD_MASTER_CURRENT_CONTROL);//master current control
    _sendCmd(0x06);                     //6
    _sendCmd(CMD_SET_PRECHARGE_SPEED_A);//Set Second Pre-change Speed For ColorA
    _sendCmd(0x64);                     //100
    _sendCmd(CMD_SET_PRECHARGE_SPEED_B);//Set Second Pre-change Speed For ColorB
    _sendCmd(0x78);                     //120
    _sendCmd(CMD_SET_PRECHARGE_SPEED_C);//Set Second Pre-change Speed For ColorC
    _sendCmd(0x64);                     //100
    _sendCmd(CMD_SET_REMAP);            //set remap & data format
    _sendCmd(0x72);                     //0x72              
    _sendCmd(CMD_SET_DISPLAY_START_LINE);//Set display Start Line
    _sendCmd(0x0);
    _sendCmd(CMD_SET_DISPLAY_OFFSET);   //Set display offset
    _sendCmd(0x0);
    _sendCmd(CMD_NORMAL_DISPLAY);       //Set display mode
    _sendCmd(CMD_SET_MULTIPLEX_RATIO);  //Set multiplex ratio
    _sendCmd(0x3F);
    _sendCmd(CMD_SET_MASTER_CONFIGURE); //Set master configuration
    _sendCmd(0x8E);
    _sendCmd(CMD_POWER_SAVE_MODE);      //Set Power Save Mode
    _sendCmd(0x00);                     //0x00
    _sendCmd(CMD_PHASE_PERIOD_ADJUSTMENT);//phase 1 and 2 period adjustment
    _sendCmd(0x31);                     //0x31
    _sendCmd(CMD_DISPLAY_CLOCK_DIV);    //display clock divider/oscillator frequency
    _sendCmd(0xF0);
    _sendCmd(CMD_SET_PRECHARGE_VOLTAGE);//Set Pre-Change Level
    _sendCmd(0x3A);
    _sendCmd(CMD_SET_V_VOLTAGE);        //Set vcomH
    _sendCmd(0x3E);
    _sendCmd(CMD_DEACTIVE_SCROLLING);   //disable scrolling
    _sendCmd(CMD_NORMAL_BRIGHTNESS_DISPLAY_ON);//set display on
}

void SSD1331::drawPixel(uint16_t x, uint16_t y, uint16_t color)
{
    if ((x >= RGB_OLED_WIDTH) || (y >= RGB_OLED_HEIGHT))
        return;
    //set column point
    _sendCmd(CMD_SET_COLUMN_ADDRESS);
    _sendCmd(x);
    _sendCmd(RGB_OLED_WIDTH-1);
    //set row point
    _sendCmd(CMD_SET_ROW_ADDRESS);
    _sendCmd(y);
    _sendCmd(RGB_OLED_HEIGHT-1);
    //fill 16bit colour
    _dc->write(HIGH);
    _cs->write(LOW);
    _spiPort->write(color >> 8);
    _spiPort->write(color);
    _cs->write(HIGH);
}

void SSD1331::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
{
    if (x0 >= RGB_OLED_WIDTH)  x0 = RGB_OLED_WIDTH - 1;
    if (y0 >= RGB_OLED_HEIGHT) y0 = RGB_OLED_HEIGHT - 1;
    if (x1 >= RGB_OLED_WIDTH)  x1 = RGB_OLED_WIDTH - 1;
    if (y1 >= RGB_OLED_HEIGHT) y1 = RGB_OLED_HEIGHT - 1;

    _sendCmd(CMD_DRAW_LINE);//draw line
    _sendCmd(x0);//start column
    _sendCmd(y0);//start row
    _sendCmd(x1);//end column
    _sendCmd(y1);//end row
    _sendCmd((uint8_t)((color>>11)&0x1F));//R
    _sendCmd((uint8_t)((color>>5)&0x3F));//G
    _sendCmd((uint8_t)(color&0x1F));//B
}

void SSD1331::drawFrame(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t outColor, uint16_t fillColor)
{
    if (x0 >= RGB_OLED_WIDTH)  x0 = RGB_OLED_WIDTH - 1;
    if (y0 >= RGB_OLED_HEIGHT) y0 = RGB_OLED_HEIGHT - 1;
    if (x1 >= RGB_OLED_WIDTH)  x1 = RGB_OLED_WIDTH - 1;
    if (y1 >= RGB_OLED_HEIGHT) y1 = RGB_OLED_HEIGHT - 1;

    _sendCmd(CMD_FILL_WINDOW);//fill window
    _sendCmd(ENABLE_FILL);
    _sendCmd(CMD_DRAW_RECTANGLE);//draw rectangle
    _sendCmd(x0);//start column
    _sendCmd(y0);//start row
    _sendCmd(x1);//end column
    _sendCmd(y1);//end row
    _sendCmd((uint8_t)((outColor>>11)&0x1F));//R
    _sendCmd((uint8_t)((outColor>>5)&0x3F));//G
    _sendCmd((uint8_t)(outColor&0x1F));//B
    _sendCmd((uint8_t)((fillColor>>11)&0x1F));//R
    _sendCmd((uint8_t)((fillColor>>5)&0x3F));//G
    _sendCmd((uint8_t)(fillColor&0x1F));//B
}

void SSD1331::copyWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,uint16_t x2, uint16_t y2)
{
    _sendCmd(CMD_COPY_WINDOW);//copy window
    _sendCmd(x0);//start column
    _sendCmd(y0);//start row
    _sendCmd(x1);//end column
    _sendCmd(y1);//end row
    _sendCmd(x2);//new column
    _sendCmd(y2);//new row
}

void SSD1331::dimWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
    _sendCmd(CMD_DIM_WINDOW);//copy area
    _sendCmd(x0);//start column
    _sendCmd(y0);//start row
    _sendCmd(x1);//end column
    _sendCmd(y1);//end row
}

void SSD1331::clearWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
    _sendCmd(CMD_CLEAR_WINDOW);//clear window
    _sendCmd(x0);//start column
    _sendCmd(y0);//start row
    _sendCmd(x1);//end column
    _sendCmd(y1);//end row
}

void SSD1331::setScolling(ScollingDirection direction, uint8_t rowAddr, uint8_t rowNum, uint8_t timeInterval)
{
    uint8_t scolling_horizontal = 0x0;
    uint8_t scolling_vertical = 0x0;
    switch(direction){
        case Horizontal:
            scolling_horizontal = 0x01;
            scolling_vertical = 0x00;
            break;
        case Vertical:
            scolling_horizontal = 0x00;
            scolling_vertical = 0x01;
            break;
        case Diagonal:
            scolling_horizontal = 0x01;
            scolling_vertical = 0x01;
            break;
        default:
            break;
    }
    _sendCmd(CMD_CONTINUOUS_SCROLLING_SETUP);
    _sendCmd(scolling_horizontal);
    _sendCmd(rowAddr);
    _sendCmd(rowNum);
    _sendCmd(scolling_vertical);
    _sendCmd(timeInterval);
    _sendCmd(CMD_ACTIVE_SCROLLING);
}

void SSD1331::enableScolling(bool enable)
{
    if(enable)
        _sendCmd(CMD_ACTIVE_SCROLLING);
    else
        _sendCmd(CMD_DEACTIVE_SCROLLING);
}

void SSD1331::setDisplayMode(DisplayMode mode)
{
    _sendCmd(mode);
}

void SSD1331::setDisplayPower(DisplayPower power)
{
    _sendCmd(power);
}