Simple clock program for LPC1768 Mini-DK

Dependencies:   RTC mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_TFT.cpp Source File

SPI_TFT.cpp

00001 /* mbed library for 240*320 pixel TFT with ILI9320 LCD Controller
00002  * Rewrite from Peter Drescher code - http://mbed.org/cookbook/SPI-driven-QVGA-TFT
00003  *
00004  * TODO : BMP routine
00005  */
00006 
00007 
00008 
00009 #include "SPI_TFT.h"
00010 #include "mbed.h"
00011 
00012 
00013 #define BPP         16                  // Bits per pixel
00014 
00015 
00016 SPI_TFT::SPI_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, const char *name)
00017     : GraphicsDisplay(name), _spi(mosi, miso, sclk), _cs(cs), _reset(reset)
00018 {
00019     char_x = 0;
00020     tft_reset();
00021     set_orientation(0);
00022 }
00023 
00024 int SPI_TFT::width()
00025 {
00026     if (orientation == 0 || orientation == 2) return 240;
00027     else return 320;
00028 }
00029 
00030 int SPI_TFT::height()
00031 {
00032     if (orientation == 0 || orientation == 2) return 320;
00033     else return 240;
00034 }
00035 
00036 //
00037 void SPI_TFT::set_orientation(unsigned int o)
00038 {
00039     orientation = o;
00040     WindowMax();
00041 }
00042 
00043 // ILI9320
00044 // Orientation is only set before a window command (registers 0x50..0x53)
00045 // reg 03h (Entry Mode) : BGR = 1 - ORG = 1 - ID0, ID1 and AM are set according to the orientation variable.
00046 // IMPORTANT : when ORG = 1, the GRAM writing direction follows the orientation (ID0, ID1, AM bits)
00047 //             AND we need to use the window command (reg 50h..53h) to write to an area on the display
00048 //             because we cannot change reg 20h and 21h to set the GRAM address (they both remain at 00h).
00049 //             This means that the pixel routine does not work when ORG = 1.
00050 //             Routines relying on the pixel routine first need to set reg 03h = 0x1030
00051 //             (cls, circle and line do so) AND need to write the data according to the orientation variable.
00052 
00053 void SPI_TFT::mod_orientation(void)
00054 {
00055     switch (orientation)
00056     {
00057         case 0:
00058             wr_reg(0x03, 0x10b0);        // ID1 = 1, ID0 = 1, AM = 0 - Portrait
00059             break;
00060         case 1:
00061             wr_reg(0x03, 0x10a8);        // ID1 = 1, ID0 = 0, AM = 0 - Landscape
00062             break;
00063         case 2:
00064             wr_reg(0x03, 0x1080);        // ID1 = 0, ID0 = 0, AM = 1 - Portrait upside down
00065             break;
00066         case 3:
00067             wr_reg(0x03, 0x1098);        // ID1 = 0, ID0 = 1, AM = 1 - Landscape upside down
00068             break;
00069     }
00070 }
00071 
00072 void SPI_TFT::wr_cmd(unsigned char cmd)
00073 {
00074     _cs = 0;
00075     _spi.write(0x70);
00076     _spi.write(0x00);
00077     _spi.write(cmd);
00078     _cs = 1;
00079 }
00080 
00081 void SPI_TFT::wr_dat(unsigned short dat)
00082 {
00083     unsigned char u,l;
00084     u = (dat >> 0x08);
00085     l = (dat & 0xff);
00086     _cs = 0;
00087     _spi.write(0x72);
00088     _spi.write(u);
00089     _spi.write(l);
00090     _cs = 1;
00091 }
00092 
00093 void SPI_TFT::wr_dat_start(void)
00094 {
00095     _spi.write(0x72);
00096 }
00097 
00098 void SPI_TFT::wr_dat_only(unsigned short dat)
00099 {
00100     unsigned char u,l;
00101     u = (dat >> 0x08);
00102     l = (dat & 0xff);
00103     _spi.write(u);
00104     _spi.write(l);
00105 }
00106 
00107 unsigned short SPI_TFT::rd_dat(void)              // SPI frequency needs to be lowered on read
00108 {
00109     unsigned short val = 0;
00110     _cs = 0;
00111     _spi.frequency(SPI_F_LO);
00112     _spi.write(0x73);
00113     _spi.write(0x00);
00114     val = _spi.write(0);                          // Dummy read
00115     val = _spi.write(0);                          // Read D8..D15
00116     val <<= 8;
00117     val |= _spi.write(0);                         // Read D0..D7
00118     _cs = 1;
00119     _spi.frequency(SPI_F_HI);
00120     return (val);
00121 }
00122 
00123 void SPI_TFT::wr_reg(unsigned char reg, unsigned short val)
00124 {
00125     wr_cmd(reg);
00126     wr_dat(val);
00127 }
00128 
00129 unsigned short SPI_TFT::rd_reg(unsigned char reg)
00130 {
00131     wr_cmd(reg);
00132     return(rd_dat());
00133 }
00134 
00135 unsigned short SPI_TFT::Read_ID(void)             // IMPORTANT : SPI frequency needs to be lowered when reading
00136 {
00137     unsigned short val = 0;
00138     _cs = 0;
00139     _spi.write(0x70);
00140     _spi.write(0x00);
00141     _spi.write(0X00);
00142     _cs = 1;
00143     _spi.frequency(SPI_F_LO);
00144     _cs = 0;
00145     _spi.write(0x73);
00146     val = _spi.write(0x00);                       // Dummy read
00147     val = _spi.write(0x00);                       // Read D8..D15
00148     val <<= 8;
00149     val |= _spi.write(0x00);                      // Read D0..D7
00150     _cs = 1;
00151     _spi.frequency(SPI_F_HI);
00152     return (val);
00153 }
00154 
00155 void SPI_TFT::SetCursor( unsigned short Xpos, unsigned short Ypos )
00156 {
00157     wr_reg(0x20, Xpos );
00158     wr_reg(0x21, Ypos );
00159 }
00160 
00161 void SPI_TFT::tft_reset()
00162 {
00163     _spi.format(8,3);                    // 8 bit spi mode 3
00164     _spi.frequency(SPI_F_HI);            // 48 Mhz SPI clock
00165 
00166     wr_reg(0x00,0x0000);
00167     wr_reg(0x01,0x0100); // Driver Output Control
00168     wr_reg(0x02,0x0700); // LCD Driver Waveform Control
00169     wr_reg(0x03,0x1030); // Set the scan mode
00170     wr_reg(0x04,0x0000); // Scaling Control
00171     wr_reg(0x08,0x0202); // Display Control 2
00172     wr_reg(0x09,0x0000); // Display Control 3
00173     wr_reg(0x0a,0x0000); // Frame Cycle Contal
00174     wr_reg(0x0c,(1<<0)); // Extern Display Interface Control 1
00175     wr_reg(0x0d,0x0000); // Frame Maker Position
00176     wr_reg(0x0f,0x0000); // Extern Display Interface Control 2
00177 
00178     wait_ms(50);
00179 
00180     wr_reg(0x07,0x0101); // Display Control
00181 
00182     wait_ms(50);
00183 
00184     wr_reg(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); // Power Control 1
00185     wr_reg(0x11,0x0007);                              // Power Control 2
00186     wr_reg(0x12,(1<<8)|(1<<4)|(0<<0));                // Power Control 3
00187     wr_reg(0x13,0x0b00);                              // Power Control 4
00188     wr_reg(0x29,0x0000);                              // Power Control 7
00189     wr_reg(0x2b,(1<<14)|(1<<4));
00190 
00191     wr_reg(0x50,0);      // Set X Start
00192     wr_reg(0x51,239);    // Set X End
00193     wr_reg(0x52,0);      // Set Y Start
00194     wr_reg(0x53,319);    // Set Y End
00195 
00196     wait_ms(50);
00197 
00198     wr_reg(0x60,0x2700); // Driver Output Control
00199     wr_reg(0x61,0x0001); // Driver Output Control
00200     wr_reg(0x6a,0x0000); // Vertical Srcoll Control
00201 
00202     wr_reg(0x80,0x0000); // Display Position Partial Display 1
00203     wr_reg(0x81,0x0000); // RAM Address Start Partial Display 1
00204     wr_reg(0x82,0x0000); // RAM Address End-Partial Display 1
00205     wr_reg(0x83,0x0000); // Displsy Position Partial Display 2
00206     wr_reg(0x84,0x0000); // RAM Address Start Partial Display 2
00207     wr_reg(0x85,0x0000); // RAM Address End Partial Display 2
00208 
00209     wr_reg(0x90,(0<<7)|(16<<0)); // Frame Cycle Control
00210     wr_reg(0x92,0x0000);         // Panel Interface Control 2
00211     wr_reg(0x93,0x0001);         // Panel Interface Control 3
00212     wr_reg(0x95,0x0110);         // Frame Cycle Control
00213     wr_reg(0x97,(0<<8));
00214     wr_reg(0x98,0x0000);         // Frame Cycle Control
00215     wr_reg(0x07,0x0133);
00216 
00217     wait_ms(100);
00218     WindowMax();
00219 }
00220 
00221 
00222 void SPI_TFT::pixel(int x, int y, int color)
00223 {
00224     switch (orientation)
00225     {
00226         case 0:
00227             wr_reg(0x20, x);
00228             wr_reg(0x21, y);
00229             break;
00230         case 1:
00231             wr_reg(0x20, 239-y);
00232             wr_reg(0x21, x);
00233             break;
00234         case 2:
00235             wr_reg(0x20, 239-x);
00236             wr_reg(0x21, 319-y);
00237             break;
00238         case 3:
00239             wr_reg(0x20, y);
00240             wr_reg(0x21, 319-x);
00241             break;
00242     }
00243     wr_cmd(0x22);
00244     wr_dat(color);
00245 }
00246 
00247 
00248 void SPI_TFT::window(int x, int y, int w, int h)
00249 {
00250     unsigned int xw1, yh1;
00251     xw1 = x + w - 1;
00252     yh1 = y + h - 1;
00253     wr_reg(0x20, x);
00254     wr_reg(0x21, y);
00255     switch (orientation)
00256     {
00257         case 0:
00258             wr_reg(0x50, x);
00259             wr_reg(0x51, xw1);
00260             wr_reg(0x52, y);
00261             wr_reg(0x53, yh1);
00262             break;
00263         case 1:
00264             wr_reg(0x50, 239 - yh1);
00265             wr_reg(0x51, 239 - y);
00266             wr_reg(0x52, x);
00267             wr_reg(0x53, xw1);
00268             break;
00269         case 2:
00270             wr_reg(0x50, 239 - xw1);
00271             wr_reg(0x51, 239 - x);
00272             wr_reg(0x52, 319 - yh1);
00273             wr_reg(0x53, 319 - y);
00274             break;
00275         case 3:
00276             wr_reg(0x50, y);
00277             wr_reg(0x51, yh1);
00278             wr_reg(0x52, 319 - xw1);
00279             wr_reg(0x53, 319 - x);
00280             break;
00281     }
00282 }
00283 
00284 
00285 void SPI_TFT::WindowMax(void)
00286 {
00287     window(0, 0, width(),  height());
00288 }
00289 
00290 
00291 void SPI_TFT::cls (void)
00292 {
00293     unsigned long int index=0;
00294     wr_reg(0x03, 0x1030);
00295     WindowMax();
00296     SetCursor(0,0);
00297     wr_cmd(0x22);
00298      _cs = 0;
00299      wr_dat_start();
00300      
00301      _spi.format(16,3);
00302      unsigned short dat = _background;
00303      
00304      for( index = 0; index<width()*height(); index++ )
00305      {
00306         _spi.write(dat);
00307      }
00308      
00309      _spi.format(8,3);
00310      
00311     /*for( index = 0; index < width() * height(); index++ )
00312     {
00313         wr_dat_only(color);
00314     }*/
00315     _cs = 1;
00316 }
00317 
00318 void SPI_TFT::hline(int x0, int x1, int y, int color)
00319 {
00320     unsigned int index=0;
00321     int w;
00322     w = x1 - x0 + 1;
00323     mod_orientation();
00324     window(x0,y,w,1);
00325     wr_cmd(0x22);
00326      _cs = 0;
00327      wr_dat_start();
00328     for( index = 0; index < (x1 - x0); index++ )
00329     {
00330         wr_dat_only(color);
00331     }
00332     _cs = 1;
00333     return;
00334 }
00335 
00336 void SPI_TFT::vline(int x, int y0, int y1, int color)
00337 {
00338     unsigned int index=0;
00339     int h;
00340     h = y1 - y0 + 1;
00341     mod_orientation();
00342     window(x,y0,1,h);
00343     wr_cmd(0x22);
00344      _cs = 0;
00345      wr_dat_start();
00346     for( index = 0; index < (y1 - y0); index++ )
00347     {
00348         wr_dat_only(color);
00349     }
00350     _cs = 1;
00351     return;
00352 }
00353 
00354 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color)
00355 {
00356     wr_reg(0x03, 0x1030);
00357     WindowMax();
00358     int   dx = 0, dy = 0;
00359     int   dx_sym = 0, dy_sym = 0;
00360     int   dx_x2 = 0, dy_x2 = 0;
00361     int   di = 0;
00362 
00363     dx = x1-x0;
00364     dy = y1-y0;
00365 
00366     if (dx == 0) {        /* vertical line */
00367         if (y1 > y0) vline(x0,y0,y1,color);
00368         else vline(x0,y1,y0,color);
00369         return;
00370     }
00371 
00372     if (dx > 0) {
00373         dx_sym = 1;
00374     } else {
00375         dx_sym = -1;
00376     }
00377     if (dy == 0) {        /* horizontal line */
00378         if (x1 > x0) hline(x0,x1,y0,color);
00379         else  hline(x1,x0,y0,color);
00380         return;
00381     }
00382 
00383     if (dy > 0) {
00384         dy_sym = 1;
00385     } else {
00386         dy_sym = -1;
00387     }
00388 
00389     dx = dx_sym*dx;
00390     dy = dy_sym*dy;
00391 
00392     dx_x2 = dx*2;
00393     dy_x2 = dy*2;
00394 
00395     if (dx >= dy) {
00396         di = dy_x2 - dx;
00397         while (x0 != x1) {
00398 
00399             pixel(x0, y0, color);
00400             x0 += dx_sym;
00401             if (di<0) {
00402                 di += dy_x2;
00403             } else {
00404                 di += dy_x2 - dx_x2;
00405                 y0 += dy_sym;
00406             }
00407         }
00408         pixel(x0, y0, color);
00409     } else {
00410         di = dx_x2 - dy;
00411         while (y0 != y1) {
00412             pixel(x0, y0, color);
00413             y0 += dy_sym;
00414             if (di < 0) {
00415                 di += dx_x2;
00416             } else {
00417                 di += dx_x2 - dy_x2;
00418                 x0 += dx_sym;
00419             }
00420         }
00421         pixel(x0, y0, color);
00422     }
00423     return;
00424 }
00425 
00426 
00427 void SPI_TFT::rect(int x0, int y0, int w, int h, int color)
00428 {
00429     hline(x0,x0+w,y0,color);
00430     vline(x0,y0,y0+h,color);
00431     hline(x0,x0+w,y0+h,color);
00432     vline(x0+w,y0,y0+h,color);
00433 
00434     return;
00435 }
00436 
00437 void SPI_TFT::fillrect(int x0, int y0, int w, int h, int color)
00438 {
00439     unsigned long int index=0;
00440     if (w < 0)
00441     {
00442         x0 = x0 + w;
00443         w = -w;
00444     }
00445     if (h < 0)
00446     {
00447         y0 = y0 + h;
00448         h = -h;
00449     }
00450     mod_orientation();
00451     window(x0,y0,w,h);
00452     wr_cmd(0x22);
00453     _cs = 0;
00454     wr_dat_start();
00455 
00456     for( index = 0; index < h * w; index++ )
00457     {
00458         wr_dat_only(color);
00459     }
00460     _cs = 1;
00461     return;
00462 }
00463 
00464 void SPI_TFT::draw_ellipse(int xc, int yc, int a, int b, unsigned int color)
00465 {           /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
00466     wr_reg(0x03, 0x1030);
00467     WindowMax();
00468     int x = 0, y = b;
00469     long a2 = (long)a*a, b2 = (long)b*b;
00470     long crit1 = -(a2/4 + a%2 + b2);
00471     long crit2 = -(b2/4 + b%2 + a2);
00472     long crit3 = -(b2/4 + b%2);
00473     long t = -a2*y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
00474     long dxt = 2*b2*x, dyt = -2*a2*y;
00475     long d2xt = 2*b2, d2yt = 2*a2;
00476 
00477     while (y>=0 && x<=a)
00478     {
00479         pixel(xc+x, yc+y, color);
00480         if (x!=0 || y!=0)
00481             pixel(xc-x, yc-y, color);
00482         if (x!=0 && y!=0)
00483         {
00484             pixel(xc+x, yc-y, color);
00485             pixel(xc-x, yc+y, color);
00486         }
00487         if (t + b2*x <= crit1 ||   /* e(x+1,y-1/2) <= 0 */
00488             t + a2*y <= crit3)     /* e(x+1/2,y) <= 0 */
00489             incx();
00490         else if (t - a2*y > crit2) /* e(x+1/2,y-1) > 0 */
00491             incy();
00492         else
00493         {
00494             incx();
00495             incy();
00496         }
00497     }
00498 }
00499 
00500 void SPI_TFT::fill_ellipse(int xc, int yc, int a, int b, unsigned int color)
00501 {           /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
00502     int x = 0, y = b;
00503     int rx = x, ry = y;
00504     unsigned int width = 1;
00505     unsigned int height = 1;
00506     long a2 = (long)a*a, b2 = (long)b*b;
00507     long crit1 = -(a2/4 + a%2 + b2);
00508     long crit2 = -(b2/4 + b%2 + a2);
00509     long crit3 = -(b2/4 + b%2);
00510     long t = -a2*y; /* e(x+1/2,y-1/2) - (a^2+b^2)/4 */
00511     long dxt = 2*b2*x, dyt = -2*a2*y;
00512     long d2xt = 2*b2, d2yt = 2*a2;
00513 
00514     if (b == 0)
00515     {
00516         fillrect(xc-a, yc, 2*a+1, 1, color);
00517         return;
00518     }
00519 
00520     while (y>=0 && x<=a)
00521     {
00522         if (t + b2*x <= crit1 ||    /* e(x+1,y-1/2) <= 0 */
00523             t + a2*y <= crit3)      /* e(x+1/2,y) <= 0 */
00524         {
00525             if (height == 1)
00526                 ; /* draw nothing */
00527             else if (ry*2+1 > (height-1)*2)
00528             {
00529                 fillrect(xc-rx, yc-ry, width, height-1, color);
00530                 fillrect(xc-rx, yc+ry+1, width, 1-height, color);
00531                 ry -= height-1;
00532                 height = 1;
00533             }
00534             else
00535             {
00536                 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
00537                 ry -= ry;
00538                 height = 1;
00539             }
00540             incx();
00541             rx++;
00542             width += 2;
00543         }
00544         else if (t - a2*y > crit2)      /* e(x+1/2,y-1) > 0 */
00545         {
00546             incy();
00547             height++;
00548         }
00549         else
00550         {
00551             if (ry*2+1 > height*2)
00552             {
00553                 fillrect(xc-rx, yc-ry, width, height, color);
00554                 fillrect(xc-rx, yc+ry+1, width, -height, color);
00555             }
00556             else
00557             {
00558                 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
00559             }
00560             incx();
00561             incy();
00562             rx++;
00563             width += 2;
00564             ry -= height;
00565             height = 1;
00566         }
00567     }
00568 
00569     if (ry > height)
00570     {
00571         fillrect(xc-rx, yc-ry, width, height, color);
00572         fillrect(xc-rx, yc+ry+1, width, -height, color);
00573     }
00574     else
00575     {
00576         fillrect(xc-rx, yc-ry, width, ry*2+1, color);
00577     }
00578 }
00579 
00580 
00581 void SPI_TFT::locate(int x, int y)
00582 {
00583     char_x = x;
00584     char_y = y;
00585 }
00586 
00587 int SPI_TFT::columns()
00588 {
00589     return width() / font[1];
00590 }
00591 
00592 int SPI_TFT::rows()
00593 {
00594     return height() / font[2];
00595 }
00596 
00597 int SPI_TFT::_putc(int value)
00598 {
00599     if (value == '\n')    // new line
00600     {
00601         char_x = 0;
00602         char_y = char_y + font[2];
00603         if (char_y >= height() - font[2])
00604         {
00605             char_y = 0;
00606         }
00607     }
00608     else
00609     {
00610         character(char_x, char_y, value);
00611     }
00612     return value;
00613 }
00614 
00615 void SPI_TFT::character(int x, int y, int c)
00616 {
00617     unsigned int hor,vert,offset,bpl,j,i,b;
00618     unsigned char* bitmap_char;
00619     unsigned char z,w;
00620 
00621     if ((c < 31) || (c > 127)) return;   // test char range
00622 
00623     // read font parameter from start of array
00624     offset = font[0];                    // bytes / char
00625     hor = font[1];                       // get hor size of font
00626     vert = font[2];                      // get vert size of font
00627     bpl = font[3];                       // bytes per line
00628 
00629     if (char_x + hor > width())
00630     {
00631         char_x = 0;
00632         char_y = char_y + vert;
00633        if (char_y >= height() - font[2])
00634        {
00635             char_y = 0;
00636         }
00637     }
00638     mod_orientation();
00639     
00640     bitmap_char = &font[((c -32) * offset) + 4]; // start of char bitmap
00641     w = bitmap_char[0];                          // width of actual char
00642     window(char_x, char_y,w,vert); // char box
00643     wr_cmd(0x22);
00644     _cs = 0;
00645     wr_dat_start();
00646 
00647 
00648     for (j=0; j<vert; j++)                         //  vert line
00649     {
00650         for (i=0; i<w; i++)                    //  horz line
00651         {
00652             z =  bitmap_char[bpl * i + ((j & 0xF8) >> 3)+1];
00653             b = 1 << (j & 0x07);
00654             if (( z & b ) == 0x00)
00655             {
00656                 wr_dat_only(_background);
00657             }
00658             else
00659             {
00660                 wr_dat_only(_foreground);
00661             }
00662         }
00663     }
00664     _cs = 1;
00665     if ((w + 2) < hor)                   // x offset to next char
00666     {
00667         char_x += w + 2;
00668     }
00669     else char_x += hor;
00670 }
00671 
00672 
00673 void SPI_TFT::set_font(unsigned char* f)
00674 {
00675     font = f;
00676 }
00677 
00678 
00679 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
00680 {
00681     unsigned int    i,j;
00682     unsigned short *bitmap_ptr = (unsigned short *)bitmap;
00683     mod_orientation();
00684     window(x, y, w, h);
00685     wr_cmd(0x22);
00686     _cs = 0;
00687     wr_dat_start();
00688     _spi.format(16,3);
00689     bitmap_ptr += ((h - 1)*w);
00690     for (j = 0; j < h; j++)             //Lines
00691     {
00692         for (i = 0; i < w; i++)         // copy pixel data to TFT
00693         {
00694             _spi.write(*bitmap_ptr);    // one line
00695             bitmap_ptr++;
00696         }
00697         bitmap_ptr -= 2*w;
00698     }
00699     _spi.format(8,3);
00700     _cs = 1;
00701 }
00702 
00703 int SPI_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
00704 {
00705 /* // Current code unusable : Rewrite without DMA is needed
00706 #define OffsetPixelWidth    18
00707 #define OffsetPixelHeigh    22
00708 #define OffsetFileSize      34
00709 #define OffsetPixData       10
00710 #define OffsetBPP           28
00711 
00712     char filename[50];
00713     unsigned char BMP_Header[54];
00714     unsigned short BPP_t;
00715     unsigned int PixelWidth,PixelHeigh,start_data;
00716     unsigned int    i,off;
00717     int padd,j;
00718     unsigned short *line;
00719 
00720     // get the filename
00721     LocalFileSystem local("local");
00722     sprintf(&filename[0],"/local/");
00723     i=7;
00724     while (*Name_BMP!='\0') {
00725         filename[i++]=*Name_BMP++;
00726     }
00727 
00728     fprintf(stderr, "filename : %s \n\r",filename);
00729 
00730     FILE *Image = fopen((const char *)&filename[0], "rb");  // open the bmp file
00731     if (!Image) {
00732         return(0);      // error file not found !
00733     }
00734 
00735     fread(&BMP_Header[0],1,54,Image);      // get the BMP Header
00736 
00737     if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) {  // check magic byte
00738         fclose(Image);
00739         return(-1);     // error no BMP file
00740     }
00741 
00742     BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
00743     if (BPP_t != 0x0010) {
00744         fclose(Image);
00745         return(-2);     // error no 16 bit BMP
00746     }
00747 
00748     PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
00749     PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
00750     if (PixelHeigh > height() + y || PixelWidth > width() + x) {
00751         fclose(Image);
00752         return(-3);      // to big
00753     }
00754 
00755     start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
00756 
00757     line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
00758     if (line == NULL) {
00759         return(-4);         // error no memory
00760     }
00761 
00762     // the bmp lines are padded to multiple of 4 bytes
00763     padd = -1;
00764     do {
00765         padd ++;
00766     } while ((PixelWidth * 2 + padd)%4 != 0);
00767 
00768 
00769 //fseek(Image, 70 ,SEEK_SET);
00770     window(x, y,PixelWidth ,PixelHeigh);
00771     wr_cmd(0x22);
00772     _cs = 0;
00773 
00774     if (spi_port == 0) {    // TFT on SSP0
00775         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
00776 //        LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
00777         LPC_SSP0->DR = 0x72;        // start Data
00778         LPC_SSP0->CR0 |= 0x08UL;    // set to 16 bit
00779         // Enable SSP0 for DMA.
00780         LPC_SSP0->DMACR = 0x2;
00781 
00782     } else {
00783         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
00784 //        LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
00785         LPC_SSP1->DR = 0x72;        // start Data
00786         LPC_SSP1->CR0 |= 0x08UL;    // set to 16 bit
00787         // Enable SSP1 for DMA.
00788         LPC_SSP1->DMACR = 0x2;
00789     }
00790     for (j = PixelHeigh - 1; j >= 0; j--) {               //Lines bottom up
00791         off = j * (PixelWidth  * 2 + padd) + start_data;   // start of line
00792         fseek(Image, off ,SEEK_SET);
00793         fread(line,1,PixelWidth * 2,Image);       // read a line - slow !
00794 
00795         LPC_GPDMA->DMACIntTCClear = 0x1;
00796         LPC_GPDMA->DMACIntErrClr = 0x1;
00797         LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)line;
00798         LPC_GPDMACH0->DMACCControl = PixelWidth | (0UL << 18) | (0UL << 21) | (1UL << 31) |  DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt
00799         LPC_GPDMACH0->DMACCConfig  = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
00800         LPC_GPDMA->DMACSoftSReq = 0x1;
00801         do {
00802         } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
00803 
00804     }
00805 
00806     if (spi_port == 0) {    // TFT on SSP0
00807         do {
00808         } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
00809         LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
00810     } else {
00811         do {
00812         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
00813         LPC_SSP1->CR0 |= 0x08UL;    // set to 16 bit
00814     }
00815     _cs = 1;
00816     free (line);
00817     fclose(Image);
00818     WindowMax();
00819 */
00820     return(1);
00821 }