Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of UniGraphicCyrillic 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 buffer16 = (unsigned short*)buffer; 00040 draw_mode = NORMAL; 00041 set_orientation(1); 00042 foreground(White); 00043 background(Black); 00044 set_auto_up(true); 00045 tftID=0; 00046 // cls(); 00047 // locate(0,0); 00048 } 00049 #endif 00050 00051 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) 00052 : 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) 00053 { 00054 if(displayproto==BUS_8) 00055 { 00056 PinName pins[16]; 00057 for(int i=0; i<16; i++) pins[i]=NC; 00058 for(int i=0; i<8; i++) pins[i]=buspins[i]; 00059 proto = new BUS8(pins, CS, reset, DC, WR, RD); 00060 } 00061 useNOP=false; 00062 buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00063 buffer16 = (unsigned short*)buffer; 00064 draw_mode = NORMAL; 00065 set_orientation(1); 00066 foreground(White); 00067 background(Black); 00068 set_auto_up(true); 00069 tftID=0; 00070 // cls(); 00071 // locate(0,0); 00072 } 00073 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) 00074 : 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) 00075 { 00076 if(displayproto==SPI_8) 00077 { 00078 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC); 00079 useNOP=false; 00080 } 00081 else if(displayproto==SPI_16) 00082 { 00083 proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC); 00084 useNOP=true; 00085 } 00086 buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00087 buffer16 = (unsigned short*)buffer; 00088 draw_mode = NORMAL; 00089 // cls(); 00090 set_orientation(1); 00091 foreground(White); 00092 background(Black); 00093 set_auto_up(true); 00094 tftID=0; 00095 // locate(0,0); 00096 00097 } 00098 LCD::~LCD() 00099 { 00100 free(buffer); 00101 } 00102 00103 void LCD::wr_cmd8(unsigned char cmd) 00104 { 00105 if(useNOP) proto->wr_cmd16(0xE300|cmd); // E3 is NOP cmd for LCD 00106 else proto->wr_cmd8(cmd); 00107 } 00108 void LCD::wr_data8(unsigned char data) 00109 { 00110 proto->wr_data8(data); 00111 } 00112 void LCD::wr_cmd16(unsigned short cmd) 00113 { 00114 proto->wr_cmd16(cmd); 00115 } 00116 void LCD::wr_gram(unsigned short data, unsigned int count) 00117 { 00118 proto->wr_gram(data, count); 00119 } 00120 void LCD::wr_grambuf(unsigned short* data, unsigned int lenght) 00121 { 00122 proto->wr_grambuf(data, lenght); 00123 } 00124 void LCD::hw_reset() 00125 { 00126 proto->hw_reset(); 00127 } 00128 void LCD::BusEnable(bool enable) 00129 { 00130 proto->BusEnable(enable); 00131 } 00132 00133 00134 00135 // monochrome LCD driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays 00136 // for portrait views, XY swap will be done in sw in pixel() function 00137 void LCD::set_orientation(int o) 00138 { 00139 orientation = o; 00140 switch (o) { 00141 case (0):// portrait view -90° 00142 mirrorXY(Y); 00143 col_offset = 0; 00144 page_offset = _IC_PAGES-_LCDPAGES; 00145 set_width(screensize_Y); 00146 set_height(screensize_X); 00147 // portrait = true; 00148 break; 00149 case (1): // default, landscape view 0° 00150 mirrorXY(NONE); 00151 col_offset = 0; 00152 page_offset = 0; 00153 set_width(screensize_X); 00154 set_height(screensize_Y); 00155 // portrait = false; 00156 break; 00157 case (2):// portrait view +90° 00158 mirrorXY(X); 00159 col_offset = _IC_X_SEGS-screensize_X; // some displays have less pixels than IC ram 00160 page_offset = 0; 00161 set_width(screensize_Y); 00162 set_height(screensize_X); 00163 // portrait = true; 00164 break; 00165 case (3):// landscape view +180° 00166 mirrorXY(XY); 00167 col_offset = _IC_X_SEGS-screensize_X; 00168 page_offset = _IC_PAGES-_LCDPAGES; 00169 set_width(screensize_X); 00170 set_height(screensize_Y); 00171 // portrait = false; 00172 break; 00173 } 00174 } 00175 void LCD::mirrorXY(mirror_t mode) 00176 { 00177 switch (mode) 00178 { 00179 case(NONE): 00180 // wr_cmd8(0xA0); 00181 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 00182 break; 00183 case(X): 00184 // wr_cmd8(0xA1); 00185 wr_cmd16(0xA1C8); 00186 break; 00187 case(Y): 00188 // wr_cmd8(0xA0); 00189 wr_cmd16(0xA0C0); 00190 break; 00191 case(XY): 00192 // wr_cmd8(0xA1); 00193 wr_cmd16(0xA1C0); 00194 break; 00195 } 00196 } 00197 void LCD::invert(unsigned char o) 00198 { 00199 if(o == 0) wr_cmd8(0xA6); 00200 else wr_cmd8(0xA7); 00201 } 00202 00203 void LCD::set_contrast(int o) 00204 { 00205 contrast = o; 00206 // wr_cmd8(0x81); // set volume 00207 wr_cmd16(0x8100|(o&0x3F)); 00208 } 00209 00210 int LCD::get_contrast(void) 00211 { 00212 return(contrast); 00213 } 00214 void LCD::window(int x, int y, int w, int h) { 00215 // current pixel location 00216 cur_x = x; 00217 cur_y = y; 00218 // window settings 00219 win_x1 = x; 00220 win_x2 = x + w - 1; 00221 win_y1 = y; 00222 win_y2 = y + h - 1; 00223 } 00224 void LCD::window_pushpixel(unsigned short color) { 00225 pixel(cur_x, cur_y, color); 00226 cur_x++; 00227 if(cur_x > win_x2) { 00228 cur_x = win_x1; 00229 cur_y++; 00230 if(cur_y > win_y2) { 00231 cur_y = win_y1; 00232 } 00233 } 00234 } 00235 void LCD::window_pushpixel(unsigned short color, unsigned int count) { 00236 while(count) 00237 { 00238 pixel(cur_x, cur_y, color); 00239 cur_x++; 00240 if(cur_x > win_x2) 00241 { 00242 cur_x = win_x1; 00243 cur_y++; 00244 if(cur_y > win_y2) 00245 { 00246 cur_y = win_y1; 00247 } 00248 } 00249 count--; 00250 } 00251 } 00252 void LCD::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { 00253 while(lenght) 00254 { 00255 pixel(cur_x, cur_y, *color++); 00256 cur_x++; 00257 if(cur_x > win_x2) 00258 { 00259 cur_x = win_x1; 00260 cur_y++; 00261 if(cur_y > win_y2) 00262 { 00263 cur_y = win_y1; 00264 } 00265 } 00266 lenght--; 00267 } 00268 } 00269 void LCD::pixel(int x, int y, unsigned short color) 00270 { 00271 if(!(orientation&1)) SWAP(x,y); 00272 // first check parameter 00273 if((x >= screensize_X) || (y >= screensize_Y)) return; 00274 00275 if(color) buffer[(x + ((y>>3)*screensize_X))^1] &= ~(1 << (y&7)); // erase pixel 00276 else buffer[(x + ((y>>3)*screensize_X))^1] |= (1 << (y&7)); //Black=0000, set pixel 00277 } 00278 unsigned short LCD::pixelread(int x, int y) 00279 { 00280 if(!(orientation&1)) SWAP(x,y); 00281 // first check parameter 00282 if((x >= screensize_X) || (y >= screensize_Y)) return 0; 00283 00284 if((buffer[(x + ((y>>3)*screensize_X))^1] & (1 << (y&7)))==0) return 0xFFFF ; // pixel not set, White 00285 else return 0; // pixel set, Black 00286 } 00287 void LCD::copy_to_lcd(void) 00288 { 00289 unsigned short i=0; 00290 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00291 for(int page=0; page<_LCDPAGES; page++) 00292 { 00293 // wr_cmd8(col_offset&0xF); // set column low nibble 00294 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00295 wr_cmd16(setcolcmd); 00296 wr_cmd8(0xB0|(page+page_offset)); // set page 00297 wr_grambuf(buffer16+i, screensize_X>>1); // send whole page pixels 00298 i+=screensize_X>>1; 00299 } 00300 } 00301 void LCD::cls(void) 00302 { 00303 unsigned short tmp = _background^0xFFFF; 00304 memset(buffer,tmp,screensize_X*_LCDPAGES); // clear display buffer 00305 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00306 for(int page=0; page<_LCDPAGES; page++) 00307 { 00308 // wr_cmd8((unsigned char)col_offset&0xF); // set column low nibble 00309 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00310 wr_cmd16(setcolcmd); 00311 wr_cmd8(0xB0|(page+page_offset)); // set page 00312 wr_gram(tmp, screensize_X>>1); // send whole page pixels = background 00313 } 00314 } 00315 int LCD::sizeX() 00316 { 00317 return screensize_X; 00318 } 00319 int LCD::sizeY() 00320 { 00321 return screensize_Y; 00322 }
Generated on Tue Jul 12 2022 20:38:04 by
1.7.2
