This is a mbed library for a 1.8 inch 128x160 pixel SPI TFT display
Dependents: ST7735_Pong ST7735_TFT SPI18TFT_FRDM-KL25Z SPI18TFT ... more
ST7735_TFT.cpp
00001 /* mbed library for 128*160 pixel display TFT based on ST7735 LCD Controller 00002 * ST7735 specific routines (initialization, window addressing, pixel output) 00003 * Copyright (c) 2011 Jonne Valola 00004 * 00005 * WARNING !! WORK IN PROGRESS !!! 00006 * 00007 * Graphics routines and SPI routines derived work used with permission from: 00008 * mbed library for 240*320 pixel display TFT based on HX8347D LCD Controller 00009 * Copyright (c) 2011 Peter Drescher - DC2PD 00010 * 00011 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00012 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00013 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00014 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00015 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00017 * THE SOFTWARE. 00018 */ 00019 00020 00021 #include "ST7735_TFT.h" 00022 #include "mbed.h" 00023 00024 #define BPP 16 // Bits per pixel 00025 00026 ST7735_TFT::ST7735_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rs, PinName reset, const char *name) 00027 : _spi(mosi, miso, sclk), _cs(cs), _rs(rs), _reset(reset),GraphicsDisplay(name) { 00028 tft_reset(); 00029 orientation = 2; 00030 char_x = 0; 00031 } 00032 00033 00034 int ST7735_TFT::width() { 00035 if (orientation == 0 || orientation == 2) return 128; 00036 else return 160; 00037 } 00038 00039 00040 int ST7735_TFT::height() { 00041 if (orientation == 0 || orientation == 2) return 160; 00042 else return 128; 00043 } 00044 00045 00046 void ST7735_TFT::set_orientation(unsigned int o) { 00047 orientation = o; 00048 switch (orientation) { 00049 case 0: 00050 wr_reg(ST7735_MADCTL, 0x0008); 00051 break; 00052 case 1: 00053 wr_reg(ST7735_MADCTL, 0x0068); 00054 break; 00055 case 2: 00056 wr_reg(ST7735_MADCTL, 0x00C8); 00057 break; 00058 case 3: 00059 wr_reg(ST7735_MADCTL, 0x00A8); 00060 break; 00061 } 00062 } 00063 00064 00065 00066 void ST7735_TFT::wr_cmd(int cmd) { 00067 _rs = 0; // rs low, cs low for transmitting command 00068 _cs = 0; 00069 _spi.write(cmd); 00070 _cs = 1; 00071 } 00072 00073 00074 00075 void ST7735_TFT::wr_dat(int dat) { 00076 _rs = 1; // rs high, cs low for transmitting data 00077 _cs = 0; 00078 _spi.write(dat); 00079 _cs = 1; 00080 } 00081 00082 00083 00084 void ST7735_TFT::wr_dat_start(void) { 00085 _rs = 1; // rs high, cs low for transmitting data 00086 _cs = 0; 00087 } 00088 00089 00090 00091 void ST7735_TFT::wr_dat_stop (void) { 00092 _cs = 1; 00093 } 00094 00095 00096 00097 void ST7735_TFT::wr_dat_only (unsigned short dat) { 00098 _spi.write(dat); 00099 } 00100 00101 00102 unsigned short ST7735_TFT::rd_dat (void) { 00103 unsigned short val = 0; 00104 _cs = 0; 00105 _spi.write(0); /* Dummy read 1 */ 00106 val = _spi.write(0); /* Read D8..D15 */ 00107 val <<= 8; 00108 val |= _spi.write(0); /* Read D0..D7 */ 00109 _cs = 1; 00110 return (val); 00111 } 00112 00113 void ST7735_TFT::wr_reg (unsigned char reg, unsigned short val) { 00114 00115 wr_cmd(reg); 00116 wr_dat(val); 00117 } 00118 00119 00120 unsigned short ST7735_TFT::rd_reg (unsigned char reg) { 00121 00122 wr_cmd(reg); 00123 return(rd_dat()); 00124 } 00125 00126 void ST7735_TFT::read_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *buffer) { 00127 // BEWARE ! 00128 // DOES NOT WORK CORRECTLY YET !!! 00129 int val; 00130 window(x,y,w,h); 00131 wr_cmd(ST7735_RAMRD); // write to RAM 00132 _cs = 0; 00133 _rs = 1; 00134 _spi.write(0); /* Dummy read 1 */ 00135 00136 val = _spi.write(0); /* Read D8..D15 */ 00137 val <<= 8; 00138 val |= _spi.write(0); /* Read D0..D7 */ 00139 _cs = 1; 00140 } 00141 00142 int ST7735_TFT::getpixel(unsigned int x, unsigned int y) { 00143 // BEWARE ! 00144 // DOES NOT WORK CORRECTLY YET !!! 00145 int val; 00146 _spi.format(8,3); 00147 wr_cmd(ST7735_CASET); // column addr set 00148 wr_dat(0x00); 00149 wr_dat(x+2); // XSTART 00150 wr_dat(0x00); 00151 wr_dat(x+2+2); // XEND 00152 00153 wr_cmd(ST7735_RASET); // row addr set 00154 wr_dat(0x00); 00155 wr_dat(y+1); // YSTART 00156 wr_dat(0x00); 00157 wr_dat(y+1+1); // YEND 00158 00159 _rs = 0; // rs low, cs low for transmitting command 00160 _cs = 0; 00161 _spi.write(0x2E); 00162 _rs = 1; 00163 _spi.write(0x00); /* Dummy read 1 */ 00164 00165 val = _spi.write(0x00); /* Read D8..D15 */ 00166 val <<= 8; 00167 val |= _spi.write(0x00); /* Read D0..D7 */ 00168 00169 _cs = 1; 00170 return val; 00171 } 00172 00173 00174 void ST7735_TFT::tft_reset() { 00175 static unsigned short driverCode; 00176 00177 // init SPI 00178 _spi.format(8,3); // 8 bit spi mode 3 00179 _spi.frequency(16000000); // 16Mhz SPI clock ... 15Mhz is maximum for display, but it seems to work 00180 00181 // reset exactly like in Arduino version 00182 _cs = 0; 00183 _reset = 1; // reset 00184 wait_ms(500); 00185 _reset = 0; // reset 00186 wait_ms(500); 00187 _reset = 1; // reset 00188 wait_ms(500); 00189 00190 /* Start Initial Sequence ----------------------------------------------------*/ 00191 wr_cmd(ST7735_SWRESET); /* SW Reset */ 00192 wait_ms(150); 00193 wr_cmd(ST7735_SLPOUT); /* Out of sleepmode */ 00194 wait_ms(500); 00195 00196 wr_cmd(ST7735_FRMCTR1); /* Frame rate in normal mode */ 00197 wr_dat(0x01); 00198 wr_dat(0x2C); 00199 wr_dat(0x2D); 00200 00201 wr_cmd(ST7735_FRMCTR2); /* Frame rate in idle mode */ 00202 wr_dat(0x01); 00203 wr_dat(0x2C); 00204 wr_dat(0x2D); 00205 00206 wr_cmd(ST7735_FRMCTR3); /* Frame rate in partial mode */ 00207 wr_dat(0x01); 00208 wr_dat(0x2C); 00209 wr_dat(0x2D); 00210 wr_dat(0x01); // inversion mode settings 00211 wr_dat(0x2C); 00212 wr_dat(0x2D); 00213 00214 wr_cmd(ST7735_INVCTR); // Inverted mode off 00215 wr_dat(0x07); 00216 00217 wr_cmd(ST7735_PWCTR1); // POWER CONTROL 1 00218 wr_dat(0xA2); 00219 wr_dat(0x02); // -4.6V 00220 wr_dat(0x84); // AUTO mode 00221 00222 wr_cmd(ST7735_PWCTR2); // POWER CONTROL 2 00223 wr_dat(0xC5); // VGH25 = 2.4C VGSEL =-10 VGH = 3*AVDD 00224 00225 wr_cmd(ST7735_PWCTR3); // POWER CONTROL 3 00226 wr_dat(0x0A); // Opamp current small 00227 wr_dat(0x00); // Boost freq 00228 00229 wr_cmd(ST7735_PWCTR4); // POWER CONTROL 4 00230 wr_dat(0x8A); // BCLK/2, Opamp current small / medium low 00231 wr_dat(0x2A); // 00232 00233 wr_cmd(ST7735_PWCTR5); // POWER CONTROL 5 00234 wr_dat(0x8A); // BCLK/2, Opamp current small / medium low 00235 wr_dat(0xEE); // 00236 00237 wr_cmd(ST7735_VMCTR1); // POWER CONTROL 6 00238 wr_dat(0x0E); // 00239 00240 wr_cmd(ST7735_INVOFF); // INVOFF 00241 00242 wr_cmd(ST7735_MADCTL); // ORIENTATION 00243 wr_dat(0xC8); // 00244 00245 wr_cmd(ST7735_COLMOD); // COLOR MODE 00246 wr_dat(0x05); // 00247 00248 wr_cmd(ST7735_CASET); // COLUMN ADDR SET 00249 wr_dat(0x00); // 00250 wr_dat(0x00); // xstart = 0 00251 wr_dat(0x00); // 00252 wr_dat(0x7F); // xend = 127 00253 00254 wr_cmd(ST7735_RASET); // ROW ADDR SET 00255 wr_dat(0x00); // 00256 wr_dat(0x00); // ystart = 0 00257 wr_dat(0x00); // 00258 wr_dat(0x9F); // yend = 159 00259 00260 /* Gamma settings -----------------------------------------------------------*/ 00261 00262 wr_cmd(0xE0); // GMCTRP1 00263 wr_dat(0x02); 00264 wr_dat(0x1c); 00265 wr_dat(0x07); 00266 wr_dat(0x12); 00267 wr_dat(0x37); 00268 wr_dat(0x32); 00269 wr_dat(0x29); 00270 wr_dat(0x2d); 00271 wr_dat(0x29); 00272 wr_dat(0x25); 00273 wr_dat(0x2B); 00274 wr_dat(0x39); 00275 wr_dat(0x00); 00276 wr_dat(0x01); 00277 wr_dat(0x03); 00278 wr_dat(0x10); 00279 wr_cmd(0xE1); // GMCTRN1 00280 wr_dat(0x03); 00281 wr_dat(0x1d); 00282 wr_dat(0x07); 00283 wr_dat(0x06); 00284 wr_dat(0x2E); 00285 wr_dat(0x2C); 00286 wr_dat(0x29); 00287 wr_dat(0x2D); 00288 wr_dat(0x2E); 00289 wr_dat(0x2E); 00290 wr_dat(0x37); 00291 wr_dat(0x3F); 00292 wr_dat(0x00); 00293 wr_dat(0x00); 00294 wr_dat(0x02); 00295 wr_dat(0x10); 00296 00297 wr_cmd(ST7735_DISPON); // display ON 00298 wait_ms(100); 00299 00300 wr_cmd(ST7735_NORON); // normal display on 00301 wait_ms(10); 00302 00303 switch (orientation) { 00304 case 0: 00305 wr_reg(0xC8, 0x0008); 00306 break; 00307 case 1: 00308 wr_reg(0xC8, 0x0068); 00309 break; 00310 case 2: 00311 wr_reg(0xC8, 0x00C8); 00312 break; 00313 case 3: 00314 wr_reg(0xC8, 0x00A8); 00315 break; 00316 } 00317 WindowMax (); 00318 } 00319 00320 00321 void ST7735_TFT::pixel(int x, int y, int color) { 00322 if ((x >= width()) || (y >= height())) return; 00323 00324 window(x,y,x+1,y+1); 00325 00326 // setup for data 00327 _rs = 1; 00328 _cs = 0; 00329 _spi.format(16,3); 00330 _spi.write(color); 00331 _cs = 1; 00332 _spi.format(8,3); 00333 } 00334 00335 void ST7735_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) { 00336 wr_cmd(ST7735_CASET); // column addr set 00337 wr_dat(0x00); 00338 wr_dat(x+2); // XSTART 00339 wr_dat(0x00); 00340 wr_dat(x+w+1); // XEND 00341 00342 wr_cmd(ST7735_RASET); // row addr set 00343 wr_dat(0x00); 00344 wr_dat(y+1); // YSTART 00345 wr_dat(0x00); 00346 wr_dat(y+h+1); // YEND 00347 00348 wr_cmd(ST7735_RAMWR); // write to RAM 00349 } 00350 00351 00352 void ST7735_TFT::WindowMax (void) { 00353 window (0, 0, width(), height()); 00354 } 00355 00356 00357 void ST7735_TFT::cls (void) { 00358 unsigned int i; 00359 WindowMax(); 00360 wr_dat_start(); 00361 _spi.format(16,3); 00362 for (i = 0; i < ( (width()+1) * (height()+3)); i++) { 00363 _spi.write(_background); 00364 } 00365 _spi.format(8,3); 00366 wr_dat_stop(); 00367 } 00368 00369 00370 void ST7735_TFT::circle(int x0, int y0, int r, int color) { 00371 00372 int draw_x0, draw_y0; 00373 int draw_x1, draw_y1; 00374 int draw_x2, draw_y2; 00375 int draw_x3, draw_y3; 00376 int draw_x4, draw_y4; 00377 int draw_x5, draw_y5; 00378 int draw_x6, draw_y6; 00379 int draw_x7, draw_y7; 00380 int xx, yy; 00381 int di; 00382 WindowMax(); 00383 if (r == 0) { /* no radius */ 00384 return; 00385 } 00386 00387 draw_x0 = draw_x1 = x0; 00388 draw_y0 = draw_y1 = y0 + r; 00389 if (draw_y0 < height()) { 00390 pixel(draw_x0, draw_y0, color); /* 90 degree */ 00391 } 00392 00393 draw_x2 = draw_x3 = x0; 00394 draw_y2 = draw_y3 = y0 - r; 00395 if (draw_y2 >= 0) { 00396 pixel(draw_x2, draw_y2, color); /* 270 degree */ 00397 } 00398 00399 draw_x4 = draw_x6 = x0 + r; 00400 draw_y4 = draw_y6 = y0; 00401 if (draw_x4 < width()) { 00402 pixel(draw_x4, draw_y4, color); /* 0 degree */ 00403 } 00404 00405 draw_x5 = draw_x7 = x0 - r; 00406 draw_y5 = draw_y7 = y0; 00407 if (draw_x5>=0) { 00408 pixel(draw_x5, draw_y5, color); /* 180 degree */ 00409 } 00410 00411 if (r == 1) { 00412 return; 00413 } 00414 00415 di = 3 - 2*r; 00416 xx = 0; 00417 yy = r; 00418 while (xx < yy) { 00419 00420 if (di < 0) { 00421 di += 4*xx + 6; 00422 } else { 00423 di += 4*(xx - yy) + 10; 00424 yy--; 00425 draw_y0--; 00426 draw_y1--; 00427 draw_y2++; 00428 draw_y3++; 00429 draw_x4--; 00430 draw_x5++; 00431 draw_x6--; 00432 draw_x7++; 00433 } 00434 xx++; 00435 draw_x0++; 00436 draw_x1--; 00437 draw_x2++; 00438 draw_x3--; 00439 draw_y4++; 00440 draw_y5++; 00441 draw_y6--; 00442 draw_y7--; 00443 00444 if ( (draw_x0 <= width()) && (draw_y0>=0) ) { 00445 pixel(draw_x0, draw_y0, color); 00446 } 00447 00448 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) { 00449 pixel(draw_x1, draw_y1, color); 00450 } 00451 00452 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) { 00453 pixel(draw_x2, draw_y2, color); 00454 } 00455 00456 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) { 00457 pixel(draw_x3, draw_y3, color); 00458 } 00459 00460 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) { 00461 pixel(draw_x4, draw_y4, color); 00462 } 00463 00464 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) { 00465 pixel(draw_x5, draw_y5, color); 00466 } 00467 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) { 00468 pixel(draw_x6, draw_y6, color); 00469 } 00470 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) { 00471 pixel(draw_x7, draw_y7, color); 00472 } 00473 } 00474 return; 00475 } 00476 00477 void ST7735_TFT::fillcircle(int x, int y, int r, int color) { 00478 int i; 00479 for (i = 0; i <= r; i++) 00480 circle(x,y,i,color); 00481 } 00482 00483 00484 00485 void ST7735_TFT::hline(int x0, int x1, int y, int color) { 00486 int w; 00487 w = x1 - x0 + 1; 00488 window(x0,y,w,1); 00489 wr_cmd(0x2C); 00490 wr_dat_start(); 00491 for (int x=0; x<w; x++) { 00492 _spi.write(color); 00493 _spi.write(color >> 8); 00494 } 00495 wr_dat_stop(); 00496 return; 00497 } 00498 00499 00500 00501 void ST7735_TFT::vline(int x, int y0, int y1, int color) { 00502 int h; 00503 h = y1 - y0 + 1; 00504 window(x,y0,1,h); 00505 wr_cmd(0x2C); 00506 wr_dat_start(); 00507 for (int y=0; y<h; y++) { 00508 _spi.write(color); 00509 _spi.write(color >> 8); 00510 } 00511 wr_dat_stop(); 00512 return; 00513 } 00514 00515 00516 00517 void ST7735_TFT::line(int x0, int y0, int x1, int y1, int color) { 00518 WindowMax(); 00519 int dx = 0, dy = 0; 00520 int dx_sym = 0, dy_sym = 0; 00521 int dx_x2 = 0, dy_x2 = 0; 00522 int di = 0; 00523 00524 dx = x1-x0; 00525 dy = y1-y0; 00526 00527 if (dx == 0) { /* vertical line */ 00528 if (y1 > y0) vline(x0,y0,y1,color); 00529 else vline(x0,y1,y0,color); 00530 return; 00531 } 00532 00533 if (dx > 0) { 00534 dx_sym = 1; 00535 } else { 00536 dx_sym = -1; 00537 } 00538 if (dy == 0) { /* horizontal line */ 00539 if (x1 > x0) hline(x0,x1,y0,color); 00540 else hline(x1,x0,y0,color); 00541 return; 00542 } 00543 00544 if (dy > 0) { 00545 dy_sym = 1; 00546 } else { 00547 dy_sym = -1; 00548 } 00549 00550 dx = dx_sym*dx; 00551 dy = dy_sym*dy; 00552 00553 dx_x2 = dx*2; 00554 dy_x2 = dy*2; 00555 00556 if (dx >= dy) { 00557 di = dy_x2 - dx; 00558 while (x0 != x1) { 00559 00560 pixel(x0, y0, color); 00561 x0 += dx_sym; 00562 if (di<0) { 00563 di += dy_x2; 00564 } else { 00565 di += dy_x2 - dx_x2; 00566 y0 += dy_sym; 00567 } 00568 } 00569 pixel(x0, y0, color); 00570 } else { 00571 di = dx_x2 - dy; 00572 while (y0 != y1) { 00573 pixel(x0, y0, color); 00574 y0 += dy_sym; 00575 if (di < 0) { 00576 di += dx_x2; 00577 } else { 00578 di += dx_x2 - dy_x2; 00579 x0 += dx_sym; 00580 } 00581 } 00582 pixel(x0, y0, color); 00583 } 00584 return; 00585 } 00586 00587 00588 00589 00590 void ST7735_TFT::rect(int x0, int y0, int x1, int y1, int color) { 00591 00592 if (x1 > x0) hline(x0,x1,y0,color); 00593 else hline(x1,x0,y0,color); 00594 00595 if (y1 > y0) vline(x0,y0,y1,color); 00596 else vline(x0,y1,y0,color); 00597 00598 if (x1 > x0) hline(x0,x1,y1,color); 00599 else hline(x1,x0,y1,color); 00600 00601 if (y1 > y0) vline(x1,y0,y1,color); 00602 else vline(x1,y1,y0,color); 00603 00604 return; 00605 } 00606 00607 00608 00609 void ST7735_TFT::fillrect(int x0, int y0, int x1, int y1, int color) { 00610 00611 int h = y1 - y0 + 1; 00612 int w = x1 - x0 + 1; 00613 int pixel = h * w; 00614 window(x0,y0,w,h); 00615 wr_cmd(0x2C); 00616 wr_dat_start(); 00617 for (int p=0; p<pixel; p++) { 00618 _spi.write(color); 00619 _spi.write(color >> 8); 00620 } 00621 wr_dat_stop(); 00622 return; 00623 } 00624 00625 00626 00627 void ST7735_TFT::locate(int x, int y) { 00628 char_x = x; 00629 char_y = y; 00630 } 00631 00632 00633 00634 int ST7735_TFT::columns() { 00635 return width() / font[1]; 00636 } 00637 00638 00639 00640 int ST7735_TFT::rows() { 00641 return height() / font[2]; 00642 } 00643 00644 00645 00646 int ST7735_TFT::_putc(int value) { 00647 if (value == '\n') { // new line 00648 char_x = 0; 00649 char_y = char_y + font[2]; 00650 if (char_y >= height() - font[2]) { 00651 char_y = 0; 00652 } 00653 } else { 00654 character(char_x, char_y, value); 00655 } 00656 return value; 00657 } 00658 00659 00660 00661 00662 void ST7735_TFT::character(int x, int y, int c) { 00663 unsigned int hor,vert,offset,bpl,j,i,b; 00664 unsigned char* zeichen; 00665 unsigned char z,w; 00666 00667 if ((c < 31) || (c > 127)) return; // test char range 00668 00669 // read font parameter from start of array 00670 offset = font[0]; // bytes / char 00671 hor = font[1]; // get hor size of font 00672 vert = font[2]; // get vert size of font 00673 bpl = font[3]; // bytes per line 00674 00675 if (char_x + hor > width()) { 00676 char_x = 0; 00677 char_y = char_y + vert; 00678 if (char_y >= height() - font[2]) { 00679 char_y = 0; 00680 } 00681 } 00682 00683 window(char_x, char_y,hor,vert); // char box 00684 wr_cmd(0x2C); 00685 wr_dat_start(); 00686 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 00687 w = zeichen[0]; // width of actual char 00688 _spi.format(16,3); // pixel are 16 bit 00689 00690 for (j=0; j<vert; j++) { // vert line 00691 for (i=0; i<hor; i++) { // horz line 00692 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00693 b = 1 << (j & 0x07); 00694 if (( z & b ) == 0x00) { 00695 _spi.write(_background); 00696 } else { 00697 _spi.write(_foreground); 00698 } 00699 } 00700 } 00701 _spi.format(8,3); // 8 bit 00702 wr_dat_stop(); 00703 if ((w + 2) < hor) { // x offset to next char 00704 char_x += w + 2; 00705 } else char_x += hor; 00706 } 00707 00708 00709 00710 00711 00712 void ST7735_TFT::set_font(unsigned char* f) { 00713 font = f; 00714 } 00715 00716 00717 00718 void ST7735_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) { 00719 unsigned int i,j,value; 00720 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00721 window(x, y, w, h); 00722 wr_cmd(0x2C); 00723 wr_dat_start(); 00724 for (j = 0; j < h; j++) { //Lines 00725 for (i = 0; i < w; i++) { // copy pixel data to TFT 00726 _spi.write(*bitmap_ptr); // one line 00727 _spi.write(*bitmap_ptr >> 8); 00728 bitmap_ptr++; 00729 } 00730 } 00731 wr_dat_stop(); 00732 } 00733 00734 00735 int ST7735_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) { 00736 // BEWARE ! 00737 // NOT TESTED 00738 #define OffsetPixelWidth 18 00739 #define OffsetPixelHeigh 22 00740 #define OffsetFileSize 34 00741 #define OffsetPixData 10 00742 #define OffsetBPP 28 00743 00744 char filename[50]; 00745 unsigned char BMP_Header[54]; 00746 unsigned short BPP_t; 00747 unsigned int PixelWidth,PixelHeigh,start_data; 00748 unsigned int i,off; 00749 int padd,j; 00750 unsigned short *line; 00751 00752 // get the filename 00753 LocalFileSystem local("local"); 00754 sprintf(&filename[0],"/local/"); 00755 i=7; 00756 while (*Name_BMP!='\0') { 00757 filename[i++]=*Name_BMP++; 00758 } 00759 FILE *Image = fopen((const char *)&filename[0], "r"); // open the bmp file 00760 if (!Image) { 00761 return(0); // error file not found ! 00762 } 00763 00764 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00765 00766 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00767 fclose(Image); 00768 return(-1); // error no BMP file 00769 } 00770 00771 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00772 if (BPP_t != 0x0010) { 00773 fclose(Image); 00774 return(-2); // error no 16 bit BMP 00775 } 00776 00777 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00778 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00779 if (PixelHeigh > height() + y || PixelWidth > width() + x) { 00780 fclose(Image); 00781 return(-3); // to big 00782 } 00783 00784 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00785 00786 line = (unsigned short *) malloc (PixelWidth); // we need a buffer for a line 00787 if (line == NULL) { 00788 return(-4); // error no memory 00789 } 00790 00791 // the lines are padded to multiple of 4 bytes 00792 padd = -1; 00793 do { 00794 padd ++; 00795 } while ((PixelWidth * 2 + padd)%4 != 0); 00796 00797 window(x, y,PixelWidth,PixelHeigh); 00798 wr_cmd(0x2C); 00799 wr_dat_start(); 00800 _spi.format(16,3); 00801 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 00802 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 00803 fseek(Image, off ,SEEK_SET); 00804 fread(line,1,PixelWidth * 2,Image); // read a line - slow ! 00805 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT 00806 _spi.write(line[i]); // one 16 bit pixel 00807 } 00808 } 00809 _spi.format(8,3); 00810 wr_dat_stop(); 00811 free (line); 00812 fclose(Image); 00813 return(1); 00814 }
Generated on Fri Jul 15 2022 16:25:48 by 1.7.2