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.
Dependents: Bicycl_Computer_NUCLEO-F411RE Bicycl_Computer_NUCLEO-L476RG
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 00021 #include "LCD.h" 00022 00023 //#include "mbed_debug.h" 00024 00025 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } 00026 00027 00028 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) 00029 : 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) 00030 { 00031 if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD); 00032 useNOP=false; 00033 buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00034 buffer16 = (unsigned short*)buffer; 00035 draw_mode = NORMAL; 00036 set_orientation(1); 00037 foreground(White); 00038 background(Black); 00039 set_auto_up(true); 00040 tftID=0; 00041 // cls(); 00042 // locate(0,0); 00043 } 00044 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) 00045 : 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) 00046 { 00047 if(displayproto==SPI_8) 00048 { 00049 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC); 00050 useNOP=false; 00051 } 00052 else if(displayproto==SPI_16) 00053 { 00054 proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC); 00055 useNOP=true; 00056 } 00057 buffer = (unsigned char*) malloc (screensize_X*_LCDPAGES); 00058 buffer16 = (unsigned short*)buffer; 00059 draw_mode = NORMAL; 00060 // cls(); 00061 set_orientation(1); 00062 foreground(White); 00063 background(Black); 00064 set_auto_up(true); 00065 tftID=0; 00066 // locate(0,0); 00067 00068 } 00069 LCD::~LCD() 00070 { 00071 free(buffer); 00072 } 00073 00074 void LCD::wr_cmd8(unsigned char cmd) 00075 { 00076 if(useNOP) proto->wr_cmd16(0xE300|cmd); // E3 is NOP cmd for LCD 00077 else proto->wr_cmd8(cmd); 00078 } 00079 void LCD::wr_data8(unsigned char data) 00080 { 00081 proto->wr_data8(data); 00082 } 00083 void LCD::wr_cmd16(unsigned short cmd) 00084 { 00085 proto->wr_cmd16(cmd); 00086 } 00087 void LCD::wr_gram(unsigned short data, unsigned int count) 00088 { 00089 proto->wr_gram(data, count); 00090 } 00091 void LCD::wr_grambuf(unsigned short* data, unsigned int lenght) 00092 { 00093 proto->wr_grambuf(data, lenght); 00094 } 00095 void LCD::hw_reset() 00096 { 00097 proto->hw_reset(); 00098 } 00099 void LCD::BusEnable(bool enable) 00100 { 00101 proto->BusEnable(enable); 00102 } 00103 00104 00105 00106 // monochrome LCD driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays 00107 // for portrait views, XY swap will be done in sw in pixel() function 00108 void LCD::set_orientation(int o) 00109 { 00110 orientation = o; 00111 switch (o) { 00112 case (0):// portrait view -90° 00113 mirrorXY(Y); 00114 col_offset = 0; 00115 page_offset = _IC_PAGES-_LCDPAGES; 00116 set_width(screensize_Y); 00117 set_height(screensize_X); 00118 // portrait = true; 00119 break; 00120 case (1): // default, landscape view 0° 00121 mirrorXY(NONE); 00122 col_offset = 0; 00123 page_offset = 0; 00124 set_width(screensize_X); 00125 set_height(screensize_Y); 00126 // portrait = false; 00127 break; 00128 case (2):// portrait view +90° 00129 mirrorXY(X); 00130 col_offset = _IC_X_SEGS-screensize_X; // some displays have less pixels than IC ram 00131 page_offset = 0; 00132 set_width(screensize_Y); 00133 set_height(screensize_X); 00134 // portrait = true; 00135 break; 00136 case (3):// landscape view +180° 00137 mirrorXY(XY); 00138 col_offset = _IC_X_SEGS-screensize_X; 00139 page_offset = _IC_PAGES-_LCDPAGES; 00140 set_width(screensize_X); 00141 set_height(screensize_Y); 00142 // portrait = false; 00143 break; 00144 } 00145 } 00146 void LCD::mirrorXY(mirror_t mode) 00147 { 00148 switch (mode) 00149 { 00150 case(NONE): 00151 // wr_cmd8(0xA0); 00152 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 00153 break; 00154 case(X): 00155 // wr_cmd8(0xA1); 00156 wr_cmd16(0xA1C8); 00157 break; 00158 case(Y): 00159 // wr_cmd8(0xA0); 00160 wr_cmd16(0xA0C0); 00161 break; 00162 case(XY): 00163 // wr_cmd8(0xA1); 00164 wr_cmd16(0xA1C0); 00165 break; 00166 } 00167 } 00168 void LCD::invert(unsigned char o) 00169 { 00170 if(o == 0) wr_cmd8(0xA6); 00171 else wr_cmd8(0xA7); 00172 } 00173 00174 void LCD::set_contrast(int o) 00175 { 00176 contrast = o; 00177 // wr_cmd8(0x81); // set volume 00178 wr_cmd16(0x8100|(o&0x3F)); 00179 } 00180 00181 int LCD::get_contrast(void) 00182 { 00183 return(contrast); 00184 } 00185 void LCD::window(int x, int y, int w, int h) { 00186 // current pixel location 00187 cur_x = x; 00188 cur_y = y; 00189 // window settings 00190 win_x1 = x; 00191 win_x2 = x + w - 1; 00192 win_y1 = y; 00193 win_y2 = y + h - 1; 00194 } 00195 void LCD::window_pushpixel(unsigned short color) { 00196 pixel(cur_x, cur_y, color); 00197 cur_x++; 00198 if(cur_x > win_x2) { 00199 cur_x = win_x1; 00200 cur_y++; 00201 if(cur_y > win_y2) { 00202 cur_y = win_y1; 00203 } 00204 } 00205 } 00206 void LCD::window_pushpixel(unsigned short color, unsigned int count) { 00207 while(count) 00208 { 00209 pixel(cur_x, cur_y, color); 00210 cur_x++; 00211 if(cur_x > win_x2) 00212 { 00213 cur_x = win_x1; 00214 cur_y++; 00215 if(cur_y > win_y2) 00216 { 00217 cur_y = win_y1; 00218 } 00219 } 00220 count--; 00221 } 00222 } 00223 void LCD::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { 00224 while(lenght) 00225 { 00226 pixel(cur_x, cur_y, *color++); 00227 cur_x++; 00228 if(cur_x > win_x2) 00229 { 00230 cur_x = win_x1; 00231 cur_y++; 00232 if(cur_y > win_y2) 00233 { 00234 cur_y = win_y1; 00235 } 00236 } 00237 lenght--; 00238 } 00239 } 00240 void LCD::pixel(int x, int y, unsigned short color) 00241 { 00242 if(!(orientation&1)) SWAP(x,y); 00243 // first check parameter 00244 if((x >= screensize_X) || (y >= screensize_Y)) return; 00245 00246 // if(draw_mode == NORMAL) 00247 // { 00248 if(color) buffer[(x + ((y>>3)*screensize_X))^1] &= ~(1 << (y&7)); // erase pixel 00249 else buffer[(x + ((y>>3)*screensize_X))^1] |= (1 << (y&7)); //Black=0000, set pixel 00250 // } 00251 // else 00252 // { // XOR mode 00253 // if(color == 1) buffer[x + ((y>>3) * screensize_X)] ^= (1 << (y&7)); // xor pixel 00254 // } 00255 } 00256 void LCD::copy_to_lcd(void) 00257 { 00258 unsigned short i=0; 00259 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00260 for(int page=0; page<_LCDPAGES; page++) 00261 { 00262 // wr_cmd8(col_offset&0xF); // set column low nibble 00263 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00264 wr_cmd16(setcolcmd); 00265 wr_cmd8(0xB0|(page+page_offset)); // set page 00266 wr_grambuf(buffer16+i, screensize_X>>1); // send whole page pixels 00267 i+=screensize_X>>1; 00268 } 00269 } 00270 void LCD::cls(void) 00271 { 00272 unsigned short tmp = _background^0xFFFF; 00273 memset(buffer,tmp,screensize_X*_LCDPAGES); // clear display buffer 00274 unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4); 00275 for(int page=0; page<_LCDPAGES; page++) 00276 { 00277 // wr_cmd8((unsigned char)col_offset&0xF); // set column low nibble 00278 // wr_cmd8(0x10|(col_offset>>4)); // set column hi nibble 00279 wr_cmd16(setcolcmd); 00280 wr_cmd8(0xB0|(page+page_offset)); // set page 00281 wr_gram(tmp, screensize_X>>1); // send whole page pixels = background 00282 } 00283 } 00284 int LCD::sizeX() 00285 { 00286 return screensize_X; 00287 } 00288 int LCD::sizeY() 00289 { 00290 return screensize_Y; 00291 }
Generated on Wed Jul 13 2022 20:11:30 by
