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.

Fork of UniGraphic by GraphicsDisplay

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 // reset and init the lcd controller
00060 void SSD1306::init()
00061 {
00062     /* Start Initial Sequence ----------------------------------------------------*/
00063     
00064   //  wr_cmd8(0xE2);   //  sw reset
00065     wait_ms(15);
00066     
00067     wr_cmd8(SSD1306_DISPLAYOFF);    // no problem in SPI_16 for single byte cmds
00068     wr_cmd16((SSD1306_SETDISPLAYCLOCKDIV<<8)|0x80);   // wr_cmd16 for multibyte cmds issue in SPI16 mode
00069   //  wr_cmd8(0x80); // in SPI_16 it would become 0xE380 and will break things up
00070     wr_cmd16((SSD1306_SETMULTIPLEX<<8)|63);
00071  //   wr_cmd8(63);
00072     
00073     wr_cmd16((SSD1306_SETDISPLAYOFFSET<<8)|0x00);
00074  //   wr_cmd8(0x0);
00075     
00076     wr_cmd8(SSD1306_SETSTARTLINE | 0x0);            // line #0
00077 
00078     wr_cmd16((SSD1306_CHARGEPUMP<<8)|0x14);
00079   //  wr_cmd8(0x14);                         // 0x10 
00080 
00081     wr_cmd16((SSD1306_MEMORYMODE<<8)|0x00);
00082  //   wr_cmd8(0x00);                                  // 0x0 act like ks0108
00083 
00084     wr_cmd8(SSD1306_SEGREMAP ); //| 0x1);
00085 
00086     wr_cmd8(SSD1306_COMSCANDEC);
00087 
00088     wr_cmd16((SSD1306_SETCOMPINS<<8)|0x12);
00089   //  wr_cmd8(0x12);                           //        LCDSIZE_Y == 32 ? 0x02 : 0x12);        
00090 
00091     wr_cmd16((SSD1306_SETCONTRAST<<8)|0xCF);
00092  //   wr_cmd8(0xCF);                              //  _rawHeight == 32 ? 0x8F : ((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF) );
00093 
00094     wr_cmd16((SSD1306_SETPRECHARGE<<8)|0xF1);
00095  //   wr_cmd8(0xF1);                               // : 0x22);
00096 
00097     wr_cmd16((SSD1306_SETVCOMDETECT<<8)|0x40);
00098  //   wr_cmd8(0x40);
00099 
00100     wr_cmd8(SSD1306_DISPLAYALLON_RESUME);
00101 
00102     //wr_cmd8(SSD1306_NORMALDISPLAY);
00103     wr_cmd8(SSD1306_INVERTDISPLAY);
00104     
00105     wr_cmd8(SSD1306_DISPLAYON);
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 // functions that overrides the standard ones implemented in LCD.cpp
00110 ////////////////////////////////////////////////////////////////////
00111 
00112 void SSD1306::mirrorXY(mirror_t mode)
00113 {
00114     switch (mode)
00115     {
00116         case(NONE):
00117             wr_cmd16(0xA0C0); 
00118             break;
00119         case(X):
00120             wr_cmd16(0xA1C0);
00121             break;
00122         case(Y):
00123             wr_cmd16(0xA0C8);
00124             break;
00125         case(XY):
00126             wr_cmd16(0xA1C8);
00127             break;
00128     }
00129 }
00130 
00131 void SSD1306::set_contrast(int o)
00132 {
00133     contrast = o;
00134   
00135     wr_cmd16(0x8100|(o&0xFF));
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 // functions that overrides the standard ones implemented in LCD.cpp
00140 ////////////////////////////////////////////////////////////////////
00141 
00142 
00143 const uint8_t scroll_speed[8]={3,2,1,6,0,5,4,7};
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 // functions addon  to LCD.cpp
00147 ////////////////////////////////////////////////////////////////////
00148 void SSD1306::horizontal_scroll(int l_r,int s_page,int e_page,int speed){
00149     wr_cmd8(0x2E);                      // deactivate scroll before change
00150     if(l_r == 1){
00151         wr_cmd16(0x2700);               // horizontal scroll left
00152     }
00153     else {
00154         wr_cmd16(0x2600);
00155     }
00156     wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
00157     wr_cmd16((e_page & 0x07)<<8 );
00158     wr_cmd16(0xFF2F);
00159 }
00160 
00161 void SSD1306::horiz_vert_scroll(int l_r,int s_page,int e_page,int v_off,int speed){
00162     wr_cmd8(0x2E);                      // deactivate scroll before change
00163     if(l_r == 1){
00164             wr_cmd16(0x2A00);               // horizontal scroll left
00165         }
00166         else {
00167             wr_cmd16(0x2900);
00168         }
00169         wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
00170         wr_cmd16((e_page & 0x07)<<8 | (v_off & 0x3F) );
00171         wr_cmd8(0x2F);
00172 
00173 }
00174 
00175 void SSD1306::end_scroll(){
00176     wr_cmd8(0x2E);
00177 }