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

Dependents:   TFT_Test1 SourceCodePro31-SB Mandelbrot Mindwave-screen ... more

See http://mbed.org/cookbook/SPI-driven-QVGA-TFT for details.

Revision:
9:a63fd1ad41b0
Parent:
8:65a4de035c3c
Child:
10:071ae6e02fcf
--- a/SPI_TFT.cpp	Sun Feb 03 00:28:19 2013 +0000
+++ b/SPI_TFT.cpp	Sun Feb 03 17:51:33 2013 +0000
@@ -29,13 +29,14 @@
 #define BPP         16                  // Bits per pixel    
             
 #if defined TARGET_LPC1768 
-#define USE_DMA
+#define USE_DMA                         // we use dma to speed up
+#define NO_MBED_LIB                     // we write direct to the SPI register to speed up  
 #endif
 
 #if defined NO_DMA
 #undef USE_DMA
 #endif
-    
+  
 
 //extern Serial pc;
 //extern DigitalOut xx;     // debug !!
@@ -92,6 +93,7 @@
     unsigned short spi_d;
     spi_d =  0x7000 | cmd ;
     _cs = 0;
+#if defined NO_MBED_LIB
     if (spi_port == 0) {    // TFT on SSP0
         LPC_SSP0->DR = spi_d;
         // we have to wait for SPI IDLE to set CS back to high
@@ -102,6 +104,9 @@
         do {
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
     }
+#else 
+    _spi.write(spi_d);      // mbed lib
+#endif    
     _cs = 1;
 }
 
@@ -112,6 +117,7 @@
     unsigned short spi_d;
     spi_d =  0x7200 | dat;
     _cs = 0;
+#if defined NO_MBED_LIB
     if (spi_port == 0) {    // TFT on SSP0
         LPC_SSP0->DR = spi_d;
         // we have to wait for SPI IDLE to set CS back to high
@@ -122,6 +128,9 @@
         do {
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
     }
+#else 
+   _spi.write(spi_d);      // mbed lib
+#endif    
     _cs = 1;
 }
 
@@ -244,7 +253,7 @@
             wr_reg(0x16, 0x00A8);
             break;
     }
-#if defined USE_DMA
+#if defined USE_DMA                     
     // setup DMA channel 0
     // Power up the GPDMA.
     LPC_SC->PCONP |= (1UL << 29);
@@ -260,34 +269,36 @@
 
 void SPI_TFT::pixel(int x, int y, int color)
 {
-    unsigned char u,l;
     wr_reg(0x03, (x >> 0));
     wr_reg(0x02, (x >> 8));
     wr_reg(0x07, (y >> 0));
     wr_reg(0x06, (y >> 8));
     wr_cmd(0x22);
-    u = color  >> 8;
-    l = color & 0xff;
     _cs = 0;
+#if defined NO_MBED_LIB    
     if (spi_port == 0) {    // TFT on SSP0
         LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
         LPC_SSP0->DR = 0x72;        // start Data
-        LPC_SSP0->DR = u;           // high byte
-        LPC_SSP0->DR = l;           // low byte
         LPC_SSP0->CR0 |= 0x08UL;    // set back to 16 bit
+        LPC_SSP0->DR = color;       // Pixel
         // we have to wait for SPI IDLE to set CS back to high
         do {
         } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
     } else {
         LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
         LPC_SSP1->DR = 0x72;        // start Data
-        LPC_SSP1->DR = u;
-        LPC_SSP1->DR = l;
         LPC_SSP1->CR0 |= 0x08UL;    // set back to 16 bit
+        LPC_SSP1->DR = color;
         // we have to wait for SPI IDLE to set CS back to high
         do {
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
     }
+#else
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    _spi.write(color);                              // Write D0..D15
+#endif        
     _cs = 1;
 }
 
@@ -322,9 +333,7 @@
     WindowMax();
     wr_cmd(0x22);
 
-    // The SSEL signal is held low until the spi FIFO is emty.
-    // We have to lower the SPI clock for the 8 bit start to get the spi running
-    // until the next data word
+#if defined NO_MBED_LIB
 #if defined USE_DMA
     LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
 #endif
@@ -385,6 +394,15 @@
     for (i = 0; i < ( width() * height()); i++)
         _spi.write(_background);
 #endif
+#else  // mbed lib
+    _cs = 0;
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    unsigned int i;
+    for (i = 0; i < ( width() * height()); i++)
+        _spi.write(_background);                     
+#endif
     _cs = 1;
 }
 
@@ -513,6 +531,7 @@
     window(x0,y,w,1);
     wr_cmd(0x22);
     _cs = 0;
+#if defined NO_MBED_LIB    
     if (spi_port == 0) {    // TFT on SSP0
         for (i = 0; i < ( width() * height()); i++)
 #if defined USE_DMA
@@ -553,8 +572,15 @@
     for (i=0; i<w; i++) {
         _spi.write(color);
     }
-    
-#endif
+#endif    
+#else  // use mbed lib    
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    for (i=0; i<w; i++) {
+        _spi.write(color);
+    }
+#endif    
     _cs = 1;
     WindowMax();
     return;
@@ -567,6 +593,7 @@
     window(x,y0,1,h);
     wr_cmd(0x22);
     _cs = 0;
+#if defined NO_MBED_LIB      
     if (spi_port == 0) {    // TFT on SSP0
 #if defined USE_DMA
         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
@@ -608,7 +635,14 @@
         _spi.write(color);
     }
 #endif
-    
+#else     // use mbed lib
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    for (int y=0; y<h; y++) {
+        _spi.write(color);
+    }
+#endif    
     _cs = 1;
     WindowMax();
     return;
@@ -720,26 +754,27 @@
     window(x0,y0,w,h);
     wr_cmd(0x22);
     _cs = 0;
+#if defined NO_MBED_LIB     
     if (spi_port == 0) {    // TFT on SSP0
-        #if defined USE_DMA
+#if defined USE_DMA
         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
         /* Enable SSP0 for DMA. */
         LPC_SSP0->DMACR = 0x2;
-        #endif
+#endif
         LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
         LPC_SSP0->DR = 0x72;        // start Data
         LPC_SSP0->CR0 |= 0x08UL;    // set to 16 bit
     } else {
-        #if defined USE_DMA
+#if defined USE_DMA
         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
         /* Enable SSP1 for DMA. */
         LPC_SSP1->DMACR = 0x2;
-        #endif
+#endif
         LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
         LPC_SSP1->DR = 0x72;        // start Data
         LPC_SSP1->CR0 |= 0x08UL;    // set to 16 bit
     }
-    #if defined USE_DMA
+#if defined USE_DMA
     do {
         if (pixel > 4095) {
             dma_count = 4095;
@@ -767,12 +802,19 @@
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
     }
    
-    #else  // no DMA 
+#else  // no DMA 
     for (int p=0; p<pixel; p++) {
         _spi.write(color);
     }
-    #endif
-  
+#endif
+#else // use mbed lib
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    for (int p=0; p<pixel; p++) {
+        _spi.write(color);
+    }
+#endif  
     _cs = 1;
     WindowMax();
     return;
@@ -816,15 +858,14 @@
 }
 
 
-
-
 void SPI_TFT::character(int x, int y, int c)
 {
-    unsigned int hor,vert,offset,bpl,j,i,b,p;
+    unsigned int hor,vert,offset,bpl,j,i,b;
     unsigned char* zeichen;
     unsigned char z,w;
     #if defined USE_DMA
     unsigned int pixel;
+    unsigned int p;
     unsigned int dma_count,dma_off;
     uint16_t *buffer;
     #endif
@@ -927,8 +968,9 @@
         LPC_SSP1->DMACR = 0x0;
     }
     
-#else
+#else  // no dma
     _cs = 0;
+#if defined NO_MBED_LIB    
     if (spi_port == 0) {    // TFT on SSP0
         LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
         LPC_SSP0->DR = 0x72;        // start Data
@@ -938,6 +980,11 @@
         LPC_SSP1->DR = 0x72;        // start Data
         LPC_SSP1->CR0 |= 0x08UL;    // set to 16 bit
     }
+#else // mbed lib
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+#endif        
     zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
     w = zeichen[0];                          // width of actual char
      for (j=0; j<vert; j++) {  //  vert line
@@ -951,14 +998,12 @@
             }
         }
     }
-#endif    
-    
+#endif  // no DMA    
     _cs = 1;
     WindowMax();
     if ((w + 2) < hor) {                   // x offset to next char
         char_x += w + 2;
     } else char_x += hor;
-
 }
 
 
@@ -982,6 +1027,7 @@
     window(x, y, w, h);
     wr_cmd(0x22);
     _cs = 0;
+#if defined NO_MBED_LIB        
     if (spi_port == 0) {    // TFT on SSP0
 #if defined USE_DMA    
         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
@@ -1036,6 +1082,20 @@
         do {
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
     }
+#else // use mbed lib
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    unsigned int i;
+    for (j = 0; j < h; j++) {        //Lines
+        for (i = 0; i < w; i++) {     // copy pixel data to TFT
+            _spi.write(*bitmap_ptr);    // one line
+            bitmap_ptr++;
+        }
+        bitmap_ptr -= 2*w;
+        bitmap_ptr -= padd;
+    }
+#endif       
     _cs = 1;
     WindowMax();
 }
@@ -1111,7 +1171,7 @@
     window(x, y,PixelWidth ,PixelHeigh);
     wr_cmd(0x22);
     _cs = 0;
-
+#if defined NO_MBED_LIB 
     if (spi_port == 0) {    // TFT on SSP0
 #if defined USE_DMA
         LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
@@ -1158,6 +1218,20 @@
         do {
         } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
     }
+    
+#else // use mbed lib
+    _spi.format(8,3);                             // 8 bit Mode 3
+    _spi.write(SPI_START | SPI_WR | SPI_DATA);    // Write : RS = 1, RW = 0
+    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    for (j = PixelHeigh - 1; j >= 0; j--) {               //Lines bottom up
+        off = j * (PixelWidth  * 2 + padd) + start_data;   // start of line
+        fseek(Image, off ,SEEK_SET);
+        fread(line,1,PixelWidth * 2,Image);       // read a line - slow !
+        for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
+            _spi.write(line[i]);                  // one 16 bit pixel
+        } 
+     }
+#endif        
     _cs = 1;
     free (line);
     fclose(Image);