A simple yet powerful library for controlling graphical displays. Multiple display controllers are supported using inheritance.

Dependents:   mbed_rifletool Hexi_Bubble_Game Hexi_Catch-the-dot_Game Hexi_Acceleromagnetic_Synth

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SSD1351_SPI.cpp Source File

SSD1351_SPI.cpp

00001 /* NeatGUI Library
00002  * Copyright (c) 2013 Neil Thiessen
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "SSD1351_SPI.h"
00018 
00019 SSD1351_SPI::SSD1351_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) : Display(128, 128), m_SPI(mosi, miso, sclk), m_CS(cs), m_DC(dc)
00020 {
00021     //Deselect the display
00022     m_CS = 1;
00023 
00024     //Set the SPI format to 8 bit data, high steady state clock, second edge capture
00025     m_SPI.format(8, 3);
00026 
00027     //Set the SPI frequency to 20MHz
00028     m_SPI.frequency(10000000);
00029 }
00030 
00031 bool SSD1351_SPI::open()
00032 {
00033     //Init sequence for 128x128 OLED module
00034     writeCommand(CMD_COMMANDLOCK);
00035     writeData(0x12);
00036     writeCommand(CMD_COMMANDLOCK);
00037     writeData(0xB1);
00038     writeCommand(CMD_DISPLAYOFF);
00039     writeCommand(CMD_CLOCKDIV);
00040     writeCommand(0xF1);
00041     writeCommand(CMD_MUXRATIO);
00042     writeData(127);
00043     writeCommand(CMD_SETREMAP);
00044     //writeData(0x74);
00045     writeData(0xB4);
00046     //writeData(0b01110100);
00047     writeCommand(CMD_SETCOLUMN);
00048     writeData(0x00);
00049     writeData(0x7F);
00050     writeCommand(CMD_SETROW);
00051     writeData(0x00);
00052     writeData(0x7F);
00053     writeCommand(CMD_STARTLINE);
00054     writeData(0x0);
00055     writeCommand(CMD_DISPLAYOFFSET);
00056     writeData(0x0);
00057     writeCommand(CMD_SETGPIO);
00058     writeData(0x00);
00059     writeCommand(CMD_FUNCTIONSELECT);
00060     writeData(0x01);
00061     writeCommand(CMD_PRECHARGE);
00062     writeCommand(0x32);
00063     writeCommand(CMD_VCOMH);
00064     writeCommand(0x05);
00065     writeCommand(CMD_NORMALDISPLAY);
00066     writeCommand(CMD_CONTRASTABC);
00067     writeData(0xC8);
00068     writeData(0x80);
00069     writeData(0xC8);
00070     writeCommand(CMD_CONTRASTMASTER);
00071     writeData(0x0F);
00072     writeCommand(CMD_SETVSL );
00073     writeData(0xA0);
00074     writeData(0xB5);
00075     writeData(0x55);
00076     writeCommand(CMD_PRECHARGE2);
00077     writeData(0x01);
00078 
00079     //Return success
00080     return true;
00081 }
00082 
00083 void SSD1351_SPI::flush()
00084 {
00085     if (m_CacheIndex > 0) {
00086         //Set DC to data and select the display
00087         m_DC = 1;
00088         m_CS = 0;
00089 
00090         //Write the entire cache at once
00091         for (int i = 0; i < m_CacheIndex; i++)
00092             m_SPI.write(m_Cache[i]);
00093 
00094         //Deselect the display
00095         m_CS = 1;
00096 
00097         //Reset the cache index
00098         m_CacheIndex = 0;
00099     }
00100 }
00101 
00102 Display::State SSD1351_SPI::state()
00103 {
00104     //Return the base class's state
00105     return Display::state();
00106 }
00107 
00108 void SSD1351_SPI::state(State s)
00109 {
00110     //Check what the requested state is
00111     if (s == Display::DISPLAY_ON) {
00112         //Turn the display on
00113         writeCommand(CMD_DISPLAYON);
00114     } else if (s == Display::DISPLAY_OFF) {
00115         //Turn the display off
00116         writeCommand(CMD_DISPLAYOFF);
00117     }
00118 
00119     //Update the base class
00120     Display::state(s);
00121 }
00122 
00123 void SSD1351_SPI::drawPixel(int x, int y, unsigned int c)
00124 {
00125     //Range check the pixel
00126     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00127         return;
00128 
00129     //Only goto if the cursor is out of position
00130     if (x != m_CursX || y != m_CursY) {
00131         //First flush the cache
00132         flush();
00133 
00134         //Set column start and end address (also moves pointer)
00135         writeCommand(CMD_SETCOLUMN);
00136         writeData(x);
00137         writeData(width() - 1);
00138 
00139         //Set row start and end address (also moves pointer)
00140         writeCommand(CMD_SETROW);
00141         writeData(y);
00142         writeData(height() - 1);
00143 
00144         writeCommand(CMD_WRITERAM);
00145 
00146         //Update the cursor variables
00147         m_StartX = x;
00148         m_StartY = y;
00149         m_CursX = x;
00150         m_CursY = y;
00151     }
00152 
00153     //Check if the cache is full
00154     if (m_CacheIndex > 1024 - 4) {
00155         //Flush the cache
00156         flush();
00157     }
00158 
00159     //Add this pixel to the cache
00160     m_Cache[m_CacheIndex++] = c >> 18;
00161     m_Cache[m_CacheIndex++] = c >> 10;
00162     m_Cache[m_CacheIndex++] = c >> 2;
00163 
00164     //Increment the cursor with wrapping
00165     if (++m_CursX > width() - 1) {
00166         m_CursX = m_StartX;
00167 
00168         if (++m_CursY > height() - 1) {
00169             m_CursY = m_StartY;
00170         }
00171     }
00172 }
00173 
00174 void SSD1351_SPI::writeCommand(char command)
00175 {
00176     //Set DC to command and select the display
00177     m_DC = 0;
00178     m_CS = 0;
00179 
00180     //Write the command byte
00181     m_SPI.write(command);
00182 
00183     //Deselect the display
00184     m_CS = 1;
00185 }
00186 
00187 void SSD1351_SPI::writeData(char data)
00188 {
00189     //Set DC to data and select the display
00190     m_DC = 1;
00191     m_CS = 0;
00192 
00193     //Write the data byte
00194     m_SPI.write(data);
00195 
00196     //Deselect the display
00197     m_CS = 1;
00198 }