Jon Buckman / NeatGUIs
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SEPS525_SPI.cpp Source File

SEPS525_SPI.cpp

00001 /* NeatGUI Library
00002  * Copyright (c) 2013 Neil Thiessen
00003  * Copyright (c) 2017 Jon Buckman
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017  
00018 #include "SEPS525_SPI.h"
00019 
00020 SEPS525_SPI::SEPS525_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc, PinName res) : Display(160, 128),  m_SPI(mosi, miso, sclk), m_CS(cs), m_DC(dc), m_RES(res)
00021 {
00022     //Deselect the display
00023     m_CS = 1;
00024  
00025     //Set the SPI format to 8 bit data, high steady state clock, second edge capture
00026     m_SPI.format(8, 3);
00027  
00028     //Set the SPI frequency to 20MHz
00029     m_SPI.frequency(10000000);
00030 }
00031 
00032 bool SEPS525_SPI::open()
00033 {
00034     //Initialize interface and reset display driver chip
00035     m_CS = 1;
00036     wait(0.01);
00037     m_RES = 0;
00038     wait(0.001);
00039     m_RES = 1;
00040     wait(0.01);
00041 
00042     //Init sequence for 160x128 OLED module
00043     writeCommand(CMD_DISP_ON_OFF);
00044     writeData(0x00);    //Display off
00045 
00046     writeCommand(CMD_OSC_CTL);
00047     writeData(0x01); //Export1 internal clock and OSC operates with external resistor
00048 
00049     writeCommand(CMD_REDUCE_CURRENT);
00050     writeData(0x00);
00051 
00052     writeCommand(CMD_CLOCK_DIV);
00053     writeData(0x30); //Clock div ratio 1: freq setting 90Hz
00054 
00055     
00056     writeCommand(CMD_IREF);
00057     writeData(0x00); //Iref controlled by external resistor
00058 
00059     writeCommand(CMD_PRECHARGE_TIME_R);
00060     writeData(0x01);
00061     writeCommand(CMD_PRECHARGE_TIME_G);
00062     writeData(0x01);
00063     writeCommand(CMD_PRECHARGE_TIME_B);
00064     writeData(0x01);
00065 
00066     writeCommand(CMD_PRECHARGE_CURRENT_R);
00067     writeData(0x0A);
00068     writeCommand(CMD_PRECHARGE_CURRENT_G);
00069     writeData(0x0A);
00070     writeCommand(CMD_PRECHARGE_CURRENT_B);
00071     writeData(0x0A);
00072 
00073     writeCommand(CMD_DRIVING_CURRENT_R);
00074     writeData(0x52); //R = 82uA
00075     writeCommand(CMD_DRIVING_CURRENT_G);
00076     writeData(0x38); //R = 56uA
00077     writeCommand(CMD_DRIVING_CURRENT_B);
00078     writeData(0x3A); //R = 58uA
00079 
00080     writeCommand(CMD_DISPLAY_MODE_SET);
00081     writeData(0x00); //RGB, column=0-159, column data display=Normal display
00082 
00083     
00084     writeCommand(CMD_RGB_IF);
00085     writeData(0x01); //External interface mode=MPU
00086 
00087     //6 bits triple transfer, 262K support, Horizontal address counter is increased,
00088     //vertical address counter is increased. The data is continuously written
00089     //horizontally
00090     writeCommand(CMD_MEMORY_WRITE_MODE);
00091     writeData(0x76);
00092 
00093     writeCommand(CMD_MX1_ADDR);  //Column start
00094     writeData(0x00);
00095     writeCommand(CMD_MX2_ADDR);  //Column end
00096     writeData(width()-1);
00097     writeCommand(CMD_MY1_ADDR);  //row start
00098     writeData(0x00);
00099     writeCommand(CMD_MY2_ADDR);  //row end
00100     writeData(height()-1);
00101 
00102     writeCommand(CMD_MEMORY_ACCESS_POINTER_X);  //X
00103     writeData(0x00);
00104     writeCommand(CMD_MEMORY_ACCESS_POINTER_Y);  //Y
00105     writeData(0x00);
00106 
00107     writeCommand(CMD_DUTY);
00108     writeData(0x7F);
00109 
00110     writeCommand(CMD_DSL);
00111     writeData(0x00);
00112 
00113     writeCommand(CMD_D1_DDRAM_FAC);  //X
00114     writeData(0x00);
00115     writeCommand(CMD_D1_DDRAM_FAR);  //Y
00116     writeData(0x00);
00117 
00118     writeCommand(CMD_SCR1_FX1);  //Screen saver columns start
00119     writeData(0x00);
00120     writeCommand(CMD_SCR1_FX2);  //Screen saver columns end
00121     writeData(width()-1);
00122     writeCommand(CMD_SCR1_FY1);  //screen saver row start
00123     writeData(0x00);
00124     writeCommand(CMD_SCR1_FY2);  //Screen saver row end
00125     writeData(height()-1);
00126 
00127     writeCommand(CMD_DISP_ON_OFF);
00128     writeData(0x01); //Display on
00129 
00130     //Return success
00131     return true;
00132 }
00133 
00134 void SEPS525_SPI::flush()
00135 {
00136 }
00137 
00138 Display::State SEPS525_SPI::state()
00139 {
00140     //Return the base class's state
00141     return Display::state();
00142 }
00143 
00144 void SEPS525_SPI::state(State s)
00145 {
00146     //Check what the requested state is
00147     if (s == Display::DISPLAY_ON) {
00148         //Turn the display on
00149         writeCommand(CMD_DISP_ON_OFF);
00150         writeData(0x01); //Display on
00151     } else if (s == Display::DISPLAY_OFF) {
00152         //Turn the display off
00153         writeCommand(CMD_DISP_ON_OFF);
00154         writeData(0x00);    //Display off
00155     }
00156  
00157     //Update the base class
00158     Display::state(s);
00159 }
00160 
00161 void SEPS525_SPI::masterCurrent(int current)
00162 {
00163     if(current < 8)
00164     {
00165         writeCommand(CMD_REDUCE_CURRENT);
00166         writeData(0x04);
00167     }
00168     else
00169     {
00170         writeCommand(CMD_REDUCE_CURRENT);
00171         writeData(0x00);
00172     }
00173 }
00174 
00175 void SEPS525_SPI::drawPixel(int x, int y, unsigned int c)
00176 {
00177     //Range check the pixel
00178     if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
00179         return;
00180  
00181     writeCommand(CMD_MEMORY_ACCESS_POINTER_X);  // memory accesspointer x
00182     writeData(x);
00183     writeCommand(CMD_MEMORY_ACCESS_POINTER_Y);  // memory accesspointer y
00184     writeData(y);
00185 
00186     writeCommand(CMD_DDRAM_DATA_ACCESS_PORT);
00187     writeData((c & 0xFF0000) >> 16);
00188     writeData((c & 0x00FF00) >> 8);
00189     writeData(c & 0xFF);
00190 }
00191 
00192 void SEPS525_SPI::writeCommand(char command)
00193 {
00194     //Set DC to command and select the display
00195     m_DC = 0;
00196     m_CS = 0;
00197  
00198     //Write the command byte
00199     m_SPI.write(command);
00200  
00201     //Deselect the display
00202     m_CS = 1;
00203 }
00204 
00205 void SEPS525_SPI::writeData(char data)
00206 {
00207     //Set DC to data and select the display
00208     m_DC = 1;
00209     m_CS = 0;
00210  
00211     //Write the data byte
00212     m_SPI.write(data);
00213  
00214     //Deselect the display
00215     m_CS = 1;
00216 }