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.
TFT932x.cpp
00001 /* mbed UniGraphic library - custom TFT driver class, ILI932x specific 00002 * Copyright (c) 2015 Giuliano Dianda 00003 * Released under the MIT License: http://mbed.org/license/mit 00004 */ 00005 00006 #include "platform.h" 00007 #include "TFT932x.h" 00008 00009 #if DEVICE_PORTINOUT 00010 #include "PAR8.h" 00011 #include "PAR16.h" 00012 #endif 00013 00014 //#include "mbed_debug.h" 00015 00016 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } 00017 00018 #if DEVICE_PORTINOUT 00019 TFT932x::TFT932x(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name) 00020 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00021 { 00022 if(displayproto==PAR_8) 00023 { 00024 proto = new PAR8(port, CS, reset, DC, WR, RD); 00025 dummycycles=1; 00026 } 00027 else if(displayproto==PAR_16) 00028 { 00029 proto = new PAR16(port, CS, reset, DC, WR, RD); 00030 dummycycles=0; 00031 } 00032 // set_orientation(0); 00033 foreground(White); 00034 background(Black); 00035 set_auto_up(false); //we don't have framebuffer 00036 usefastwindow=false; 00037 fastwindowready=false; 00038 is18bit=false; 00039 isBGR=false; 00040 flipped=0; 00041 // cls(); 00042 // locate(0,0); 00043 } 00044 #endif 00045 00046 TFT932x::TFT932x(proto_t displayproto, PinName* buspins, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name) 00047 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00048 { 00049 if(displayproto==BUS_8) 00050 { 00051 PinName pins[16]; 00052 for(int i=0; i<16; i++) pins[i]=NC; 00053 for(int i=0; i<8; i++) pins[i]=buspins[i]; 00054 proto = new BUS8(pins, CS, reset, DC, WR, RD); 00055 dummycycles=1; 00056 } 00057 else if(displayproto==BUS_16) 00058 { 00059 proto = new BUS16(buspins, CS, reset, DC, WR, RD); 00060 dummycycles=0; 00061 } 00062 // set_orientation(0); 00063 foreground(White); 00064 background(Black); 00065 set_auto_up(false); //we don't have framebuffer 00066 usefastwindow=false; 00067 fastwindowready=false; 00068 is18bit=false; 00069 isBGR=false; 00070 flipped=0; 00071 // cls(); 00072 // locate(0,0); 00073 } 00074 TFT932x::TFT932x(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, const int lcdsize_x, const int lcdsize_y, const char *name) 00075 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00076 { 00077 if(displayproto==SPI_8) 00078 { 00079 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset); 00080 dummycycles=4; 00081 } 00082 else if(displayproto==SPI_16) 00083 { 00084 proto = new SPI16(Hz, mosi, miso, sclk, CS, reset); 00085 dummycycles=2; 00086 } 00087 // set_orientation(0); 00088 foreground(White); 00089 background(Black); 00090 set_auto_up(false); 00091 usefastwindow=false; 00092 fastwindowready=false; 00093 is18bit=false; 00094 isBGR=false; 00095 flipped=0; 00096 // locate(0,0); 00097 } 00098 // dummy read needed before read gram 00099 // read gram protocol function does 1 dymmy read as for MIPI standard, but ILI932x needs more and protocol specific number of cycles 00100 // for example in spi mode, 5 dummy byte read needed, so for SPI16 2x16bit clocks done here and the 5th dummy will be handled by read gram function 00101 void TFT932x::dummyread() 00102 { 00103 for(unsigned int i=0; i<dummycycles; i++) proto->dummyread(); 00104 } 00105 void TFT932x::reg_select(unsigned char reg, bool forread) 00106 { 00107 proto->reg_select(reg, forread); 00108 } 00109 void TFT932x::reg_write(unsigned char reg, unsigned short data) 00110 { 00111 proto->reg_write(reg, data); 00112 } 00113 unsigned short TFT932x::reg_read(unsigned char reg) 00114 { 00115 return proto->reg_read(reg); 00116 } 00117 void TFT932x::wr_gram(unsigned short data) 00118 { 00119 proto->wr_gram(data); 00120 } 00121 void TFT932x::wr_gram(unsigned short data, unsigned int count) 00122 { 00123 proto->wr_gram(data, count); 00124 } 00125 void TFT932x::wr_grambuf(unsigned short* data, unsigned int lenght) 00126 { 00127 proto->wr_grambuf(data, lenght); 00128 } 00129 unsigned short TFT932x::rd_gram() 00130 { 00131 return proto->rd_gram(is18bit); // protocol will handle 18to16 bit conversion 00132 00133 } 00134 //for TFT, just send data, position counters are in hw 00135 void TFT932x::window_pushpixel(unsigned short color) 00136 { 00137 proto->wr_gram(color); 00138 } 00139 void TFT932x::window_pushpixel(unsigned short color, unsigned int count) 00140 { 00141 proto->wr_gram(color, count); 00142 } 00143 void TFT932x::window_pushpixelbuf(unsigned short* color, unsigned int lenght) 00144 { 00145 proto->wr_grambuf(color, lenght); 00146 } 00147 void TFT932x::hw_reset() 00148 { 00149 proto->hw_reset(); 00150 BusEnable(true); 00151 } 00152 void TFT932x::BusEnable(bool enable) 00153 { 00154 proto->BusEnable(enable); 00155 } 00156 // ILI932x can't rotate in hw (swap raw<->columns) for landscape views, 00157 // but can change the way address counter is auto incremented/decremented 00158 void TFT932x::set_orientation(int o) 00159 { 00160 // if(orientation == o) return; 00161 orientation = o; 00162 switch (orientation) 00163 // BGR bit set for all modes, seems most TFT are like that, in case override set_orientation() in init 00164 // ORG bit set for all modes 00165 { 00166 case 0:// default, portrait view 0° 00167 reg_write(0x0001,((flipped&FLIP_X)==0) ? 0x0100:0x0000); // S720toS1 or S1toS720 00168 reg_write(0x0060,((flipped&FLIP_Y)==0) ? 0xA700:0x2700); // G320toG1 or G1toG320 00169 reg_write(0x03, 0x10B0); 00170 set_width(screensize_X); 00171 set_height(screensize_Y); 00172 break; 00173 case 1:// landscape view +90° 00174 reg_write(0x0001,((flipped&FLIP_X)==0) ? 0x0000:0x0100); // S1toS720 or S720toS1 00175 reg_write(0x0060,((flipped&FLIP_Y)==0) ? 0xA700:0x2700); // G320toG1 or G1toG320 00176 reg_write(0x03, 0x10B8); // AM=1 increase addr ctr first vertically then horizontally 00177 set_width(screensize_Y); 00178 set_height(screensize_X); 00179 break; 00180 case 2:// portrait view +180° 00181 reg_write(0x0001,((flipped&FLIP_X)==0) ? 0x0000:0x0100); // S1toS720 or S720toS1 00182 reg_write(0x0060,((flipped&FLIP_Y)==0) ? 0x2700:0xA700); // G1toG320 or G320toG1 00183 reg_write(0x03, 0x10B0); 00184 set_width(screensize_X); 00185 set_height(screensize_Y); 00186 break; 00187 case 3:// landscape view -90° 00188 reg_write(0x0001,((flipped&FLIP_X)==0) ? 0x0100:0x0000); // S720toS1 or S1toS720 00189 reg_write(0x0060,((flipped&FLIP_Y)==0) ? 0x2700:0xA700); // G1toG320 or G320toG1 00190 reg_write(0x03, 0x10B8); // AM=1 increase addr ctr first vertically then horizontally 00191 set_width(screensize_Y); 00192 set_height(screensize_X); 00193 break; 00194 } 00195 } 00196 void TFT932x::invert(unsigned char o) 00197 { 00198 unsigned short oldreg = reg_read(0x61); 00199 if(o == 0) reg_write(0x61, oldreg|1); // seems most TFT have REV bit enabled for normal display 00200 else reg_write(0x61, oldreg&0xFFFE); 00201 } 00202 void TFT932x::FastWindow(bool enable) 00203 { 00204 usefastwindow=enable; 00205 } 00206 // TFT have both column and raw autoincrement inside a window, with internal counters 00207 void TFT932x::window(int x, int y, int w, int h) 00208 { 00209 if(orientation==1 || orientation==3) 00210 { 00211 SWAP(x,y); 00212 SWAP(w,h); 00213 } 00214 fastwindowready=false; // end raw/column going to be set to lower value than bottom-right corner 00215 reg_write(0x50, x);//start column 00216 reg_write(0x51, x+w-1);//end column 00217 reg_write(0x52, y);//start page 00218 reg_write(0x53, y+h-1);//end page 00219 00220 reg_write(0x20, 0); // since ORG bit is set, address is windows relative, so should be set always to 0000 00221 reg_write(0x21, 0); 00222 00223 reg_select(0x22, false); //write mem, just write gram next 00224 } 00225 void TFT932x::window4read(int x, int y, int w, int h) 00226 { 00227 if(orientation==1 || orientation==3) 00228 { 00229 SWAP(x,y); 00230 SWAP(w,h); 00231 } 00232 fastwindowready=false; // end raw/column going to be set to lower value than bottom-right corner 00233 reg_write(0x50, x);//start column 00234 reg_write(0x51, x+w-1);//end column 00235 reg_write(0x52, y);//start page 00236 reg_write(0x53, y+h-1);//end page 00237 00238 reg_write(0x20, 0); // since ORG bit is set, address is windows relative, so should be set always to 0000 00239 reg_write(0x21, 0); 00240 00241 reg_select(0x22, true); //read mem, just read gram next 00242 dummyread(); 00243 } 00244 void TFT932x::pixel(int x, int y, unsigned short color) 00245 { 00246 if(usefastwindow) 00247 { 00248 if(fastwindowready) //setting only start column/page does speedup, but needs end raw/column previously set to bottom-right corner 00249 { 00250 if(orientation==1 || orientation==3) SWAP(x,y); 00251 reg_write(0x50, x);//start column only 00252 reg_write(0x52, y);//start page only 00253 reg_write(0x20, 0); // since ORG bit is set, address is window relative, so should be set always to 0000 00254 reg_write(0x21, 0); 00255 reg_select(0x22, false); //write mem, just write gram next 00256 } 00257 else 00258 { 00259 window(x,y,width()-x,height()-y); // set also end raw/column to bottom-right corner 00260 fastwindowready=true; 00261 } 00262 } 00263 else window(x,y,1,1); 00264 wr_gram(color); 00265 } 00266 unsigned short TFT932x::pixelread(int x, int y) 00267 { 00268 /* if(usefastwindow) // for ILI9325 fastwindows for reading works only in PAR16 00269 { 00270 if(fastwindowready) //setting only start column/page does speedup, but needs end raw/column previously set to bottom-right corner 00271 { 00272 if(orientation==1 || orientation==3) SWAP(x,y); 00273 reg_write(0x50, x);//start column only 00274 reg_write(0x52, y);//start page only 00275 reg_write(0x20, 0); // since ORG bit is set, address is window relative, so should be set always to 0000 00276 reg_write(0x21, 0); 00277 reg_select(0x22, true); //read mem, just read gram next 00278 } 00279 else 00280 { 00281 window4read(x,y,width()-x,height()-y); // set also end raw/column to bottom-right corner 00282 fastwindowready=true; 00283 } 00284 } 00285 else*/ 00286 window4read(x,y,1,1); 00287 00288 unsigned short color; 00289 color = rd_gram(); 00290 if(isBGR) color = BGR2RGB(color); // in case, convert BGR to RGB 00291 return color; 00292 } 00293 void TFT932x::setscrollarea (int startY, int areasize) // ie 0,480 for whole screen 00294 { 00295 // ILI932x allows only ful lscreen scrolling 00296 unsigned short oldreg = reg_read(0x61); 00297 reg_write(0x61, oldreg|2); // enable scroll 00298 } 00299 void TFT932x::scroll (int lines) // ie 1= scrollup 1, 479= scrolldown 1 00300 { 00301 reg_write(0x6A, lines%screensize_Y); // select the (absolute)line which will be displayed as first line 00302 } 00303 void TFT932x::scrollreset() 00304 { 00305 unsigned short oldreg = reg_read(0x61); 00306 // reg_write(0x61, oldreg&0xFFFD); // disable scroll 00307 reg_write(0x6A, 0); 00308 } 00309 void TFT932x::cls (void) 00310 { 00311 WindowMax(); 00312 wr_gram(_background,screensize_X*screensize_Y); 00313 } 00314 // try to get read gram pixel format, could be 16bit or 18bit, RGB or BGR 00315 void TFT932x::auto_gram_read_format() 00316 { 00317 unsigned short px=0xCDB1; 00318 unsigned short rback, rback18; 00319 pixel(0,0,px); 00320 window4read(0,0,1,1); 00321 rback=proto->rd_gram(0); // try 16bit 00322 window4read(0,0,1,1); 00323 rback18=proto->rd_gram(1); // try 18bit converted to 16 00324 if((rback18==px) || (BGR2RGB(rback18)==px)) 00325 { 00326 is18bit=true; 00327 if(BGR2RGB(rback18)==px) isBGR=true; 00328 } 00329 else if((rback==px) || (BGR2RGB(rback)==px)) 00330 { 00331 if(BGR2RGB(rback)==px) isBGR=true; 00332 } 00333 // debug("\r\nIdentify gram read color format,\r\nsent %.4X read16 %.4X(bgr%.4X) read18 %.4X(bgr%.4X)", px, rback, BGR2RGB(rback), rback18, BGR2RGB(rback18)); 00334 } 00335 // try to identify display controller 00336 void TFT932x::identify() 00337 { 00338 tftID = reg_read(0x00); 00339 hw_reset(); // in case wrong cmd messed up important settings 00340 } 00341 int TFT932x::sizeX() 00342 { 00343 return screensize_X; 00344 } 00345 int TFT932x::sizeY() 00346 { 00347 return screensize_Y; 00348 }
Generated on Fri Jul 15 2022 13:58:04 by
