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