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 SPI_TFT_ILI9341 by
SPI_TFT_ILI9341.cpp
00001 /* mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller 00002 * Copyright (c) 2013 Peter Drescher - DC2PD 00003 * 00004 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00005 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00006 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00007 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00008 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00009 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00010 * THE SOFTWARE. 00011 */ 00012 00013 // 12.06.13 fork from SPI_TFT code because controller is different ... 00014 // 14.07.13 Test with real display and bugfix 00015 // 18.10.13 Better Circle function from Michael Ammann 00016 // 22.10.13 Fixes for Kinetis Board - 8 bit spi 00017 // 26.01.14 Change interface for BMP_16 to also use SD-cards 00018 // 23.06.14 switch back to old Version - fork for L152 00019 // 24.06.14 Add compiler flag for optimized L152 version 00020 // 25.06.14 Add optimized F103 version 00021 00022 // exclude this file for platforms with optimized version 00023 #if defined TARGET_NUCLEO_L152RE || defined TARGET_NUCLEO_F103RB || defined TARGET_LPC1768 00024 // this platforms are supported by special version in different source file 00025 #else 00026 00027 #include "SPI_TFT_ILI9341.h" 00028 #include "mbed.h" 00029 00030 #define BPP 16 // Bits per pixel 00031 00032 //extern Serial pc; 00033 //extern DigitalOut xx; // debug !! 00034 00035 SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name) 00036 : GraphicsDisplay(name), SPI(mosi, miso, sclk,NC), _cs(cs), _reset(reset), _dc(dc) 00037 { 00038 00039 orientation = 0; 00040 char_x = 0; 00041 SPI::format(8,3); // 8 bit spi mode 3 00042 SPI::frequency(50000000); // 10 Mhz SPI clock 00043 tft_reset(); 00044 } 00045 00046 int SPI_TFT_ILI9341::width() 00047 { 00048 if (orientation == 0 || orientation == 2) return 240; 00049 else return 320; 00050 } 00051 00052 00053 int SPI_TFT_ILI9341::height() 00054 { 00055 if (orientation == 0 || orientation == 2) return 320; 00056 else return 240; 00057 } 00058 00059 00060 void SPI_TFT_ILI9341::set_orientation(unsigned int o) 00061 { 00062 orientation = o; 00063 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL 00064 switch (orientation) { 00065 case 0: 00066 SPI::write(0x48); 00067 break; 00068 case 1: 00069 SPI::write(0x28); 00070 break; 00071 case 2: 00072 SPI::write(0x88); 00073 break; 00074 case 3: 00075 SPI::write(0xE8); 00076 break; 00077 } 00078 _cs = 1; 00079 WindowMax(); 00080 } 00081 00082 00083 // write command to tft register 00084 00085 void SPI_TFT_ILI9341::wr_cmd(unsigned char cmd) 00086 { 00087 _dc = 0; 00088 _cs = 0; 00089 SPI::write(cmd); // mbed lib 00090 _dc = 1; 00091 } 00092 00093 00094 00095 void SPI_TFT_ILI9341::wr_dat(unsigned char dat) 00096 { 00097 SPI::write(dat); // mbed lib 00098 } 00099 00100 00101 00102 // the ILI9341 can read 00103 00104 char SPI_TFT_ILI9341::rd_byte(unsigned char cmd) 00105 { 00106 char r; 00107 _dc = 0; 00108 _cs = 0; 00109 SPI::write(cmd); // mbed lib 00110 _cs = 1; 00111 r = SPI::write(0xff); 00112 _cs = 1; 00113 return(r); 00114 } 00115 00116 // read 32 bit 00117 int SPI_TFT_ILI9341::rd_32(unsigned char cmd) 00118 { 00119 int d; 00120 char r; 00121 _dc = 0; 00122 _cs = 0; 00123 d = cmd; 00124 d = d << 1; 00125 SPI::format(9,3); // we have to add a dummy clock cycle 00126 SPI::write(d); 00127 SPI::format(8,3); 00128 _dc = 1; 00129 r = SPI::write(0xff); 00130 d = r; 00131 r = SPI::write(0xff); 00132 d = (d << 8) | r; 00133 r = SPI::write(0xff); 00134 d = (d << 8) | r; 00135 r = SPI::write(0xff); 00136 d = (d << 8) | r; 00137 _cs = 1; 00138 return(d); 00139 } 00140 00141 int SPI_TFT_ILI9341::Read_ID(void){ 00142 int r; 00143 r = rd_byte(0x0A); 00144 r = rd_byte(0x0A); 00145 r = rd_byte(0x0A); 00146 r = rd_byte(0x0A); 00147 return(r); 00148 } 00149 00150 00151 // Init code based on MI0283QT datasheet 00152 00153 void SPI_TFT_ILI9341::tft_reset() 00154 { 00155 _cs = 1; // cs high 00156 _dc = 1; // dc high 00157 _reset = 0; // display reset 00158 00159 wait_us(50); 00160 _reset = 1; // end hardware reset 00161 wait_ms(5); 00162 00163 wr_cmd(0x01); // SW reset 00164 wait_ms(5); 00165 wr_cmd(0x28); // display off 00166 00167 /* Start Initial Sequence ----------------------------------------------------*/ 00168 wr_cmd(0xCF); 00169 SPI::write(0x00); 00170 SPI::write(0x83); 00171 SPI::write(0x30); 00172 _cs = 1; 00173 00174 wr_cmd(0xED); 00175 SPI::write(0x64); 00176 SPI::write(0x03); 00177 SPI::write(0x12); 00178 SPI::write(0x81); 00179 _cs = 1; 00180 00181 wr_cmd(0xE8); 00182 SPI::write(0x85); 00183 SPI::write(0x01); 00184 SPI::write(0x79); 00185 _cs = 1; 00186 00187 wr_cmd(0xCB); 00188 SPI::write(0x39); 00189 SPI::write(0x2C); 00190 SPI::write(0x00); 00191 SPI::write(0x34); 00192 SPI::write(0x02); 00193 _cs = 1; 00194 00195 wr_cmd(0xF7); 00196 SPI::write(0x20); 00197 _cs = 1; 00198 00199 wr_cmd(0xEA); 00200 SPI::write(0x00); 00201 SPI::write(0x00); 00202 _cs = 1; 00203 00204 wr_cmd(0xC0); // POWER_CONTROL_1 00205 SPI::write(0x26); 00206 _cs = 1; 00207 00208 wr_cmd(0xC1); // POWER_CONTROL_2 00209 SPI::write(0x11); 00210 _cs = 1; 00211 00212 wr_cmd(0xC5); // VCOM_CONTROL_1 00213 SPI::write(0x35); 00214 SPI::write(0x3E); 00215 _cs = 1; 00216 00217 wr_cmd(0xC7); // VCOM_CONTROL_2 00218 SPI::write(0xBE); 00219 _cs = 1; 00220 00221 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL 00222 SPI::write(0x48); 00223 _cs = 1; 00224 00225 wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET 00226 SPI::write(0x55); // 16 bit pixel 00227 _cs = 1; 00228 00229 wr_cmd(0xB1); // Frame Rate 00230 SPI::write(0x00); 00231 SPI::write(0x1B); 00232 _cs = 1; 00233 00234 wr_cmd(0xF2); // Gamma Function Disable 00235 SPI::write(0x08); 00236 _cs = 1; 00237 00238 wr_cmd(0x26); 00239 SPI::write(0x01); // gamma set for curve 01/2/04/08 00240 _cs = 1; 00241 00242 wr_cmd(0xE0); // positive gamma correction 00243 SPI::write(0x1F); 00244 SPI::write(0x1A); 00245 SPI::write(0x18); 00246 SPI::write(0x0A); 00247 SPI::write(0x0F); 00248 SPI::write(0x06); 00249 SPI::write(0x45); 00250 SPI::write(0x87); 00251 SPI::write(0x32); 00252 SPI::write(0x0A); 00253 SPI::write(0x07); 00254 SPI::write(0x02); 00255 SPI::write(0x07); 00256 SPI::write(0x05); 00257 SPI::write(0x00); 00258 _cs = 1; 00259 00260 wr_cmd(0xE1); // negativ gamma correction 00261 SPI::write(0x00); 00262 SPI::write(0x25); 00263 SPI::write(0x27); 00264 SPI::write(0x05); 00265 SPI::write(0x10); 00266 SPI::write(0x09); 00267 SPI::write(0x3A); 00268 SPI::write(0x78); 00269 SPI::write(0x4D); 00270 SPI::write(0x05); 00271 SPI::write(0x18); 00272 SPI::write(0x0D); 00273 SPI::write(0x38); 00274 SPI::write(0x3A); 00275 SPI::write(0x1F); 00276 _cs = 1; 00277 00278 WindowMax (); 00279 00280 //wr_cmd(0x34); // tearing effect off 00281 //_cs = 1; 00282 00283 //wr_cmd(0x35); // tearing effect on 00284 //_cs = 1; 00285 00286 wr_cmd(0xB7); // entry mode 00287 SPI::write(0x07); 00288 _cs = 1; 00289 00290 wr_cmd(0xB6); // display function control 00291 SPI::write(0x0A); 00292 SPI::write(0x82); 00293 SPI::write(0x27); 00294 SPI::write(0x00); 00295 _cs = 1; 00296 00297 wr_cmd(0x11); // sleep out 00298 _cs = 1; 00299 00300 wait_ms(100); 00301 00302 wr_cmd(0x29); // display on 00303 _cs = 1; 00304 00305 wait_ms(100); 00306 00307 } 00308 00309 00310 void SPI_TFT_ILI9341::pixel(int x, int y, int color) 00311 { 00312 wr_cmd(0x2A); 00313 SPI::write(x >> 8); 00314 SPI::write(x); 00315 _cs = 1; 00316 wr_cmd(0x2B); 00317 SPI::write(y >> 8); 00318 SPI::write(y); 00319 _cs = 1; 00320 wr_cmd(0x2C); // send pixel 00321 #if defined TARGET_KL25Z || defined TARGET_DISCO_F429ZI // 8 Bit SPI 00322 SPI::write(color >> 8); 00323 SPI::write(color & 0xff); 00324 #else 00325 SPI::format(16,3); // switch to 16 bit Mode 3 00326 SPI::write(color); // Write D0..D15 00327 SPI::format(8,3); 00328 #endif 00329 _cs = 1; 00330 } 00331 00332 00333 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) 00334 { 00335 wr_cmd(0x2A); 00336 SPI::write(x >> 8); 00337 SPI::write(x); 00338 SPI::write((x+w-1) >> 8); 00339 SPI::write(x+w-1); 00340 00341 _cs = 1; 00342 wr_cmd(0x2B); 00343 SPI::write(y >> 8); 00344 SPI::write(y); 00345 SPI::write((y+h-1) >> 8); 00346 SPI::write(y+h-1); 00347 _cs = 1; 00348 } 00349 00350 00351 void SPI_TFT_ILI9341::WindowMax (void) 00352 { 00353 window (0, 0, width(), height()); 00354 } 00355 00356 00357 00358 void SPI_TFT_ILI9341::cls (void) 00359 { 00360 // we can use the fillrect function 00361 fillrect(0,0,width()-1,height()-1,_background); 00362 } 00363 00364 00365 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color) 00366 { 00367 00368 int x = -r, y = 0, err = 2-2*r, e2; 00369 do { 00370 pixel(x0-x, y0+y,color); 00371 pixel(x0+x, y0+y,color); 00372 pixel(x0+x, y0-y,color); 00373 pixel(x0-x, y0-y,color); 00374 e2 = err; 00375 if (e2 <= y) { 00376 err += ++y*2+1; 00377 if (-x == y && e2 <= x) e2 = 0; 00378 } 00379 if (e2 > x) err += ++x*2+1; 00380 } while (x <= 0); 00381 00382 } 00383 00384 void SPI_TFT_ILI9341::fillcircle(int x0, int y0, int r, int color) 00385 { 00386 int x = -r, y = 0, err = 2-2*r, e2; 00387 do { 00388 vline(x0-x, y0-y, y0+y, color); 00389 vline(x0+x, y0-y, y0+y, color); 00390 e2 = err; 00391 if (e2 <= y) { 00392 err += ++y*2+1; 00393 if (-x == y && e2 <= x) e2 = 0; 00394 } 00395 if (e2 > x) err += ++x*2+1; 00396 } while (x <= 0); 00397 } 00398 00399 00400 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color) 00401 { 00402 int w; 00403 w = x1 - x0 + 1; 00404 window(x0,y,w,1); 00405 wr_cmd(0x2C); // send pixel 00406 #if defined TARGET_KL25Z || defined TARGET_DISCO_F429ZI // 8 Bit SPI 00407 int j; 00408 for (j=0; j<w; j++) { 00409 SPI::write(color >> 8); 00410 SPI::write(color & 0xff); 00411 } 00412 #else 00413 SPI::format(16,3); // switch to 16 bit Mode 3 00414 int j; 00415 for (j=0; j<w; j++) { 00416 SPI::write(color); 00417 } 00418 SPI::format(8,3); 00419 #endif 00420 _cs = 1; 00421 WindowMax(); 00422 return; 00423 } 00424 00425 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color) 00426 { 00427 int h; 00428 h = y1 - y0 + 1; 00429 window(x,y0,1,h); 00430 wr_cmd(0x2C); // send pixel 00431 #if defined TARGET_KL25Z || defined TARGET_DISCO_F429ZI // 8 Bit SPI 00432 for (int y=0; y<h; y++) { 00433 SPI::write(color >> 8); 00434 SPI::write(color & 0xff); 00435 } 00436 #else 00437 SPI::format(16,3); // switch to 16 bit Mode 3 00438 for (int y=0; y<h; y++) { 00439 SPI::write(color); 00440 } 00441 SPI::format(8,3); 00442 #endif 00443 _cs = 1; 00444 WindowMax(); 00445 return; 00446 } 00447 00448 00449 00450 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color) 00451 { 00452 //WindowMax(); 00453 int dx = 0, dy = 0; 00454 int dx_sym = 0, dy_sym = 0; 00455 int dx_x2 = 0, dy_x2 = 0; 00456 int di = 0; 00457 00458 dx = x1-x0; 00459 dy = y1-y0; 00460 00461 if (dx == 0) { /* vertical line */ 00462 if (y1 > y0) vline(x0,y0,y1,color); 00463 else vline(x0,y1,y0,color); 00464 return; 00465 } 00466 00467 if (dx > 0) { 00468 dx_sym = 1; 00469 } else { 00470 dx_sym = -1; 00471 } 00472 if (dy == 0) { /* horizontal line */ 00473 if (x1 > x0) hline(x0,x1,y0,color); 00474 else hline(x1,x0,y0,color); 00475 return; 00476 } 00477 00478 if (dy > 0) { 00479 dy_sym = 1; 00480 } else { 00481 dy_sym = -1; 00482 } 00483 00484 dx = dx_sym*dx; 00485 dy = dy_sym*dy; 00486 00487 dx_x2 = dx*2; 00488 dy_x2 = dy*2; 00489 00490 if (dx >= dy) { 00491 di = dy_x2 - dx; 00492 while (x0 != x1) { 00493 00494 pixel(x0, y0, color); 00495 x0 += dx_sym; 00496 if (di<0) { 00497 di += dy_x2; 00498 } else { 00499 di += dy_x2 - dx_x2; 00500 y0 += dy_sym; 00501 } 00502 } 00503 pixel(x0, y0, color); 00504 } else { 00505 di = dx_x2 - dy; 00506 while (y0 != y1) { 00507 pixel(x0, y0, color); 00508 y0 += dy_sym; 00509 if (di < 0) { 00510 di += dx_x2; 00511 } else { 00512 di += dx_x2 - dy_x2; 00513 x0 += dx_sym; 00514 } 00515 } 00516 pixel(x0, y0, color); 00517 } 00518 return; 00519 } 00520 00521 00522 void SPI_TFT_ILI9341::rect(int x0, int y0, int x1, int y1, int color) 00523 { 00524 00525 if (x1 > x0) hline(x0,x1,y0,color); 00526 else hline(x1,x0,y0,color); 00527 00528 if (y1 > y0) vline(x0,y0,y1,color); 00529 else vline(x0,y1,y0,color); 00530 00531 if (x1 > x0) hline(x0,x1,y1,color); 00532 else hline(x1,x0,y1,color); 00533 00534 if (y1 > y0) vline(x1,y0,y1,color); 00535 else vline(x1,y1,y0,color); 00536 00537 return; 00538 } 00539 00540 00541 00542 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color) 00543 { 00544 00545 int h = y1 - y0 + 1; 00546 int w = x1 - x0 + 1; 00547 int pixel = h * w; 00548 window(x0,y0,w,h); 00549 wr_cmd(0x2C); // send pixel 00550 #if defined TARGET_KL25Z || defined TARGET_DISCO_F429ZI // 8 Bit SPI 00551 for (int p=0; p<pixel; p++) { 00552 SPI::write(color >> 8); 00553 SPI::write(color & 0xff); 00554 } 00555 #else 00556 SPI::format(16,3); // switch to 16 bit Mode 3 00557 for (int p=0; p<pixel; p++) { 00558 SPI::write(color); 00559 } 00560 SPI::format(8,3); 00561 #endif 00562 _cs = 1; 00563 WindowMax(); 00564 return; 00565 } 00566 00567 00568 void SPI_TFT_ILI9341::locate(int x, int y) 00569 { 00570 char_x = x; 00571 char_y = y; 00572 } 00573 00574 00575 00576 int SPI_TFT_ILI9341::columns() 00577 { 00578 return width() / font[FONT_WIDTH_INDEX]; 00579 } 00580 00581 00582 00583 int SPI_TFT_ILI9341::rows() 00584 { 00585 return height() / font[FONT_HEIGHT_INDEX]; 00586 } 00587 00588 00589 00590 int SPI_TFT_ILI9341::_putc(int value) 00591 { 00592 if (value == '\n') { // new line 00593 char_x = 0; 00594 char_y = char_y + font[FONT_HEIGHT_INDEX]; 00595 if (char_y >= height() - font[FONT_HEIGHT_INDEX]) { 00596 char_y = 0; 00597 } 00598 } else { 00599 character(char_x, char_y, value); 00600 } 00601 return value; 00602 } 00603 00604 00605 void SPI_TFT_ILI9341::character(int x, int y, int c) 00606 { 00607 unsigned int hor, vert, offset, bpl, j, i, b; 00608 unsigned char* zeichen; 00609 unsigned char z, w; 00610 00611 if ((c < 31) || (c > 127)) return; // test char range 00612 00613 // read font parameter from start of array 00614 offset = font[FONT_OFFSET_INDEX]; // bytes / char 00615 hor = font[FONT_WIDTH_INDEX]; // get hor size of font 00616 vert = font[FONT_HEIGHT_INDEX]; // get vert size of font 00617 bpl = font[FONT_BSP_INDEX]; // bytes per line 00618 00619 if (char_x + hor > width()) { 00620 char_x = 0; 00621 char_y = char_y + vert; 00622 if (char_y >= height() - font[FONT_HEIGHT_INDEX]) { 00623 char_y = 0; 00624 } 00625 } 00626 window(char_x, char_y,hor,vert); // char box 00627 wr_cmd(0x2C); // send pixel 00628 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI // 16 Bit SPI 00629 SPI::format(16,3); 00630 #endif // switch to 16 bit Mode 3 00631 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 00632 w = zeichen[0]; // width of actual char 00633 for (j=0; j<vert; j++) { // vert line 00634 for (i=0; i<hor; i++) { // horz line 00635 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00636 b = 1 << (j & 0x07); 00637 if (( z & b ) == 0x00) { 00638 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI // 16 Bit SPI 00639 SPI::write(_background); 00640 #else 00641 SPI::write(_background >> 8); 00642 SPI::write(_background & 0xff); 00643 #endif 00644 } else { 00645 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI // 16 Bit SPI 00646 SPI::write(_foreground); 00647 #else 00648 SPI::write(_foreground >> 8); 00649 SPI::write(_foreground & 0xff); 00650 #endif 00651 } 00652 } 00653 } 00654 _cs = 1; 00655 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI // 16 Bit SPI 00656 SPI::format(8,3); 00657 #endif 00658 WindowMax(); 00659 if ((w + 2) < hor) { // x offset to next char 00660 char_x += w + 2; 00661 } else char_x += hor; 00662 } 00663 00664 00665 void SPI_TFT_ILI9341::set_font(unsigned char* f) 00666 { 00667 font = f; 00668 } 00669 00670 00671 00672 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) 00673 { 00674 unsigned int j; 00675 int padd; 00676 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00677 #if defined TARGET_KL25Z || defined TARGET_DISCO_F429ZI // 8 Bit SPI 00678 unsigned short pix_temp; 00679 #endif 00680 00681 unsigned int i; 00682 00683 // the lines are padded to multiple of 4 bytes in a bitmap 00684 padd = -1; 00685 do { 00686 padd ++; 00687 } while (2*(w + padd)%4 != 0); 00688 window(x, y, w, h); 00689 bitmap_ptr += ((h - 1)* (w + padd)); 00690 wr_cmd(0x2C); // send pixel 00691 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI // 16 Bit SPI 00692 SPI::format(16,3); 00693 #endif // switch to 16 bit Mode 3 00694 for (j = 0; j < h; j++) { //Lines 00695 for (i = 0; i < w; i++) { // one line 00696 #if defined TARGET_KL25Z // 8 Bit SPI 00697 pix_temp = *bitmap_ptr; 00698 SPI::write(pix_temp >> 8); 00699 SPI::write(pix_temp); 00700 bitmap_ptr++; 00701 #else 00702 SPI::write(*bitmap_ptr); // one line 00703 bitmap_ptr++; 00704 #endif 00705 } 00706 bitmap_ptr -= 2*w; 00707 bitmap_ptr -= padd; 00708 } 00709 _cs = 1; 00710 #if ! defined TARGET_KL25Z && ! defined TARGET_DISCO_F429ZI 00711 SPI::format(8,3); 00712 #endif 00713 WindowMax(); 00714 } 00715 00716 00717 // local filesystem is not implemented in kinetis board , but you can add a SD card 00718 00719 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) 00720 { 00721 00722 #define OffsetPixelWidth 18 00723 #define OffsetPixelHeigh 22 00724 #define OffsetFileSize 34 00725 #define OffsetPixData 10 00726 #define OffsetBPP 28 00727 00728 char filename[50]; 00729 unsigned char BMP_Header[54]; 00730 unsigned short BPP_t; 00731 unsigned int PixelWidth,PixelHeigh,start_data; 00732 unsigned int i,off; 00733 int padd,j; 00734 unsigned short *line; 00735 00736 // get the filename 00737 i=0; 00738 while (*Name_BMP!='\0') { 00739 filename[i++]=*Name_BMP++; 00740 } 00741 filename[i] = 0; 00742 00743 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00744 if (!Image) { 00745 return(0); // error file not found ! 00746 } 00747 00748 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00749 00750 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00751 fclose(Image); 00752 return(-1); // error no BMP file 00753 } 00754 00755 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00756 if (BPP_t != 0x0010) { 00757 fclose(Image); 00758 return(-2); // error no 16 bit BMP 00759 } 00760 00761 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00762 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00763 if (PixelHeigh > height() + y || PixelWidth > width() + x) { 00764 fclose(Image); 00765 return(-3); // to big 00766 } 00767 00768 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00769 00770 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00771 if (line == NULL) { 00772 return(-4); // error no memory 00773 } 00774 00775 // the bmp lines are padded to multiple of 4 bytes 00776 padd = -1; 00777 do { 00778 padd ++; 00779 } while ((PixelWidth * 2 + padd)%4 != 0); 00780 00781 window(x, y,PixelWidth ,PixelHeigh); 00782 wr_cmd(0x2C); // send pixel 00783 #ifndef TARGET_KL25Z // only 8 Bit SPI 00784 SPI::format(16,3); 00785 #endif // switch to 16 bit Mode 3 00786 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00787 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00788 fseek(Image, off ,SEEK_SET); 00789 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00790 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT 00791 #ifndef TARGET_KL25Z // only 8 Bit SPI 00792 SPI::write(line[i]); // one 16 bit pixel 00793 #else 00794 SPI::write(line[i] >> 8); 00795 SPI::write(line[i]); 00796 #endif 00797 } 00798 } 00799 _cs = 1; 00800 SPI::format(8,3); 00801 free (line); 00802 fclose(Image); 00803 WindowMax(); 00804 return(1); 00805 } 00806 00807 void SPI_TFT_ILI9341::locateChar(uint16_t row, uint16_t column, Text_AlignModeTypdef mode, uint16_t textLength) 00808 { 00809 uint16_t x = 0; 00810 switch (mode) 00811 { 00812 case LEFT_MODE: 00813 x = getCharLeft(column); 00814 break; 00815 case CENTER_MODE: 00816 x = (width() / 2) - ((textLength + 1) * font[FONT_WIDTH_INDEX]) / 2; 00817 break; 00818 case RIGHT_MODE: 00819 x = width() - textLength * font[FONT_WIDTH_INDEX]; 00820 break; 00821 } 00822 locate(x, getCharTop(row)); 00823 } 00824 00825 uint16_t SPI_TFT_ILI9341::getCharLeft(uint16_t column) 00826 { 00827 return font[FONT_WIDTH_INDEX] * column; 00828 } 00829 00830 uint16_t SPI_TFT_ILI9341::getCharTop(uint16_t row) 00831 { 00832 return font[FONT_HEIGHT_INDEX] * row; 00833 } 00834 00835 uint16_t SPI_TFT_ILI9341::getCharBottom(uint16_t row) 00836 { 00837 return font[FONT_HEIGHT_INDEX] * (row + 1) - 1; 00838 } 00839 00840 uint16_t SPI_TFT_ILI9341::getCharRight(uint16_t column) 00841 { 00842 return font[FONT_WIDTH_INDEX] * (column + 1) - 1; 00843 } 00844 00845 void SPI_TFT_ILI9341::ClearStringLine(uint16_t row) 00846 { 00847 fillrect(0, getCharTop(row), width(), getCharBottom(row), _background); 00848 } 00849 00850 #endif
Generated on Wed Jul 13 2022 13:26:36 by
