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.
Diff: SPI_TFT.cpp
- 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);