Lib for the new LCD Display with ILI9341 controller Modified for huge fonts (>255 bytes/char). Needs modified font.h files with 2-byte size parameter. Window size is set on a per-character basis to minimise the number of pixels written (speed-up, plus better detection of whether one last character will fit on the current line). NUCLEO & NXP DMA-enabled versions are modified but untested.
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(40000000); // 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 // 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 // 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 // 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 // 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[2]; 00579 } 00580 00581 00582 00583 int SPI_TFT_ILI9341::rows() 00584 { 00585 return height() / font[3]; 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[3]; 00595 if (char_y >= height() - font[3]) { 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[0]<<8)+font[1]; // bytes / char now 16bits 00615 hor = font[2]; // get hor size of font 00616 vert = font[3]; // get vert size of font 00617 bpl = font[4]; // bytes per line 00618 00619 zeichen = &font[((c-32) * offset)+5]; 00620 w=zeichen[0]; 00621 00622 //check whether there are sufficient pixels to render character 00623 if (char_x + (w+2) > width()) { //was hor, now w+2 -> enables squeezing extra char at end of line) 00624 char_x = 0; 00625 char_y = char_y + vert; 00626 if (char_y >= height() - vert) { 00627 char_y = 0; 00628 } 00629 } 00630 window(char_x, char_y,(w+2),vert); // was hor, now w+2 -> char box shrunk to smallest size we need (speedup) 00631 wr_cmd(0x2C); // send pixel 00632 #ifndef TARGET_KL25Z // 16 Bit SPI 00633 SPI::format(16,3); 00634 #endif // switch to 16 bit Mode 3 00635 for (j=0; j<vert; j++) { // vert line 00636 for (i=0; i<(w+2); i++) { //w+2 was hor, send just enough pixel data to fill window // horz line 00637 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00638 b = 1 << (j & 0x07); 00639 if (( z & b ) == 0x00) { 00640 #ifndef TARGET_KL25Z // 16 Bit SPI 00641 SPI::write(_background); 00642 #else 00643 SPI::write(_background >> 8); 00644 SPI::write(_background & 0xff); 00645 #endif 00646 } else { 00647 #ifndef TARGET_KL25Z // 16 Bit SPI 00648 SPI::write(_foreground); 00649 #else 00650 SPI::write(_foreground >> 8); 00651 SPI::write(_foreground & 0xff); 00652 #endif 00653 } 00654 } 00655 } 00656 _cs = 1; 00657 #ifndef TARGET_KL25Z // 16 Bit SPI 00658 SPI::format(8,3); 00659 #endif 00660 WindowMax(); 00661 if ((w + 2) < hor) { // x offset to next char 00662 char_x += w + 2; 00663 } else char_x += hor; 00664 } 00665 00666 00667 void SPI_TFT_ILI9341::set_font(unsigned char* f) 00668 { 00669 font = f; 00670 } 00671 00672 00673 00674 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) 00675 { 00676 unsigned int j; 00677 int padd; 00678 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00679 #if defined TARGET_KL25Z // 8 Bit SPI 00680 unsigned short pix_temp; 00681 #endif 00682 00683 unsigned int i; 00684 00685 // the lines are padded to multiple of 4 bytes in a bitmap 00686 padd = -1; 00687 do { 00688 padd ++; 00689 } while (2*(w + padd)%4 != 0); 00690 window(x, y, w, h); 00691 bitmap_ptr += ((h - 1)* (w + padd)); 00692 wr_cmd(0x2C); // send pixel 00693 #ifndef TARGET_KL25Z // 16 Bit SPI 00694 SPI::format(16,3); 00695 #endif // switch to 16 bit Mode 3 00696 for (j = 0; j < h; j++) { //Lines 00697 for (i = 0; i < w; i++) { // one line 00698 #if defined TARGET_KL25Z // 8 Bit SPI 00699 pix_temp = *bitmap_ptr; 00700 SPI::write(pix_temp >> 8); 00701 SPI::write(pix_temp); 00702 bitmap_ptr++; 00703 #else 00704 SPI::write(*bitmap_ptr); // one line 00705 bitmap_ptr++; 00706 #endif 00707 } 00708 bitmap_ptr -= 2*w; 00709 bitmap_ptr -= padd; 00710 } 00711 _cs = 1; 00712 #ifndef TARGET_KL25Z // 16 Bit SPI 00713 SPI::format(8,3); 00714 #endif 00715 WindowMax(); 00716 } 00717 00718 00719 // local filesystem is not implemented in kinetis board , but you can add a SD card 00720 00721 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) 00722 { 00723 00724 #define OffsetPixelWidth 18 00725 #define OffsetPixelHeigh 22 00726 #define OffsetFileSize 34 00727 #define OffsetPixData 10 00728 #define OffsetBPP 28 00729 00730 char filename[50]; 00731 unsigned char BMP_Header[54]; 00732 unsigned short BPP_t; 00733 unsigned int PixelWidth,PixelHeigh,start_data; 00734 unsigned int i,off; 00735 int padd,j; 00736 unsigned short *line; 00737 00738 // get the filename 00739 i=0; 00740 while (*Name_BMP!='\0') { 00741 filename[i++]=*Name_BMP++; 00742 } 00743 filename[i] = 0; 00744 00745 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00746 if (!Image) { 00747 return(0); // error file not found ! 00748 } 00749 00750 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00751 00752 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00753 fclose(Image); 00754 return(-1); // error no BMP file 00755 } 00756 00757 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00758 if (BPP_t != 0x0010) { 00759 fclose(Image); 00760 return(-2); // error no 16 bit BMP 00761 } 00762 00763 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00764 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00765 if (PixelHeigh > height() + y || PixelWidth > width() + x) { 00766 fclose(Image); 00767 return(-3); // to big 00768 } 00769 00770 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00771 00772 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00773 if (line == NULL) { 00774 return(-4); // error no memory 00775 } 00776 00777 // the bmp lines are padded to multiple of 4 bytes 00778 padd = -1; 00779 do { 00780 padd ++; 00781 } while ((PixelWidth * 2 + padd)%4 != 0); 00782 00783 window(x, y,PixelWidth ,PixelHeigh); 00784 wr_cmd(0x2C); // send pixel 00785 #ifndef TARGET_KL25Z // only 8 Bit SPI 00786 SPI::format(16,3); 00787 #endif // switch to 16 bit Mode 3 00788 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00789 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00790 fseek(Image, off ,SEEK_SET); 00791 fread(line,1,PixelWidth * 2,Image); // read a line - slow 00792 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT 00793 #ifndef TARGET_KL25Z // only 8 Bit SPI 00794 SPI::write(line[i]); // one 16 bit pixel 00795 #else 00796 SPI::write(line[i] >> 8); 00797 SPI::write(line[i]); 00798 #endif 00799 } 00800 } 00801 _cs = 1; 00802 SPI::format(8,3); 00803 free (line); 00804 fclose(Image); 00805 WindowMax(); 00806 return(1); 00807 } 00808 00809 #endif
Generated on Wed Jul 13 2022 12:41:38 by 1.7.2