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:
- 14:ea3206e8e3bd
- Parent:
- 13:2c91cb947161
- Child:
- 15:f5772cffc2b2
diff -r 2c91cb947161 -r ea3206e8e3bd SPI_TFT.cpp --- a/SPI_TFT.cpp Tue Mar 05 14:50:51 2013 +0000 +++ b/SPI_TFT.cpp Tue Mar 05 21:48:14 2013 +0000 @@ -30,8 +30,8 @@ #define BPP 16 // Bits per pixel #if defined TARGET_LPC1768 -#define USE_DMA // we use dma to speed up -#define NO_MBED_LIB // we write direct to the SPI register to speed up +#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 // if LPC1768 user want no DMA @@ -47,10 +47,16 @@ { orientation = 0; char_x = 0; -#if defined TARGET_LPC1768 - if (mosi == p11 || mosi == P0_18) spi_port = 0; // we must know the used SPI port to setup the DMA - else spi_port = 1; -#endif + #if defined TARGET_LPC1768 + if (mosi == p11 || mosi == P0_18){ + spi_port = 0; // we must know the used SPI port to setup the DMA + fprintf(stderr, "spi_port 0 \n\r"); + } + else { + spi_port = 1; + fprintf(stderr, "spi_port 1 \n\r"); + } + #endif tft_reset(); } @@ -94,27 +100,29 @@ void SPI_TFT::wr_cmd(unsigned char 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 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle - } else { - LPC_SSP1->DR = spi_d; - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle - } -#else -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(0x70); - _spi.write(cmd); -#else // 16 Bit SPI - unsigned short spi_d; - spi_d = 0x7000 | cmd ; - _spi.write(spi_d); // mbed lib -#endif -#endif + #if defined NO_MBED_LIB + unsigned short spi_d; + spi_d = 0x7000 | cmd ; + 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 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle + } else { + LPC_SSP1->DR = spi_d; + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle + } + #else // use mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(0x70); + _spi.write(cmd); + #else // 16 Bit SPI + unsigned short spi_d; + spi_d = 0x7000 | cmd ; + _spi.write(spi_d); // mbed lib + #endif + #endif _cs = 1; } @@ -122,29 +130,30 @@ // write data to tft register void SPI_TFT::wr_dat(unsigned char 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 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle - } else { - LPC_SSP1->DR = spi_d; - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle - } -#else -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(0x72); - _spi.write(dat); -#else // 16 Bit SPI - unsigned short spi_d; - spi_d = 0x7200 | dat; - _spi.write(spi_d); // mbed lib -#endif -#endif + _cs = 0; + #if defined NO_MBED_LIB + unsigned short spi_d; + spi_d = 0x7200 | dat; + 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 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle + } else { + LPC_SSP1->DR = spi_d; + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle + } + #else // use mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(0x72); + _spi.write(dat); + #else // 16 Bit SPI + unsigned short spi_d; + spi_d = 0x7200 | dat; + _spi.write(spi_d); + #endif + #endif _cs = 1; } @@ -152,7 +161,7 @@ // the HX8347-D controller do not use the MISO (SDO) Signal. // This is a bug - ? -// A read will return 0 at the moment +// A read will return 0 at the moment unsigned short SPI_TFT::rd_dat (void) { @@ -182,8 +191,10 @@ { #if defined TARGET_KL25Z // 8 Bit SPI _spi.format(8,3); + fprintf(stderr, "8 Bit mode\n\r"); #else // 16 Bit SPI _spi.format(16,3); // 16 bit spi mode 3 + fprintf(stderr, "16 Bit mode\n\r"); #endif _spi.frequency(48000000); // 48 Mhz SPI clock _cs = 1; // cs high @@ -241,37 +252,39 @@ wr_reg(0x5D,0xCC); // /* Power + Osc ---------------------------------------------------------------*/ - wr_reg(0x18, 0x0036); /* OSC Control 1 */ - wr_reg(0x19, 0x0001); /* OSC Control 2 */ - wr_reg(0x01, 0x0000); /* Display Mode Control */ - wr_reg(0x1F, 0x0088); /* Power Control 6 */ + wr_reg(0x18, 0x36); /* OSC Control 1 */ + wr_reg(0x19, 0x01); /* OSC Control 2 */ + wr_reg(0x01, 0x00); /* Display Mode Control */ + wr_reg(0x1F, 0x88); /* Power Control 6 */ wait_ms(5); /* Delay 5 ms */ - wr_reg(0x1F, 0x0080); /* Power Control 6 */ + wr_reg(0x1F, 0x80); /* Power Control 6 */ + wait_ms(5); /* Delay 5 ms */ + wr_reg(0x1F, 0x90); /* Power Control 6 */ wait_ms(5); /* Delay 5 ms */ - wr_reg(0x1F, 0x0090); /* Power Control 6 */ - wait_ms(5); /* Delay 5 ms */ - wr_reg(0x1F, 0x00D0); /* Power Control 6 */ + wr_reg(0x1F, 0xD0); /* Power Control 6 */ wait_ms(5); /* Delay 5 ms */ - wr_reg(0x17, 0x0005); /* Colmod 16Bit/Pixel */ + wr_reg(0x17, 0x05); /* Colmod 16Bit/Pixel */ - wr_reg(0x36, 0x0000); /* Panel Characteristic */ - wr_reg(0x28, 0x0038); /* Display Control 3 */ + wr_reg(0x36, 0x00); /* Panel Characteristic */ + wr_reg(0x28, 0x38); /* Display Control 3 */ wait_ms(40); - wr_reg(0x28, 0x003C); /* Display Control 3 */ + wr_reg(0x28, 0x3C); /* Display Control 3 */ switch (orientation) { case 0: - wr_reg(0x16, 0x0008); - break; - case 1: - wr_reg(0x16, 0x0068); + wr_reg(0x16, 0x08); break; case 2: - wr_reg(0x16, 0x00C8); + wr_reg(0x16, 0xC8); break; case 3: - wr_reg(0x16, 0x00A8); - break; + wr_reg(0x16, 0xA8); + break; + case 1: + default: + wr_reg(0x16, 0x68); + break; + } #if defined USE_DMA // setup DMA channel 0 LPC_SC->PCONP |= (1UL << 29); // Power up the GPDMA. @@ -292,35 +305,37 @@ wr_reg(0x06, (y >> 8)); wr_cmd(0x22); _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->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->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 -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(color >> 8); - _spi.write(color & 0xff); -#else - _spi.format(16,3); // switch to 16 bit Mode 3 - _spi.write(color); // Write D0..D15 -#endif -#endif + #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->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 { // TFT on SSP1 + LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP1->DR = 0x72; // start Data + 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 // use mbed lib + + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + _spi.write(color >> 8); + _spi.write(color & 0xff); + #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 + #endif _cs = 1; } @@ -347,94 +362,94 @@ // clear screen void SPI_TFT::cls (void) { + fprintf(stderr, "CLS \n\r"); int pixel = ( width() * height()); -#if defined USE_DMA - int dma_count; - int color = _background; -#endif + #if defined USE_DMA + int dma_count; + int color = _background; + #endif WindowMax(); wr_cmd(0x22); -#if defined NO_MBED_LIB -#if defined USE_DMA - LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; -#endif - _cs = 0; - if (spi_port == 0) { // TFT on SSP0 -#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 - LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit - LPC_SSP0->DR = 0x72; // start byte - LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit - } else { -#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 - 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 - // start DMA - do { - if (pixel > 4095) { - dma_count = 4095; - pixel = pixel - 4095; - } else { - dma_count = pixel; - pixel = 0; + #if defined NO_MBED_LIB + #if defined USE_DMA + LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; + #endif + _cs = 0; + if (spi_port == 0) { // TFT on SSP0 + #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 + LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP0->DR = 0x72; // start byte + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + #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 + LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP1->DR = 0x72; // start Data + LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit } - LPC_GPDMA->DMACIntTCClear = 0x1; - LPC_GPDMA->DMACIntErrClr = 0x1; - LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt - LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); - LPC_GPDMA->DMACSoftSReq = 0x1; // DMA request - - do { - } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running - } while (pixel > 0); - if (spi_port == 0) { // TFT on SSP0 - do { - } while ((0x0010 & LPC_SSP0->SR) == 0x10); // SPI FIFO not empty - /* disable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x0; - } else { - do { - } while ((0x0010 & LPC_SSP1->SR) == 0x10); // SPI FIFO not empty - /* disable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x0; - } -#else // no DMA - unsigned int i; - for (i = 0; i < ( width() * height()); i++) - _spi.write(_background); -#endif + #if defined USE_DMA + // start DMA + do { + if (pixel > 4095) { + dma_count = 4095; + pixel = pixel - 4095; + } else { + dma_count = pixel; + pixel = 0; + } + LPC_GPDMA->DMACIntTCClear = 0x1; + LPC_GPDMA->DMACIntErrClr = 0x1; + LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt + LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); + LPC_GPDMA->DMACSoftSReq = 0x1; // DMA request + do { + } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running + } while (pixel > 0); + if (spi_port == 0) { // TFT on SSP0 + do { + } while ((0x0010 & LPC_SSP0->SR) == 0x10); // SPI FIFO not empty + /* disable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x0; + } else { // TFT on SSP1 + do { + } while ((0x0010 & LPC_SSP1->SR) == 0x10); // SPI FIFO not empty + /* disable SSP1 for DMA. */ + LPC_SSP1->DMACR = 0x0; + } -#else // use mbed lib - _cs = 0; -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 - unsigned int i; - for (i = 0; i < ( width() * height()); i++) { - _spi.write(_background >> 8); - _spi.write(_background & 0xff); - } -#else // 16 bit SPI - _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 back to 16 bit Mode 3 - unsigned int i; - for (i = 0; i < ( width() * height()); i++) - _spi.write(_background); -#endif -#endif + #else // no DMA + unsigned int i; + for (i = 0; i < ( width() * height()); i++) + _spi.write(_background); + #endif + + #else // use mbed lib + _cs = 0; + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + unsigned int i; + for (i = 0; i < ( width() * height()); i++) { + _spi.write(_background >> 8); + _spi.write(_background & 0xff); + } + #else // 16 bit SPI + _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 back to 16 bit Mode 3 + unsigned int i; + for (i = 0; i < ( width() * height()); i++) + _spi.write(_background); + #endif + #endif _cs = 1; } @@ -563,65 +578,64 @@ window(x0,y,w,1); 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 - /* Enable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x2; -#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 - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 - /* Enable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x2; -#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 - LPC_GPDMA->DMACIntTCClear = 0x1; - LPC_GPDMA->DMACIntErrClr = 0x1; - LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; - LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt - LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); - LPC_GPDMA->DMACSoftSReq = 0x1; // start DMA - do { - } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running - if (spi_port == 0) { // TFT on SSP0 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty - } else { - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty - } -#else // USE_DMA - int i; - for (i=0; i<w; i++) { - _spi.write(color); - } -#endif -#else // use mbed lib -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 - for (int j=0; j<w; j++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - -#else // 16 Bit SPI - _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 back to 16 bit Mode 3 - for (int j=0; j<w; j++) { - _spi.write(color); - } -#endif -#endif + #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 + /* Enable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x2; + #endif + LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP0->DR = 0x72; // start Data + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + #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 + 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 + LPC_GPDMA->DMACIntTCClear = 0x1; + LPC_GPDMA->DMACIntErrClr = 0x1; + LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; + LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt + LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); + LPC_GPDMA->DMACSoftSReq = 0x1; // start DMA + do { + } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running + if (spi_port == 0) { // TFT on SSP0 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty + } else { // TFT on SSP1 + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty + } + #else // no DMA + int i; + for (i=0; i<w; i++) { + _spi.write(color); + } + #endif + #else // use mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + for (int j=0; j<w; j++) { + _spi.write(color >> 8); + _spi.write(color & 0xff); + } + #else // 16 Bit SPI + _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 back to 16 bit Mode 3 + for (int j=0; j<w; j++) { + _spi.write(color); + } + #endif + #endif _cs = 1; WindowMax(); return; @@ -635,64 +649,64 @@ 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 - /* Enable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x2; -#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 - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 - /* Enable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x2; -#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 - LPC_GPDMA->DMACIntTCClear = 0x1; - LPC_GPDMA->DMACIntErrClr = 0x1; - LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; - LPC_GPDMACH0->DMACCControl = h | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt - LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); - LPC_GPDMA->DMACSoftSReq = 0x1; - do { - } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running + #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 + /* Enable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x2; + #endif + LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP0->DR = 0x72; // start Data + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + #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 + 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 + LPC_GPDMA->DMACIntTCClear = 0x1; + LPC_GPDMA->DMACIntErrClr = 0x1; + LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; + LPC_GPDMACH0->DMACCControl = h | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt + LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); + LPC_GPDMA->DMACSoftSReq = 0x1; + do { + } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running - if (spi_port == 0) { // TFT on SSP0 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty - } else { - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty - } -#else - for (int y=0; y<h; y++) { - _spi.write(color); - } -#endif -#else // use mbed lib -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 - for (int y=0; y<h; y++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } -#else // 16 bit SPI - _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 -#endif + if (spi_port == 0) { // TFT on SSP0 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty + } else { // TFT on SSP1 + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty + } + #else // no DMA + for (int y=0; y<h; y++) { + _spi.write(color); + } + #endif + #else // use mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + for (int y=0; y<h; y++) { + _spi.write(color >> 8); + _spi.write(color & 0xff); + } + #else // 16 bit SPI + _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 + #endif _cs = 1; WindowMax(); return; @@ -798,83 +812,83 @@ int h = y1 - y0 + 1; int w = x1 - x0 + 1; int pixel = h * w; -#if defined USE_DMA - int dma_count; -#endif + #if defined USE_DMA + int dma_count; + #endif 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 - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 - /* Enable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x2; -#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 - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 - /* Enable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x2; -#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 - do { - if (pixel > 4095) { - dma_count = 4095; - pixel = pixel - 4095; - } else { - dma_count = pixel; - pixel = 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 + /* Enable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x2; + #endif + LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP0->DR = 0x72; // start Data + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + #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 + LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP1->DR = 0x72; // start Data + LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit } - LPC_GPDMA->DMACIntTCClear = 0x1; - LPC_GPDMA->DMACIntErrClr = 0x1; - LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; - LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt - LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); - LPC_GPDMA->DMACSoftSReq = 0x1; - do { - } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running + #if defined USE_DMA + do { + if (pixel > 4095) { + dma_count = 4095; + pixel = pixel - 4095; + } else { + dma_count = pixel; + pixel = 0; + } + LPC_GPDMA->DMACIntTCClear = 0x1; + LPC_GPDMA->DMACIntErrClr = 0x1; + LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; + LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt + LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); + LPC_GPDMA->DMACSoftSReq = 0x1; + do { + } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running - } while (pixel > 0); - - if (spi_port == 0) { // TFT on SSP0 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty - } else { - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty - } + } while (pixel > 0); -#else // no DMA - for (int p=0; p<pixel; p++) { - _spi.write(color); - } -#endif + if (spi_port == 0) { // TFT on SSP0 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty + } else { // TFT on SSP1 + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty + } + + #else // no DMA + for (int p=0; p<pixel; p++) { + _spi.write(color); + } + #endif -#else // use mbed lib -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 - for (int p=0; p<pixel; p++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } + #else // use mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + for (int p=0; p<pixel; p++) { + _spi.write(color >> 8); + _spi.write(color & 0xff); + } -#else // 16 bit SPI - _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 -#endif + #else // 16 bit SPI + _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 + #endif _cs = 1; WindowMax(); return; @@ -921,12 +935,12 @@ 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 + #if defined USE_DMA + unsigned int pixel; + unsigned int p; + unsigned int dma_count,dma_off; + uint16_t *buffer; + #endif if ((c < 31) || (c > 127)) return; // test char range @@ -946,131 +960,132 @@ window(char_x, char_y,hor,vert); // char box wr_cmd(0x22); -#if defined USE_DMA - pixel = hor * vert; // calculate buffer size - - buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit - if (buffer == NULL) { - //led = 1; - //pc.printf("Malloc error !\n\r"); - return; // error no memory - } - - zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap - w = zeichen[0]; // width of actual char - p = 0; - // construct the char into the buffer - for (j=0; j<vert; j++) { // vert line - for (i=0; i<hor; i++) { // horz line - z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; - b = 1 << (j & 0x07); - if (( z & b ) == 0x00) { - buffer[p] = _background; - } else { - buffer[p] = _foreground; - } - p++; - } - } + #if defined USE_DMA + pixel = hor * vert; // calculate buffer size - // copy the buffer with DMA SPI to display - dma_off = 0; // offset for DMA transfer - _cs = 0; - if (spi_port == 0) { // TFT on SSP0 - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 - /* Enable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x2; - LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit - LPC_SSP0->DR = 0x72; // start Data - LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit - } else { - LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 - /* Enable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x2; - LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit - LPC_SSP1->DR = 0x72; // start Data - LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit - } - - // start DMA - do { - if (pixel > 4095) { // this is a giant font ! - dma_count = 4095; - pixel = pixel - 4095; - } else { - dma_count = pixel; - pixel = 0; + buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit + if (buffer == NULL) { + //led = 1; + //pc.printf("Malloc error !\n\r"); + return; // error no memory } - LPC_GPDMA->DMACIntTCClear = 0x1; - LPC_GPDMA->DMACIntErrClr = 0x1; - LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + dma_off); - LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt - LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); - LPC_GPDMA->DMACSoftSReq = 0x1; - do { - } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running - dma_off = dma_off + dma_count; - } while (pixel > 0); - free ((uint16_t *) buffer); - - if (spi_port == 0) { // TFT on SSP0 - do { - } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle - /* disable SSP0 for DMA. */ - LPC_SSP0->DMACR = 0x0; - } else { - do { - } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle - /* disable SSP1 for DMA. */ - LPC_SSP1->DMACR = 0x0; - } - -#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 - LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit - } else { - LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit - LPC_SSP1->DR = 0x72; // start Data - LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit - } -#else // mbed lib -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 -#else // 16 bit SPI - _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 back to 16 bit Mode 3 -#endif -#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 - for (i=0; i<hor; i++) { // horz line - z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; - b = 1 << (j & 0x07); - if (( z & b ) == 0x00) { -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(_background >> 8); - _spi.write(_background & 0xff); -#else - _spi.write(_background); -#endif - } else { -#if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(_foreground >> 8); - _spi.write(_foreground & 0xff); -#else - _spi.write(_foreground); -#endif + zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap + w = zeichen[0]; // width of actual char + p = 0; + // construct the char into the buffer + for (j=0; j<vert; j++) { // vert line + for (i=0; i<hor; i++) { // horz line + z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; + b = 1 << (j & 0x07); + if (( z & b ) == 0x00) { + buffer[p] = _background; + } else { + buffer[p] = _foreground; + } + p++; } } - } -#endif // no DMA + + // copy the buffer with DMA SPI to display + dma_off = 0; // offset for DMA transfer + _cs = 0; + if (spi_port == 0) { // TFT on SSP0 + LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 + /* Enable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x2; + LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP0->DR = 0x72; // start Data + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 + /* Enable SSP1 for DMA. */ + LPC_SSP1->DMACR = 0x2; + LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP1->DR = 0x72; // start Data + LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit + } + + // start DMA + do { + if (pixel > 4095) { // this is a giant font ! + dma_count = 4095; + pixel = pixel - 4095; + } else { + dma_count = pixel; + pixel = 0; + } + LPC_GPDMA->DMACIntTCClear = 0x1; + LPC_GPDMA->DMACIntErrClr = 0x1; + LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + dma_off); + LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt + LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); + LPC_GPDMA->DMACSoftSReq = 0x1; + do { + } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running + dma_off = dma_off + dma_count; + } while (pixel > 0); + + free ((uint16_t *) buffer); + + if (spi_port == 0) { // TFT on SSP0 + do { + } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle + /* disable SSP0 for DMA. */ + LPC_SSP0->DMACR = 0x0; + } else { // TFT on SSP1 + do { + } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle + /* disable SSP1 for DMA. */ + LPC_SSP1->DMACR = 0x0; + } + + #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 + LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit + } else { // TFT on SSP1 + LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit + LPC_SSP1->DR = 0x72; // start Data + LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit + } + #else // mbed lib + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0 + #else // 16 bit SPI + _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 back to 16 bit Mode 3 + #endif + #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 + for (i=0; i<hor; i++) { // horz line + z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; + b = 1 << (j & 0x07); + if (( z & b ) == 0x00) { + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(_background >> 8); + _spi.write(_background & 0xff); + #else + _spi.write(_background); + #endif + } else { + #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(_foreground >> 8); + _spi.write(_foreground & 0xff); + #else + _spi.write(_foreground); + #endif + } + } + } + #endif // no DMA _cs = 1; WindowMax(); if ((w + 2) < hor) { // x offset to next char @@ -1085,16 +1100,15 @@ } - void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) { unsigned int j; int padd; -#if defined TARGET_KL25Z // 8 Bit SPI - unsigned char *bitmap_ptr = (unsigned char *)bitmap; -#else - unsigned short *bitmap_ptr = (unsigned short *)bitmap; -#endif + #if defined TARGET_KL25Z // 8 Bit SPI + unsigned char *bitmap_ptr = (unsigned char *)bitmap; + #else + unsigned short *bitmap_ptr = (unsigned short *)bitmap; + #endif // the lines are padded to multiple of 4 bytes in a bitmap padd = -1; do {