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