Basically i glued Peter Drescher and Simon Ford libs in a GraphicsDisplay class, then derived TFT or LCD class (which inherits Protocols class), then the most derived ones (Inits), which are per-display and are the only part needed to be adapted to diff hw.

Dependents:   testUniGraphic_150217 maze_TFT_MMA8451Q TFT_test_frdm-kl25z TFT_test_NUCLEO-F411RE ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SSD1306.cpp Source File

SSD1306.cpp

00001 /* mbed UniGraphic library - Device specific class
00002  * Copyright (c) 2015 Peter Drescher
00003  * Released under the MIT License: http://mbed.org/license/mit
00004  */
00005   
00006 #include "Protocols.h "
00007 #include "SSD1306.h"
00008 
00009 //////////////////////////////////////////////////////////////////////////////////
00010 // display settings ///////////////////////////////////////////////////////
00011 /////////////////////////////////////////////////////////////////////////
00012 
00013 
00014 #define IC_X_SEGS    128 // UC1608 SEG has range 0-239 (239-0 if MX=1), check your datasheet, important for the orientation
00015 #define IC_Y_COMS    64  // UC1608 COM has range 0-127 (127-0 if MY=1), check your datasheet, important for the orientation
00016 
00017 #define SSD1306_SETCONTRAST         0x81
00018 #define SSD1306_DISPLAYALLON_RESUME 0xA4
00019 #define SSD1306_DISPLAYALLON        0xA5
00020 #define SSD1306_NORMALDISPLAY       0xA6
00021 #define SSD1306_INVERTDISPLAY       0xA7
00022 #define SSD1306_DISPLAYOFF          0xAE
00023 #define SSD1306_DISPLAYON           0xAF
00024 #define SSD1306_SETDISPLAYOFFSET    0xD3
00025 #define SSD1306_SETCOMPINS          0xDA
00026 #define SSD1306_SETVCOMDETECT       0xDB
00027 #define SSD1306_SETDISPLAYCLOCKDIV  0xD5
00028 #define SSD1306_SETPRECHARGE        0xD9
00029 #define SSD1306_SETMULTIPLEX        0xA8
00030 #define SSD1306_SETLOWCOLUMN        0x00
00031 #define SSD1306_SETHIGHCOLUMN       0x10
00032 #define SSD1306_SETSTARTLINE        0x40
00033 #define SSD1306_MEMORYMODE          0x20
00034 #define SSD1306_COMSCANINC          0xC0
00035 #define SSD1306_COMSCANDEC          0xC8
00036 #define SSD1306_SEGREMAP            0xA0
00037 #define SSD1306_CHARGEPUMP          0x8D
00038 
00039 SSD1306::SSD1306(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
00040     : LCD(displayproto, port, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
00041 {
00042     hw_reset();
00043     BusEnable(true);
00044     init();
00045     cls();
00046     set_orientation(1);
00047     locate(0,0);
00048 }
00049 SSD1306::SSD1306(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name, unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
00050     : LCD(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
00051 {
00052     hw_reset();
00053     BusEnable(true);
00054     init();
00055     cls();
00056     set_orientation(1);
00057     locate(0,0);
00058 }
00059 
00060 SSD1306::SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const char* name , unsigned int LCDSIZE_X, unsigned  int LCDSIZE_Y)
00061     : LCD(displayproto, Hz, address, sda, scl, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
00062 {
00063     init();
00064     cls();
00065     set_orientation(1);
00066     locate(0,0);
00067 }
00068 
00069 
00070 // reset and init the lcd controller
00071 void SSD1306::init()
00072 {
00073     /* Start Initial Sequence ----------------------------------------------------*/
00074     
00075   //  wr_cmd8(0xE2);   //  sw reset
00076     thread_sleep_for(15);
00077     
00078     wr_cmd8(SSD1306_DISPLAYOFF);    // no problem in SPI_16 for single byte cmds
00079     wr_cmd16((SSD1306_SETDISPLAYCLOCKDIV<<8)|0x80);   // wr_cmd16 for multibyte cmds issue in SPI16 mode
00080   //  wr_cmd8(0x80); // in SPI_16 it would become 0xE380 and will break things up
00081     wr_cmd16((SSD1306_SETMULTIPLEX<<8)|63);
00082  //   wr_cmd8(63);
00083     
00084     wr_cmd16((SSD1306_SETDISPLAYOFFSET<<8)|0x00);
00085  //   wr_cmd8(0x0);
00086     
00087     wr_cmd8(SSD1306_SETSTARTLINE | 0x0);            // line #0
00088 
00089     wr_cmd16((SSD1306_CHARGEPUMP<<8)|0x14);
00090   //  wr_cmd8(0x14);                         // 0x10 
00091 
00092     wr_cmd16((SSD1306_MEMORYMODE<<8)|0x00);
00093  //   wr_cmd8(0x00);                                  // 0x0 act like ks0108
00094 
00095     wr_cmd8(SSD1306_SEGREMAP ); //| 0x1);
00096 
00097     wr_cmd8(SSD1306_COMSCANDEC);
00098 
00099     wr_cmd16((SSD1306_SETCOMPINS<<8)|0x12);
00100   //  wr_cmd8(0x12);                           //        LCDSIZE_Y == 32 ? 0x02 : 0x12);        
00101 
00102     wr_cmd16((SSD1306_SETCONTRAST<<8)|0xCF);
00103  //   wr_cmd8(0xCF);                              //  _rawHeight == 32 ? 0x8F : ((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF) );
00104 
00105     wr_cmd16((SSD1306_SETPRECHARGE<<8)|0xF1);
00106  //   wr_cmd8(0xF1);                               // : 0x22);
00107 
00108     wr_cmd16((SSD1306_SETVCOMDETECT<<8)|0x40);
00109  //   wr_cmd8(0x40);
00110 
00111     wr_cmd8(SSD1306_DISPLAYALLON_RESUME);
00112 
00113     //wr_cmd8(SSD1306_NORMALDISPLAY);
00114     wr_cmd8(SSD1306_INVERTDISPLAY);
00115     
00116     wr_cmd8(SSD1306_DISPLAYON);
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 // functions that overrides the standard ones implemented in LCD.cpp
00121 ////////////////////////////////////////////////////////////////////
00122 
00123 void SSD1306::mirrorXY(mirror_t mode)
00124 {
00125     switch (mode)
00126     {
00127         case(NONE):
00128             wr_cmd16(0xA0C0); 
00129             break;
00130         case(X):
00131             wr_cmd16(0xA1C0);
00132             break;
00133         case(Y):
00134             wr_cmd16(0xA0C8);
00135             break;
00136         case(XY):
00137             wr_cmd16(0xA1C8);
00138             break;
00139     }
00140 }
00141 
00142 void SSD1306::set_contrast(int o)
00143 {
00144     contrast = o;
00145   
00146     wr_cmd16(0x8100|(o&0xFF));
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 // functions that overrides the standard ones implemented in LCD.cpp
00151 ////////////////////////////////////////////////////////////////////
00152 
00153 
00154 const uint8_t scroll_speed[8]={3,2,1,6,0,5,4,7};
00155 
00156 ////////////////////////////////////////////////////////////////////
00157 // functions addon  to LCD.cpp
00158 ////////////////////////////////////////////////////////////////////
00159 void SSD1306::horizontal_scroll(int l_r,int s_page,int e_page,int speed){
00160     wr_cmd8(0x2E);                      // deactivate scroll before change
00161     if(l_r == 1){
00162         wr_cmd16(0x2700);               // horizontal scroll left
00163     }
00164     else {
00165         wr_cmd16(0x2600);
00166     }
00167     wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
00168     wr_cmd16((e_page & 0x07)<<8 );
00169     wr_cmd16(0xFF2F);
00170 }
00171 
00172 void SSD1306::horiz_vert_scroll(int l_r,int s_page,int e_page,int v_off,int speed){
00173     wr_cmd8(0x2E);                      // deactivate scroll before change
00174     if(l_r == 1){
00175             wr_cmd16(0x2A00);               // horizontal scroll left
00176         }
00177         else {
00178             wr_cmd16(0x2900);
00179         }
00180         wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
00181         wr_cmd16((e_page & 0x07)<<8 | (v_off & 0x3F) );
00182         wr_cmd8(0x2F);
00183 
00184 }
00185 
00186 void SSD1306::end_scroll(){
00187     wr_cmd8(0x2E);
00188 }