This is the final version of Mini Gateway for Automation and Security desgined for Renesas GR Peach Design Contest
Dependencies: GR-PEACH_video GraphicsFramework HTTPServer R_BSP mbed-rpc mbed-rtos Socket lwip-eth lwip-sys lwip FATFileSystem
Fork of mbed-os-example-mbed5-blinky by
TFT.cpp
00001 /* mbed UniGraphic library - universal TFT 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 240*320 pixel display TFT based on ILI9341 LCD Controller 00008 * Copyright (c) 2013 Peter Drescher - DC2PD 00009 * 00010 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00011 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00012 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00013 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00014 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00015 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00016 * THE SOFTWARE. 00017 */ 00018 00019 #include "TFT.h" 00020 00021 //#include "mbed_debug.h" 00022 00023 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } 00024 00025 #if DEVICE_PORTINOUT 00026 TFT::TFT(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) 00027 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00028 { 00029 if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD); 00030 else if(displayproto==PAR_16) proto = new PAR16(port, CS, reset, DC, WR, RD); 00031 useNOP=false; 00032 scrollbugfix=0; 00033 mipistd=false; 00034 set_orientation(0); 00035 foreground(White); 00036 background(Black); 00037 set_auto_up(false); //we don't have framebuffer 00038 topfixedareasize=0; 00039 scrollareasize=0; 00040 usefastwindow=true; 00041 fastwindowready=false; 00042 is18bit=true; 00043 isBGR=true; 00044 // cls(); 00045 // locate(0,0); 00046 } 00047 #endif 00048 00049 TFT::TFT(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) 00050 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00051 { 00052 if(displayproto==BUS_8) 00053 { 00054 PinName pins[16]; 00055 for(int i=0; i<16; i++) pins[i]=NC; 00056 for(int i=0; i<8; i++) pins[i]=buspins[i]; 00057 proto = new BUS8(pins, CS, reset, DC, WR, RD); 00058 } 00059 else if(displayproto==BUS_16) 00060 { 00061 proto = new BUS16(buspins, CS, reset, DC, WR, RD); 00062 } 00063 useNOP=false; 00064 scrollbugfix=0; 00065 mipistd=false; 00066 set_orientation(0); 00067 foreground(White); 00068 background(Black); 00069 set_auto_up(false); //we don't have framebuffer 00070 topfixedareasize=0; 00071 scrollareasize=0; 00072 usefastwindow=false; 00073 fastwindowready=false; 00074 is18bit=false; 00075 isBGR=false; 00076 // cls(); 00077 // locate(0,0); 00078 } 00079 TFT::TFT(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 char *name) 00080 : GraphicsDisplay(name), screensize_X(lcdsize_x), screensize_Y(lcdsize_y) 00081 { 00082 if(displayproto==SPI_8) 00083 { 00084 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC); 00085 useNOP=false; 00086 } 00087 else if(displayproto==SPI_16) 00088 { 00089 proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC); 00090 useNOP=true; 00091 } 00092 scrollbugfix=0; 00093 mipistd=false; 00094 set_orientation(0); 00095 foreground(White); 00096 background(Black); 00097 set_auto_up(false); 00098 topfixedareasize=0; 00099 scrollareasize=0; 00100 usefastwindow=false; 00101 fastwindowready=false; 00102 is18bit=false; 00103 isBGR=true; 00104 // locate(0,0); 00105 } 00106 void TFT::wr_cmd8(unsigned char cmd) 00107 { 00108 if(useNOP) proto->wr_cmd16(cmd); // 0x0000|cmd, 00 is NOP cmd for TFT 00109 else proto->wr_cmd8(cmd); 00110 } 00111 void TFT::wr_data8(unsigned char data) 00112 { 00113 proto->wr_data8(data); 00114 } 00115 void TFT::wr_data16(unsigned short data) 00116 { 00117 proto->wr_data16(data); 00118 } 00119 void TFT::wr_gram(unsigned short data) 00120 { 00121 proto->wr_gram(data); 00122 } 00123 void TFT::wr_gram(unsigned short data, unsigned int count) 00124 { 00125 proto->wr_gram(data, count); 00126 } 00127 void TFT::wr_grambuf(unsigned short* data, unsigned int lenght) 00128 { 00129 proto->wr_grambuf(data, lenght); 00130 } 00131 unsigned short TFT::rd_gram() 00132 { 00133 return proto->rd_gram(is18bit); // protocol will handle 18to16 bit conversion 00134 } 00135 unsigned int TFT::rd_reg_data32(unsigned char reg) 00136 { 00137 return proto->rd_reg_data32(reg); 00138 } 00139 unsigned int TFT::rd_extcreg_data32(unsigned char reg, unsigned char SPIreadenablecmd) 00140 { 00141 return proto->rd_extcreg_data32(reg, SPIreadenablecmd); 00142 } 00143 //for TFT, just send data, position counters are in hw 00144 void TFT::window_pushpixel(unsigned short color) 00145 { 00146 proto->wr_gram(color); 00147 } 00148 void TFT::window_pushpixel(unsigned short color, unsigned int count) 00149 { 00150 proto->wr_gram(color, count); 00151 } 00152 void TFT::window_pushpixelbuf(unsigned short* color, unsigned int lenght) 00153 { 00154 proto->wr_grambuf(color, lenght); 00155 } 00156 void TFT::hw_reset() 00157 { 00158 proto->hw_reset(); 00159 BusEnable(true); 00160 } 00161 void TFT::BusEnable(bool enable) 00162 { 00163 proto->BusEnable(enable); 00164 } 00165 // color TFT can rotate in hw (swap raw<->columns) for landscape views 00166 void TFT::set_orientation(int o) 00167 { 00168 orientation = o; 00169 wr_cmd8(0x36); 00170 switch (orientation) { 00171 case 0:// default, portrait view 0° 00172 if(mipistd) wr_data8(0x0A); // this is in real a vertical flip enabled, seems most displays are vertical flipped 00173 else wr_data8(0x48); //for some other ILIxxxx 00174 set_width(screensize_X); 00175 set_height(screensize_Y); 00176 break; 00177 case 1:// landscape view +90° 00178 if(mipistd) wr_data8(0x28); 00179 else wr_data8(0x29);//for some other ILIxxxx 00180 set_width(screensize_Y); 00181 set_height(screensize_X); 00182 break; 00183 case 2:// portrait view +180° 00184 if(mipistd) wr_data8(0x09); 00185 else wr_data8(0x99);//for some other ILIxxxx 00186 set_width(screensize_X); 00187 set_height(screensize_Y); 00188 break; 00189 case 3:// landscape view -90° 00190 if(mipistd) wr_data8(0x2B); 00191 else wr_data8(0xF8);//for some other ILIxxxx 00192 set_width(screensize_Y); 00193 set_height(screensize_X); 00194 break; 00195 } 00196 } 00197 void TFT::invert(unsigned char o) 00198 { 00199 if(o == 0) wr_cmd8(0x20); 00200 else wr_cmd8(0x21); 00201 } 00202 void TFT::FastWindow(bool enable) 00203 { 00204 usefastwindow=enable; 00205 } 00206 // TFT have both column and raw autoincrement inside a window, with internal counters 00207 void TFT::window(int x, int y, int w, int h) 00208 { 00209 fastwindowready=false; // end raw/column going to be set to lower value than bottom-right corner 00210 wr_cmd8(0x2A); 00211 wr_data16((x>>8)&0xff); 00212 wr_data16(x&0xff); //start column 00213 wr_data16(((x+w-1)>>8)&0xff);//end column 00214 wr_data16((x+w-1)&0xff); 00215 00216 wr_cmd8(0x2B); 00217 wr_data16(y>>8); //start page 00218 wr_data16(y&0xff); 00219 wr_data16(((y+h-1)>>8)&0xff);//end page 00220 wr_data16((y+h-1)&0xff); 00221 00222 wr_cmd8(0x2C); //write mem, just send pixels color next 00223 } 00224 void TFT::window4read(int x, int y, int w, int h) 00225 { 00226 fastwindowready=false; 00227 wr_cmd8(0x2A); 00228 wr_data16(x); //start column 00229 wr_data16(x+w-1);//end column 00230 00231 wr_cmd8(0x2B); 00232 wr_data16(y); //start page 00233 wr_data16(y+h-1);//end page 00234 00235 wr_cmd8(0x2E); //read mem, just pixelread next 00236 } 00237 void TFT::pixel(int x, int y, unsigned short color) 00238 { 00239 if(usefastwindow) //ili9486 does not like truncated 2A/2B cmds, at least in par mode 00240 { 00241 if(fastwindowready) //setting only start column/page does speedup, but needs end raw/column previously set to bottom-right corner 00242 { 00243 wr_cmd8(0x2A); 00244 wr_data16((x>>8)&0xff); 00245 wr_data16(x&0xff); //start column 00246 wr_cmd8(0x2B); 00247 wr_data16(y>>8); //start page 00248 wr_data16(y&0xff); 00249 wr_cmd8(0x2C); //write mem, just send pixels color next 00250 } 00251 else 00252 { 00253 window(x,y,width()-x,height()-y); // set also end raw/column to bottom-right corner 00254 fastwindowready=true; 00255 } 00256 } 00257 else window(x,y,width()-x,height()-y); 00258 // proto->wr_gram(color); // 2C expects 16bit parameters 00259 wr_gram(color); 00260 } 00261 unsigned short TFT::pixelread(int x, int y) 00262 { 00263 if(usefastwindow) //ili9486 does not like truncated 2A/2B cmds, at least in par mode 00264 { 00265 if(fastwindowready) //setting only start column/page does speedup, but needs end raw/column previously set to bottom-right corner 00266 { 00267 wr_cmd8(0x2A); 00268 wr_data16(x); //start column only 00269 wr_cmd8(0x2B); 00270 wr_data16(y); //start page only 00271 wr_cmd8(0x2E); //read mem, just pixelread next 00272 } 00273 else 00274 { 00275 window4read(x,y,width()-x,height()-y); // set also end raw/column to bottom-right corner 00276 fastwindowready=true; 00277 } 00278 } 00279 else window4read(x,y,1,1); 00280 00281 unsigned short color; 00282 // proto->wr_gram(color); // 2C expects 16bit parameters 00283 color = rd_gram(); 00284 if(isBGR) color = BGR2RGB(color); // in case, convert BGR to RGB (should depend on cmd36 bit3) but maybe is device specific 00285 return color; 00286 } 00287 void TFT::setscrollarea (int startY, int areasize) // ie 0,480 for whole screen 00288 { 00289 unsigned int bfa; 00290 topfixedareasize=startY; 00291 scrollareasize=areasize; 00292 wr_cmd8(0x33); 00293 wr_data16(topfixedareasize); //num lines of top fixed area 00294 wr_data16(scrollareasize+scrollbugfix); //num lines of vertical scroll area, +1 for ILI9481 fix 00295 if((areasize+startY)>screensize_Y) bfa=0; 00296 else bfa = screensize_Y-(areasize+startY); 00297 wr_data16(bfa); //num lines of bottom fixed area 00298 } 00299 void TFT::scroll (int lines) // ie 1= scrollup 1, 479= scrolldown 1 00300 { 00301 wr_cmd8(0x37); 00302 wr_data16(topfixedareasize+(lines%scrollareasize)); // select the (absolute)line which will be displayed as first scrollarea line 00303 } 00304 void TFT::scrollreset() 00305 { 00306 wr_cmd8(0x13); //normal display mode 00307 } 00308 void TFT::cls (void) 00309 { 00310 WindowMax(); 00311 // proto->wr_gram(_background,screensize_X*screensize_Y); 00312 // proto->wr_gram(0,screensize_X*screensize_Y); 00313 wr_gram(_background,screensize_X*screensize_Y); 00314 } 00315 // try to get read gram pixel format, could be 16bit or 18bit, RGB or BGR 00316 void TFT::auto_gram_read_format() 00317 { 00318 unsigned short px=0xCDB1; 00319 unsigned short rback, rback18; 00320 pixel(0,0,px); 00321 window4read(0,0,1,1); 00322 rback=proto->rd_gram(0); // try 16bit 00323 window4read(0,0,1,1); 00324 rback18=proto->rd_gram(1); // try 18bit converted to 16 00325 if((rback18==px) || (BGR2RGB(rback18)==px)) 00326 { 00327 is18bit=true; 00328 if(BGR2RGB(rback18)==px) isBGR=true; 00329 } 00330 else if((rback==px) || (BGR2RGB(rback)==px)) 00331 { 00332 if(BGR2RGB(rback)==px) isBGR=true; 00333 } 00334 // 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)); 00335 } 00336 // try to identify display controller 00337 void TFT::identify() 00338 { 00339 // MIPI std read ID cmd 00340 tftID=rd_reg_data32(0xBF); 00341 mipistd=false; 00342 // debug("ID MIPI : 0x%8X\r\n",tftID); 00343 if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF))) 00344 { 00345 mipistd=false; 00346 // ILI specfic read ID cmd 00347 tftID=rd_reg_data32(0xD3)>>8; 00348 // debug("ID ILI : 0x%8X\r\n",tftID); 00349 } 00350 if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF))) 00351 { 00352 // ILI specfic read ID cmd with ili9341 specific spi read-in enable 0xD9 cmd 00353 tftID=rd_extcreg_data32(0xD3, 0xD9); 00354 // debug("ID D9 extc ILI : 0x%8X\r\n",tftID); 00355 } 00356 if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF))) 00357 { 00358 // ILI specfic read ID cmd with ili9486/88 specific spi read-in enable 0xFB cmd 00359 tftID=rd_extcreg_data32(0xD3, 0xFB); 00360 // debug("ID D9 extc ILI : 0x%8X\r\n",tftID); 00361 } 00362 if(((tftID&0xFF)==((tftID>>8)&0xFF)) && ((tftID&0xFF)==((tftID>>16)&0xFF))) tftID=0xDEAD; 00363 if ((tftID&0xFFFF)==0x9481) scrollbugfix=1; 00364 else scrollbugfix=0; 00365 hw_reset(); // in case wrong cmds messed up important settings 00366 } 00367 int TFT::sizeX() 00368 { 00369 return screensize_X; 00370 } 00371 int TFT::sizeY() 00372 { 00373 return screensize_Y; 00374 }
Generated on Tue Jul 12 2022 15:10:53 by 1.7.2