Adapted from Peter Dresche's original for Waveshare 2.8inch TFT Touch Shield Board and Mbed 6. RGB order reversed by changing reg 16 commands, spi write code adjusted as there is no reset pin but there is data command pin. Wait commands changed for new thread_sleep style, Stream class explicitly included. Library to control a QVGA TFT connected to SPI. You can use printf to print text The lib can handle different fonts, draw lines, circles, rect and bmp
SPI_TFT.cpp
00001 /* mbed library for 240*320 pixel display TFT based on HX8347D LCD Controller 00002 * Copyright (c) 2011 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 00014 // fix bmp padding for Bitmap function 00015 // speed up pixel 00016 // 30.12.11 fix cls 00017 // 11.03.12 use DMA to speed up 00018 // 15.03.12 use SSEL for TFT CS to enable DMA Register writes 00019 // 06.04.12 fix SSEL CS problem 00020 // 06.04.12 use direct access to the spi register to speed up the library. 00021 // 11.09.12 switch back to using io pin as cs to avoid problems with SSEL CS. 00022 // 21.09.12 fix Bug in BMP_16 00023 // 11.10.12 patch from Hans Bergles to get SPI1 working again 00024 // 03.02.13 add a switch to switch off DMA use for LPC11U24 00025 // 04.03.13 add support for new Kinetis board 00026 // 25.03.13 fix Bug in bitmap for Kinetis board 00027 // 18.10.13 Better Circle function from Michael Ammann 00028 // 2020-2021 Hacked by JHD 00029 00030 #include "SPI_TFT.h" 00031 #include "mbed.h" 00032 // for fast performance on some STM boards 00033 00034 00035 00036 00037 #define BPP 16 // Bits per pixel 00038 00039 #if defined TARGET_LPC1768 00040 #define USE_DMA // we use dma to speed up 00041 #define NO_MBED_LIB // we write direct to the SPI register to speed up 00042 #endif 00043 00044 #if defined NO_DMA // if LPC1768 user want no DMA 00045 #undef USE_DMA 00046 #endif 00047 00048 00049 //extern Serial pc; 00050 //extern DigitalOut xx; // debug !! 00051 00052 SPI_TFT::SPI_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, const char *name) 00053 : _spi(mosi, miso, sclk), _cs(cs), _reset(reset),GraphicsDisplay(name) 00054 { 00055 orientation = 0; 00056 char_x = 0; 00057 tft_reset(); 00058 } 00059 00060 int SPI_TFT::width() 00061 { 00062 if (orientation == 0 || orientation == 2) return 240; 00063 else return 320; 00064 } 00065 00066 00067 int SPI_TFT::height() 00068 { 00069 if (orientation == 0 || orientation == 2) return 320; 00070 else return 240; 00071 } 00072 00073 00074 void SPI_TFT::set_orientation(unsigned int o) 00075 { 00076 orientation = o; 00077 switch (orientation) { 00078 case 0: 00079 wr_reg(0x16, 0x08); 00080 break; 00081 case 1: 00082 wr_reg(0x16, 0x68); 00083 break; 00084 case 2: 00085 wr_reg(0x16, 0xC8); 00086 break; 00087 case 3: 00088 wr_reg(0x16, 0xA8); 00089 break; 00090 } 00091 WindowMax(); 00092 } 00093 00094 00095 // write command to tft register 00096 00097 void SPI_TFT::wr_cmd(unsigned char cmd) 00098 { 00099 unsigned short spi_d; 00100 spi_d = 0x7000 | cmd ; 00101 _spi.write(spi_d); // mbed lib 00102 00103 } 00104 00105 00106 // write data to tft register 00107 void SPI_TFT::wr_dat(unsigned char dat) 00108 { 00109 unsigned short spi_d; 00110 spi_d = 0x7200 | dat; 00111 _spi.write(spi_d); 00112 } 00113 00114 00115 00116 // the HX8347-D controller do not use the MISO (SDO) Signal. 00117 // This is a bug - ? 00118 // A read will return 0 at the moment 00119 00120 unsigned short SPI_TFT::rd_dat (void) 00121 { 00122 unsigned short val = 0; 00123 00124 //val = _spi.write(0x73ff); /* Dummy read 1 */ 00125 //val = _spi.write(0x0000); /* Read D8..D15 */ 00126 return (val); 00127 } 00128 00129 // write to a TFT register 00130 void SPI_TFT::wr_reg (unsigned char reg, unsigned char val) 00131 { 00132 _spi.lock(); 00133 _spi.format(16,3); 00134 _cs=0; 00135 _reset=0; 00136 wr_cmd(reg); 00137 _reset=1; 00138 wr_dat(val); 00139 _cs=1; 00140 _spi.unlock(); 00141 } 00142 00143 // read from a TFT register 00144 unsigned short SPI_TFT::rd_reg (unsigned char reg) 00145 { 00146 wr_cmd(reg); 00147 return(rd_dat()); 00148 } 00149 00150 // setup TFT controller - this is called by constructor 00151 void SPI_TFT::tft_reset() 00152 { 00153 // 16 Bit SPI 00154 _spi.format(16,3); // 16 bit spi mode 3 00155 00156 _spi.frequency(48000000); // 48 Mhz SPI clock 00157 _cs = 1; // cs high 00158 // end reset 00159 thread_sleep_for(5); 00160 00161 /* Start Initial Sequence ----------------------------------------------------*/ 00162 wr_reg(0xEA, 0x00); /* Reset Power Control 1 */ 00163 wr_reg(0xEB, 0x20); /* Power Control 2 */ 00164 wr_reg(0xEC, 0x0C); /* Power Control 3 */ 00165 wr_reg(0xED, 0xC4); /* Power Control 4 */ 00166 wr_reg(0xE8, 0x40); /* Source OPON_N */ 00167 wr_reg(0xE9, 0x38); /* Source OPON_I */ 00168 wr_reg(0xF1, 0x01); /* */ 00169 wr_reg(0xF2, 0x10); /* */ 00170 wr_reg(0x27, 0xA3); /* Display Control 2 */ 00171 00172 /* Power On sequence ---------------------------------------------------------*/ 00173 wr_reg(0x1B, 0x1B); /* Power Control 2 */ 00174 wr_reg(0x1A, 0x01); /* Power Control 1 */ 00175 wr_reg(0x24, 0x2F); /* Vcom Control 2 */ 00176 wr_reg(0x25, 0x57); /* Vcom Control 3 */ 00177 wr_reg(0x23, 0x8D); /* Vcom Control 1 */ 00178 00179 /* Gamma settings -----------------------------------------------------------*/ 00180 wr_reg(0x40,0x00); // default setup 00181 wr_reg(0x41,0x00); // 00182 wr_reg(0x42,0x01); // 00183 wr_reg(0x43,0x13); // 00184 wr_reg(0x44,0x10); // 00185 wr_reg(0x45,0x26); // 00186 wr_reg(0x46,0x08); // 00187 wr_reg(0x47,0x51); // 00188 wr_reg(0x48,0x02); // 00189 wr_reg(0x49,0x12); // 00190 wr_reg(0x4A,0x18); // 00191 wr_reg(0x4B,0x19); // 00192 wr_reg(0x4C,0x14); // 00193 wr_reg(0x50,0x19); // 00194 wr_reg(0x51,0x2F); // 00195 wr_reg(0x52,0x2C); // 00196 wr_reg(0x53,0x3E); // 00197 wr_reg(0x54,0x3F); // 00198 wr_reg(0x55,0x3F); // 00199 wr_reg(0x56,0x2E); // 00200 wr_reg(0x57,0x77); // 00201 wr_reg(0x58,0x0B); // 00202 wr_reg(0x59,0x06); // 00203 wr_reg(0x5A,0x07); // 00204 wr_reg(0x5B,0x0D); // 00205 wr_reg(0x5C,0x1D); // 00206 wr_reg(0x5D,0xCC); // 00207 00208 /* Power + Osc ---------------------------------------------------------------*/ 00209 wr_reg(0x18, 0x36); /* OSC Control 1 */ 00210 wr_reg(0x19, 0x01); /* OSC Control 2 */ 00211 wr_reg(0x01, 0x00); /* Display Mode Control */ 00212 wr_reg(0x1F, 0x88); /* Power Control 6 */ 00213 thread_sleep_for(5); /* Delay 5 ms */ 00214 wr_reg(0x1F, 0x80); /* Power Control 6 */ 00215 thread_sleep_for(5); /* Delay 5 ms */ 00216 wr_reg(0x1F, 0x90); /* Power Control 6 */ 00217 thread_sleep_for(5); /* Delay 5 ms */ 00218 wr_reg(0x1F, 0xD0); /* Power Control 6 */ 00219 thread_sleep_for(5); /* Delay 5 ms */ 00220 00221 wr_reg(0x17, 0x05); /* Colmod 16Bit/Pixel */ 00222 00223 wr_reg(0x36, 0x00); /* Panel Characteristic */ 00224 wr_reg(0x28, 0x38); /* Display Control 3 */ 00225 thread_sleep_for(40); 00226 wr_reg(0x28, 0x3C); /* Display Control 3 */ 00227 switch (orientation) { 00228 case 0: 00229 wr_reg(0x16, 0x08); 00230 break; 00231 case 2: 00232 wr_reg(0x16, 0xC8); 00233 break; 00234 case 3: 00235 wr_reg(0x16, 0xA8); 00236 break; 00237 case 1: 00238 default: 00239 wr_reg(0x16, 0x68); 00240 break; 00241 00242 } 00243 00244 WindowMax (); 00245 } 00246 00247 // Set one pixel 00248 void SPI_TFT::pixel(int x, int y, int color) 00249 { 00250 wr_reg(0x03, (x >> 0)); 00251 wr_reg(0x02, (x >> 8)); 00252 wr_reg(0x07, (y >> 0)); 00253 wr_reg(0x06, (y >> 8)); 00254 _spi.lock(); 00255 _cs = 0; 00256 _reset=0; 00257 wr_cmd(0x22); 00258 _reset=1; 00259 // _spi.format(8,3); // 8 bit Mode 3 00260 // _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 00261 // _spi.format(16,3); // switch to 16 bit Mode 3 00262 #ifdef __DIRECTSPI_H_ 00263 _spi.directWrite(color); 00264 #else 00265 _spi.write(color); 00266 #endif // Write D0..D15 00267 _cs = 1; 00268 _spi.unlock(); 00269 } 00270 00271 // define draw area 00272 void SPI_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) 00273 { 00274 wr_reg(0x03, x ); 00275 wr_reg(0x02, (x >> 8)); 00276 wr_reg(0x05, x+w-1 ); 00277 wr_reg(0x04, ((x+w-1) >> 8)); 00278 wr_reg(0x07, y ); 00279 wr_reg(0x06, ( y >> 8)); 00280 wr_reg(0x09, ( y+h-1 )); 00281 wr_reg(0x08, ( (y+h-1) >> 8)); 00282 } 00283 00284 // set draw area to max 00285 void SPI_TFT::WindowMax (void) 00286 { 00287 window (0, 0, width(), height()); 00288 } 00289 00290 00291 // clear screen 00292 void SPI_TFT::cls (void) 00293 { 00294 fprintf(stderr, "CLS \n\r"); 00295 int pixel = ( width() * height()); 00296 WindowMax(); 00297 _spi.lock(); 00298 _cs = 0; 00299 _reset=0; 00300 wr_cmd(0x22); 00301 _reset=1; // 16 bit SPI 00302 // _spi.format(8,3); // 8 bit Mode 3 00303 // _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 00304 // _spi.format(16,3); // switch back to 16 bit Mode 3 00305 unsigned int i; 00306 for (i = 0; i < ( width() * height()); i++) 00307 #ifdef __DIRECTSPI_H_ 00308 _spi.directWrite(_background); 00309 #else 00310 _spi.write(_background); 00311 #endif 00312 _cs = 1; 00313 _spi.unlock(); 00314 } 00315 00316 void SPI_TFT::circle(int x0, int y0, int r, int color) 00317 { 00318 int x = -r, y = 0, err = 2-2*r, e2; 00319 do { 00320 pixel(x0-x, y0+y,color); 00321 pixel(x0+x, y0+y,color); 00322 pixel(x0+x, y0-y,color); 00323 pixel(x0-x, y0-y,color); 00324 e2 = err; 00325 if (e2 <= y) { 00326 err += ++y*2+1; 00327 if (-x == y && e2 <= x) e2 = 0; 00328 } 00329 if (e2 > x) err += ++x*2+1; 00330 } while (x <= 0); 00331 00332 } 00333 00334 void SPI_TFT::fillcircle(int x0, int y0, int r, int color) 00335 { 00336 int x = -r, y = 0, err = 2-2*r, e2; 00337 do { 00338 vline(x0-x, y0-y, y0+y, color); 00339 vline(x0+x, y0-y, y0+y, color); 00340 e2 = err; 00341 if (e2 <= y) { 00342 err += ++y*2+1; 00343 if (-x == y && e2 <= x) e2 = 0; 00344 } 00345 if (e2 > x) err += ++x*2+1; 00346 } while (x <= 0); 00347 } 00348 00349 00350 // draw horizontal line 00351 void SPI_TFT::hline(int x0, int x1, int y, int color) 00352 { 00353 int w; 00354 w = x1 - x0 + 1; 00355 window(x0,y,w,1); 00356 _spi.lock(); 00357 _cs = 0; 00358 _reset=0; 00359 wr_cmd(0x22); 00360 _reset=1; 00361 // switch back to 16 bit Mode 3 00362 for (int j=0; j<w; j++) { 00363 #ifdef __DIRECTSPI_H_ 00364 _spi.directWrite(color); 00365 #else 00366 _spi.write(color); 00367 #endif // one line 00368 } 00369 00370 _cs = 1; 00371 _spi.unlock(); 00372 WindowMax(); 00373 return; 00374 } 00375 00376 // draw vertical line 00377 void SPI_TFT::vline(int x, int y0, int y1, int color) 00378 { 00379 int h; 00380 h = y1 - y0 + 1; 00381 window(x,y0,1,h); 00382 _spi.lock(); 00383 _cs = 0; 00384 _reset=0; 00385 wr_cmd(0x22); 00386 _reset=1; 00387 // switch to 16 bit Mode 3 00388 for (int y=0; y<h; y++) { 00389 #ifdef __DIRECTSPI_H_ 00390 _spi.directWrite(color); 00391 #else 00392 _spi.write(color); 00393 #endif // one line 00394 } 00395 00396 _cs = 1; 00397 _spi.unlock(); 00398 WindowMax(); 00399 return; 00400 } 00401 00402 00403 // draw line 00404 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color) 00405 { 00406 //WindowMax(); 00407 int dx = 0, dy = 0; 00408 int dx_sym = 0, dy_sym = 0; 00409 int dx_x2 = 0, dy_x2 = 0; 00410 int di = 0; 00411 00412 dx = x1-x0; 00413 dy = y1-y0; 00414 00415 if (dx == 0) { /* vertical line */ 00416 if (y1 > y0) vline(x0,y0,y1,color); 00417 else vline(x0,y1,y0,color); 00418 return; 00419 } 00420 00421 if (dx > 0) { 00422 dx_sym = 1; 00423 } else { 00424 dx_sym = -1; 00425 } 00426 if (dy == 0) { /* horizontal line */ 00427 if (x1 > x0) hline(x0,x1,y0,color); 00428 else hline(x1,x0,y0,color); 00429 return; 00430 } 00431 00432 if (dy > 0) { 00433 dy_sym = 1; 00434 } else { 00435 dy_sym = -1; 00436 } 00437 00438 dx = dx_sym*dx; 00439 dy = dy_sym*dy; 00440 00441 dx_x2 = dx*2; 00442 dy_x2 = dy*2; 00443 00444 if (dx >= dy) { 00445 di = dy_x2 - dx; 00446 while (x0 != x1) { 00447 00448 pixel(x0, y0, color); 00449 x0 += dx_sym; 00450 if (di<0) { 00451 di += dy_x2; 00452 } else { 00453 di += dy_x2 - dx_x2; 00454 y0 += dy_sym; 00455 } 00456 } 00457 pixel(x0, y0, color); 00458 } else { 00459 di = dx_x2 - dy; 00460 while (y0 != y1) { 00461 pixel(x0, y0, color); 00462 y0 += dy_sym; 00463 if (di < 0) { 00464 di += dx_x2; 00465 } else { 00466 di += dx_x2 - dy_x2; 00467 x0 += dx_sym; 00468 } 00469 } 00470 pixel(x0, y0, color); 00471 } 00472 return; 00473 } 00474 00475 // draw rect 00476 void SPI_TFT::rect(int x0, int y0, int x1, int y1, int color) 00477 { 00478 00479 if (x1 > x0) hline(x0,x1,y0,color); 00480 else hline(x1,x0,y0,color); 00481 00482 if (y1 > y0) vline(x0,y0,y1,color); 00483 else vline(x0,y1,y0,color); 00484 00485 if (x1 > x0) hline(x0,x1,y1,color); 00486 else hline(x1,x0,y1,color); 00487 00488 if (y1 > y0) vline(x1,y0,y1,color); 00489 else vline(x1,y1,y0,color); 00490 00491 return; 00492 } 00493 00494 00495 // fill rect 00496 void SPI_TFT::fillrect(int x0, int y0, int x1, int y1, int color) 00497 { 00498 00499 int h = y1 - y0 + 1; 00500 int w = x1 - x0 + 1; 00501 int pixel = h * w; 00502 window(x0,y0,w,h); 00503 _spi.lock(); 00504 _cs = 0; 00505 _reset=0; 00506 wr_cmd(0x22); 00507 _reset=1; 00508 00509 for (int p=0; p<pixel; p++) { 00510 #ifdef __DIRECTSPI_H_ 00511 _spi.directWrite(color); 00512 #else 00513 _spi.write(color); 00514 #endif // one line 00515 } 00516 00517 _cs = 1; 00518 _spi.unlock(); 00519 WindowMax(); 00520 return; 00521 } 00522 00523 // set cursor position 00524 void SPI_TFT::locate(int x, int y) 00525 { 00526 char_x = x; 00527 char_y = y; 00528 } 00529 00530 00531 // calculate num of chars in a row 00532 int SPI_TFT::columns() 00533 { 00534 return width() / font[1]; 00535 } 00536 00537 // calculate num of rows on the screen 00538 int SPI_TFT::rows() 00539 { 00540 return height() / font[2]; 00541 } 00542 00543 // print a char on the screen 00544 int SPI_TFT::_putc(int value) 00545 { 00546 if (value == '\n') { // new line 00547 char_x = 0; 00548 char_y = char_y + font[2]; 00549 if (char_y >= height() - font[2]) { 00550 char_y = 0; 00551 } 00552 } else { 00553 character(char_x, char_y, value); 00554 } 00555 return value; 00556 } 00557 00558 // consrtuct the char out of the font 00559 void SPI_TFT::character(int x, int y, int c) 00560 { 00561 unsigned int hor,vert,offset,bpl,j,i,b; 00562 unsigned char* zeichen; 00563 unsigned char z,w; 00564 00565 if ((c < 31) || (c > 127)) return; // test char range 00566 00567 // read font parameter from start of array 00568 offset = font[0]; // bytes / char 00569 hor = font[1]; // get hor size of font 00570 vert = font[2]; // get vert size of font 00571 bpl = font[3]; // bytes per line 00572 00573 if (char_x + hor > width()) { 00574 char_x = 0; 00575 char_y = char_y + vert; 00576 if (char_y >= height() - font[2]) { 00577 char_y = 0; 00578 } 00579 } 00580 window(char_x, char_y,hor,vert); // char box 00581 _spi.lock(); 00582 _cs = 0; 00583 _reset=0; 00584 wr_cmd(0x22); 00585 _reset=1; 00586 00587 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 00588 w = zeichen[0]; // width of actual char 00589 for (j=0; j<vert; j++) { // vert line 00590 for (i=0; i<hor; i++) { // horz line 00591 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00592 b = 1 << (j & 0x07); 00593 if (( z & b ) == 0x00) { 00594 00595 #ifdef __DIRECTSPI_H_ 00596 _spi.directWrite(_background); 00597 #else 00598 _spi.write(_background); 00599 #endif // one line 00600 00601 } else { 00602 #ifdef __DIRECTSPI_H_ 00603 _spi.directWrite(_foreground); 00604 #else 00605 _spi.write(_foreground); 00606 #endif // one line 00607 } 00608 } 00609 } 00610 00611 _cs = 1; 00612 _spi.unlock(); 00613 WindowMax(); 00614 if ((w + 2) < hor) { // x offset to next char 00615 char_x += w + 2; 00616 } else char_x += hor; 00617 } 00618 00619 00620 void SPI_TFT::set_font(unsigned char* f) 00621 { 00622 font = f; 00623 } 00624 00625 00626 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) 00627 { 00628 unsigned int j; 00629 int padd; 00630 00631 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00632 00633 00634 // the lines are padded to multiple of 4 bytes in a bitmap 00635 padd = -1; 00636 do { 00637 padd ++; 00638 } while (2*(w + padd)%4 != 0); 00639 window(x, y, w, h); 00640 _spi.lock(); 00641 _cs = 0; 00642 _reset=0; 00643 wr_cmd(0x22); 00644 _reset=1; 00645 00646 bitmap_ptr += ((h - 1)* (w + padd)); 00647 unsigned int i; 00648 for (j = 0; j < h; j++) { //Lines 00649 for (i = 0; i < w; i++) { // copy pixel data to TFT 00650 00651 #ifdef __DIRECTSPI_H_ 00652 _spi.directWrite(*bitmap_ptr); 00653 #else 00654 _spi.write(*bitmap_ptr); 00655 #endif // one line 00656 bitmap_ptr++; 00657 00658 } 00659 bitmap_ptr -= 2*w; 00660 bitmap_ptr -= padd; 00661 } 00662 00663 _cs = 1; 00664 _spi.unlock(); 00665 WindowMax(); 00666 } 00667 00668 int SPI_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) 00669 { 00670 00671 #define OffsetPixelWidth 18 00672 #define OffsetPixelHeigh 22 00673 #define OffsetFileSize 34 00674 #define OffsetPixData 10 00675 #define OffsetBPP 28 00676 00677 char filename[50]; 00678 unsigned char BMP_Header[54]; 00679 unsigned short BPP_t; 00680 int PixelWidth,PixelHeigh; 00681 unsigned int start_data; 00682 unsigned int i,off; 00683 int padd,j; 00684 unsigned short *line; 00685 00686 sprintf(&filename[0],"%s",Name_BMP); 00687 00688 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 00689 if (!Image) { 00690 return(0); // error file not found ! 00691 } 00692 00693 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 00694 00695 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00696 fclose(Image); 00697 return(-1); // error no BMP file 00698 } 00699 00700 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00701 if (BPP_t != 0x0010) { 00702 fclose(Image); 00703 return(-2); // error no 16 bit BMP 00704 } 00705 00706 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00707 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00708 if (PixelHeigh > height() + y || PixelWidth > width() + x) { 00709 fclose(Image); 00710 return(-3); // to big 00711 } 00712 00713 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00714 00715 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 00716 if (line == NULL) { 00717 return(-4); // error no memory 00718 } 00719 00720 // the bmp lines are padded to multiple of 4 bytes 00721 padd = -1; 00722 do { 00723 padd ++; 00724 } while ((PixelWidth * 2 + padd)%4 != 0); 00725 int k,l; 00726 00727 for ( j = PixelHeigh-1 ; j >=0 ; j-- ) { //Lines bottom up 00728 00729 off = (j * (PixelWidth * 2 + padd)) + (start_data); // start of line 00730 int erra=fseek(Image, off,SEEK_SET); 00731 int errb=fread(line,1,PixelWidth * 2,Image); // read a line - slow ! 00732 window(x, (y+PixelHeigh)-j , PixelWidth ,1); 00733 _spi.lock(); 00734 _cs=0; 00735 _reset=0; 00736 wr_cmd(0x22); 00737 _reset=1; 00738 _spi.format(16,3); 00739 // switch to 16 bit Mode 3 00740 for (l = PixelWidth - 1; l >= 0 ; l--) { // copy pixel data to TFT 00741 int out = line[(PixelWidth-1)-l]; 00742 #ifdef __DIRECTSPI_H_ 00743 _spi.directWrite(line[(PixelWidth-1)-l]); 00744 #else 00745 _spi.write(ine[(PixelWidth-1)-l]); 00746 #endif // one line 00747 } 00748 00749 _cs=1; 00750 _spi.unlock(); 00751 00752 } 00753 00754 free (line); 00755 fclose(Image); 00756 WindowMax(); 00757 return(1); 00758 } 00759
Generated on Sun Jul 17 2022 11:36:08 by
1.7.2