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

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);