A web server for monitoring and controlling a MakerBot Replicator over the USB host and ethernet.
Dependencies: IAP NTPClient RTC mbed-rtos mbed Socket lwip-sys lwip BurstSPI
Fork of LPC1768_Mini-DK by
SPI_TFT_ILI9320.cpp
00001 /************************************************************************************************** 00002 ***** ***** 00003 ***** Name: SPI_TFT.cpp ***** 00004 ***** Ver.: 1.0 ***** 00005 ***** Date: 04/01/2013 ***** 00006 ***** Auth: Frank Vannieuwkerke ***** 00007 ***** Erik Olieman ***** 00008 ***** Func: library for 240*320 pixel TFT with ILI9320 LCD Controller ***** 00009 ***** ***** 00010 ***** Rewrite from Peter Drescher code - http://mbed.org/cookbook/SPI-driven-QVGA-TFT ***** 00011 ***** ***** 00012 **************************************************************************************************/ 00013 00014 #include "SPI_TFT_ILI9320.h" 00015 #include "mbed.h" 00016 00017 00018 #define BPP 16 // Bits per pixel 00019 00020 00021 SPI_TFT::SPI_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, const char *name) 00022 : GraphicsDisplay(name), _spi(mosi, miso, sclk), _cs(cs) 00023 { 00024 char_x = 0; 00025 tft_reset(); 00026 set_orientation(0); 00027 backgroundimage = false; 00028 #ifndef NO_FLASH_BUFFER 00029 backgroundOrientation = 0; 00030 #endif 00031 } 00032 00033 int SPI_TFT::width() 00034 { 00035 if (orientation == 0 || orientation == 2) return 240; 00036 else return 320; 00037 } 00038 00039 int SPI_TFT::height() 00040 { 00041 if (orientation == 0 || orientation == 2) return 320; 00042 else return 240; 00043 } 00044 00045 void SPI_TFT::set_orientation(unsigned int o) 00046 { 00047 orientation = o; 00048 WindowMax(); 00049 } 00050 00051 void SPI_TFT::mod_orientation(void) 00052 { 00053 switch (orientation) { 00054 case 0: 00055 wr_reg(0x03, 0x10b0); // ID1 = 1, ID0 = 1, AM = 0 - Portrait 00056 break; 00057 case 1: 00058 wr_reg(0x03, 0x10a8); // ID1 = 1, ID0 = 0, AM = 0 - Landscape 00059 break; 00060 case 2: 00061 wr_reg(0x03, 0x1080); // ID1 = 0, ID0 = 0, AM = 1 - Portrait upside down 00062 break; 00063 case 3: 00064 wr_reg(0x03, 0x1098); // ID1 = 0, ID0 = 1, AM = 1 - Landscape upside down 00065 break; 00066 } 00067 } 00068 00069 void SPI_TFT::wr_cmd(unsigned char cmd) 00070 { 00071 _cs = 0; 00072 _spi.write(0x70); 00073 _spi.write(0x00); 00074 _spi.write(cmd); 00075 _cs = 1; 00076 } 00077 00078 void SPI_TFT::wr_dat(unsigned short dat) 00079 { 00080 unsigned char u,l; 00081 u = (dat >> 0x08); 00082 l = (dat & 0xff); 00083 _cs = 0; 00084 _spi.write(0x72); 00085 _spi.write(u); 00086 _spi.write(l); 00087 _cs = 1; 00088 } 00089 00090 void SPI_TFT::wr_dat_start(void) 00091 { 00092 _spi.write(0x72); 00093 } 00094 00095 unsigned short SPI_TFT::rd_dat(void) // IMPORTANT : SPI frequency needs to be lowered when reading 00096 { 00097 unsigned short val = 0; 00098 _cs = 0; 00099 _spi.frequency(SPI_F_LO); 00100 _spi.write(0x73); 00101 _spi.write(0x00); 00102 val = _spi.write(0x00); // Dummy read 00103 val = _spi.write(0x00); // Read D8..D15 00104 val <<= 8; 00105 val |= _spi.write(0x00); // Read D0..D7 00106 _cs = 1; 00107 _spi.frequency(SPI_F_HI); 00108 return (val); 00109 } 00110 00111 void SPI_TFT::wr_reg(unsigned char reg, unsigned short val) 00112 { 00113 wr_cmd(reg); 00114 wr_dat(val); 00115 } 00116 00117 unsigned short SPI_TFT::rd_reg(unsigned char reg) 00118 { 00119 wr_cmd(reg); 00120 return(rd_dat()); 00121 } 00122 00123 unsigned short SPI_TFT::Read_ID(void) // IMPORTANT : SPI frequency needs to be lowered when reading 00124 { 00125 unsigned short val = 0; 00126 _cs = 0; 00127 _spi.write(0x70); 00128 _spi.write(0x00); 00129 _spi.write(0x00); 00130 _cs = 1; 00131 _spi.frequency(SPI_F_LO); 00132 _cs = 0; 00133 _spi.write(0x73); 00134 val = _spi.write(0x00); // Dummy read 00135 val = _spi.write(0x00); // Read D8..D15 00136 val <<= 8; 00137 val |= _spi.write(0x00); // Read D0..D7 00138 _cs = 1; 00139 _spi.frequency(SPI_F_HI); 00140 return (val); 00141 } 00142 00143 void SPI_TFT::SetCursor( unsigned short Xpos, unsigned short Ypos ) 00144 { 00145 wr_reg(0x20, Xpos ); 00146 wr_reg(0x21, Ypos ); 00147 } 00148 00149 void SPI_TFT::tft_reset() 00150 { 00151 _spi.format(8,3); // 8 bit spi mode 3 00152 _spi.frequency(SPI_F_HI); // 48 Mhz SPI clock 00153 00154 wr_reg(0x00,0x0000); 00155 wr_reg(0x01,0x0100); // Driver Output Control 00156 wr_reg(0x02,0x0700); // LCD Driver Waveform Control 00157 wr_reg(0x03,0x1030); // Set the scan mode 00158 wr_reg(0x04,0x0000); // Scaling Control 00159 wr_reg(0x08,0x0202); // Display Control 2 00160 wr_reg(0x09,0x0000); // Display Control 3 00161 wr_reg(0x0a,0x0000); // Frame Cycle Contal 00162 wr_reg(0x0c,(1<<0)); // Extern Display Interface Control 1 00163 wr_reg(0x0d,0x0000); // Frame Maker Position 00164 wr_reg(0x0f,0x0000); // Extern Display Interface Control 2 00165 00166 wait_ms(50); 00167 00168 wr_reg(0x07,0x0101); // Display Control 00169 00170 wait_ms(50); 00171 00172 wr_reg(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); // Power Control 1 00173 wr_reg(0x11,0x0007); // Power Control 2 00174 wr_reg(0x12,(1<<8)|(1<<4)|(0<<0)); // Power Control 3 00175 wr_reg(0x13,0x0b00); // Power Control 4 00176 wr_reg(0x29,0x0000); // Power Control 7 00177 wr_reg(0x2b,(1<<14)|(1<<4)); 00178 00179 wr_reg(0x50,0); // Set X Start 00180 wr_reg(0x51,239); // Set X End 00181 wr_reg(0x52,0); // Set Y Start 00182 wr_reg(0x53,319); // Set Y End 00183 00184 wait_ms(50); 00185 00186 wr_reg(0x60,0x2700); // Driver Output Control 00187 wr_reg(0x61,0x0001); // Driver Output Control 00188 wr_reg(0x6a,0x0000); // Vertical Srcoll Control 00189 00190 wr_reg(0x80,0x0000); // Display Position Partial Display 1 00191 wr_reg(0x81,0x0000); // RAM Address Start Partial Display 1 00192 wr_reg(0x82,0x0000); // RAM Address End-Partial Display 1 00193 wr_reg(0x83,0x0000); // Displsy Position Partial Display 2 00194 wr_reg(0x84,0x0000); // RAM Address Start Partial Display 2 00195 wr_reg(0x85,0x0000); // RAM Address End Partial Display 2 00196 00197 wr_reg(0x90,(0<<7)|(16<<0)); // Frame Cycle Control 00198 wr_reg(0x92,0x0000); // Panel Interface Control 2 00199 wr_reg(0x93,0x0001); // Panel Interface Control 3 00200 wr_reg(0x95,0x0110); // Frame Cycle Control 00201 wr_reg(0x97,(0<<8)); 00202 wr_reg(0x98,0x0000); // Frame Cycle Control 00203 wr_reg(0x07,0x0133); 00204 00205 wait_ms(100); 00206 WindowMax(); 00207 } 00208 00209 00210 void SPI_TFT::pixel(int x, int y, int color) 00211 { 00212 switch (orientation) { 00213 case 0: 00214 wr_reg(0x20, x); 00215 wr_reg(0x21, y); 00216 break; 00217 case 1: 00218 wr_reg(0x20, 239-y); 00219 wr_reg(0x21, x); 00220 break; 00221 case 2: 00222 wr_reg(0x20, 239-x); 00223 wr_reg(0x21, 319-y); 00224 break; 00225 case 3: 00226 wr_reg(0x20, y); 00227 wr_reg(0x21, 319-x); 00228 break; 00229 } 00230 wr_cmd(0x22); 00231 wr_dat(color); 00232 } 00233 00234 00235 void SPI_TFT::window(int x, int y, int w, int h) 00236 { 00237 unsigned int xw1, yh1; 00238 xw1 = x + w - 1; 00239 yh1 = y + h - 1; 00240 wr_reg(0x20, x); 00241 wr_reg(0x21, y); 00242 switch (orientation) { 00243 case 0: 00244 wr_reg(0x50, x); 00245 wr_reg(0x51, xw1); 00246 wr_reg(0x52, y); 00247 wr_reg(0x53, yh1); 00248 break; 00249 case 1: 00250 wr_reg(0x50, 239 - yh1); 00251 wr_reg(0x51, 239 - y); 00252 wr_reg(0x52, x); 00253 wr_reg(0x53, xw1); 00254 break; 00255 case 2: 00256 wr_reg(0x50, 239 - xw1); 00257 wr_reg(0x51, 239 - x); 00258 wr_reg(0x52, 319 - yh1); 00259 wr_reg(0x53, 319 - y); 00260 break; 00261 case 3: 00262 wr_reg(0x50, y); 00263 wr_reg(0x51, yh1); 00264 wr_reg(0x52, 319 - xw1); 00265 wr_reg(0x53, 319 - x); 00266 break; 00267 } 00268 } 00269 00270 00271 void SPI_TFT::WindowMax(void) 00272 { 00273 window(0, 0, width(), height()); 00274 } 00275 00276 00277 void SPI_TFT::cls (void) 00278 { 00279 if (backgroundimage == false) { 00280 unsigned long int index=0; 00281 wr_reg(0x03, 0x1030); 00282 WindowMax(); 00283 SetCursor(0,0); 00284 wr_cmd(0x22); 00285 _cs = 0; 00286 wr_dat_start(); 00287 _spi.format(16,3); 00288 int num = width()*height(); 00289 00290 for( index = 0; index<num; index++ ) { 00291 _spi.fastWrite(_background); 00292 } 00293 _spi.clearRX(); 00294 00295 _spi.format(8,3); 00296 _cs = 1; 00297 } 00298 #ifndef NO_FLASH_BUFFER 00299 else { 00300 int _orientation=orientation; 00301 set_orientation(backgroundOrientation); 00302 Bitmap(0,0,width(),height(),(unsigned char*) sector_start_adress[ 25 ]); 00303 set_orientation(_orientation); 00304 } 00305 #endif 00306 } 00307 00308 void SPI_TFT::hline(int x0, int x1, int y, int color) 00309 { 00310 unsigned int index=0; 00311 int w; 00312 w = x1 - x0 + 1; 00313 mod_orientation(); 00314 window(x0,y,w,1); 00315 wr_cmd(0x22); 00316 _cs = 0; 00317 wr_dat_start(); 00318 00319 _spi.format(16,3); 00320 int num = x1-x0; 00321 for( index = 0; index<num; index++ ) { 00322 _spi.fastWrite(color); 00323 } 00324 _spi.clearRX(); 00325 00326 _spi.format(8,3); 00327 _cs = 1; 00328 return; 00329 } 00330 00331 void SPI_TFT::vline(int x, int y0, int y1, int color) 00332 { 00333 unsigned int index=0; 00334 int h; 00335 h = y1 - y0 + 1; 00336 mod_orientation(); 00337 window(x,y0,1,h); 00338 wr_cmd(0x22); 00339 _cs = 0; 00340 wr_dat_start(); 00341 _spi.format(16,3); 00342 int num = y1-y0; 00343 for( index = 0; index<num; index++ ) { 00344 _spi.fastWrite(color); 00345 } 00346 _spi.clearRX(); 00347 _spi.format(8,3); 00348 _cs = 1; 00349 return; 00350 } 00351 00352 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color) 00353 { 00354 wr_reg(0x03, 0x1030); 00355 WindowMax(); 00356 int dx = 0, dy = 0; 00357 int dx_sym = 0, dy_sym = 0; 00358 int dx_x2 = 0, dy_x2 = 0; 00359 int di = 0; 00360 00361 dx = x1-x0; 00362 dy = y1-y0; 00363 00364 if (dx == 0) { // vertical line 00365 if (y1 > y0) vline(x0,y0,y1,color); 00366 else vline(x0,y1,y0,color); 00367 return; 00368 } 00369 00370 if (dx > 0) { 00371 dx_sym = 1; 00372 } else { 00373 dx_sym = -1; 00374 } 00375 if (dy == 0) { // horizontal line 00376 if (x1 > x0) hline(x0,x1,y0,color); 00377 else hline(x1,x0,y0,color); 00378 return; 00379 } 00380 00381 if (dy > 0) { 00382 dy_sym = 1; 00383 } else { 00384 dy_sym = -1; 00385 } 00386 00387 dx = dx_sym*dx; 00388 dy = dy_sym*dy; 00389 00390 dx_x2 = dx*2; 00391 dy_x2 = dy*2; 00392 00393 if (dx >= dy) { 00394 di = dy_x2 - dx; 00395 while (x0 != x1) { 00396 00397 pixel(x0, y0, color); 00398 x0 += dx_sym; 00399 if (di<0) { 00400 di += dy_x2; 00401 } else { 00402 di += dy_x2 - dx_x2; 00403 y0 += dy_sym; 00404 } 00405 } 00406 pixel(x0, y0, color); 00407 } else { 00408 di = dx_x2 - dy; 00409 while (y0 != y1) { 00410 pixel(x0, y0, color); 00411 y0 += dy_sym; 00412 if (di < 0) { 00413 di += dx_x2; 00414 } else { 00415 di += dx_x2 - dy_x2; 00416 x0 += dx_sym; 00417 } 00418 } 00419 pixel(x0, y0, color); 00420 } 00421 return; 00422 } 00423 00424 00425 void SPI_TFT::rect(int x0, int y0, int w, int h, int color) 00426 { 00427 hline(x0,x0+w,y0,color); 00428 vline(x0,y0,y0+h,color); 00429 hline(x0,x0+w,y0+h,color); 00430 vline(x0+w,y0,y0+h,color); 00431 00432 return; 00433 } 00434 00435 void SPI_TFT::fillrect(int x0, int y0, int w, int h, int color) 00436 { 00437 unsigned long int index=0; 00438 if (w < 0) { 00439 x0 = x0 + w; 00440 w = -w; 00441 } 00442 if (h < 0) { 00443 y0 = y0 + h; 00444 h = -h; 00445 } 00446 mod_orientation(); 00447 window(x0,y0,w,h); 00448 wr_cmd(0x22); 00449 _cs = 0; 00450 wr_dat_start(); 00451 _spi.format(16,3); 00452 int num = h*w; 00453 for( index = 0; index<num; index++ ) { 00454 _spi.fastWrite(color); 00455 } 00456 _spi.clearRX(); 00457 _spi.format(8,3); 00458 _cs = 1; 00459 return; 00460 } 00461 00462 void SPI_TFT::draw_ellipse(int xc, int yc, int a, int b, unsigned int color) 00463 { 00464 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */ 00465 wr_reg(0x03, 0x1030); 00466 WindowMax(); 00467 int x = 0, y = b; 00468 long a2 = (long)a*a, b2 = (long)b*b; 00469 long crit1 = -(a2/4 + a%2 + b2); 00470 long crit2 = -(b2/4 + b%2 + a2); 00471 long crit3 = -(b2/4 + b%2); 00472 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4 00473 long dxt = 2*b2*x, dyt = -2*a2*y; 00474 long d2xt = 2*b2, d2yt = 2*a2; 00475 00476 while (y>=0 && x<=a) { 00477 pixel(xc+x, yc+y, color); 00478 if (x!=0 || y!=0) 00479 pixel(xc-x, yc-y, color); 00480 if (x!=0 && y!=0) { 00481 pixel(xc+x, yc-y, color); 00482 pixel(xc-x, yc+y, color); 00483 } 00484 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0 00485 t + a2*y <= crit3) // e(x+1/2,y) <= 0 00486 incx(); 00487 else if (t - a2*y > crit2) // e(x+1/2,y-1) > 0 00488 incy(); 00489 else { 00490 incx(); 00491 incy(); 00492 } 00493 } 00494 } 00495 00496 void SPI_TFT::fill_ellipse(int xc, int yc, int a, int b, unsigned int color) 00497 { 00498 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */ 00499 int x = 0, y = b; 00500 int rx = x, ry = y; 00501 unsigned int width = 1; 00502 unsigned int height = 1; 00503 long a2 = (long)a*a, b2 = (long)b*b; 00504 long crit1 = -(a2/4 + a%2 + b2); 00505 long crit2 = -(b2/4 + b%2 + a2); 00506 long crit3 = -(b2/4 + b%2); 00507 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4 00508 long dxt = 2*b2*x, dyt = -2*a2*y; 00509 long d2xt = 2*b2, d2yt = 2*a2; 00510 00511 if (b == 0) { 00512 fillrect(xc-a, yc, 2*a+1, 1, color); 00513 return; 00514 } 00515 00516 while (y>=0 && x<=a) { 00517 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0 00518 t + a2*y <= crit3) { // e(x+1/2,y) <= 0 00519 if (height == 1) 00520 ; // draw nothing 00521 else if (ry*2+1 > (height-1)*2) { 00522 fillrect(xc-rx, yc-ry, width, height-1, color); 00523 fillrect(xc-rx, yc+ry+1, width, 1-height, color); 00524 ry -= height-1; 00525 height = 1; 00526 } else { 00527 fillrect(xc-rx, yc-ry, width, ry*2+1, color); 00528 ry -= ry; 00529 height = 1; 00530 } 00531 incx(); 00532 rx++; 00533 width += 2; 00534 } else if (t - a2*y > crit2) { // e(x+1/2,y-1) > 0 00535 incy(); 00536 height++; 00537 } else { 00538 if (ry*2+1 > height*2) { 00539 fillrect(xc-rx, yc-ry, width, height, color); 00540 fillrect(xc-rx, yc+ry+1, width, -height, color); 00541 } else { 00542 fillrect(xc-rx, yc-ry, width, ry*2+1, color); 00543 } 00544 incx(); 00545 incy(); 00546 rx++; 00547 width += 2; 00548 ry -= height; 00549 height = 1; 00550 } 00551 } 00552 00553 if (ry > height) { 00554 fillrect(xc-rx, yc-ry, width, height, color); 00555 fillrect(xc-rx, yc+ry+1, width, -height, color); 00556 } else { 00557 fillrect(xc-rx, yc-ry, width, ry*2+1, color); 00558 } 00559 } 00560 00561 00562 void SPI_TFT::locate(int x, int y) 00563 { 00564 char_x = x; 00565 char_y = y; 00566 } 00567 00568 int SPI_TFT::columns() 00569 { 00570 return width() / font[1]; 00571 } 00572 00573 int SPI_TFT::rows() 00574 { 00575 return height() / font[2]; 00576 } 00577 00578 int SPI_TFT::_putc(int value) 00579 { 00580 if (value == '\n') { // new line 00581 char_x = 0; 00582 char_y = char_y + font[2]; 00583 if (char_y >= height() - font[2]) { 00584 char_y = 0; 00585 } 00586 } else { 00587 character(char_x, char_y, value); 00588 } 00589 return value; 00590 } 00591 00592 void SPI_TFT::character(int x, int y, int c) 00593 { 00594 unsigned int hor,vert,offset,bpl,j,i,b; 00595 unsigned char* bitmap_char; 00596 unsigned char z,w; 00597 00598 if ((c < 31) || (c > 127)) return; // test char range 00599 00600 // read font parameter from start of array 00601 offset = font[0]; // bytes / char 00602 hor = font[1]; // get hor size of font 00603 vert = font[2]; // get vert size of font 00604 bpl = font[3]; // bytes per line 00605 00606 if (char_x + hor > width()) { 00607 char_x = 0; 00608 char_y = char_y + vert; 00609 if (char_y >= height() - font[2]) { 00610 char_y = 0; 00611 } 00612 } 00613 mod_orientation(); 00614 00615 bitmap_char = &font[((c -32) * offset) + 4]; // start of char bitmap 00616 w = bitmap_char[0]; // width of actual char 00617 window(char_x, char_y,hor,vert); // char box 00618 wr_cmd(0x22); 00619 _cs = 0; 00620 wr_dat_start(); 00621 _spi.format(16,3); 00622 for (j=0; j<vert; j++) { // vert line 00623 for (i=0; i<hor; i++) { // horz line 00624 z = bitmap_char[bpl * i + ((j & 0xF8) >> 3)+1]; 00625 b = 1 << (j & 0x07); 00626 if (( z & b ) == 0x00) { 00627 #ifndef NO_FLASH_BUFFER 00628 if (backgroundimage==false) 00629 #endif 00630 _spi.fastWrite(_background); 00631 #ifndef NO_FLASH_BUFFER 00632 else 00633 { 00634 unsigned short *bitmap_ptr = (unsigned short *)sector_start_adress[ 25 ]; 00635 int angle = (orientation - backgroundOrientation)%4; //Get the difference in orientation between background and current 00636 switch (angle) { 00637 case 0: //Same orientation 00638 bitmap_ptr += width() * (height()-(y+j+1))+x+i; 00639 break; 00640 case 1: //Rotated 1 (don't ask me which direction) 00641 bitmap_ptr += height() * (width()-(x+i+1))+height()-(y+j + 1); 00642 break; 00643 case 2: //Upside down 00644 bitmap_ptr += width() * (y+j)+width() - (x+i + 1); 00645 break; 00646 case 3: //Rotated 3 00647 bitmap_ptr += height() * (x+i)+y+j; 00648 break; 00649 default: 00650 break; 00651 } 00652 00653 _spi.fastWrite(*bitmap_ptr); 00654 } 00655 #endif 00656 } else { 00657 _spi.fastWrite(_foreground); 00658 } 00659 } 00660 } 00661 _spi.clearRX(); 00662 _spi.format(8,3); 00663 _cs = 1; 00664 if ((w + 2) < hor) { // x offset to next char 00665 char_x += w + 2; 00666 } else char_x += hor; 00667 } 00668 00669 void SPI_TFT::set_font(unsigned char* f) 00670 { 00671 font = f; 00672 } 00673 00674 00675 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) 00676 { 00677 unsigned int i,j; 00678 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 00679 mod_orientation(); 00680 window(x, y, w, h); 00681 wr_cmd(0x22); 00682 _cs = 0; 00683 wr_dat_start(); 00684 _spi.format(16,3); 00685 bitmap_ptr += ((h - 1)*w); 00686 for (j = 0; j < h; j++) { //Lines 00687 for (i = 0; i < w; i++) { // copy pixel data to TFT 00688 _spi.fastWrite(*bitmap_ptr); // one line 00689 bitmap_ptr++; 00690 } 00691 bitmap_ptr -= 2*w; 00692 } 00693 _spi.clearRX(); 00694 _spi.format(8,3); 00695 _cs = 1; 00696 } 00697 00698 int SPI_TFT::Bitmap(unsigned int x, unsigned int y, const char *Name_BMP) 00699 { 00700 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 )) 00701 mod_orientation(); 00702 00703 bitmapData bmp = getBitmapData(Name_BMP); 00704 if (bmp.return_code != 1) 00705 return bmp.return_code; 00706 00707 00708 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line 00709 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short 00710 00711 00712 if ((bmp.height > height()+y) || (bmp.width > width()+x)) 00713 return -3; //Size mismatch 00714 00715 if (line == NULL) 00716 return(-4); // error no memory 00717 00718 00719 for (int j = bmp.height-1; j >= 0; j--) { //Lines bottom up 00720 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line 00721 fseek(bmp.file, off ,SEEK_SET); 00722 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow ! 00723 00724 //If 24 bit format, convert to 565 00725 if (bmp.bits == 24) { 00726 for (int i = 0; i<bmp.width; i++) { 00727 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]); 00728 } 00729 } 00730 00731 window(x, y+bmp.height - 1 - j,bmp.width ,1); 00732 wr_cmd(0x22); 00733 00734 _cs = 0; 00735 wr_dat_start(); 00736 _spi.format(16, 3); 00737 _spi.setFormat(); 00738 00739 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT 00740 _spi.fastWrite(line_short[i]); // one line 00741 } 00742 00743 _spi.clearRX(); 00744 _spi.format(8,3); 00745 _cs = 1; 00746 00747 } 00748 00749 00750 free (line); 00751 fclose(bmp.file); 00752 WindowMax(); 00753 00754 return(1); 00755 } 00756 00757 #ifndef NO_FLASH_BUFFER 00758 00759 int SPI_TFT::fileToFlash(const char *Name_BMP) 00760 { 00761 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 )) 00762 00763 mod_orientation(); 00764 00765 bitmapData bmp = getBitmapData(Name_BMP); 00766 if (bmp.return_code != 1) 00767 return bmp.return_code; 00768 00769 00770 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line 00771 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short 00772 00773 unsigned short *flashSector = (unsigned short *) malloc (256); //And one to send to flash 00774 00775 if ((bmp.height != height()) || (bmp.width != width())) 00776 return -3; //Size mismatch 00777 00778 if ((line == NULL) || (flashSector == NULL)) 00779 return(-4); // error no memory 00780 00781 00782 int flashPointer = 0, flashWrites = 0; 00783 00784 //Erase Flash that will be used: 00785 if ( iap.blank_check( 25, 29 ) == SECTOR_NOT_BLANK ) { 00786 iap.prepare( 25, 29 ); 00787 iap.erase( 25, 29 ); 00788 } 00789 00790 for (int j = 0; j < bmp.height; j++) { //Lines bottom up 00791 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line 00792 fseek(bmp.file, off ,SEEK_SET); 00793 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow ! 00794 00795 //If 24 bit format, do some processing 00796 if (bmp.bits == 24) { 00797 for (int i = 0; i<bmp.width; i++) { 00798 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]); 00799 } 00800 } 00801 00802 00803 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT 00804 flashSector[flashPointer] = line_short[i]; // one line 00805 flashPointer++; 00806 00807 //If flashpointer reached the end, write to flash 00808 if (flashPointer == 128) { 00809 iap.prepare( 25, 29 ); 00810 iap.write((char *)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256); 00811 flashPointer = 0; 00812 flashWrites++; 00813 if (flashWrites == 1000) 00814 error("Too many flashwrites"); 00815 } 00816 } 00817 } 00818 //write remaining data 00819 if (flashPointer!=0) { 00820 iap.prepare( 25, 29 ); 00821 iap.write((char*)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256); 00822 flashPointer = 0; 00823 flashWrites++; 00824 if (flashWrites == 1000) 00825 error("Too many flashwrites"); 00826 } 00827 00828 00829 00830 free (line); 00831 fclose(bmp.file); 00832 backgroundImage(true); 00833 backgroundOrientation = orientation; 00834 return(1); 00835 } 00836 00837 void SPI_TFT::backgroundImage( bool active) { 00838 backgroundimage = active; 00839 } 00840 #endif 00841 00842 00843 SPI_TFT::bitmapData SPI_TFT::getBitmapData(const char *Name_BMP){ 00844 #define OffsetPixelWidth 18 00845 #define OffsetPixelHeigh 22 00846 #define OffsetFileSize 34 00847 #define OffsetPixData 10 00848 #define OffsetBPP 28 00849 00850 00851 bitmapData retval; 00852 retval.return_code = 1; 00853 unsigned char BMP_Header[54]; 00854 00855 retval.file = fopen(Name_BMP, "rb"); // open the bmp file 00856 if (!retval.file) { 00857 retval.return_code = 0; 00858 return(retval); // error file not found ! 00859 } 00860 00861 fread(&BMP_Header[0],1,54,retval.file); // get the BMP Header 00862 00863 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 00864 fclose(retval.file); 00865 retval.return_code = -1; 00866 return(retval); // error not a BMP file 00867 } 00868 00869 int BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 00870 if (BPP_t == 0x0010) 00871 retval.bits = 16; 00872 else if (BPP_t == 0x0018) 00873 retval.bits = 24; 00874 else { 00875 fclose(retval.file); 00876 retval.return_code = -2; 00877 return(retval); // error no 16/24 bit BMP 00878 } 00879 00880 retval.height = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 00881 retval.width = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 00882 if (retval.height > height()|| retval.width > width()) { 00883 fclose(retval.file); 00884 retval.return_code = -3; 00885 return(retval); // too big 00886 } 00887 00888 00889 retval.start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 00890 00891 // the bmp lines are padded to multiple of 4 bytes 00892 retval.pad = -1; 00893 do { 00894 retval.pad ++; 00895 } while ((retval.width * retval.bits/8 + retval.pad)%4 != 0); 00896 return retval; 00897 00898 }
Generated on Tue Jul 12 2022 17:52:03 by 1.7.2