UniGraphic-Fork for ST7920-LCD-controller and SH1106. Tested with 128x64 LCD with SPI and 128x64-OLED with IIC
Dependents: UniGraphic-St7920-Test AfficheurUTILECO
Fork of UniGraphic by
LCD.cpp
00001 /* mbed UniGraphic library - universal LCD driver class 00002 * Copyright (c) 2015 Giuliano Dianda 00003 * Released under the MIT License: http://mbed.org/license/mit 00004 * 00005 * Derived work of: 00006 * 00007 * mbed library for the mbed Lab Board 128*32 pixel LCD 00008 * use C12832 controller 00009 * Copyright (c) 2012 Peter Drescher - DC2PD 00010 * Released under the MIT License: http://mbed.org/license/mit 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00013 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00014 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00015 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00016 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00018 * THE SOFTWARE. 00019 */ 00020 #include "platform.h" 00021 #include "LCD.h" 00022 00023 #if DEVICE_PORTINOUT 00024 #include "PAR8.h" 00025 #include "PAR16.h" 00026 #endif 00027 00028 //#include "mbed_debug.h" 00029 00030 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } 00031 00032 #if DEVICE_PORTINOUT 00033 LCD::LCD(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name) 00034 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) 00035 { 00036 if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD); 00037 useNOP=false; 00038 //buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00039 //posix_memalign(void **memptr, size_t alignment, size_t size); 00040 posix_memalign((void **)&buffer, 16,screensize_X*_LCDPAGES); 00041 buffer16 = (unsigned short*)buffer; 00042 draw_mode = NORMAL; 00043 set_orientation(1); 00044 foreground(White); 00045 background(Black); 00046 set_auto_up(true); 00047 tftID=0; 00048 // cls(); 00049 // locate(0,0); 00050 } 00051 #endif 00052 00053 LCD::LCD(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name) 00054 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) 00055 { 00056 if(displayproto==BUS_8) 00057 { 00058 PinName pins[16]; 00059 for(int i=0; i<16; i++) pins[i]=NC; 00060 for(int i=0; i<8; i++) pins[i]=buspins[i]; 00061 proto = new BUS8(pins, CS, reset, DC, WR, RD); 00062 } 00063 useNOP=false; 00064 //buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00065 //posix_memalign(void **memptr, size_t alignment, size_t size); 00066 posix_memalign((void **)&buffer, 16,screensize_X*_LCDPAGES); 00067 buffer16 = (unsigned short*)buffer; 00068 draw_mode = NORMAL; 00069 set_orientation(1); 00070 foreground(White); 00071 background(Black); 00072 set_auto_up(true); 00073 tftID=0; 00074 // cls(); 00075 // locate(0,0); 00076 } 00077 LCD::LCD(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name) 00078 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) 00079 { 00080 if(displayproto==SPI_8) 00081 { 00082 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC); 00083 useNOP=false; 00084 } 00085 else if(displayproto==SPI_16) 00086 { 00087 proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC); 00088 useNOP=true; 00089 } 00090 //buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00091 //posix_memalign(void **memptr, size_t alignment, size_t size); 00092 posix_memalign((void **)&buffer, 16,screensize_X*_LCDPAGES); 00093 buffer16 = (unsigned short*)buffer; 00094 draw_mode = NORMAL; 00095 // cls(); 00096 set_orientation(1); 00097 foreground(White); 00098 background(Black); 00099 set_auto_up(true); 00100 tftID=0; 00101 // locate(0,0); 00102 } 00103 LCD::LCD(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, PinName reset, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name) 00104 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y), _LCDPAGES(lcdsize_y>>3), _IC_X_SEGS(ic_x_segs), _IC_Y_COMS(ic_y_coms), _IC_PAGES(ic_y_coms>>3) 00105 { 00106 if(displayproto==I2C_){ 00107 proto = new I2C_bus(Hz,address,sda,scl, reset); 00108 useNOP=false; 00109 } 00110 //buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00111 //posix_memalign(void **memptr, size_t alignment, size_t size); 00112 posix_memalign((void **)&buffer, 16,screensize_X*_LCDPAGES); 00113 buffer16 = (unsigned short*)buffer; 00114 00115 draw_mode = NORMAL; 00116 // cls(); 00117 set_orientation(1); 00118 foreground(White); 00119 background(Black); 00120 set_auto_up(true); 00121 tftID=0; 00122 } 00123 00124 LCD::~LCD() 00125 { 00126 free(buffer); 00127 } 00128 00129 void LCD::wr_cmd8(unsigned char cmd) 00130 { 00131 if(useNOP) proto->wr_cmd16(0xE300|cmd); // E3 is NOP cmd for LCD 00132 else proto->wr_cmd8(cmd); 00133 } 00134 void LCD::wr_data8(unsigned char data) 00135 { 00136 proto->wr_data8(data); 00137 } 00138 void LCD::wr_cmd16(unsigned short cmd) 00139 { 00140 proto->wr_cmd16(cmd); 00141 } 00142 void LCD::wr_gram(unsigned short data, unsigned int count) 00143 { 00144 proto->wr_gram(data, count); 00145 } 00146 void LCD::wr_grambuf(unsigned short* data, unsigned int lenght) 00147 { 00148 proto->wr_grambuf(data, lenght); 00149 } 00150 void LCD::hw_reset() 00151 { 00152 proto->hw_reset(); 00153 } 00154 void LCD::BusEnable(bool enable) 00155 { 00156 proto->BusEnable(enable); 00157 } 00158 00159 00160 00161 // monochrome LCD driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays 00162 // for portrait views, XY swap will be done in sw in pixel() function 00163 void LCD::set_orientation(int o) 00164 { 00165 orientation = o; 00166 switch (o) { 00167 case (0):// portrait view -90° 00168 mirrorXY(Y); 00169 col_offset = 0; 00170 page_offset = _IC_PAGES-_LCDPAGES; 00171 set_width(screensize_Y); 00172 set_height(screensize_X); 00173 // portrait = true; 00174 break; 00175 case (1): // default, landscape view 0° 00176 mirrorXY(NONE); 00177 col_offset = 0; 00178 page_offset = 0; 00179 set_width(screensize_X); 00180 set_height(screensize_Y); 00181 // portrait = false; 00182 break; 00183 case (2):// portrait view +90° 00184 mirrorXY(X); 00185 col_offset = _IC_X_SEGS-screensize_X; // some displays have less pixels than IC ram 00186 page_offset = 0; 00187 set_width(screensize_Y); 00188 set_height(screensize_X); 00189 // portrait = true; 00190 break; 00191 case (3):// landscape view +180° 00192 mirrorXY(XY); 00193 col_offset = _IC_X_SEGS-screensize_X; 00194 page_offset = _IC_PAGES-_LCDPAGES; 00195 set_width(screensize_X); 00196 set_height(screensize_Y); 00197 // portrait = false; 00198 break; 00199 } 00200 } 00201 void LCD::mirrorXY(mirror_t mode) 00202 { 00203 switch (mode) 00204 { 00205 case(NONE): 00206 // wr_cmd8(0xA0); 00207 wr_cmd16(0xA0C8); // this is in real Y mirror command, but seems most displays have COMs wired inverted, so assume this is the default no-y-mirror 00208 break; 00209 case(X): 00210 // wr_cmd8(0xA1); 00211 wr_cmd16(0xA1C8); 00212 break; 00213 case(Y): 00214 // wr_cmd8(0xA0); 00215 wr_cmd16(0xA0C0); 00216 break; 00217 case(XY): 00218 // wr_cmd8(0xA1); 00219 wr_cmd16(0xA1C0); 00220 break; 00221 } 00222 } 00223 void LCD::invert(unsigned char o) 00224 { 00225 if(o == 0) wr_cmd8(0xA6); 00226 else wr_cmd8(0xA7); 00227 } 00228 00229 void LCD::set_contrast(int o) 00230 { 00231 contrast = o; 00232 // wr_cmd8(0x81); // set volume 00233 wr_cmd16(0x8100|(o&0x3F)); 00234 } 00235 00236 int LCD::get_contrast(void) 00237 { 00238 return(contrast); 00239 } 00240 void LCD::window(int x, int y, int w, int h) { 00241 // current pixel location 00242 cur_x = x; 00243 cur_y = y; 00244 // window settings 00245 win_x1 = x; 00246 win_x2 = x + w - 1; 00247 win_y1 = y; 00248 win_y2 = y + h - 1; 00249 } 00250 void LCD::window_pushpixel(unsigned short color) { 00251 pixel(cur_x, cur_y, color); 00252 cur_x++; 00253 if(cur_x > win_x2) { 00254 cur_x = win_x1; 00255 cur_y++; 00256 if(cur_y > win_y2) { 00257 cur_y = win_y1; 00258 } 00259 } 00260 } 00261 void LCD::window_pushpixel(unsigned short color, unsigned int count) { 00262 while(count) 00263 { 00264 pixel(cur_x, cur_y, color); 00265 cur_x++; 00266 if(cur_x > win_x2) 00267 { 00268 cur_x = win_x1; 00269 cur_y++; 00270 if(cur_y > win_y2) 00271 { 00272 cur_y = win_y1; 00273 } 00274 } 00275 count--; 00276 } 00277 } 00278 void LCD::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { 00279 while(lenght) 00280 { 00281 pixel(cur_x, cur_y, *color++); 00282 cur_x++; 00283 if(cur_x > win_x2) 00284 { 00285 cur_x = win_x1; 00286 cur_y++; 00287 if(cur_y > win_y2) 00288 { 00289 cur_y = win_y1; 00290 } 00291 } 00292 lenght--; 00293 } 00294 } 00295 00296 void LCD::pixel(int x, int y, unsigned short color) 00297 { 00298 /* 00299 if(!(orientation&1)) SWAP(x,y); 00300 // first check parameter 00301 if((x >= screensize_X) || (y >= screensize_Y)) return; 00302 00303 00304 if (color) {buffer[(x>>3)+(y*_IC_X_SEGS>>4)]&= ~(1 << (7-(x&7)));} 00305 else {buffer[(x>>3)+(y*_IC_X_SEGS>>4)]|= (1 << (7-(x&7)));} 00306 00307 //buffer[0]=0xFF; 00308 //buffer[16]=0xAA; 00309 //buffer[1023]=0xFF; 00310 */ 00311 } 00312 00313 unsigned short LCD::pixelread(int x, int y) 00314 { 00315 /* 00316 if(!(orientation&1)) SWAP(x,y); 00317 // first check parameter 00318 if((x >= screensize_X) || (y >= screensize_Y)) return 0; 00319 00320 00321 if((buffer[(x>>3)+(y*_IC_X_SEGS>>4)] & (1 << (7-(x&7))))==0) return 0xFFFF ; // pixel not set, White 00322 else return 0; // pixel set, Black 00323 */ 00324 return 0; 00325 } 00326 void LCD::copy_to_lcd(void) 00327 { 00328 /* 00329 unsigned short i=0; 00330 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00331 for(int page=0; page<_LCDPAGES; page++) 00332 { 00333 // wr_cmd8(col_offset&0xF); // set column low nibble 00334 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00335 wr_cmd16(setcolcmd); 00336 wr_cmd8(0xB0|(page+page_offset)); // set page 00337 wr_grambuf(buffer16+i, screensize_X>>1); // send whole page pixels 00338 i+=screensize_X>>1; 00339 } 00340 */ 00341 } 00342 void LCD::cls(void) 00343 { 00344 /* 00345 unsigned short tmp = _background^0xFFFF; 00346 memset(buffer,tmp,screensize_X*_LCDPAGES); // clear display buffer 00347 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00348 for(int page=0; page<_LCDPAGES; page++) 00349 { 00350 // wr_cmd8((unsigned char)col_offset&0xF); // set column low nibble 00351 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00352 wr_cmd16(setcolcmd); 00353 wr_cmd8(0xB0|(page+page_offset)); // set page 00354 wr_gram(tmp, screensize_X>>1); // send whole page pixels = background 00355 } 00356 */ 00357 } 00358 int LCD::sizeX() 00359 { 00360 return screensize_X; 00361 } 00362 int LCD::sizeY() 00363 { 00364 return screensize_Y; 00365 }
Generated on Tue Jul 12 2022 18:00:35 by 1.7.2