Scott Teal / Adafruit_ST7735

Fork of Adafruit_ST7735 by justin kim

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_ST7735.cpp Source File

Adafruit_ST7735.cpp

00001 /***************************************************
00002   This is a library for the Adafruit 1.8" SPI display.
00003   This library works with the Adafruit 1.8" TFT Breakout w/SD card
00004   ----> http://www.adafruit.com/products/358
00005   as well as Adafruit raw 1.8" TFT display
00006   ----> http://www.adafruit.com/products/618
00007 
00008   Check out the links above for our tutorials and wiring diagrams
00009   These displays use SPI to communicate, 4 or 5 pins are required to
00010   interface (RST is optional)
00011   Adafruit invests time and resources providing this open source code,
00012   please support Adafruit and open-source hardware by purchasing
00013   products from Adafruit!
00014 
00015   Written by Limor Fried/Ladyada for Adafruit Industries.
00016   MIT license, all text above must be included in any redistribution
00017  ****************************************************/
00018 
00019 #include "mbed.h"
00020 #include "Adafruit_ST7735.h"
00021 #include <stdio.h>
00022 
00023 // Constructor 
00024 Adafruit_ST7735::Adafruit_ST7735(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rs, PinName rst) 
00025         : lcdPort(mosi, miso, sck), _cs(cs), _rs(rs), _rst(rst), Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT) 
00026 { }
00027 
00028 Serial pc(USBTX, USBRX);
00029 
00030 void Adafruit_ST7735::writecommand(uint8_t c)
00031 {
00032     _rs = 0;
00033     _cs = 0;
00034     lcdPort.write( c );
00035     _cs = 1;
00036 }
00037 
00038 
00039 void Adafruit_ST7735::writedata(uint8_t c)
00040 {
00041     _rs = 1;
00042     _cs = 0;
00043     lcdPort.write( c );
00044 
00045     _cs = 1;
00046 }
00047 
00048 
00049 // Rather than a bazillion writecommand() and writedata() calls, screen
00050 // initialization commands and arguments are organized in these tables
00051 // stored in PROGMEM.  The table may look bulky, but that's mostly the
00052 // formatting -- storage-wise this is hundreds of bytes more compact
00053 // than the equivalent code.  Companion function follows.
00054 #define DELAY 0x80
00055 static unsigned char
00056 Bcmd[] = {                  // Initialization commands for 7735B screens
00057     18,                       // 18 commands in list:
00058     ST7735_SWRESET,   DELAY,  //  1: Software reset, no args, w/delay
00059     50,                     //     50 ms delay
00060     ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
00061     255,                    //     255 = 500 ms delay
00062     ST7735_COLMOD , 1+DELAY,  //  3: Set color mode, 1 arg + delay:
00063     0x05,                   //     16-bit color
00064     10,                     //     10 ms delay
00065     ST7735_FRMCTR1, 3+DELAY,  //  4: Frame rate control, 3 args + delay:
00066     0x00,                   //     fastest refresh
00067     0x06,                   //     6 lines front porch
00068     0x03,                   //     3 lines back porch
00069     10,                     //     10 ms delay
00070     ST7735_MADCTL , 1      ,  //  5: Memory access ctrl (directions), 1 arg:
00071     0x08,                   //     Row addr/col addr, bottom to top refresh
00072     ST7735_DISSET5, 2      ,  //  6: Display settings #5, 2 args, no delay:
00073     0x15,                   //     1 clk cycle nonoverlap, 2 cycle gate
00074     //     rise, 3 cycle osc equalize
00075     0x02,                   //     Fix on VTL
00076     ST7735_INVCTR , 1      ,  //  7: Display inversion control, 1 arg:
00077     0x0,                    //     Line inversion
00078     ST7735_PWCTR1 , 2+DELAY,  //  8: Power control, 2 args + delay:
00079     0x02,                   //     GVDD = 4.7V
00080     0x70,                   //     1.0uA
00081     10,                     //     10 ms delay
00082     ST7735_PWCTR2 , 1      ,  //  9: Power control, 1 arg, no delay:
00083     0x05,                   //     VGH = 14.7V, VGL = -7.35V
00084     ST7735_PWCTR3 , 2      ,  // 10: Power control, 2 args, no delay:
00085     0x01,                   //     Opamp current small
00086     0x02,                   //     Boost frequency
00087     ST7735_VMCTR1 , 2+DELAY,  // 11: Power control, 2 args + delay:
00088     0x3C,                   //     VCOMH = 4V
00089     0x38,                   //     VCOML = -1.1V
00090     10,                     //     10 ms delay
00091     ST7735_PWCTR6 , 2      ,  // 12: Power control, 2 args, no delay:
00092     0x11, 0x15,
00093     ST7735_GMCTRP1,16      ,  // 13: Magical unicorn dust, 16 args, no delay:
00094     0x09, 0x16, 0x09, 0x20, //     (seriously though, not sure what
00095     0x21, 0x1B, 0x13, 0x19, //      these config values represent)
00096     0x17, 0x15, 0x1E, 0x2B,
00097     0x04, 0x05, 0x02, 0x0E,
00098     ST7735_GMCTRN1,16+DELAY,  // 14: Sparkles and rainbows, 16 args + delay:
00099     0x0B, 0x14, 0x08, 0x1E, //     (ditto)
00100     0x22, 0x1D, 0x18, 0x1E,
00101     0x1B, 0x1A, 0x24, 0x2B,
00102     0x06, 0x06, 0x02, 0x0F,
00103     10,                     //     10 ms delay
00104     ST7735_CASET  , 4      ,  // 15: Column addr set, 4 args, no delay:
00105     0x00, 0x02,             //     XSTART = 2
00106     0x00, 0x81,             //     XEND = 129
00107     ST7735_RASET  , 4      ,  // 16: Row addr set, 4 args, no delay:
00108     0x00, 0x02,             //     XSTART = 1
00109     0x00, 0x81,             //     XEND = 160
00110     ST7735_NORON  ,   DELAY,  // 17: Normal display on, no args, w/delay
00111     10,                     //     10 ms delay
00112     ST7735_DISPON ,   DELAY,  // 18: Main screen turn on, no args, w/delay
00113     255
00114 },                  //     255 = 500 ms delay
00115 
00116 Rcmd1[] = {                 // Init for 7735R, part 1 (red or green tab)
00117     15,                       // 16 commands in list:
00118     ST7735_SWRESET,   DELAY,  //  1: Software reset, 0 args, w/delay
00119     150,                    //     150 ms delay
00120     ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, 0 args, w/delay
00121     255,                    //     500 ms delay
00122     ST7735_FRMCTR1, 3      ,  //  3: Frame rate ctrl - normal mode, 3 args:
00123     0x01, 0x2C, 0x2D,       //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
00124     ST7735_FRMCTR2, 3      ,  //  4: Frame rate control - idle mode, 3 args:
00125     0x01, 0x2C, 0x2D,       //     Rate = fosc/(1x2+40) * (LINE+2C+2D)
00126     ST7735_FRMCTR3, 6      ,  //  5: Frame rate ctrl - partial mode, 6 args:
00127     0x01, 0x2C, 0x2D,       //     Dot inversion mode
00128     0x01, 0x2C, 0x2D,       //     Line inversion mode
00129     ST7735_INVCTR , 1      ,  //  6: Display inversion ctrl, 1 arg, no delay:
00130     0x07,                   //     No inversion
00131     ST7735_PWCTR1 , 3      ,  //  7: Power control, 3 args, no delay:
00132     0xA2,
00133     0x02,                   //     -4.6V
00134     0x84,                   //     AUTO mode
00135     ST7735_PWCTR2 , 1      ,  //  8: Power control, 1 arg, no delay:
00136     0xC5,                   //     VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
00137     ST7735_PWCTR3 , 2      ,  //  9: Power control, 2 args, no delay:
00138     0x0A,                   //     Opamp current small
00139     0x00,                   //     Boost frequency
00140     ST7735_PWCTR4 , 2      ,  // 10: Power control, 2 args, no delay:
00141     0x8A,                   //     BCLK/2, Opamp current small & Medium low
00142     0x2A,
00143     ST7735_PWCTR5 , 2      ,  // 11: Power control, 2 args, no delay:
00144     0x8A, 0xEE,
00145     ST7735_VMCTR1 , 1      ,  // 12: Power control, 1 arg, no delay:
00146     0x0E,
00147     ST7735_INVOFF , 0      ,  // 13: Don't invert display, no args, no delay
00148     ST7735_MADCTL , 1      ,  // 14: Memory access control (directions), 1 arg:
00149     0xC0,                   //     row addr/col addr, bottom to top refresh
00150     ST7735_COLMOD , 1      ,  // 15: set color mode, 1 arg, no delay:
00151     0x05
00152 },                 //     16-bit color
00153 
00154 Scmd[] = {                  // Initialization commands for 7735S screens
00155     16,                       // 17 commands in list:
00156     ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
00157     120,                    //     255 = 500 ms delay
00158     ST7735_FRMCTR1, 3,      //  4: Frame rate control 1, 3 args
00159     0x05,                   //     fastest refresh
00160     0x3C,                   //     6 lines front porch
00161     0x3C,                   //     3 lines back porch
00162     ST7735_FRMCTR2, 3,
00163     0x05,
00164     0x3C,
00165     0x3C,
00166     ST7735_FRMCTR3, 6,
00167     0x05,
00168     0x3C,
00169     0x3C,
00170     0x05,
00171     0x3C,
00172     0x3C,
00173     ST7735_INVCTR , 1      ,  //  7: Display inversion control, 1 arg:
00174     0x03,                    //     Line inversion
00175     ST7735_PWCTR1 , 3,  //  8: Power control, 2 args + delay:
00176     0x28,                   //     GVDD = 4.7V
00177     0x08,                   //     1.0uA
00178     0x04,
00179     ST7735_PWCTR2 , 1      ,  //  9: Power control, 1 arg, no delay:
00180     0xC0,                   //     VGH = 14.7V, VGL = -7.35V
00181     ST7735_PWCTR3 , 2      ,  // 10: Power control, 2 args, no delay:
00182     0x0D,                   //     Opamp current small
00183     0x00,                   //     Boost frequency
00184     ST7735_PWCTR4, 2,
00185     0x8D,
00186     0x2A,
00187     ST7735_PWCTR5, 2,
00188     0x8D,
00189     0xEE,
00190     ST7735_VMCTR1 , 1,  // 11: Power control, 2 args + delay:
00191     0x1A,                   //     VCOMH = 4V
00192     ST7735_MADCTL , 1      ,  //  5: Memory access ctrl (directions), 1 arg:
00193     0xC0,                   //     Row addr/col addr, bottom to top refresh
00194     ST7735_GMCTRP1, 16,     // 13: Magical unicorn dust, 16 args, no delay:
00195     0x04, 0x22, 0x07, 0x0A, //     (seriously though, not sure what
00196     0x2E, 0x30, 0x25, 0x2A, //      these config values represent)
00197     0x28, 0x26, 0x2E, 0x3A,
00198     0x00, 0x01, 0x03, 0x13,
00199     ST7735_GMCTRN1, 16,     // 14: Sparkles and rainbows, 16 args + delay:
00200     0x04, 0x16, 0x06, 0x0D, //     (ditto)
00201     0x2D, 0x26, 0x23, 0x27,
00202     0x27, 0x25, 0x2D, 0x3B,
00203     0x00, 0x01, 0x04, 0x13,
00204     ST7735_COLMOD , 1,  //  3: Set color mode, 1 arg + delay:
00205     0x05,                   //     16-bit color
00206     ST7735_DISPON ,   DELAY,  // 18: Main screen turn on, no args, w/delay
00207     255
00208 },                  //     255 = 500 ms delay
00209 
00210 Rcmd2green[] = {            // Init for 7735R, part 2 (green tab only)
00211     2,                        //  2 commands in list:
00212     ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
00213     0x00, 0x02,             //     XSTART = 0
00214     0x00, 0x7F+0x02,        //     XEND = 127
00215     ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
00216     0x00, 0x01,             //     XSTART = 0
00217     0x00, 0x9F+0x01
00218 },      //     XEND = 159
00219 Rcmd2red[] = {              // Init for 7735R, part 2 (red tab only)
00220     2,                        //  2 commands in list:
00221     ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
00222     0x00, 0x00,             //     XSTART = 0
00223     0x00, 0x7F,             //     XEND = 127
00224     ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
00225     0x00, 0x00,             //     XSTART = 0
00226     0x00, 0x9F
00227 },           //     XEND = 159
00228 
00229 Rcmd3[] = {                 // Init for 7735R, part 3 (red or green tab)
00230     4,                        //  4 commands in list:
00231     ST7735_GMCTRP1, 16      , //  1: Magical unicorn dust, 16 args, no delay:
00232     0x02, 0x1c, 0x07, 0x12,
00233     0x37, 0x32, 0x29, 0x2d,
00234     0x29, 0x25, 0x2B, 0x39,
00235     0x00, 0x01, 0x03, 0x10,
00236     ST7735_GMCTRN1, 16      , //  2: Sparkles and rainbows, 16 args, no delay:
00237     0x03, 0x1d, 0x07, 0x06,
00238     0x2E, 0x2C, 0x29, 0x2D,
00239     0x2E, 0x2E, 0x37, 0x3F,
00240     0x00, 0x00, 0x02, 0x10,
00241     ST7735_NORON  ,    DELAY, //  3: Normal display on, no args, w/delay
00242     10,                     //     10 ms delay
00243     ST7735_DISPON ,    DELAY, //  4: Main screen turn on, no args w/delay
00244     100
00245 };                  //     100 ms delay
00246 
00247 
00248 // Companion code to the above tables.  Reads and issues
00249 // a series of LCD commands stored in byte array.
00250 void Adafruit_ST7735::commandList(uint8_t *addr)
00251 {
00252 
00253     uint8_t  numCommands, numArgs;
00254     uint16_t ms;
00255 
00256     numCommands = *addr++;   // Number of commands to follow
00257     while(numCommands--) {                 // For each command...
00258         writecommand(*addr++); //   Read, issue command
00259         numArgs  = *addr++;    //   Number of args to follow
00260         ms       = numArgs & DELAY;          //   If hibit set, delay follows args
00261         numArgs &= ~DELAY;                   //   Mask out delay bit
00262         while(numArgs--) {                   //   For each argument...
00263             writedata(*addr++);  //     Read, issue argument
00264         }
00265 
00266         if(ms) {
00267             ms = *addr++; // Read post-command delay time (ms)
00268             if(ms == 255) ms = 500;     // If 255, delay for 500 ms
00269             wait_ms(ms);
00270         }
00271     }
00272 }
00273 
00274 
00275 // Initialization code common to both 'B' and 'R' type displays
00276 void Adafruit_ST7735::commonInit(uint8_t *cmdList)
00277 {
00278 
00279     colstart  = rowstart = 0; // May be overridden in init func
00280 
00281     _rs = 1;
00282     _cs = 1;
00283 
00284     // use default SPI format
00285     lcdPort.format(8,0);
00286     lcdPort.frequency(4000000);     // Lets try 4MHz
00287 
00288     // toggle RST low to reset
00289     _cs = 1;
00290     _rst = 1;
00291     wait_ms(5);
00292     _rst = 0;
00293     wait_ms(5);
00294     _rst = 1;
00295     wait_ms(5);
00296     _cs = 1;
00297     wait_ms(5);
00298     _cs = 0;
00299 
00300     if(cmdList) commandList(cmdList);
00301 }
00302 
00303 
00304 // Initialization for ST7735B screens
00305 void Adafruit_ST7735::initB(void)
00306 {
00307     commonInit(Bcmd);
00308 }
00309 
00310 void Adafruit_ST7735::initS(void)
00311 {
00312     commonInit(Scmd);
00313 }
00314 
00315 // Initialization for ST7735R screens (green or red tabs)
00316 void Adafruit_ST7735::initR(uint8_t options)
00317 {
00318     commonInit(Rcmd1);
00319     if(options == INITR_GREENTAB) {
00320         commandList(Rcmd2green);
00321         colstart = 2;
00322         rowstart = 1;
00323     } else {
00324         // colstart, rowstart left at default '0' values
00325         commandList(Rcmd2red);
00326     }
00327     commandList(Rcmd3);
00328 }
00329 
00330 
00331 void Adafruit_ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1,
00332                                     uint8_t y1)
00333 {
00334 
00335     writecommand(ST7735_CASET); // Column addr set
00336     writedata(0x00);
00337     writedata(x0+colstart);     // XSTART
00338     writedata(0x00);
00339     writedata(x1+colstart);     // XEND
00340 
00341     writecommand(ST7735_RASET); // Row addr set
00342     writedata(0x00);
00343     writedata(y0+rowstart);     // YSTART
00344     writedata(0x00);
00345     writedata(y1+rowstart);     // YEND
00346 
00347     writecommand(ST7735_RAMWR); // write to RAM
00348 }
00349 
00350 void Adafruit_ST7735::fillScreen(uint16_t color)
00351 {
00352 
00353     uint8_t x, y, hi = color >> 8, lo = color;
00354 
00355     setAddrWindow(0, 0, _width-1, _height-1);
00356 
00357     _rs = 1;
00358     _cs = 0;
00359 
00360     for(y=_height; y>0; y--) {
00361         for(x=_width; x>0; x--) {
00362             lcdPort.write( hi );
00363             lcdPort.write( lo );
00364         }
00365     }
00366 
00367     _cs = 1;
00368 }
00369 
00370 
00371 void Adafruit_ST7735::pushColor(uint16_t color)
00372 {
00373     _rs = 1;
00374     _cs = 0;
00375 
00376     lcdPort.write( color >> 8 );
00377     lcdPort.write( color );
00378     _cs = 1;
00379 }
00380 
00381 void Adafruit_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color)
00382 {
00383 
00384     if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
00385 
00386     setAddrWindow(x,y,x+1,y+1);
00387 
00388     _rs = 1;
00389     _cs = 0;
00390     
00391     lcdPort.write( color >> 8 );
00392     lcdPort.write( color );
00393 
00394     _cs = 1;
00395 }
00396 
00397 void Adafruit_ST7735::drawFastVLine(int16_t x, int16_t y, int16_t h,
00398                                     uint16_t color)
00399 {
00400 
00401     // Rudimentary clipping
00402     if((x >= _width) || (y >= _height)) return;
00403     if((y+h-1) >= _height) h = _height-y;
00404     setAddrWindow(x, y, x, y+h-1);
00405 
00406     uint8_t hi = color >> 8, lo = color;
00407     _rs = 1;
00408     _cs = 0;
00409     while (h--) {
00410         lcdPort.write( hi );
00411         lcdPort.write( lo );
00412     }
00413     _cs = 1;
00414 }
00415 
00416 
00417 void Adafruit_ST7735::drawFastHLine(int16_t x, int16_t y, int16_t w,
00418                                     uint16_t color)
00419 {
00420 
00421     // Rudimentary clipping
00422     if((x >= _width) || (y >= _height)) return;
00423     if((x+w-1) >= _width)  w = _width-x;
00424     setAddrWindow(x, y, x+w-1, y);
00425 
00426     uint8_t hi = color >> 8, lo = color;
00427     _rs = 1;
00428     _cs = 0;
00429     while (w--) {
00430         lcdPort.write( hi );
00431         lcdPort.write( lo );
00432     }
00433     _cs = 1;
00434 }
00435 
00436 
00437 // fill a rectangle
00438 void Adafruit_ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
00439                                uint16_t color)
00440 {
00441 
00442     // rudimentary clipping (drawChar w/big text requires this)
00443     if((x >= _width) || (y >= _height)) return;
00444     if((x + w - 1) >= _width)  w = _width  - x;
00445     if((y + h - 1) >= _height) h = _height - y;
00446 
00447     setAddrWindow(x, y, x+w-1, y+h-1);
00448 
00449     uint8_t hi = color >> 8, lo = color;
00450     _rs = 1;
00451     _cs = 0;
00452     for(y=h; y>0; y--) {
00453         for(x=w; x>0; x--) {
00454             lcdPort.write( hi );
00455             lcdPort.write( lo );
00456         }
00457     }
00458 
00459     _cs = 1;
00460 }
00461 
00462 
00463 // Pass 8-bit (each) R,G,B, get back 16-bit packed color
00464 uint16_t Adafruit_ST7735::Color565(uint8_t r, uint8_t g, uint8_t b)
00465 {
00466     return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
00467 }
00468 
00469 
00470 #define MADCTL_MY  0x80
00471 #define MADCTL_MX  0x40
00472 #define MADCTL_MV  0x20
00473 #define MADCTL_ML  0x10
00474 #define MADCTL_RGB 0x00
00475 #define MADCTL_MH  0x04
00476 
00477 void Adafruit_ST7735::setRotation(uint8_t m)
00478 {
00479 
00480     writecommand(ST7735_MADCTL);
00481     rotation = m % 4; // can't be higher than 3
00482     switch (rotation) {
00483         case 0:
00484             writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB);
00485             _width  = ST7735_TFTWIDTH;
00486             _height = ST7735_TFTHEIGHT;
00487             break;
00488         case 1:
00489             writedata(MADCTL_MY | MADCTL_MV | MADCTL_RGB);
00490             _width  = ST7735_TFTHEIGHT;
00491             _height = ST7735_TFTWIDTH;
00492             break;
00493         case 2:
00494             writedata(MADCTL_RGB);
00495             _width  = ST7735_TFTWIDTH;
00496             _height = ST7735_TFTHEIGHT;
00497             break;
00498         case 3:
00499             writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB);
00500             _width  = ST7735_TFTHEIGHT;
00501             _height = ST7735_TFTWIDTH;
00502             break;
00503     }
00504 }
00505 
00506 void Adafruit_ST7735::invertDisplay(bool i)
00507 {
00508     writecommand(i ? ST7735_INVON : ST7735_INVOFF);
00509 }
00510 
00511 // BMP File Constants
00512 #define OffsetPixelWidth    18
00513 #define OffsetPixelHeigh    22
00514 #define OffsetFileSize      34
00515 #define OffsetPixData       10
00516 #define OffsetBPP           28
00517 #define RGB(r,g,b)  (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue
00518 #define TFT_DEBUG
00519 
00520 int Adafruit_ST7735::DrawBitmapFile(const char *Name_BMP)
00521 {
00522     return DrawBitmapFile(0,0,Name_BMP);
00523 }
00524 
00525 int Adafruit_ST7735::DrawBitmapFile(unsigned int x, unsigned int y, const char *Name_BMP)
00526 {
00527    
00528     char img[3*240];
00529     uint32_t imgsize = 0;
00530     uint32_t offset = 0;
00531     uint32_t imgw = 0;
00532     uint32_t imgh = 0;
00533     char colbits;
00534     uint16_t col;
00535 
00536     int i, j;
00537     
00538     char filename[50];
00539     i=0;
00540     while (*Name_BMP!='\0') {
00541         filename[i++]=*Name_BMP++;
00542     }
00543     filename[i] = 0;  
00544     
00545     FILE *Image = fopen((const char *)&filename[0], "rb");  // open the bmp file
00546 
00547     if(Image == NULL) return -1;
00548     if(fgetc(Image) != 0x42) return -2;
00549     if(fgetc(Image) != 0x4D) return -2;
00550 
00551     for(i = 0; i < 4; i++)
00552     {
00553         imgsize += (((uint32_t)fgetc(Image)) << i*8);
00554     }
00555     fseek(Image,4,SEEK_CUR);
00556     for(i = 0; i < 4; i++)
00557     {
00558         offset += (((uint32_t)fgetc(Image)) << i*8);
00559     }
00560     fseek(Image,4,SEEK_CUR);
00561     for(i = 0; i < 4; i++)
00562     {
00563         imgw += (((uint32_t)fgetc(Image)) << i*8);
00564     }
00565     if(imgw > ST7735_TFTHEIGHT) return -3;
00566     
00567     for(i = 0; i < 4; i++)
00568     {
00569         imgh += (((uint32_t)fgetc(Image)) << i*8);
00570     }
00571     if(imgh > ST7735_TFTWIDTH) return -3;
00572     
00573     fseek(Image,2,SEEK_CUR);
00574     colbits = fgetc(Image);
00575     fgetc(Image);
00576     if(fgetc(Image) != 0) // Check for compression
00577     {
00578         return -4;    
00579     }
00580    
00581     fseek(Image, offset, SEEK_SET);
00582     for (j = imgh; j >= 0; j--)        //Lines
00583     {  
00584         fread(img,sizeof(char),imgw*3,Image);
00585         _cs = 1;
00586         setAddrWindow(x, y+j, x+imgw, y+j+1);
00587         writecommand(0x2C);  // send pixel
00588         _rs = 1;
00589         _cs = 0;
00590         for(i = 0; i < imgw; i++)
00591         {
00592             col = RGB((uint16_t)img[3*i+2],(uint16_t)img[3*i+1], (uint16_t)img[3*i]);
00593             lcdPort.write( col >> 8 );
00594             lcdPort.write( col );
00595         }
00596         _cs = 1;
00597     }
00598     setAddrWindow(0,0,_width,_height);
00599     
00600     return 0;
00601 }