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.
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(proto_t displayproto, int Hz, int address, PinName sda, PinName scl, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char* name) 00099 : 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) 00100 { 00101 if(displayproto==I2C_){ 00102 proto = new I2C_bus(Hz,address,sda,scl); 00103 useNOP=false; 00104 } 00105 buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00106 buffer16 = (unsigned short*)buffer; 00107 draw_mode = NORMAL; 00108 // cls(); 00109 set_orientation(1); 00110 foreground(White); 00111 background(Black); 00112 set_auto_up(true); 00113 tftID=0; 00114 } 00115 00116 LCD::~LCD() 00117 { 00118 free(buffer); 00119 } 00120 00121 void LCD::wr_cmd8(unsigned char cmd) 00122 { 00123 if(useNOP) proto->wr_cmd16(0xE300|cmd); // E3 is NOP cmd for LCD 00124 else proto->wr_cmd8(cmd); 00125 } 00126 void LCD::wr_data8(unsigned char data) 00127 { 00128 proto->wr_data8(data); 00129 } 00130 void LCD::wr_cmd16(unsigned short cmd) 00131 { 00132 proto->wr_cmd16(cmd); 00133 } 00134 void LCD::wr_gram(unsigned short data, unsigned int count) 00135 { 00136 proto->wr_gram(data, count); 00137 } 00138 void LCD::wr_grambuf(unsigned short* data, unsigned int lenght) 00139 { 00140 proto->wr_grambuf(data, lenght); 00141 } 00142 void LCD::hw_reset() 00143 { 00144 proto->hw_reset(); 00145 } 00146 void LCD::BusEnable(bool enable) 00147 { 00148 proto->BusEnable(enable); 00149 } 00150 00151 00152 00153 // monochrome LCD driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays 00154 // for portrait views, XY swap will be done in sw in pixel() function 00155 void LCD::set_orientation(int o) 00156 { 00157 orientation = o; 00158 switch (o) { 00159 case (0):// portrait view -90° 00160 mirrorXY(Y); 00161 col_offset = 0; 00162 page_offset = _IC_PAGES-_LCDPAGES; 00163 set_width(screensize_Y); 00164 set_height(screensize_X); 00165 // portrait = true; 00166 break; 00167 case (1): // default, landscape view 0° 00168 mirrorXY(NONE); 00169 col_offset = 0; 00170 page_offset = 0; 00171 set_width(screensize_X); 00172 set_height(screensize_Y); 00173 // portrait = false; 00174 break; 00175 case (2):// portrait view +90° 00176 mirrorXY(X); 00177 col_offset = _IC_X_SEGS-screensize_X; // some displays have less pixels than IC ram 00178 page_offset = 0; 00179 set_width(screensize_Y); 00180 set_height(screensize_X); 00181 // portrait = true; 00182 break; 00183 case (3):// landscape view +180° 00184 mirrorXY(XY); 00185 col_offset = _IC_X_SEGS-screensize_X; 00186 page_offset = _IC_PAGES-_LCDPAGES; 00187 set_width(screensize_X); 00188 set_height(screensize_Y); 00189 // portrait = false; 00190 break; 00191 } 00192 } 00193 void LCD::mirrorXY(mirror_t mode) 00194 { 00195 switch (mode) 00196 { 00197 case(NONE): 00198 // wr_cmd8(0xA0); 00199 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 00200 break; 00201 case(X): 00202 // wr_cmd8(0xA1); 00203 wr_cmd16(0xA1C8); 00204 break; 00205 case(Y): 00206 // wr_cmd8(0xA0); 00207 wr_cmd16(0xA0C0); 00208 break; 00209 case(XY): 00210 // wr_cmd8(0xA1); 00211 wr_cmd16(0xA1C0); 00212 break; 00213 } 00214 } 00215 void LCD::invert(unsigned char o) 00216 { 00217 if(o == 0) wr_cmd8(0xA6); 00218 else wr_cmd8(0xA7); 00219 } 00220 00221 void LCD::set_contrast(int o) 00222 { 00223 contrast = o; 00224 // wr_cmd8(0x81); // set volume 00225 wr_cmd16(0x8100|(o&0x3F)); 00226 } 00227 00228 int LCD::get_contrast(void) 00229 { 00230 return(contrast); 00231 } 00232 void LCD::window(int x, int y, int w, int h) { 00233 // current pixel location 00234 cur_x = x; 00235 cur_y = y; 00236 // window settings 00237 win_x1 = x; 00238 win_x2 = x + w - 1; 00239 win_y1 = y; 00240 win_y2 = y + h - 1; 00241 } 00242 void LCD::window_pushpixel(unsigned short color) { 00243 pixel(cur_x, cur_y, color); 00244 cur_x++; 00245 if(cur_x > win_x2) { 00246 cur_x = win_x1; 00247 cur_y++; 00248 if(cur_y > win_y2) { 00249 cur_y = win_y1; 00250 } 00251 } 00252 } 00253 void LCD::window_pushpixel(unsigned short color, unsigned int count) { 00254 while(count) 00255 { 00256 pixel(cur_x, cur_y, color); 00257 cur_x++; 00258 if(cur_x > win_x2) 00259 { 00260 cur_x = win_x1; 00261 cur_y++; 00262 if(cur_y > win_y2) 00263 { 00264 cur_y = win_y1; 00265 } 00266 } 00267 count--; 00268 } 00269 } 00270 void LCD::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { 00271 while(lenght) 00272 { 00273 pixel(cur_x, cur_y, *color++); 00274 cur_x++; 00275 if(cur_x > win_x2) 00276 { 00277 cur_x = win_x1; 00278 cur_y++; 00279 if(cur_y > win_y2) 00280 { 00281 cur_y = win_y1; 00282 } 00283 } 00284 lenght--; 00285 } 00286 } 00287 void LCD::pixel(int x, int y, unsigned short color) 00288 { 00289 if(!(orientation&1)) SWAP(x,y); 00290 // first check parameter 00291 if((x >= screensize_X) || (y >= screensize_Y)) return; 00292 00293 if(color) buffer[(x + ((y>>3)*screensize_X))^1] &= ~(1 << (y&7)); // erase pixel 00294 else buffer[(x + ((y>>3)*screensize_X))^1] |= (1 << (y&7)); //Black=0000, set pixel 00295 } 00296 unsigned short LCD::pixelread(int x, int y) 00297 { 00298 if(!(orientation&1)) SWAP(x,y); 00299 // first check parameter 00300 if((x >= screensize_X) || (y >= screensize_Y)) return 0; 00301 00302 if((buffer[(x + ((y>>3)*screensize_X))^1] & (1 << (y&7)))==0) return 0xFFFF ; // pixel not set, White 00303 else return 0; // pixel set, Black 00304 } 00305 void LCD::copy_to_lcd(void) 00306 { 00307 unsigned short i=0; 00308 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00309 for(int page=0; page<_LCDPAGES; page++) 00310 { 00311 // wr_cmd8(col_offset&0xF); // set column low nibble 00312 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00313 wr_cmd16(setcolcmd); 00314 wr_cmd8(0xB0|(page+page_offset)); // set page 00315 wr_grambuf(buffer16+i, screensize_X>>1); // send whole page pixels 00316 i+=screensize_X>>1; 00317 } 00318 } 00319 void LCD::cls(void) 00320 { 00321 unsigned short tmp = _background^0xFFFF; 00322 memset(buffer,tmp,screensize_X*_LCDPAGES); // clear display buffer 00323 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00324 for(int page=0; page<_LCDPAGES; page++) 00325 { 00326 // wr_cmd8((unsigned char)col_offset&0xF); // set column low nibble 00327 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00328 wr_cmd16(setcolcmd); 00329 wr_cmd8(0xB0|(page+page_offset)); // set page 00330 wr_gram(tmp, screensize_X>>1); // send whole page pixels = background 00331 } 00332 } 00333 int LCD::sizeX() 00334 { 00335 return screensize_X; 00336 } 00337 int LCD::sizeY() 00338 { 00339 return screensize_Y; 00340 }
Generated on Fri Jul 15 2022 13:58:04 by
