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

NOTE: This library is in beta right now. As far as I know, everything here works, but there are many features that are lacking so far. Most notably containers, button handling, and display drivers other than the SSD1306.

Committer:
neilt6
Date:
Tue May 27 21:41:28 2014 +0000
Revision:
3:a8f72d4864e6
Parent:
2:bbfc18022ee5
Syntax improvements

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 2:bbfc18022ee5 1 /* NeatGUI Library
neilt6 2:bbfc18022ee5 2 * Copyright (c) 2013 Neil Thiessen
neilt6 2:bbfc18022ee5 3 *
neilt6 2:bbfc18022ee5 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 2:bbfc18022ee5 5 * you may not use this file except in compliance with the License.
neilt6 2:bbfc18022ee5 6 * You may obtain a copy of the License at
neilt6 2:bbfc18022ee5 7 *
neilt6 2:bbfc18022ee5 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 2:bbfc18022ee5 9 *
neilt6 2:bbfc18022ee5 10 * Unless required by applicable law or agreed to in writing, software
neilt6 2:bbfc18022ee5 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 2:bbfc18022ee5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 2:bbfc18022ee5 13 * See the License for the specific language governing permissions and
neilt6 2:bbfc18022ee5 14 * limitations under the License.
neilt6 2:bbfc18022ee5 15 */
neilt6 2:bbfc18022ee5 16
neilt6 2:bbfc18022ee5 17 #include "SSD1351_SPI.h"
neilt6 2:bbfc18022ee5 18
neilt6 2:bbfc18022ee5 19 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)
neilt6 2:bbfc18022ee5 20 {
neilt6 2:bbfc18022ee5 21 //Deselect the display
neilt6 2:bbfc18022ee5 22 m_CS = 1;
neilt6 2:bbfc18022ee5 23
neilt6 2:bbfc18022ee5 24 //Set the SPI format to 8 bit data, high steady state clock, second edge capture
neilt6 2:bbfc18022ee5 25 m_SPI.format(8, 3);
neilt6 2:bbfc18022ee5 26
neilt6 2:bbfc18022ee5 27 //Set the SPI frequency to 20MHz
neilt6 2:bbfc18022ee5 28 m_SPI.frequency(10000000);
neilt6 2:bbfc18022ee5 29 }
neilt6 2:bbfc18022ee5 30
neilt6 2:bbfc18022ee5 31 bool SSD1351_SPI::open()
neilt6 2:bbfc18022ee5 32 {
neilt6 2:bbfc18022ee5 33 //Init sequence for 128x128 OLED module
neilt6 2:bbfc18022ee5 34 writeCommand(CMD_COMMANDLOCK);
neilt6 2:bbfc18022ee5 35 writeData(0x12);
neilt6 2:bbfc18022ee5 36 writeCommand(CMD_COMMANDLOCK);
neilt6 2:bbfc18022ee5 37 writeData(0xB1);
neilt6 2:bbfc18022ee5 38 writeCommand(CMD_DISPLAYOFF);
neilt6 2:bbfc18022ee5 39 writeCommand(CMD_CLOCKDIV);
neilt6 2:bbfc18022ee5 40 writeCommand(0xF1);
neilt6 2:bbfc18022ee5 41 writeCommand(CMD_MUXRATIO);
neilt6 2:bbfc18022ee5 42 writeData(127);
neilt6 2:bbfc18022ee5 43 writeCommand(CMD_SETREMAP);
neilt6 2:bbfc18022ee5 44 //writeData(0x74);
neilt6 2:bbfc18022ee5 45 writeData(0xB4);
neilt6 2:bbfc18022ee5 46 //writeData(0b01110100);
neilt6 2:bbfc18022ee5 47 writeCommand(CMD_SETCOLUMN);
neilt6 2:bbfc18022ee5 48 writeData(0x00);
neilt6 2:bbfc18022ee5 49 writeData(0x7F);
neilt6 2:bbfc18022ee5 50 writeCommand(CMD_SETROW);
neilt6 2:bbfc18022ee5 51 writeData(0x00);
neilt6 2:bbfc18022ee5 52 writeData(0x7F);
neilt6 2:bbfc18022ee5 53 writeCommand(CMD_STARTLINE);
neilt6 2:bbfc18022ee5 54 writeData(0x0);
neilt6 2:bbfc18022ee5 55 writeCommand(CMD_DISPLAYOFFSET);
neilt6 2:bbfc18022ee5 56 writeData(0x0);
neilt6 2:bbfc18022ee5 57 writeCommand(CMD_SETGPIO);
neilt6 2:bbfc18022ee5 58 writeData(0x00);
neilt6 2:bbfc18022ee5 59 writeCommand(CMD_FUNCTIONSELECT);
neilt6 2:bbfc18022ee5 60 writeData(0x01);
neilt6 2:bbfc18022ee5 61 writeCommand(CMD_PRECHARGE);
neilt6 2:bbfc18022ee5 62 writeCommand(0x32);
neilt6 2:bbfc18022ee5 63 writeCommand(CMD_VCOMH);
neilt6 2:bbfc18022ee5 64 writeCommand(0x05);
neilt6 2:bbfc18022ee5 65 writeCommand(CMD_NORMALDISPLAY);
neilt6 2:bbfc18022ee5 66 writeCommand(CMD_CONTRASTABC);
neilt6 2:bbfc18022ee5 67 writeData(0xC8);
neilt6 2:bbfc18022ee5 68 writeData(0x80);
neilt6 2:bbfc18022ee5 69 writeData(0xC8);
neilt6 2:bbfc18022ee5 70 writeCommand(CMD_CONTRASTMASTER);
neilt6 2:bbfc18022ee5 71 writeData(0x0F);
neilt6 2:bbfc18022ee5 72 writeCommand(CMD_SETVSL );
neilt6 2:bbfc18022ee5 73 writeData(0xA0);
neilt6 2:bbfc18022ee5 74 writeData(0xB5);
neilt6 2:bbfc18022ee5 75 writeData(0x55);
neilt6 2:bbfc18022ee5 76 writeCommand(CMD_PRECHARGE2);
neilt6 2:bbfc18022ee5 77 writeData(0x01);
neilt6 2:bbfc18022ee5 78
neilt6 2:bbfc18022ee5 79 //Return success
neilt6 2:bbfc18022ee5 80 return true;
neilt6 2:bbfc18022ee5 81 }
neilt6 2:bbfc18022ee5 82
neilt6 2:bbfc18022ee5 83 void SSD1351_SPI::flush()
neilt6 2:bbfc18022ee5 84 {
neilt6 2:bbfc18022ee5 85 if (m_CacheIndex > 0) {
neilt6 2:bbfc18022ee5 86 //Set DC to data and select the display
neilt6 2:bbfc18022ee5 87 m_DC = 1;
neilt6 2:bbfc18022ee5 88 m_CS = 0;
neilt6 2:bbfc18022ee5 89
neilt6 2:bbfc18022ee5 90 //Write the entire cache at once
neilt6 2:bbfc18022ee5 91 for (int i = 0; i < m_CacheIndex; i++)
neilt6 2:bbfc18022ee5 92 m_SPI.write(m_Cache[i]);
neilt6 2:bbfc18022ee5 93
neilt6 2:bbfc18022ee5 94 //Deselect the display
neilt6 2:bbfc18022ee5 95 m_CS = 1;
neilt6 2:bbfc18022ee5 96
neilt6 2:bbfc18022ee5 97 //Reset the cache index
neilt6 2:bbfc18022ee5 98 m_CacheIndex = 0;
neilt6 2:bbfc18022ee5 99 }
neilt6 2:bbfc18022ee5 100 }
neilt6 2:bbfc18022ee5 101
neilt6 2:bbfc18022ee5 102 Display::State SSD1351_SPI::state()
neilt6 2:bbfc18022ee5 103 {
neilt6 2:bbfc18022ee5 104 //Return the base class's state
neilt6 2:bbfc18022ee5 105 return Display::state();
neilt6 2:bbfc18022ee5 106 }
neilt6 2:bbfc18022ee5 107
neilt6 2:bbfc18022ee5 108 void SSD1351_SPI::state(State s)
neilt6 2:bbfc18022ee5 109 {
neilt6 2:bbfc18022ee5 110 //Check what the requested state is
neilt6 2:bbfc18022ee5 111 if (s == Display::DISPLAY_ON) {
neilt6 2:bbfc18022ee5 112 //Turn the display on
neilt6 2:bbfc18022ee5 113 writeCommand(CMD_DISPLAYON);
neilt6 2:bbfc18022ee5 114 } else if (s == Display::DISPLAY_OFF) {
neilt6 2:bbfc18022ee5 115 //Turn the display off
neilt6 2:bbfc18022ee5 116 writeCommand(CMD_DISPLAYOFF);
neilt6 2:bbfc18022ee5 117 }
neilt6 2:bbfc18022ee5 118
neilt6 2:bbfc18022ee5 119 //Update the base class
neilt6 2:bbfc18022ee5 120 Display::state(s);
neilt6 2:bbfc18022ee5 121 }
neilt6 2:bbfc18022ee5 122
neilt6 2:bbfc18022ee5 123 void SSD1351_SPI::drawPixel(int x, int y, unsigned int c)
neilt6 2:bbfc18022ee5 124 {
neilt6 2:bbfc18022ee5 125 //Range check the pixel
neilt6 2:bbfc18022ee5 126 if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
neilt6 2:bbfc18022ee5 127 return;
neilt6 2:bbfc18022ee5 128
neilt6 2:bbfc18022ee5 129 //Only goto if the cursor is out of position
neilt6 2:bbfc18022ee5 130 if (x != m_CursX || y != m_CursY) {
neilt6 2:bbfc18022ee5 131 //First flush the cache
neilt6 2:bbfc18022ee5 132 flush();
neilt6 2:bbfc18022ee5 133
neilt6 2:bbfc18022ee5 134 //Set column start and end address (also moves pointer)
neilt6 2:bbfc18022ee5 135 writeCommand(CMD_SETCOLUMN);
neilt6 2:bbfc18022ee5 136 writeData(x);
neilt6 2:bbfc18022ee5 137 writeData(width() - 1);
neilt6 2:bbfc18022ee5 138
neilt6 2:bbfc18022ee5 139 //Set row start and end address (also moves pointer)
neilt6 2:bbfc18022ee5 140 writeCommand(CMD_SETROW);
neilt6 2:bbfc18022ee5 141 writeData(y);
neilt6 2:bbfc18022ee5 142 writeData(height() - 1);
neilt6 2:bbfc18022ee5 143
neilt6 2:bbfc18022ee5 144 writeCommand(CMD_WRITERAM);
neilt6 2:bbfc18022ee5 145
neilt6 2:bbfc18022ee5 146 //Update the cursor variables
neilt6 2:bbfc18022ee5 147 m_StartX = x;
neilt6 2:bbfc18022ee5 148 m_StartY = y;
neilt6 2:bbfc18022ee5 149 m_CursX = x;
neilt6 2:bbfc18022ee5 150 m_CursY = y;
neilt6 2:bbfc18022ee5 151 }
neilt6 2:bbfc18022ee5 152
neilt6 2:bbfc18022ee5 153 //Check if the cache is full
neilt6 2:bbfc18022ee5 154 if (m_CacheIndex > 1024 - 4) {
neilt6 2:bbfc18022ee5 155 //Flush the cache
neilt6 2:bbfc18022ee5 156 flush();
neilt6 2:bbfc18022ee5 157 }
neilt6 2:bbfc18022ee5 158
neilt6 2:bbfc18022ee5 159 //Add this pixel to the cache
neilt6 2:bbfc18022ee5 160 m_Cache[m_CacheIndex++] = c >> 18;
neilt6 2:bbfc18022ee5 161 m_Cache[m_CacheIndex++] = c >> 10;
neilt6 2:bbfc18022ee5 162 m_Cache[m_CacheIndex++] = c >> 2;
neilt6 2:bbfc18022ee5 163
neilt6 2:bbfc18022ee5 164 //Increment the cursor with wrapping
neilt6 2:bbfc18022ee5 165 if (++m_CursX > width() - 1) {
neilt6 2:bbfc18022ee5 166 m_CursX = m_StartX;
neilt6 2:bbfc18022ee5 167
neilt6 2:bbfc18022ee5 168 if (++m_CursY > height() - 1) {
neilt6 2:bbfc18022ee5 169 m_CursY = m_StartY;
neilt6 2:bbfc18022ee5 170 }
neilt6 2:bbfc18022ee5 171 }
neilt6 2:bbfc18022ee5 172 }
neilt6 2:bbfc18022ee5 173
neilt6 2:bbfc18022ee5 174 void SSD1351_SPI::writeCommand(char command)
neilt6 2:bbfc18022ee5 175 {
neilt6 2:bbfc18022ee5 176 //Set DC to command and select the display
neilt6 2:bbfc18022ee5 177 m_DC = 0;
neilt6 2:bbfc18022ee5 178 m_CS = 0;
neilt6 2:bbfc18022ee5 179
neilt6 2:bbfc18022ee5 180 //Write the command byte
neilt6 2:bbfc18022ee5 181 m_SPI.write(command);
neilt6 2:bbfc18022ee5 182
neilt6 2:bbfc18022ee5 183 //Deselect the display
neilt6 2:bbfc18022ee5 184 m_CS = 1;
neilt6 2:bbfc18022ee5 185 }
neilt6 2:bbfc18022ee5 186
neilt6 2:bbfc18022ee5 187 void SSD1351_SPI::writeData(char data)
neilt6 2:bbfc18022ee5 188 {
neilt6 2:bbfc18022ee5 189 //Set DC to data and select the display
neilt6 2:bbfc18022ee5 190 m_DC = 1;
neilt6 2:bbfc18022ee5 191 m_CS = 0;
neilt6 2:bbfc18022ee5 192
neilt6 2:bbfc18022ee5 193 //Write the data byte
neilt6 2:bbfc18022ee5 194 m_SPI.write(data);
neilt6 2:bbfc18022ee5 195
neilt6 2:bbfc18022ee5 196 //Deselect the display
neilt6 2:bbfc18022ee5 197 m_CS = 1;
neilt6 2:bbfc18022ee5 198 }