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