My controller identifies as an ILI9328, but only works if initialised as an ILI9325. This fork includes a fix to force 9325 initialization when a 9328 is detected.

Dependents:   TouchScreenCalibrate TouchScreenGUIDemo

Fork of UniGraphic by GraphicsDisplay

Committer:
Duncan McIntyre
Date:
Sun Jun 21 15:23:02 2020 +0100
Revision:
34:091b954c3205
Parent:
17:1dafb896c6f5
Updated to include latest changes from upstream
Added a class to provide an interface for my MINI-STM32-V3.0 board.
This class uses direct GPIO access to achieve decent update speeds.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 12:9c8f3076347c 1 /* mbed UniGraphic library - Device specific class
dreschpe 12:9c8f3076347c 2 * Copyright (c) 2015 Peter Drescher
dreschpe 12:9c8f3076347c 3 * Released under the MIT License: http://mbed.org/license/mit
dreschpe 12:9c8f3076347c 4 */
dreschpe 12:9c8f3076347c 5
dreschpe 12:9c8f3076347c 6 #include "Protocols.h"
dreschpe 12:9c8f3076347c 7 #include "SSD1306.h"
dreschpe 12:9c8f3076347c 8
dreschpe 12:9c8f3076347c 9 //////////////////////////////////////////////////////////////////////////////////
dreschpe 12:9c8f3076347c 10 // display settings ///////////////////////////////////////////////////////
dreschpe 12:9c8f3076347c 11 /////////////////////////////////////////////////////////////////////////
dreschpe 12:9c8f3076347c 12
dreschpe 12:9c8f3076347c 13
dreschpe 12:9c8f3076347c 14 #define IC_X_SEGS 128 // UC1608 SEG has range 0-239 (239-0 if MX=1), check your datasheet, important for the orientation
dreschpe 12:9c8f3076347c 15 #define IC_Y_COMS 64 // UC1608 COM has range 0-127 (127-0 if MY=1), check your datasheet, important for the orientation
dreschpe 12:9c8f3076347c 16
dreschpe 12:9c8f3076347c 17 #define SSD1306_SETCONTRAST 0x81
dreschpe 12:9c8f3076347c 18 #define SSD1306_DISPLAYALLON_RESUME 0xA4
dreschpe 12:9c8f3076347c 19 #define SSD1306_DISPLAYALLON 0xA5
dreschpe 12:9c8f3076347c 20 #define SSD1306_NORMALDISPLAY 0xA6
dreschpe 12:9c8f3076347c 21 #define SSD1306_INVERTDISPLAY 0xA7
dreschpe 12:9c8f3076347c 22 #define SSD1306_DISPLAYOFF 0xAE
dreschpe 12:9c8f3076347c 23 #define SSD1306_DISPLAYON 0xAF
dreschpe 12:9c8f3076347c 24 #define SSD1306_SETDISPLAYOFFSET 0xD3
dreschpe 12:9c8f3076347c 25 #define SSD1306_SETCOMPINS 0xDA
dreschpe 12:9c8f3076347c 26 #define SSD1306_SETVCOMDETECT 0xDB
dreschpe 12:9c8f3076347c 27 #define SSD1306_SETDISPLAYCLOCKDIV 0xD5
dreschpe 12:9c8f3076347c 28 #define SSD1306_SETPRECHARGE 0xD9
dreschpe 12:9c8f3076347c 29 #define SSD1306_SETMULTIPLEX 0xA8
dreschpe 12:9c8f3076347c 30 #define SSD1306_SETLOWCOLUMN 0x00
dreschpe 12:9c8f3076347c 31 #define SSD1306_SETHIGHCOLUMN 0x10
dreschpe 12:9c8f3076347c 32 #define SSD1306_SETSTARTLINE 0x40
dreschpe 12:9c8f3076347c 33 #define SSD1306_MEMORYMODE 0x20
dreschpe 12:9c8f3076347c 34 #define SSD1306_COMSCANINC 0xC0
dreschpe 12:9c8f3076347c 35 #define SSD1306_COMSCANDEC 0xC8
dreschpe 12:9c8f3076347c 36 #define SSD1306_SEGREMAP 0xA0
dreschpe 12:9c8f3076347c 37 #define SSD1306_CHARGEPUMP 0x8D
dreschpe 12:9c8f3076347c 38
dreschpe 12:9c8f3076347c 39 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)
dreschpe 12:9c8f3076347c 40 : LCD(displayproto, port, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
dreschpe 12:9c8f3076347c 41 {
dreschpe 12:9c8f3076347c 42 hw_reset();
dreschpe 12:9c8f3076347c 43 BusEnable(true);
dreschpe 12:9c8f3076347c 44 init();
dreschpe 12:9c8f3076347c 45 cls();
dreschpe 12:9c8f3076347c 46 set_orientation(1);
dreschpe 12:9c8f3076347c 47 locate(0,0);
dreschpe 12:9c8f3076347c 48 }
dreschpe 12:9c8f3076347c 49 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)
dreschpe 12:9c8f3076347c 50 : LCD(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
dreschpe 12:9c8f3076347c 51 {
dreschpe 12:9c8f3076347c 52 hw_reset();
dreschpe 12:9c8f3076347c 53 BusEnable(true);
dreschpe 12:9c8f3076347c 54 init();
dreschpe 12:9c8f3076347c 55 cls();
dreschpe 12:9c8f3076347c 56 set_orientation(1);
dreschpe 12:9c8f3076347c 57 locate(0,0);
dreschpe 12:9c8f3076347c 58 }
Duncan McIntyre 34:091b954c3205 59
Duncan McIntyre 34:091b954c3205 60 SSD1306::SSD1306(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const char* name , unsigned int LCDSIZE_X, unsigned int LCDSIZE_Y)
Duncan McIntyre 34:091b954c3205 61 : LCD(displayproto, Hz, address, sda, scl, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
Duncan McIntyre 34:091b954c3205 62 {
Duncan McIntyre 34:091b954c3205 63 init();
Duncan McIntyre 34:091b954c3205 64 cls();
Duncan McIntyre 34:091b954c3205 65 set_orientation(1);
Duncan McIntyre 34:091b954c3205 66 locate(0,0);
Duncan McIntyre 34:091b954c3205 67 }
Duncan McIntyre 34:091b954c3205 68
Duncan McIntyre 34:091b954c3205 69
dreschpe 12:9c8f3076347c 70 // reset and init the lcd controller
dreschpe 12:9c8f3076347c 71 void SSD1306::init()
dreschpe 12:9c8f3076347c 72 {
dreschpe 12:9c8f3076347c 73 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 12:9c8f3076347c 74
dreschpe 12:9c8f3076347c 75 // wr_cmd8(0xE2); // sw reset
Duncan McIntyre 34:091b954c3205 76 ThisThread::sleep_for(15);
dreschpe 12:9c8f3076347c 77
Geremia 13:d8c593fa7705 78 wr_cmd8(SSD1306_DISPLAYOFF); // no problem in SPI_16 for single byte cmds
Geremia 13:d8c593fa7705 79 wr_cmd16((SSD1306_SETDISPLAYCLOCKDIV<<8)|0x80); // wr_cmd16 for multibyte cmds issue in SPI16 mode
Geremia 13:d8c593fa7705 80 // wr_cmd8(0x80); // in SPI_16 it would become 0xE380 and will break things up
Geremia 13:d8c593fa7705 81 wr_cmd16((SSD1306_SETMULTIPLEX<<8)|63);
Geremia 13:d8c593fa7705 82 // wr_cmd8(63);
dreschpe 12:9c8f3076347c 83
Geremia 13:d8c593fa7705 84 wr_cmd16((SSD1306_SETDISPLAYOFFSET<<8)|0x00);
Geremia 13:d8c593fa7705 85 // wr_cmd8(0x0);
dreschpe 12:9c8f3076347c 86
dreschpe 12:9c8f3076347c 87 wr_cmd8(SSD1306_SETSTARTLINE | 0x0); // line #0
dreschpe 12:9c8f3076347c 88
Geremia 13:d8c593fa7705 89 wr_cmd16((SSD1306_CHARGEPUMP<<8)|0x14);
Geremia 13:d8c593fa7705 90 // wr_cmd8(0x14); // 0x10
dreschpe 12:9c8f3076347c 91
Geremia 13:d8c593fa7705 92 wr_cmd16((SSD1306_MEMORYMODE<<8)|0x00);
Geremia 13:d8c593fa7705 93 // wr_cmd8(0x00); // 0x0 act like ks0108
dreschpe 12:9c8f3076347c 94
dreschpe 12:9c8f3076347c 95 wr_cmd8(SSD1306_SEGREMAP ); //| 0x1);
dreschpe 12:9c8f3076347c 96
dreschpe 12:9c8f3076347c 97 wr_cmd8(SSD1306_COMSCANDEC);
dreschpe 12:9c8f3076347c 98
Geremia 13:d8c593fa7705 99 wr_cmd16((SSD1306_SETCOMPINS<<8)|0x12);
Geremia 13:d8c593fa7705 100 // wr_cmd8(0x12); // LCDSIZE_Y == 32 ? 0x02 : 0x12);
dreschpe 12:9c8f3076347c 101
Geremia 13:d8c593fa7705 102 wr_cmd16((SSD1306_SETCONTRAST<<8)|0xCF);
Geremia 13:d8c593fa7705 103 // wr_cmd8(0xCF); // _rawHeight == 32 ? 0x8F : ((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF) );
dreschpe 12:9c8f3076347c 104
Geremia 13:d8c593fa7705 105 wr_cmd16((SSD1306_SETPRECHARGE<<8)|0xF1);
Geremia 13:d8c593fa7705 106 // wr_cmd8(0xF1); // : 0x22);
dreschpe 12:9c8f3076347c 107
Geremia 13:d8c593fa7705 108 wr_cmd16((SSD1306_SETVCOMDETECT<<8)|0x40);
Geremia 13:d8c593fa7705 109 // wr_cmd8(0x40);
dreschpe 12:9c8f3076347c 110
dreschpe 12:9c8f3076347c 111 wr_cmd8(SSD1306_DISPLAYALLON_RESUME);
dreschpe 12:9c8f3076347c 112
dreschpe 12:9c8f3076347c 113 //wr_cmd8(SSD1306_NORMALDISPLAY);
dreschpe 12:9c8f3076347c 114 wr_cmd8(SSD1306_INVERTDISPLAY);
dreschpe 12:9c8f3076347c 115
dreschpe 12:9c8f3076347c 116 wr_cmd8(SSD1306_DISPLAYON);
dreschpe 12:9c8f3076347c 117 }
dreschpe 12:9c8f3076347c 118
dreschpe 12:9c8f3076347c 119 ////////////////////////////////////////////////////////////////////
dreschpe 12:9c8f3076347c 120 // functions that overrides the standard ones implemented in LCD.cpp
dreschpe 12:9c8f3076347c 121 ////////////////////////////////////////////////////////////////////
dreschpe 12:9c8f3076347c 122
dreschpe 12:9c8f3076347c 123 void SSD1306::mirrorXY(mirror_t mode)
dreschpe 12:9c8f3076347c 124 {
dreschpe 12:9c8f3076347c 125 switch (mode)
dreschpe 12:9c8f3076347c 126 {
dreschpe 12:9c8f3076347c 127 case(NONE):
dreschpe 12:9c8f3076347c 128 wr_cmd16(0xA0C0);
dreschpe 12:9c8f3076347c 129 break;
dreschpe 12:9c8f3076347c 130 case(X):
dreschpe 12:9c8f3076347c 131 wr_cmd16(0xA1C0);
dreschpe 12:9c8f3076347c 132 break;
dreschpe 12:9c8f3076347c 133 case(Y):
dreschpe 12:9c8f3076347c 134 wr_cmd16(0xA0C8);
dreschpe 12:9c8f3076347c 135 break;
dreschpe 12:9c8f3076347c 136 case(XY):
dreschpe 12:9c8f3076347c 137 wr_cmd16(0xA1C8);
dreschpe 12:9c8f3076347c 138 break;
dreschpe 12:9c8f3076347c 139 }
dreschpe 12:9c8f3076347c 140 }
dreschpe 12:9c8f3076347c 141
dreschpe 12:9c8f3076347c 142 void SSD1306::set_contrast(int o)
dreschpe 12:9c8f3076347c 143 {
dreschpe 12:9c8f3076347c 144 contrast = o;
dreschpe 12:9c8f3076347c 145
Geremia 15:b9483ba842c8 146 wr_cmd16(0x8100|(o&0xFF));
dreschpe 12:9c8f3076347c 147 }
dreschpe 17:1dafb896c6f5 148
dreschpe 17:1dafb896c6f5 149 ////////////////////////////////////////////////////////////////////
dreschpe 17:1dafb896c6f5 150 // functions that overrides the standard ones implemented in LCD.cpp
dreschpe 17:1dafb896c6f5 151 ////////////////////////////////////////////////////////////////////
dreschpe 17:1dafb896c6f5 152
dreschpe 17:1dafb896c6f5 153
dreschpe 17:1dafb896c6f5 154 const uint8_t scroll_speed[8]={3,2,1,6,0,5,4,7};
dreschpe 17:1dafb896c6f5 155
dreschpe 17:1dafb896c6f5 156 ////////////////////////////////////////////////////////////////////
dreschpe 17:1dafb896c6f5 157 // functions addon to LCD.cpp
dreschpe 17:1dafb896c6f5 158 ////////////////////////////////////////////////////////////////////
dreschpe 17:1dafb896c6f5 159 void SSD1306::horizontal_scroll(int l_r,int s_page,int e_page,int speed){
dreschpe 17:1dafb896c6f5 160 wr_cmd8(0x2E); // deactivate scroll before change
dreschpe 17:1dafb896c6f5 161 if(l_r == 1){
dreschpe 17:1dafb896c6f5 162 wr_cmd16(0x2700); // horizontal scroll left
dreschpe 17:1dafb896c6f5 163 }
dreschpe 17:1dafb896c6f5 164 else {
dreschpe 17:1dafb896c6f5 165 wr_cmd16(0x2600);
dreschpe 17:1dafb896c6f5 166 }
dreschpe 17:1dafb896c6f5 167 wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
dreschpe 17:1dafb896c6f5 168 wr_cmd16((e_page & 0x07)<<8 );
dreschpe 17:1dafb896c6f5 169 wr_cmd16(0xFF2F);
dreschpe 17:1dafb896c6f5 170 }
dreschpe 17:1dafb896c6f5 171
dreschpe 17:1dafb896c6f5 172 void SSD1306::horiz_vert_scroll(int l_r,int s_page,int e_page,int v_off,int speed){
dreschpe 17:1dafb896c6f5 173 wr_cmd8(0x2E); // deactivate scroll before change
dreschpe 17:1dafb896c6f5 174 if(l_r == 1){
dreschpe 17:1dafb896c6f5 175 wr_cmd16(0x2A00); // horizontal scroll left
dreschpe 17:1dafb896c6f5 176 }
dreschpe 17:1dafb896c6f5 177 else {
dreschpe 17:1dafb896c6f5 178 wr_cmd16(0x2900);
dreschpe 17:1dafb896c6f5 179 }
dreschpe 17:1dafb896c6f5 180 wr_cmd16((s_page & 0x07)<<8 | (scroll_speed[speed & 0x07]));
dreschpe 17:1dafb896c6f5 181 wr_cmd16((e_page & 0x07)<<8 | (v_off & 0x3F) );
dreschpe 17:1dafb896c6f5 182 wr_cmd8(0x2F);
dreschpe 17:1dafb896c6f5 183
dreschpe 17:1dafb896c6f5 184 }
dreschpe 17:1dafb896c6f5 185
dreschpe 17:1dafb896c6f5 186 void SSD1306::end_scroll(){
dreschpe 17:1dafb896c6f5 187 wr_cmd8(0x2E);
dreschpe 17:1dafb896c6f5 188 }