Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 13:2c91cb947161, committed 2013-03-05
- Comitter:
- dreschpe
- Date:
- Tue Mar 05 14:50:51 2013 +0000
- Parent:
- 11:9bb71766cafc
- Child:
- 14:ea3206e8e3bd
- Commit message:
- Add Freescale KL25Z support
Changed in this revision
| SPI_TFT.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/SPI_TFT.cpp Tue Feb 19 21:49:55 2013 +0000
+++ b/SPI_TFT.cpp Tue Mar 05 14:50:51 2013 +0000
@@ -19,24 +19,25 @@
// 06.04.12 fix SSEL CS problem
// 06.04.12 use direct access to the spi register to speed up the library.
// 11.09.12 switch back to using io pin as cs to avoid problems with SSEL CS.
-// 21.09.12 fix Bug in BMP_16
+// 21.09.12 fix Bug in BMP_16
// 11.10.12 patch from Hans Bergles to get SPI1 working again
// 03.02.13 add a switch to switch off DMA use for LPC11U24
+// 04.03.13 add support for new Kinetis board
#include "SPI_TFT.h"
#include "mbed.h"
#define BPP 16 // Bits per pixel
-
-#if defined TARGET_LPC1768
+
+#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
#endif
-#if defined NO_DMA
+#if defined NO_DMA // if LPC1768 user want no DMA
#undef USE_DMA
#endif
-
+
//extern Serial pc;
//extern DigitalOut xx; // debug !!
@@ -46,8 +47,10 @@
{
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
tft_reset();
}
@@ -90,8 +93,6 @@
void SPI_TFT::wr_cmd(unsigned char cmd)
{
- unsigned short spi_d;
- spi_d = 0x7000 | cmd ;
_cs = 0;
#if defined NO_MBED_LIB
if (spi_port == 0) { // TFT on SSP0
@@ -104,18 +105,24 @@
do {
} while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
}
-#else
+#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
+#endif
_cs = 1;
}
-
+// write data to tft register
void SPI_TFT::wr_dat(unsigned char dat)
{
- unsigned short spi_d;
- spi_d = 0x7200 | dat;
+
_cs = 0;
#if defined NO_MBED_LIB
if (spi_port == 0) { // TFT on SSP0
@@ -128,9 +135,16 @@
do {
} while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
}
-#else
- _spi.write(spi_d); // mbed lib
-#endif
+#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 = 1;
}
@@ -149,22 +163,28 @@
return (val);
}
+// write to a TFT register
void SPI_TFT::wr_reg (unsigned char reg, unsigned char val)
{
wr_cmd(reg);
wr_dat(val);
}
+// read from a TFT register
unsigned short SPI_TFT::rd_reg (unsigned char reg)
{
wr_cmd(reg);
return(rd_dat());
}
+// setup TFT controller - this is called by constructor
void SPI_TFT::tft_reset()
{
- //static unsigned short driverCode;
+#if defined TARGET_KL25Z // 8 Bit SPI
+ _spi.format(8,3);
+#else // 16 Bit SPI
_spi.format(16,3); // 16 bit spi mode 3
+#endif
_spi.frequency(48000000); // 48 Mhz SPI clock
_cs = 1; // cs high
_reset = 0; // display reset
@@ -192,7 +212,7 @@
wr_reg(0x23, 0x8D); /* Vcom Control 1 */
/* Gamma settings -----------------------------------------------------------*/
- wr_reg(0x40,0x00); //
+ wr_reg(0x40,0x00); // default setup
wr_reg(0x41,0x00); //
wr_reg(0x42,0x01); //
wr_reg(0x43,0x13); //
@@ -253,20 +273,17 @@
wr_reg(0x16, 0x00A8);
break;
}
-#if defined USE_DMA
- // setup DMA channel 0
- // Power up the GPDMA.
- LPC_SC->PCONP |= (1UL << 29);
+#if defined USE_DMA // setup DMA channel 0
+ LPC_SC->PCONP |= (1UL << 29); // Power up the GPDMA.
LPC_GPDMA->DMACConfig = 1; // enable DMA controller
- // Reset the Interrupt status
- LPC_GPDMA->DMACIntTCClear = 0x1;
+ LPC_GPDMA->DMACIntTCClear = 0x1; // Reset the Interrupt status
LPC_GPDMA->DMACIntErrClr = 0x1;
LPC_GPDMACH0->DMACCLLI = 0;
#endif
WindowMax ();
}
-
+// Set one pixel
void SPI_TFT::pixel(int x, int y, int color)
{
wr_reg(0x03, (x >> 0));
@@ -275,7 +292,7 @@
wr_reg(0x06, (y >> 8));
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -296,13 +313,18 @@
#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
+#endif
_cs = 1;
}
-
+// define draw area
void SPI_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
wr_reg(0x03, x );
@@ -315,14 +337,14 @@
wr_reg(0x08, ( y+h-1 >> 8));
}
-
+// set draw area to max
void SPI_TFT::WindowMax (void)
{
window (0, 0, width(), height());
}
-
+// clear screen
void SPI_TFT::cls (void)
{
int pixel = ( width() * height());
@@ -394,19 +416,29 @@
for (i = 0; i < ( width() * height()); i++)
_spi.write(_background);
#endif
-#else // mbed lib
+
+#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 to 16 bit Mode 3
+ _spi.format(16,3); // switch back to 16 bit Mode 3
unsigned int i;
for (i = 0; i < ( width() * height()); i++)
- _spi.write(_background);
+ _spi.write(_background);
+#endif
#endif
_cs = 1;
}
-
+// draw circle
void SPI_TFT::circle(int x0, int y0, int r, int color)
{
@@ -523,7 +555,7 @@
}
-
+// draw horizontal line
void SPI_TFT::hline(int x0, int x1, int y, int color)
{
int w;
@@ -531,7 +563,7 @@
window(x0,y,w,1);
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -567,25 +599,35 @@
do {
} while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
}
-#else
+#else // USE_DMA
int i;
for (i=0; i<w; i++) {
_spi.write(color);
}
-#endif
+#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 to 16 bit Mode 3
- for (i=0; i<w; i++) {
+ _spi.format(16,3); // switch back to 16 bit Mode 3
+ for (int j=0; j<w; j++) {
_spi.write(color);
}
-#endif
+#endif
+#endif
_cs = 1;
WindowMax();
return;
}
+// draw vertical line
void SPI_TFT::vline(int x, int y0, int y1, int color)
{
int h;
@@ -593,7 +635,7 @@
window(x,y0,1,h);
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -636,20 +678,28 @@
}
#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
+#endif
_cs = 1;
WindowMax();
return;
}
-
+// draw line
void SPI_TFT::line(int x0, int y0, int x1, int y1, int color)
{
//WindowMax();
@@ -721,7 +771,7 @@
return;
}
-
+// draw rect
void SPI_TFT::rect(int x0, int y0, int x1, int y1, int color)
{
@@ -741,20 +791,20 @@
}
-
+// fill rect
void SPI_TFT::fillrect(int x0, int y0, int x1, int y1, int color)
{
int h = y1 - y0 + 1;
int w = x1 - x0 + 1;
int pixel = h * w;
- #if defined USE_DMA
+#if defined USE_DMA
int dma_count;
- #endif
+#endif
window(x0,y0,w,h);
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -801,26 +851,36 @@
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 // 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
+#endif
_cs = 1;
WindowMax();
return;
}
-
+// set cursor position
void SPI_TFT::locate(int x, int y)
{
char_x = x;
@@ -828,21 +888,19 @@
}
-
+// calculate num of chars in a row
int SPI_TFT::columns()
{
return width() / font[1];
}
-
-
+// calculate num of rows on the screen
int SPI_TFT::rows()
{
return height() / font[2];
}
-
-
+// print a char on the screen
int SPI_TFT::_putc(int value)
{
if (value == '\n') { // new line
@@ -857,18 +915,18 @@
return value;
}
-
+// consrtuct the char out of the font
void SPI_TFT::character(int x, int y, int c)
{
unsigned int hor,vert,offset,bpl,j,i,b;
unsigned char* zeichen;
unsigned char z,w;
- #if defined USE_DMA
+#if defined USE_DMA
unsigned int pixel;
unsigned int p;
unsigned int dma_count,dma_off;
uint16_t *buffer;
- #endif
+#endif
if ((c < 31) || (c > 127)) return; // test char range
@@ -967,10 +1025,10 @@
/* disable SSP1 for DMA. */
LPC_SSP1->DMACR = 0x0;
}
-
+
#else // no dma
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -981,20 +1039,34 @@
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 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
+ _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
}
}
}
@@ -1018,7 +1090,11 @@
{
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
// the lines are padded to multiple of 4 bytes in a bitmap
padd = -1;
do {
@@ -1027,30 +1103,30 @@
window(x, y, w, h);
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
+ LPC_SSP1->DMACR = 0x2;
+#endif
LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
LPC_SSP1->DR = 0x72; // start Data command
LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
}
bitmap_ptr += ((h - 1)* (w + padd));
-#if defined USE_DMA
+#if defined USE_DMA
for (j = 0; j < h; j++) { //Lines
LPC_GPDMA->DMACIntTCClear = 0x1;
LPC_GPDMA->DMACIntErrClr = 0x1;
@@ -1073,8 +1149,8 @@
}
bitmap_ptr -= 2*w;
bitmap_ptr -= padd;
- }
-#endif
+ }
+#endif
if (spi_port == 0) { // TFT on SSP0
do {
} while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
@@ -1083,24 +1159,39 @@
} while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
}
#else // use mbed lib
+#if defined TARGET_KL25Z // 8 Bit SPI
+ _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
+#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
+#endif
unsigned int i;
for (j = 0; j < h; j++) { //Lines
for (i = 0; i < w; i++) { // copy pixel data to TFT
+#if defined TARGET_KL25Z // 8 Bit SPI
+ _spi.write(*bitmap_ptr);
+ bitmap_ptr++;
+ _spi.write(*bitmap_ptr);
+ bitmap_ptr++;
+#else
_spi.write(*bitmap_ptr); // one line
bitmap_ptr++;
+#endif
}
bitmap_ptr -= 2*w;
bitmap_ptr -= padd;
}
-#endif
+#endif
_cs = 1;
WindowMax();
}
+// local filesystem is not implemented in kinetis board
+#if defined TARGET_LPC1768 || defined TARGET_LPC11U24
+
+
int SPI_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
{
@@ -1171,7 +1262,7 @@
window(x, y,PixelWidth ,PixelHeigh);
wr_cmd(0x22);
_cs = 0;
-#if defined NO_MBED_LIB
+#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
@@ -1183,14 +1274,14 @@
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
LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
LPC_SSP1->DR = 0x72; // start Data
- LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
+ LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
}
for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
off = j * (PixelWidth * 2 + padd) + start_data; // start of line
@@ -1206,10 +1297,10 @@
do {
} while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
#else
- for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
+ for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
_spi.write(line[i]); // one 16 bit pixel
- }
-#endif
+ }
+#endif
}
if (spi_port == 0) { // TFT on SSP0
do {
@@ -1218,7 +1309,7 @@
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
@@ -1229,12 +1320,14 @@
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
+ }
+ }
+#endif
_cs = 1;
free (line);
fclose(Image);
WindowMax();
return(1);
-}
\ No newline at end of file
+}
+
+#endif