SPI Library for 240x320 TFT LCD with ILI9320, ILI9325 and ILI9328 chip

Dependencies:   BurstSPI

Dependents:   KL25Z_ILI9320_Demo Mini-DK

Other LCD drivers

05-30-2014
Device initialization for ILI9325 and ILI9328 has been added to the library.
The library will auto-detect what driver chip is connected (ILI9320, ILI9325 or ILI9328) and use the appropriate init sequence.
Please use the Issues tab to report any problems.

SPI TFT library for LPC1768, LPC11U24 and KL25Z

Loading fonts

When using this libary, don't forget to load the TFT_FONTS library from Peter Drescher at http://mbed.org/users/dreschpe/code/TFT_fonts/

KL25Z : limitations

The filetoflash function (see below) is not available.
Writing to the LCD is a little slower as the KL25Z only supports 8-bit SPI communication.

LPC1768 and LPC11U24 : filetoflash (SD to CPU flash)

This library contains a function to copy an image from the SD card to the CPU flash memory.
It allows you to use an image as background without speed loss when writing other text and graphics.
By default, this option is enabled.
It can be disabled by adding following instruction BEFORE you load the library:

#define NO_FLASH_BUFFER

Since the flash memory has limited write endurance, DO NOT use this feature when you intend to read multiple images from the SD card (eg: when used as a photo frame).

Sample code

#include "mbed.h"

// SPI TFT demo
// NOTES
// - Connect the LCD reset pin to the reset pin of the CPU board or connect a
//   separate reset circuit to the LCD reset pin (pull-up 10k to 3v3 + 100nf capacitor to GND).
// - When using the mbed LPC1768 board, following hardware modifications are needed:
//       Connect the LCD reset pin to the nR input.
//       Connect a 100nF capacitor between the nR input and GND.
//       Connect a pushbutton parallel to the 100nF capacitor.
//   Use the new pushbutton as the reset button (instead of the LPC1768 on-board reset button).
#define NO_FLASH_BUFFER         // Do not use CPU flash for storing bitmaps
#include "SPI_TFT_ILI9320.h"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "font_big.h"
SPI_TFT TFT(p11, p12, p13, p14,"TFT");  //mosi, miso, clk, cs

int main (void)
{

    TFT.claim(stdout);        // send stdout to the TFT display
    // Disable stdout buffering, allows us to omit \n with printf.
    // More info at http://www.cplusplus.com/reference/cstdio/setvbuf/
    setvbuf ( stdout , NULL , _IONBF , NULL );
    TFT.background(Black);    // set background to black
    TFT.foreground(White);    // set chars to white
    TFT.cls();                // clear the screen
    TFT.set_font((unsigned char*) Arial12x12);  // select the font

    TFT.locate(0,0);
    printf("ILI9320 SPI TFT library\n");
    printf("Simple demo\n");
}



Demo code LPC1768 (Mini-DK board)

Import programLPC1768_Mini-DK

LPC1768 Mini-DK board with 2.8" SPI TFT and SPI touch


Demo code FRDM-KL25Z board

Import programKL25Z_ILI9320_Demo

KL25Z driving an ILI9320 LCD board with touch panel (HY28A-LCDB SPI)

Committer:
frankvnk
Date:
Fri Jan 11 16:10:06 2013 +0000
Revision:
0:630b4da97968
Child:
2:45a3c5aa99c3
Extracted from Mini-DK to create separate library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 0:630b4da97968 1 /**************************************************************************************************
frankvnk 0:630b4da97968 2 ***** *****
frankvnk 0:630b4da97968 3 ***** Name: SPI_TFT.cpp *****
frankvnk 0:630b4da97968 4 ***** Ver.: 1.0 *****
frankvnk 0:630b4da97968 5 ***** Date: 04/01/2013 *****
frankvnk 0:630b4da97968 6 ***** Auth: Frank Vannieuwkerke *****
frankvnk 0:630b4da97968 7 ***** Erik Olieman *****
frankvnk 0:630b4da97968 8 ***** Func: library for 240*320 pixel TFT with ILI9320 LCD Controller *****
frankvnk 0:630b4da97968 9 ***** *****
frankvnk 0:630b4da97968 10 ***** Rewrite from Peter Drescher code - http://mbed.org/cookbook/SPI-driven-QVGA-TFT *****
frankvnk 0:630b4da97968 11 ***** *****
frankvnk 0:630b4da97968 12 **************************************************************************************************/
frankvnk 0:630b4da97968 13
frankvnk 0:630b4da97968 14 #include "SPI_TFT_ILI9320.h"
frankvnk 0:630b4da97968 15 #include "mbed.h"
frankvnk 0:630b4da97968 16
frankvnk 0:630b4da97968 17
frankvnk 0:630b4da97968 18 #define BPP 16 // Bits per pixel
frankvnk 0:630b4da97968 19
frankvnk 0:630b4da97968 20
frankvnk 0:630b4da97968 21 SPI_TFT::SPI_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, const char *name)
frankvnk 0:630b4da97968 22 : GraphicsDisplay(name), _spi(mosi, miso, sclk), _cs(cs)
frankvnk 0:630b4da97968 23 {
frankvnk 0:630b4da97968 24 char_x = 0;
frankvnk 0:630b4da97968 25 tft_reset();
frankvnk 0:630b4da97968 26 set_orientation(0);
frankvnk 0:630b4da97968 27 backgroundimage = false;
frankvnk 0:630b4da97968 28 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 29 backgroundOrientation = 0;
frankvnk 0:630b4da97968 30 #endif
frankvnk 0:630b4da97968 31 }
frankvnk 0:630b4da97968 32
frankvnk 0:630b4da97968 33 int SPI_TFT::width()
frankvnk 0:630b4da97968 34 {
frankvnk 0:630b4da97968 35 if (orientation == 0 || orientation == 2) return 240;
frankvnk 0:630b4da97968 36 else return 320;
frankvnk 0:630b4da97968 37 }
frankvnk 0:630b4da97968 38
frankvnk 0:630b4da97968 39 int SPI_TFT::height()
frankvnk 0:630b4da97968 40 {
frankvnk 0:630b4da97968 41 if (orientation == 0 || orientation == 2) return 320;
frankvnk 0:630b4da97968 42 else return 240;
frankvnk 0:630b4da97968 43 }
frankvnk 0:630b4da97968 44
frankvnk 0:630b4da97968 45 void SPI_TFT::set_orientation(unsigned int o)
frankvnk 0:630b4da97968 46 {
frankvnk 0:630b4da97968 47 orientation = o;
frankvnk 0:630b4da97968 48 WindowMax();
frankvnk 0:630b4da97968 49 }
frankvnk 0:630b4da97968 50
frankvnk 0:630b4da97968 51 void SPI_TFT::mod_orientation(void)
frankvnk 0:630b4da97968 52 {
frankvnk 0:630b4da97968 53 switch (orientation) {
frankvnk 0:630b4da97968 54 case 0:
frankvnk 0:630b4da97968 55 wr_reg(0x03, 0x10b0); // ID1 = 1, ID0 = 1, AM = 0 - Portrait
frankvnk 0:630b4da97968 56 break;
frankvnk 0:630b4da97968 57 case 1:
frankvnk 0:630b4da97968 58 wr_reg(0x03, 0x10a8); // ID1 = 1, ID0 = 0, AM = 0 - Landscape
frankvnk 0:630b4da97968 59 break;
frankvnk 0:630b4da97968 60 case 2:
frankvnk 0:630b4da97968 61 wr_reg(0x03, 0x1080); // ID1 = 0, ID0 = 0, AM = 1 - Portrait upside down
frankvnk 0:630b4da97968 62 break;
frankvnk 0:630b4da97968 63 case 3:
frankvnk 0:630b4da97968 64 wr_reg(0x03, 0x1098); // ID1 = 0, ID0 = 1, AM = 1 - Landscape upside down
frankvnk 0:630b4da97968 65 break;
frankvnk 0:630b4da97968 66 }
frankvnk 0:630b4da97968 67 }
frankvnk 0:630b4da97968 68
frankvnk 0:630b4da97968 69 void SPI_TFT::wr_cmd(unsigned char cmd)
frankvnk 0:630b4da97968 70 {
frankvnk 0:630b4da97968 71 _cs = 0;
frankvnk 0:630b4da97968 72 _spi.write(0x70);
frankvnk 0:630b4da97968 73 _spi.write(0x00);
frankvnk 0:630b4da97968 74 _spi.write(cmd);
frankvnk 0:630b4da97968 75 _cs = 1;
frankvnk 0:630b4da97968 76 }
frankvnk 0:630b4da97968 77
frankvnk 0:630b4da97968 78 void SPI_TFT::wr_dat(unsigned short dat)
frankvnk 0:630b4da97968 79 {
frankvnk 0:630b4da97968 80 unsigned char u,l;
frankvnk 0:630b4da97968 81 u = (dat >> 0x08);
frankvnk 0:630b4da97968 82 l = (dat & 0xff);
frankvnk 0:630b4da97968 83 _cs = 0;
frankvnk 0:630b4da97968 84 _spi.write(0x72);
frankvnk 0:630b4da97968 85 _spi.write(u);
frankvnk 0:630b4da97968 86 _spi.write(l);
frankvnk 0:630b4da97968 87 _cs = 1;
frankvnk 0:630b4da97968 88 }
frankvnk 0:630b4da97968 89
frankvnk 0:630b4da97968 90 void SPI_TFT::wr_dat_start(void)
frankvnk 0:630b4da97968 91 {
frankvnk 0:630b4da97968 92 _spi.write(0x72);
frankvnk 0:630b4da97968 93 }
frankvnk 0:630b4da97968 94
frankvnk 0:630b4da97968 95 unsigned short SPI_TFT::rd_dat(void) // IMPORTANT : SPI frequency needs to be lowered when reading
frankvnk 0:630b4da97968 96 {
frankvnk 0:630b4da97968 97 unsigned short val = 0;
frankvnk 0:630b4da97968 98 _cs = 0;
frankvnk 0:630b4da97968 99 _spi.frequency(SPI_F_LO);
frankvnk 0:630b4da97968 100 _spi.write(0x73);
frankvnk 0:630b4da97968 101 _spi.write(0x00);
frankvnk 0:630b4da97968 102 val = _spi.write(0x00); // Dummy read
frankvnk 0:630b4da97968 103 val = _spi.write(0x00); // Read D8..D15
frankvnk 0:630b4da97968 104 val <<= 8;
frankvnk 0:630b4da97968 105 val |= _spi.write(0x00); // Read D0..D7
frankvnk 0:630b4da97968 106 _cs = 1;
frankvnk 0:630b4da97968 107 _spi.frequency(SPI_F_HI);
frankvnk 0:630b4da97968 108 return (val);
frankvnk 0:630b4da97968 109 }
frankvnk 0:630b4da97968 110
frankvnk 0:630b4da97968 111 void SPI_TFT::wr_reg(unsigned char reg, unsigned short val)
frankvnk 0:630b4da97968 112 {
frankvnk 0:630b4da97968 113 wr_cmd(reg);
frankvnk 0:630b4da97968 114 wr_dat(val);
frankvnk 0:630b4da97968 115 }
frankvnk 0:630b4da97968 116
frankvnk 0:630b4da97968 117 unsigned short SPI_TFT::rd_reg(unsigned char reg)
frankvnk 0:630b4da97968 118 {
frankvnk 0:630b4da97968 119 wr_cmd(reg);
frankvnk 0:630b4da97968 120 return(rd_dat());
frankvnk 0:630b4da97968 121 }
frankvnk 0:630b4da97968 122
frankvnk 0:630b4da97968 123 unsigned short SPI_TFT::Read_ID(void) // IMPORTANT : SPI frequency needs to be lowered when reading
frankvnk 0:630b4da97968 124 {
frankvnk 0:630b4da97968 125 unsigned short val = 0;
frankvnk 0:630b4da97968 126 _cs = 0;
frankvnk 0:630b4da97968 127 _spi.write(0x70);
frankvnk 0:630b4da97968 128 _spi.write(0x00);
frankvnk 0:630b4da97968 129 _spi.write(0x00);
frankvnk 0:630b4da97968 130 _cs = 1;
frankvnk 0:630b4da97968 131 _spi.frequency(SPI_F_LO);
frankvnk 0:630b4da97968 132 _cs = 0;
frankvnk 0:630b4da97968 133 _spi.write(0x73);
frankvnk 0:630b4da97968 134 val = _spi.write(0x00); // Dummy read
frankvnk 0:630b4da97968 135 val = _spi.write(0x00); // Read D8..D15
frankvnk 0:630b4da97968 136 val <<= 8;
frankvnk 0:630b4da97968 137 val |= _spi.write(0x00); // Read D0..D7
frankvnk 0:630b4da97968 138 _cs = 1;
frankvnk 0:630b4da97968 139 _spi.frequency(SPI_F_HI);
frankvnk 0:630b4da97968 140 return (val);
frankvnk 0:630b4da97968 141 }
frankvnk 0:630b4da97968 142
frankvnk 0:630b4da97968 143 void SPI_TFT::SetCursor( unsigned short Xpos, unsigned short Ypos )
frankvnk 0:630b4da97968 144 {
frankvnk 0:630b4da97968 145 wr_reg(0x20, Xpos );
frankvnk 0:630b4da97968 146 wr_reg(0x21, Ypos );
frankvnk 0:630b4da97968 147 }
frankvnk 0:630b4da97968 148
frankvnk 0:630b4da97968 149 void SPI_TFT::tft_reset()
frankvnk 0:630b4da97968 150 {
frankvnk 0:630b4da97968 151 _spi.format(8,3); // 8 bit spi mode 3
frankvnk 0:630b4da97968 152 _spi.frequency(SPI_F_HI); // 48 Mhz SPI clock
frankvnk 0:630b4da97968 153
frankvnk 0:630b4da97968 154 wr_reg(0x00,0x0000);
frankvnk 0:630b4da97968 155 wr_reg(0x01,0x0100); // Driver Output Control
frankvnk 0:630b4da97968 156 wr_reg(0x02,0x0700); // LCD Driver Waveform Control
frankvnk 0:630b4da97968 157 wr_reg(0x03,0x1030); // Set the scan mode
frankvnk 0:630b4da97968 158 wr_reg(0x04,0x0000); // Scaling Control
frankvnk 0:630b4da97968 159 wr_reg(0x08,0x0202); // Display Control 2
frankvnk 0:630b4da97968 160 wr_reg(0x09,0x0000); // Display Control 3
frankvnk 0:630b4da97968 161 wr_reg(0x0a,0x0000); // Frame Cycle Contal
frankvnk 0:630b4da97968 162 wr_reg(0x0c,(1<<0)); // Extern Display Interface Control 1
frankvnk 0:630b4da97968 163 wr_reg(0x0d,0x0000); // Frame Maker Position
frankvnk 0:630b4da97968 164 wr_reg(0x0f,0x0000); // Extern Display Interface Control 2
frankvnk 0:630b4da97968 165
frankvnk 0:630b4da97968 166 wait_ms(50);
frankvnk 0:630b4da97968 167
frankvnk 0:630b4da97968 168 wr_reg(0x07,0x0101); // Display Control
frankvnk 0:630b4da97968 169
frankvnk 0:630b4da97968 170 wait_ms(50);
frankvnk 0:630b4da97968 171
frankvnk 0:630b4da97968 172 wr_reg(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); // Power Control 1
frankvnk 0:630b4da97968 173 wr_reg(0x11,0x0007); // Power Control 2
frankvnk 0:630b4da97968 174 wr_reg(0x12,(1<<8)|(1<<4)|(0<<0)); // Power Control 3
frankvnk 0:630b4da97968 175 wr_reg(0x13,0x0b00); // Power Control 4
frankvnk 0:630b4da97968 176 wr_reg(0x29,0x0000); // Power Control 7
frankvnk 0:630b4da97968 177 wr_reg(0x2b,(1<<14)|(1<<4));
frankvnk 0:630b4da97968 178
frankvnk 0:630b4da97968 179 wr_reg(0x50,0); // Set X Start
frankvnk 0:630b4da97968 180 wr_reg(0x51,239); // Set X End
frankvnk 0:630b4da97968 181 wr_reg(0x52,0); // Set Y Start
frankvnk 0:630b4da97968 182 wr_reg(0x53,319); // Set Y End
frankvnk 0:630b4da97968 183
frankvnk 0:630b4da97968 184 wait_ms(50);
frankvnk 0:630b4da97968 185
frankvnk 0:630b4da97968 186 wr_reg(0x60,0x2700); // Driver Output Control
frankvnk 0:630b4da97968 187 wr_reg(0x61,0x0001); // Driver Output Control
frankvnk 0:630b4da97968 188 wr_reg(0x6a,0x0000); // Vertical Srcoll Control
frankvnk 0:630b4da97968 189
frankvnk 0:630b4da97968 190 wr_reg(0x80,0x0000); // Display Position Partial Display 1
frankvnk 0:630b4da97968 191 wr_reg(0x81,0x0000); // RAM Address Start Partial Display 1
frankvnk 0:630b4da97968 192 wr_reg(0x82,0x0000); // RAM Address End-Partial Display 1
frankvnk 0:630b4da97968 193 wr_reg(0x83,0x0000); // Displsy Position Partial Display 2
frankvnk 0:630b4da97968 194 wr_reg(0x84,0x0000); // RAM Address Start Partial Display 2
frankvnk 0:630b4da97968 195 wr_reg(0x85,0x0000); // RAM Address End Partial Display 2
frankvnk 0:630b4da97968 196
frankvnk 0:630b4da97968 197 wr_reg(0x90,(0<<7)|(16<<0)); // Frame Cycle Control
frankvnk 0:630b4da97968 198 wr_reg(0x92,0x0000); // Panel Interface Control 2
frankvnk 0:630b4da97968 199 wr_reg(0x93,0x0001); // Panel Interface Control 3
frankvnk 0:630b4da97968 200 wr_reg(0x95,0x0110); // Frame Cycle Control
frankvnk 0:630b4da97968 201 wr_reg(0x97,(0<<8));
frankvnk 0:630b4da97968 202 wr_reg(0x98,0x0000); // Frame Cycle Control
frankvnk 0:630b4da97968 203 wr_reg(0x07,0x0133);
frankvnk 0:630b4da97968 204
frankvnk 0:630b4da97968 205 wait_ms(100);
frankvnk 0:630b4da97968 206 WindowMax();
frankvnk 0:630b4da97968 207 }
frankvnk 0:630b4da97968 208
frankvnk 0:630b4da97968 209
frankvnk 0:630b4da97968 210 void SPI_TFT::pixel(int x, int y, int color)
frankvnk 0:630b4da97968 211 {
frankvnk 0:630b4da97968 212 switch (orientation) {
frankvnk 0:630b4da97968 213 case 0:
frankvnk 0:630b4da97968 214 wr_reg(0x20, x);
frankvnk 0:630b4da97968 215 wr_reg(0x21, y);
frankvnk 0:630b4da97968 216 break;
frankvnk 0:630b4da97968 217 case 1:
frankvnk 0:630b4da97968 218 wr_reg(0x20, 239-y);
frankvnk 0:630b4da97968 219 wr_reg(0x21, x);
frankvnk 0:630b4da97968 220 break;
frankvnk 0:630b4da97968 221 case 2:
frankvnk 0:630b4da97968 222 wr_reg(0x20, 239-x);
frankvnk 0:630b4da97968 223 wr_reg(0x21, 319-y);
frankvnk 0:630b4da97968 224 break;
frankvnk 0:630b4da97968 225 case 3:
frankvnk 0:630b4da97968 226 wr_reg(0x20, y);
frankvnk 0:630b4da97968 227 wr_reg(0x21, 319-x);
frankvnk 0:630b4da97968 228 break;
frankvnk 0:630b4da97968 229 }
frankvnk 0:630b4da97968 230 wr_cmd(0x22);
frankvnk 0:630b4da97968 231 wr_dat(color);
frankvnk 0:630b4da97968 232 }
frankvnk 0:630b4da97968 233
frankvnk 0:630b4da97968 234
frankvnk 0:630b4da97968 235 void SPI_TFT::window(int x, int y, int w, int h)
frankvnk 0:630b4da97968 236 {
frankvnk 0:630b4da97968 237 unsigned int xw1, yh1;
frankvnk 0:630b4da97968 238 xw1 = x + w - 1;
frankvnk 0:630b4da97968 239 yh1 = y + h - 1;
frankvnk 0:630b4da97968 240 wr_reg(0x20, x);
frankvnk 0:630b4da97968 241 wr_reg(0x21, y);
frankvnk 0:630b4da97968 242 switch (orientation) {
frankvnk 0:630b4da97968 243 case 0:
frankvnk 0:630b4da97968 244 wr_reg(0x50, x);
frankvnk 0:630b4da97968 245 wr_reg(0x51, xw1);
frankvnk 0:630b4da97968 246 wr_reg(0x52, y);
frankvnk 0:630b4da97968 247 wr_reg(0x53, yh1);
frankvnk 0:630b4da97968 248 break;
frankvnk 0:630b4da97968 249 case 1:
frankvnk 0:630b4da97968 250 wr_reg(0x50, 239 - yh1);
frankvnk 0:630b4da97968 251 wr_reg(0x51, 239 - y);
frankvnk 0:630b4da97968 252 wr_reg(0x52, x);
frankvnk 0:630b4da97968 253 wr_reg(0x53, xw1);
frankvnk 0:630b4da97968 254 break;
frankvnk 0:630b4da97968 255 case 2:
frankvnk 0:630b4da97968 256 wr_reg(0x50, 239 - xw1);
frankvnk 0:630b4da97968 257 wr_reg(0x51, 239 - x);
frankvnk 0:630b4da97968 258 wr_reg(0x52, 319 - yh1);
frankvnk 0:630b4da97968 259 wr_reg(0x53, 319 - y);
frankvnk 0:630b4da97968 260 break;
frankvnk 0:630b4da97968 261 case 3:
frankvnk 0:630b4da97968 262 wr_reg(0x50, y);
frankvnk 0:630b4da97968 263 wr_reg(0x51, yh1);
frankvnk 0:630b4da97968 264 wr_reg(0x52, 319 - xw1);
frankvnk 0:630b4da97968 265 wr_reg(0x53, 319 - x);
frankvnk 0:630b4da97968 266 break;
frankvnk 0:630b4da97968 267 }
frankvnk 0:630b4da97968 268 }
frankvnk 0:630b4da97968 269
frankvnk 0:630b4da97968 270
frankvnk 0:630b4da97968 271 void SPI_TFT::WindowMax(void)
frankvnk 0:630b4da97968 272 {
frankvnk 0:630b4da97968 273 window(0, 0, width(), height());
frankvnk 0:630b4da97968 274 }
frankvnk 0:630b4da97968 275
frankvnk 0:630b4da97968 276
frankvnk 0:630b4da97968 277 void SPI_TFT::cls (void)
frankvnk 0:630b4da97968 278 {
frankvnk 0:630b4da97968 279 if (backgroundimage == false) {
frankvnk 0:630b4da97968 280 unsigned long int index=0;
frankvnk 0:630b4da97968 281 wr_reg(0x03, 0x1030);
frankvnk 0:630b4da97968 282 WindowMax();
frankvnk 0:630b4da97968 283 SetCursor(0,0);
frankvnk 0:630b4da97968 284 wr_cmd(0x22);
frankvnk 0:630b4da97968 285 _cs = 0;
frankvnk 0:630b4da97968 286 wr_dat_start();
frankvnk 0:630b4da97968 287 _spi.format(16,3);
frankvnk 0:630b4da97968 288 int num = width()*height();
frankvnk 0:630b4da97968 289
frankvnk 0:630b4da97968 290 for( index = 0; index<num; index++ ) {
frankvnk 0:630b4da97968 291 _spi.fastWrite(_background);
frankvnk 0:630b4da97968 292 }
frankvnk 0:630b4da97968 293 _spi.clearRX();
frankvnk 0:630b4da97968 294
frankvnk 0:630b4da97968 295 _spi.format(8,3);
frankvnk 0:630b4da97968 296 _cs = 1;
frankvnk 0:630b4da97968 297 }
frankvnk 0:630b4da97968 298 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 299 else {
frankvnk 0:630b4da97968 300 int _orientation=orientation;
frankvnk 0:630b4da97968 301 set_orientation(backgroundOrientation);
frankvnk 0:630b4da97968 302 Bitmap(0,0,width(),height(),(unsigned char*) sector_start_adress[ 25 ]);
frankvnk 0:630b4da97968 303 set_orientation(_orientation);
frankvnk 0:630b4da97968 304 }
frankvnk 0:630b4da97968 305 #endif
frankvnk 0:630b4da97968 306 }
frankvnk 0:630b4da97968 307
frankvnk 0:630b4da97968 308 void SPI_TFT::hline(int x0, int x1, int y, int color)
frankvnk 0:630b4da97968 309 {
frankvnk 0:630b4da97968 310 unsigned int index=0;
frankvnk 0:630b4da97968 311 int w;
frankvnk 0:630b4da97968 312 w = x1 - x0 + 1;
frankvnk 0:630b4da97968 313 mod_orientation();
frankvnk 0:630b4da97968 314 window(x0,y,w,1);
frankvnk 0:630b4da97968 315 wr_cmd(0x22);
frankvnk 0:630b4da97968 316 _cs = 0;
frankvnk 0:630b4da97968 317 wr_dat_start();
frankvnk 0:630b4da97968 318
frankvnk 0:630b4da97968 319 _spi.format(16,3);
frankvnk 0:630b4da97968 320 int num = x1-x0;
frankvnk 0:630b4da97968 321 for( index = 0; index<num; index++ ) {
frankvnk 0:630b4da97968 322 _spi.fastWrite(color);
frankvnk 0:630b4da97968 323 }
frankvnk 0:630b4da97968 324 _spi.clearRX();
frankvnk 0:630b4da97968 325
frankvnk 0:630b4da97968 326 _spi.format(8,3);
frankvnk 0:630b4da97968 327 _cs = 1;
frankvnk 0:630b4da97968 328 return;
frankvnk 0:630b4da97968 329 }
frankvnk 0:630b4da97968 330
frankvnk 0:630b4da97968 331 void SPI_TFT::vline(int x, int y0, int y1, int color)
frankvnk 0:630b4da97968 332 {
frankvnk 0:630b4da97968 333 unsigned int index=0;
frankvnk 0:630b4da97968 334 int h;
frankvnk 0:630b4da97968 335 h = y1 - y0 + 1;
frankvnk 0:630b4da97968 336 mod_orientation();
frankvnk 0:630b4da97968 337 window(x,y0,1,h);
frankvnk 0:630b4da97968 338 wr_cmd(0x22);
frankvnk 0:630b4da97968 339 _cs = 0;
frankvnk 0:630b4da97968 340 wr_dat_start();
frankvnk 0:630b4da97968 341 _spi.format(16,3);
frankvnk 0:630b4da97968 342 int num = y1-y0;
frankvnk 0:630b4da97968 343 for( index = 0; index<num; index++ ) {
frankvnk 0:630b4da97968 344 _spi.fastWrite(color);
frankvnk 0:630b4da97968 345 }
frankvnk 0:630b4da97968 346 _spi.clearRX();
frankvnk 0:630b4da97968 347 _spi.format(8,3);
frankvnk 0:630b4da97968 348 _cs = 1;
frankvnk 0:630b4da97968 349 return;
frankvnk 0:630b4da97968 350 }
frankvnk 0:630b4da97968 351
frankvnk 0:630b4da97968 352 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color)
frankvnk 0:630b4da97968 353 {
frankvnk 0:630b4da97968 354 wr_reg(0x03, 0x1030);
frankvnk 0:630b4da97968 355 WindowMax();
frankvnk 0:630b4da97968 356 int dx = 0, dy = 0;
frankvnk 0:630b4da97968 357 int dx_sym = 0, dy_sym = 0;
frankvnk 0:630b4da97968 358 int dx_x2 = 0, dy_x2 = 0;
frankvnk 0:630b4da97968 359 int di = 0;
frankvnk 0:630b4da97968 360
frankvnk 0:630b4da97968 361 dx = x1-x0;
frankvnk 0:630b4da97968 362 dy = y1-y0;
frankvnk 0:630b4da97968 363
frankvnk 0:630b4da97968 364 if (dx == 0) { // vertical line
frankvnk 0:630b4da97968 365 if (y1 > y0) vline(x0,y0,y1,color);
frankvnk 0:630b4da97968 366 else vline(x0,y1,y0,color);
frankvnk 0:630b4da97968 367 return;
frankvnk 0:630b4da97968 368 }
frankvnk 0:630b4da97968 369
frankvnk 0:630b4da97968 370 if (dx > 0) {
frankvnk 0:630b4da97968 371 dx_sym = 1;
frankvnk 0:630b4da97968 372 } else {
frankvnk 0:630b4da97968 373 dx_sym = -1;
frankvnk 0:630b4da97968 374 }
frankvnk 0:630b4da97968 375 if (dy == 0) { // horizontal line
frankvnk 0:630b4da97968 376 if (x1 > x0) hline(x0,x1,y0,color);
frankvnk 0:630b4da97968 377 else hline(x1,x0,y0,color);
frankvnk 0:630b4da97968 378 return;
frankvnk 0:630b4da97968 379 }
frankvnk 0:630b4da97968 380
frankvnk 0:630b4da97968 381 if (dy > 0) {
frankvnk 0:630b4da97968 382 dy_sym = 1;
frankvnk 0:630b4da97968 383 } else {
frankvnk 0:630b4da97968 384 dy_sym = -1;
frankvnk 0:630b4da97968 385 }
frankvnk 0:630b4da97968 386
frankvnk 0:630b4da97968 387 dx = dx_sym*dx;
frankvnk 0:630b4da97968 388 dy = dy_sym*dy;
frankvnk 0:630b4da97968 389
frankvnk 0:630b4da97968 390 dx_x2 = dx*2;
frankvnk 0:630b4da97968 391 dy_x2 = dy*2;
frankvnk 0:630b4da97968 392
frankvnk 0:630b4da97968 393 if (dx >= dy) {
frankvnk 0:630b4da97968 394 di = dy_x2 - dx;
frankvnk 0:630b4da97968 395 while (x0 != x1) {
frankvnk 0:630b4da97968 396
frankvnk 0:630b4da97968 397 pixel(x0, y0, color);
frankvnk 0:630b4da97968 398 x0 += dx_sym;
frankvnk 0:630b4da97968 399 if (di<0) {
frankvnk 0:630b4da97968 400 di += dy_x2;
frankvnk 0:630b4da97968 401 } else {
frankvnk 0:630b4da97968 402 di += dy_x2 - dx_x2;
frankvnk 0:630b4da97968 403 y0 += dy_sym;
frankvnk 0:630b4da97968 404 }
frankvnk 0:630b4da97968 405 }
frankvnk 0:630b4da97968 406 pixel(x0, y0, color);
frankvnk 0:630b4da97968 407 } else {
frankvnk 0:630b4da97968 408 di = dx_x2 - dy;
frankvnk 0:630b4da97968 409 while (y0 != y1) {
frankvnk 0:630b4da97968 410 pixel(x0, y0, color);
frankvnk 0:630b4da97968 411 y0 += dy_sym;
frankvnk 0:630b4da97968 412 if (di < 0) {
frankvnk 0:630b4da97968 413 di += dx_x2;
frankvnk 0:630b4da97968 414 } else {
frankvnk 0:630b4da97968 415 di += dx_x2 - dy_x2;
frankvnk 0:630b4da97968 416 x0 += dx_sym;
frankvnk 0:630b4da97968 417 }
frankvnk 0:630b4da97968 418 }
frankvnk 0:630b4da97968 419 pixel(x0, y0, color);
frankvnk 0:630b4da97968 420 }
frankvnk 0:630b4da97968 421 return;
frankvnk 0:630b4da97968 422 }
frankvnk 0:630b4da97968 423
frankvnk 0:630b4da97968 424
frankvnk 0:630b4da97968 425 void SPI_TFT::rect(int x0, int y0, int w, int h, int color)
frankvnk 0:630b4da97968 426 {
frankvnk 0:630b4da97968 427 hline(x0,x0+w,y0,color);
frankvnk 0:630b4da97968 428 vline(x0,y0,y0+h,color);
frankvnk 0:630b4da97968 429 hline(x0,x0+w,y0+h,color);
frankvnk 0:630b4da97968 430 vline(x0+w,y0,y0+h,color);
frankvnk 0:630b4da97968 431
frankvnk 0:630b4da97968 432 return;
frankvnk 0:630b4da97968 433 }
frankvnk 0:630b4da97968 434
frankvnk 0:630b4da97968 435 void SPI_TFT::fillrect(int x0, int y0, int w, int h, int color)
frankvnk 0:630b4da97968 436 {
frankvnk 0:630b4da97968 437 unsigned long int index=0;
frankvnk 0:630b4da97968 438 if (w < 0) {
frankvnk 0:630b4da97968 439 x0 = x0 + w;
frankvnk 0:630b4da97968 440 w = -w;
frankvnk 0:630b4da97968 441 }
frankvnk 0:630b4da97968 442 if (h < 0) {
frankvnk 0:630b4da97968 443 y0 = y0 + h;
frankvnk 0:630b4da97968 444 h = -h;
frankvnk 0:630b4da97968 445 }
frankvnk 0:630b4da97968 446 mod_orientation();
frankvnk 0:630b4da97968 447 window(x0,y0,w,h);
frankvnk 0:630b4da97968 448 wr_cmd(0x22);
frankvnk 0:630b4da97968 449 _cs = 0;
frankvnk 0:630b4da97968 450 wr_dat_start();
frankvnk 0:630b4da97968 451 _spi.format(16,3);
frankvnk 0:630b4da97968 452 int num = h*w;
frankvnk 0:630b4da97968 453 for( index = 0; index<num; index++ ) {
frankvnk 0:630b4da97968 454 _spi.fastWrite(color);
frankvnk 0:630b4da97968 455 }
frankvnk 0:630b4da97968 456 _spi.clearRX();
frankvnk 0:630b4da97968 457 _spi.format(8,3);
frankvnk 0:630b4da97968 458 _cs = 1;
frankvnk 0:630b4da97968 459 return;
frankvnk 0:630b4da97968 460 }
frankvnk 0:630b4da97968 461
frankvnk 0:630b4da97968 462 void SPI_TFT::draw_ellipse(int xc, int yc, int a, int b, unsigned int color)
frankvnk 0:630b4da97968 463 {
frankvnk 0:630b4da97968 464 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
frankvnk 0:630b4da97968 465 wr_reg(0x03, 0x1030);
frankvnk 0:630b4da97968 466 WindowMax();
frankvnk 0:630b4da97968 467 int x = 0, y = b;
frankvnk 0:630b4da97968 468 long a2 = (long)a*a, b2 = (long)b*b;
frankvnk 0:630b4da97968 469 long crit1 = -(a2/4 + a%2 + b2);
frankvnk 0:630b4da97968 470 long crit2 = -(b2/4 + b%2 + a2);
frankvnk 0:630b4da97968 471 long crit3 = -(b2/4 + b%2);
frankvnk 0:630b4da97968 472 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
frankvnk 0:630b4da97968 473 long dxt = 2*b2*x, dyt = -2*a2*y;
frankvnk 0:630b4da97968 474 long d2xt = 2*b2, d2yt = 2*a2;
frankvnk 0:630b4da97968 475
frankvnk 0:630b4da97968 476 while (y>=0 && x<=a) {
frankvnk 0:630b4da97968 477 pixel(xc+x, yc+y, color);
frankvnk 0:630b4da97968 478 if (x!=0 || y!=0)
frankvnk 0:630b4da97968 479 pixel(xc-x, yc-y, color);
frankvnk 0:630b4da97968 480 if (x!=0 && y!=0) {
frankvnk 0:630b4da97968 481 pixel(xc+x, yc-y, color);
frankvnk 0:630b4da97968 482 pixel(xc-x, yc+y, color);
frankvnk 0:630b4da97968 483 }
frankvnk 0:630b4da97968 484 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0
frankvnk 0:630b4da97968 485 t + a2*y <= crit3) // e(x+1/2,y) <= 0
frankvnk 0:630b4da97968 486 incx();
frankvnk 0:630b4da97968 487 else if (t - a2*y > crit2) // e(x+1/2,y-1) > 0
frankvnk 0:630b4da97968 488 incy();
frankvnk 0:630b4da97968 489 else {
frankvnk 0:630b4da97968 490 incx();
frankvnk 0:630b4da97968 491 incy();
frankvnk 0:630b4da97968 492 }
frankvnk 0:630b4da97968 493 }
frankvnk 0:630b4da97968 494 }
frankvnk 0:630b4da97968 495
frankvnk 0:630b4da97968 496 void SPI_TFT::fill_ellipse(int xc, int yc, int a, int b, unsigned int color)
frankvnk 0:630b4da97968 497 {
frankvnk 0:630b4da97968 498 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
frankvnk 0:630b4da97968 499 int x = 0, y = b;
frankvnk 0:630b4da97968 500 int rx = x, ry = y;
frankvnk 0:630b4da97968 501 unsigned int width = 1;
frankvnk 0:630b4da97968 502 unsigned int height = 1;
frankvnk 0:630b4da97968 503 long a2 = (long)a*a, b2 = (long)b*b;
frankvnk 0:630b4da97968 504 long crit1 = -(a2/4 + a%2 + b2);
frankvnk 0:630b4da97968 505 long crit2 = -(b2/4 + b%2 + a2);
frankvnk 0:630b4da97968 506 long crit3 = -(b2/4 + b%2);
frankvnk 0:630b4da97968 507 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
frankvnk 0:630b4da97968 508 long dxt = 2*b2*x, dyt = -2*a2*y;
frankvnk 0:630b4da97968 509 long d2xt = 2*b2, d2yt = 2*a2;
frankvnk 0:630b4da97968 510
frankvnk 0:630b4da97968 511 if (b == 0) {
frankvnk 0:630b4da97968 512 fillrect(xc-a, yc, 2*a+1, 1, color);
frankvnk 0:630b4da97968 513 return;
frankvnk 0:630b4da97968 514 }
frankvnk 0:630b4da97968 515
frankvnk 0:630b4da97968 516 while (y>=0 && x<=a) {
frankvnk 0:630b4da97968 517 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0
frankvnk 0:630b4da97968 518 t + a2*y <= crit3) { // e(x+1/2,y) <= 0
frankvnk 0:630b4da97968 519 if (height == 1)
frankvnk 0:630b4da97968 520 ; // draw nothing
frankvnk 0:630b4da97968 521 else if (ry*2+1 > (height-1)*2) {
frankvnk 0:630b4da97968 522 fillrect(xc-rx, yc-ry, width, height-1, color);
frankvnk 0:630b4da97968 523 fillrect(xc-rx, yc+ry+1, width, 1-height, color);
frankvnk 0:630b4da97968 524 ry -= height-1;
frankvnk 0:630b4da97968 525 height = 1;
frankvnk 0:630b4da97968 526 } else {
frankvnk 0:630b4da97968 527 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 528 ry -= ry;
frankvnk 0:630b4da97968 529 height = 1;
frankvnk 0:630b4da97968 530 }
frankvnk 0:630b4da97968 531 incx();
frankvnk 0:630b4da97968 532 rx++;
frankvnk 0:630b4da97968 533 width += 2;
frankvnk 0:630b4da97968 534 } else if (t - a2*y > crit2) { // e(x+1/2,y-1) > 0
frankvnk 0:630b4da97968 535 incy();
frankvnk 0:630b4da97968 536 height++;
frankvnk 0:630b4da97968 537 } else {
frankvnk 0:630b4da97968 538 if (ry*2+1 > height*2) {
frankvnk 0:630b4da97968 539 fillrect(xc-rx, yc-ry, width, height, color);
frankvnk 0:630b4da97968 540 fillrect(xc-rx, yc+ry+1, width, -height, color);
frankvnk 0:630b4da97968 541 } else {
frankvnk 0:630b4da97968 542 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 543 }
frankvnk 0:630b4da97968 544 incx();
frankvnk 0:630b4da97968 545 incy();
frankvnk 0:630b4da97968 546 rx++;
frankvnk 0:630b4da97968 547 width += 2;
frankvnk 0:630b4da97968 548 ry -= height;
frankvnk 0:630b4da97968 549 height = 1;
frankvnk 0:630b4da97968 550 }
frankvnk 0:630b4da97968 551 }
frankvnk 0:630b4da97968 552
frankvnk 0:630b4da97968 553 if (ry > height) {
frankvnk 0:630b4da97968 554 fillrect(xc-rx, yc-ry, width, height, color);
frankvnk 0:630b4da97968 555 fillrect(xc-rx, yc+ry+1, width, -height, color);
frankvnk 0:630b4da97968 556 } else {
frankvnk 0:630b4da97968 557 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 558 }
frankvnk 0:630b4da97968 559 }
frankvnk 0:630b4da97968 560
frankvnk 0:630b4da97968 561
frankvnk 0:630b4da97968 562 void SPI_TFT::locate(int x, int y)
frankvnk 0:630b4da97968 563 {
frankvnk 0:630b4da97968 564 char_x = x;
frankvnk 0:630b4da97968 565 char_y = y;
frankvnk 0:630b4da97968 566 }
frankvnk 0:630b4da97968 567
frankvnk 0:630b4da97968 568 int SPI_TFT::columns()
frankvnk 0:630b4da97968 569 {
frankvnk 0:630b4da97968 570 return width() / font[1];
frankvnk 0:630b4da97968 571 }
frankvnk 0:630b4da97968 572
frankvnk 0:630b4da97968 573 int SPI_TFT::rows()
frankvnk 0:630b4da97968 574 {
frankvnk 0:630b4da97968 575 return height() / font[2];
frankvnk 0:630b4da97968 576 }
frankvnk 0:630b4da97968 577
frankvnk 0:630b4da97968 578 int SPI_TFT::_putc(int value)
frankvnk 0:630b4da97968 579 {
frankvnk 0:630b4da97968 580 if (value == '\n') { // new line
frankvnk 0:630b4da97968 581 char_x = 0;
frankvnk 0:630b4da97968 582 char_y = char_y + font[2];
frankvnk 0:630b4da97968 583 if (char_y >= height() - font[2]) {
frankvnk 0:630b4da97968 584 char_y = 0;
frankvnk 0:630b4da97968 585 }
frankvnk 0:630b4da97968 586 } else {
frankvnk 0:630b4da97968 587 character(char_x, char_y, value);
frankvnk 0:630b4da97968 588 }
frankvnk 0:630b4da97968 589 return value;
frankvnk 0:630b4da97968 590 }
frankvnk 0:630b4da97968 591
frankvnk 0:630b4da97968 592 void SPI_TFT::character(int x, int y, int c)
frankvnk 0:630b4da97968 593 {
frankvnk 0:630b4da97968 594 unsigned int hor,vert,offset,bpl,j,i,b;
frankvnk 0:630b4da97968 595 unsigned char* bitmap_char;
frankvnk 0:630b4da97968 596 unsigned char z,w;
frankvnk 0:630b4da97968 597
frankvnk 0:630b4da97968 598 if ((c < 31) || (c > 127)) return; // test char range
frankvnk 0:630b4da97968 599
frankvnk 0:630b4da97968 600 // read font parameter from start of array
frankvnk 0:630b4da97968 601 offset = font[0]; // bytes / char
frankvnk 0:630b4da97968 602 hor = font[1]; // get hor size of font
frankvnk 0:630b4da97968 603 vert = font[2]; // get vert size of font
frankvnk 0:630b4da97968 604 bpl = font[3]; // bytes per line
frankvnk 0:630b4da97968 605
frankvnk 0:630b4da97968 606 if (char_x + hor > width()) {
frankvnk 0:630b4da97968 607 char_x = 0;
frankvnk 0:630b4da97968 608 char_y = char_y + vert;
frankvnk 0:630b4da97968 609 if (char_y >= height() - font[2]) {
frankvnk 0:630b4da97968 610 char_y = 0;
frankvnk 0:630b4da97968 611 }
frankvnk 0:630b4da97968 612 }
frankvnk 0:630b4da97968 613 mod_orientation();
frankvnk 0:630b4da97968 614
frankvnk 0:630b4da97968 615 bitmap_char = &font[((c -32) * offset) + 4]; // start of char bitmap
frankvnk 0:630b4da97968 616 w = bitmap_char[0]; // width of actual char
frankvnk 0:630b4da97968 617 window(char_x, char_y,w,vert); // char box
frankvnk 0:630b4da97968 618 wr_cmd(0x22);
frankvnk 0:630b4da97968 619 _cs = 0;
frankvnk 0:630b4da97968 620 wr_dat_start();
frankvnk 0:630b4da97968 621 _spi.format(16,3);
frankvnk 0:630b4da97968 622 for (j=0; j<vert; j++) { // vert line
frankvnk 0:630b4da97968 623 for (i=0; i<w; i++) { // horz line
frankvnk 0:630b4da97968 624 z = bitmap_char[bpl * i + ((j & 0xF8) >> 3)+1];
frankvnk 0:630b4da97968 625 b = 1 << (j & 0x07);
frankvnk 0:630b4da97968 626 if (( z & b ) == 0x00) {
frankvnk 0:630b4da97968 627 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 628 if (backgroundimage==false)
frankvnk 0:630b4da97968 629 #endif
frankvnk 0:630b4da97968 630 _spi.fastWrite(_background);
frankvnk 0:630b4da97968 631 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 632 else
frankvnk 0:630b4da97968 633 {
frankvnk 0:630b4da97968 634 unsigned short *bitmap_ptr = (unsigned short *)sector_start_adress[ 25 ];
frankvnk 0:630b4da97968 635 int angle = (orientation - backgroundOrientation)%4; //Get the difference in orientation between background and current
frankvnk 0:630b4da97968 636 switch (angle) {
frankvnk 0:630b4da97968 637 case 0: //Same orientation
frankvnk 0:630b4da97968 638 bitmap_ptr += width() * (height()-(y+j+1))+x+i;
frankvnk 0:630b4da97968 639 break;
frankvnk 0:630b4da97968 640 case 1: //Rotated 1 (don't ask me which direction)
frankvnk 0:630b4da97968 641 bitmap_ptr += height() * (width()-(x+i+1))+height()-(y+j + 1);
frankvnk 0:630b4da97968 642 break;
frankvnk 0:630b4da97968 643 case 2: //Upside down
frankvnk 0:630b4da97968 644 bitmap_ptr += width() * (y+j)+width() - (x+i + 1);
frankvnk 0:630b4da97968 645 break;
frankvnk 0:630b4da97968 646 case 3: //Rotated 3
frankvnk 0:630b4da97968 647 bitmap_ptr += height() * (x+i)+y+j;
frankvnk 0:630b4da97968 648 break;
frankvnk 0:630b4da97968 649 default:
frankvnk 0:630b4da97968 650 break;
frankvnk 0:630b4da97968 651 }
frankvnk 0:630b4da97968 652
frankvnk 0:630b4da97968 653 _spi.fastWrite(*bitmap_ptr);
frankvnk 0:630b4da97968 654 }
frankvnk 0:630b4da97968 655 #endif
frankvnk 0:630b4da97968 656 } else {
frankvnk 0:630b4da97968 657 _spi.fastWrite(_foreground);
frankvnk 0:630b4da97968 658 }
frankvnk 0:630b4da97968 659 }
frankvnk 0:630b4da97968 660 }
frankvnk 0:630b4da97968 661 _spi.clearRX();
frankvnk 0:630b4da97968 662 _spi.format(8,3);
frankvnk 0:630b4da97968 663 _cs = 1;
frankvnk 0:630b4da97968 664 if ((w + 2) < hor) { // x offset to next char
frankvnk 0:630b4da97968 665 char_x += w + 2;
frankvnk 0:630b4da97968 666 } else char_x += hor;
frankvnk 0:630b4da97968 667 }
frankvnk 0:630b4da97968 668
frankvnk 0:630b4da97968 669 void SPI_TFT::set_font(unsigned char* f)
frankvnk 0:630b4da97968 670 {
frankvnk 0:630b4da97968 671 font = f;
frankvnk 0:630b4da97968 672 }
frankvnk 0:630b4da97968 673
frankvnk 0:630b4da97968 674
frankvnk 0:630b4da97968 675 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
frankvnk 0:630b4da97968 676 {
frankvnk 0:630b4da97968 677 unsigned int i,j;
frankvnk 0:630b4da97968 678 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
frankvnk 0:630b4da97968 679 mod_orientation();
frankvnk 0:630b4da97968 680 window(x, y, w, h);
frankvnk 0:630b4da97968 681 wr_cmd(0x22);
frankvnk 0:630b4da97968 682 _cs = 0;
frankvnk 0:630b4da97968 683 wr_dat_start();
frankvnk 0:630b4da97968 684 _spi.format(16,3);
frankvnk 0:630b4da97968 685 bitmap_ptr += ((h - 1)*w);
frankvnk 0:630b4da97968 686 for (j = 0; j < h; j++) { //Lines
frankvnk 0:630b4da97968 687 for (i = 0; i < w; i++) { // copy pixel data to TFT
frankvnk 0:630b4da97968 688 _spi.fastWrite(*bitmap_ptr); // one line
frankvnk 0:630b4da97968 689 bitmap_ptr++;
frankvnk 0:630b4da97968 690 }
frankvnk 0:630b4da97968 691 bitmap_ptr -= 2*w;
frankvnk 0:630b4da97968 692 }
frankvnk 0:630b4da97968 693 _spi.clearRX();
frankvnk 0:630b4da97968 694 _spi.format(8,3);
frankvnk 0:630b4da97968 695 _cs = 1;
frankvnk 0:630b4da97968 696 }
frankvnk 0:630b4da97968 697
frankvnk 0:630b4da97968 698 int SPI_TFT::Bitmap(unsigned int x, unsigned int y, const char *Name_BMP)
frankvnk 0:630b4da97968 699 {
frankvnk 0:630b4da97968 700 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
frankvnk 0:630b4da97968 701 mod_orientation();
frankvnk 0:630b4da97968 702
frankvnk 0:630b4da97968 703 bitmapData bmp = getBitmapData(Name_BMP);
frankvnk 0:630b4da97968 704 if (bmp.return_code != 1)
frankvnk 0:630b4da97968 705 return bmp.return_code;
frankvnk 0:630b4da97968 706
frankvnk 0:630b4da97968 707
frankvnk 0:630b4da97968 708 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line
frankvnk 0:630b4da97968 709 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short
frankvnk 0:630b4da97968 710
frankvnk 0:630b4da97968 711
frankvnk 0:630b4da97968 712 if ((bmp.height > height()+y) || (bmp.width > width()+x))
frankvnk 0:630b4da97968 713 return -3; //Size mismatch
frankvnk 0:630b4da97968 714
frankvnk 0:630b4da97968 715 if (line == NULL)
frankvnk 0:630b4da97968 716 return(-4); // error no memory
frankvnk 0:630b4da97968 717
frankvnk 0:630b4da97968 718
frankvnk 0:630b4da97968 719 for (int j = bmp.height-1; j >= 0; j--) { //Lines bottom up
frankvnk 0:630b4da97968 720 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line
frankvnk 0:630b4da97968 721 fseek(bmp.file, off ,SEEK_SET);
frankvnk 0:630b4da97968 722 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow !
frankvnk 0:630b4da97968 723
frankvnk 0:630b4da97968 724 //If 24 bit format, convert to 565
frankvnk 0:630b4da97968 725 if (bmp.bits == 24) {
frankvnk 0:630b4da97968 726 for (int i = 0; i<bmp.width; i++) {
frankvnk 0:630b4da97968 727 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]);
frankvnk 0:630b4da97968 728 }
frankvnk 0:630b4da97968 729 }
frankvnk 0:630b4da97968 730
frankvnk 0:630b4da97968 731 window(x, y+bmp.height - 1 - j,bmp.width ,1);
frankvnk 0:630b4da97968 732 wr_cmd(0x22);
frankvnk 0:630b4da97968 733
frankvnk 0:630b4da97968 734 _cs = 0;
frankvnk 0:630b4da97968 735 wr_dat_start();
frankvnk 0:630b4da97968 736 _spi.format(16, 3);
frankvnk 0:630b4da97968 737 _spi.setFormat();
frankvnk 0:630b4da97968 738
frankvnk 0:630b4da97968 739 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT
frankvnk 0:630b4da97968 740 _spi.fastWrite(line_short[i]); // one line
frankvnk 0:630b4da97968 741 }
frankvnk 0:630b4da97968 742
frankvnk 0:630b4da97968 743 _spi.clearRX();
frankvnk 0:630b4da97968 744 _spi.format(8,3);
frankvnk 0:630b4da97968 745 _cs = 1;
frankvnk 0:630b4da97968 746
frankvnk 0:630b4da97968 747 }
frankvnk 0:630b4da97968 748
frankvnk 0:630b4da97968 749
frankvnk 0:630b4da97968 750 free (line);
frankvnk 0:630b4da97968 751 fclose(bmp.file);
frankvnk 0:630b4da97968 752 WindowMax();
frankvnk 0:630b4da97968 753
frankvnk 0:630b4da97968 754 return(1);
frankvnk 0:630b4da97968 755 }
frankvnk 0:630b4da97968 756
frankvnk 0:630b4da97968 757 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 758
frankvnk 0:630b4da97968 759 int SPI_TFT::fileToFlash(const char *Name_BMP)
frankvnk 0:630b4da97968 760 {
frankvnk 0:630b4da97968 761 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
frankvnk 0:630b4da97968 762
frankvnk 0:630b4da97968 763 mod_orientation();
frankvnk 0:630b4da97968 764
frankvnk 0:630b4da97968 765 bitmapData bmp = getBitmapData(Name_BMP);
frankvnk 0:630b4da97968 766 if (bmp.return_code != 1)
frankvnk 0:630b4da97968 767 return bmp.return_code;
frankvnk 0:630b4da97968 768
frankvnk 0:630b4da97968 769
frankvnk 0:630b4da97968 770 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line
frankvnk 0:630b4da97968 771 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short
frankvnk 0:630b4da97968 772
frankvnk 0:630b4da97968 773 unsigned short *flashSector = (unsigned short *) malloc (256); //And one to send to flash
frankvnk 0:630b4da97968 774
frankvnk 0:630b4da97968 775 if ((bmp.height != height()) || (bmp.width != width()))
frankvnk 0:630b4da97968 776 return -3; //Size mismatch
frankvnk 0:630b4da97968 777
frankvnk 0:630b4da97968 778 if ((line == NULL) || (flashSector == NULL))
frankvnk 0:630b4da97968 779 return(-4); // error no memory
frankvnk 0:630b4da97968 780
frankvnk 0:630b4da97968 781
frankvnk 0:630b4da97968 782 int flashPointer = 0, flashWrites = 0;
frankvnk 0:630b4da97968 783
frankvnk 0:630b4da97968 784 //Erase Flash that will be used:
frankvnk 0:630b4da97968 785 if ( iap.blank_check( 25, 29 ) == SECTOR_NOT_BLANK ) {
frankvnk 0:630b4da97968 786 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 787 iap.erase( 25, 29 );
frankvnk 0:630b4da97968 788 }
frankvnk 0:630b4da97968 789
frankvnk 0:630b4da97968 790 for (int j = 0; j < bmp.height; j++) { //Lines bottom up
frankvnk 0:630b4da97968 791 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line
frankvnk 0:630b4da97968 792 fseek(bmp.file, off ,SEEK_SET);
frankvnk 0:630b4da97968 793 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow !
frankvnk 0:630b4da97968 794
frankvnk 0:630b4da97968 795 //If 24 bit format, do some processing
frankvnk 0:630b4da97968 796 if (bmp.bits == 24) {
frankvnk 0:630b4da97968 797 for (int i = 0; i<bmp.width; i++) {
frankvnk 0:630b4da97968 798 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]);
frankvnk 0:630b4da97968 799 }
frankvnk 0:630b4da97968 800 }
frankvnk 0:630b4da97968 801
frankvnk 0:630b4da97968 802
frankvnk 0:630b4da97968 803 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT
frankvnk 0:630b4da97968 804 flashSector[flashPointer] = line_short[i]; // one line
frankvnk 0:630b4da97968 805 flashPointer++;
frankvnk 0:630b4da97968 806
frankvnk 0:630b4da97968 807 //If flashpointer reached the end, write to flash
frankvnk 0:630b4da97968 808 if (flashPointer == 128) {
frankvnk 0:630b4da97968 809 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 810 iap.write((char *)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256);
frankvnk 0:630b4da97968 811 flashPointer = 0;
frankvnk 0:630b4da97968 812 flashWrites++;
frankvnk 0:630b4da97968 813 if (flashWrites == 1000)
frankvnk 0:630b4da97968 814 error("Too many flashwrites");
frankvnk 0:630b4da97968 815 }
frankvnk 0:630b4da97968 816 }
frankvnk 0:630b4da97968 817 }
frankvnk 0:630b4da97968 818 //write remaining data
frankvnk 0:630b4da97968 819 if (flashPointer!=0) {
frankvnk 0:630b4da97968 820 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 821 iap.write((char*)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256);
frankvnk 0:630b4da97968 822 flashPointer = 0;
frankvnk 0:630b4da97968 823 flashWrites++;
frankvnk 0:630b4da97968 824 if (flashWrites == 1000)
frankvnk 0:630b4da97968 825 error("Too many flashwrites");
frankvnk 0:630b4da97968 826 }
frankvnk 0:630b4da97968 827
frankvnk 0:630b4da97968 828
frankvnk 0:630b4da97968 829
frankvnk 0:630b4da97968 830 free (line);
frankvnk 0:630b4da97968 831 fclose(bmp.file);
frankvnk 0:630b4da97968 832 backgroundImage(true);
frankvnk 0:630b4da97968 833 backgroundOrientation = orientation;
frankvnk 0:630b4da97968 834 return(1);
frankvnk 0:630b4da97968 835 }
frankvnk 0:630b4da97968 836
frankvnk 0:630b4da97968 837 void SPI_TFT::backgroundImage( bool active) {
frankvnk 0:630b4da97968 838 backgroundimage = active;
frankvnk 0:630b4da97968 839 }
frankvnk 0:630b4da97968 840 #endif
frankvnk 0:630b4da97968 841
frankvnk 0:630b4da97968 842
frankvnk 0:630b4da97968 843 SPI_TFT::bitmapData SPI_TFT::getBitmapData(const char *Name_BMP){
frankvnk 0:630b4da97968 844 #define OffsetPixelWidth 18
frankvnk 0:630b4da97968 845 #define OffsetPixelHeigh 22
frankvnk 0:630b4da97968 846 #define OffsetFileSize 34
frankvnk 0:630b4da97968 847 #define OffsetPixData 10
frankvnk 0:630b4da97968 848 #define OffsetBPP 28
frankvnk 0:630b4da97968 849
frankvnk 0:630b4da97968 850
frankvnk 0:630b4da97968 851 bitmapData retval;
frankvnk 0:630b4da97968 852 retval.return_code = 1;
frankvnk 0:630b4da97968 853 unsigned char BMP_Header[54];
frankvnk 0:630b4da97968 854
frankvnk 0:630b4da97968 855 retval.file = fopen(Name_BMP, "rb"); // open the bmp file
frankvnk 0:630b4da97968 856 if (!retval.file) {
frankvnk 0:630b4da97968 857 retval.return_code = 0;
frankvnk 0:630b4da97968 858 return(retval); // error file not found !
frankvnk 0:630b4da97968 859 }
frankvnk 0:630b4da97968 860
frankvnk 0:630b4da97968 861 fread(&BMP_Header[0],1,54,retval.file); // get the BMP Header
frankvnk 0:630b4da97968 862
frankvnk 0:630b4da97968 863 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
frankvnk 0:630b4da97968 864 fclose(retval.file);
frankvnk 0:630b4da97968 865 retval.return_code = -1;
frankvnk 0:630b4da97968 866 return(retval); // error not a BMP file
frankvnk 0:630b4da97968 867 }
frankvnk 0:630b4da97968 868
frankvnk 0:630b4da97968 869 int BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
frankvnk 0:630b4da97968 870 if (BPP_t == 0x0010)
frankvnk 0:630b4da97968 871 retval.bits = 16;
frankvnk 0:630b4da97968 872 else if (BPP_t == 0x0018)
frankvnk 0:630b4da97968 873 retval.bits = 24;
frankvnk 0:630b4da97968 874 else {
frankvnk 0:630b4da97968 875 fclose(retval.file);
frankvnk 0:630b4da97968 876 retval.return_code = -2;
frankvnk 0:630b4da97968 877 return(retval); // error no 16/24 bit BMP
frankvnk 0:630b4da97968 878 }
frankvnk 0:630b4da97968 879
frankvnk 0:630b4da97968 880 retval.height = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
frankvnk 0:630b4da97968 881 retval.width = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
frankvnk 0:630b4da97968 882 if (retval.height > height()|| retval.width > width()) {
frankvnk 0:630b4da97968 883 fclose(retval.file);
frankvnk 0:630b4da97968 884 retval.return_code = -3;
frankvnk 0:630b4da97968 885 return(retval); // too big
frankvnk 0:630b4da97968 886 }
frankvnk 0:630b4da97968 887
frankvnk 0:630b4da97968 888
frankvnk 0:630b4da97968 889 retval.start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
frankvnk 0:630b4da97968 890
frankvnk 0:630b4da97968 891 // the bmp lines are padded to multiple of 4 bytes
frankvnk 0:630b4da97968 892 retval.pad = -1;
frankvnk 0:630b4da97968 893 do {
frankvnk 0:630b4da97968 894 retval.pad ++;
frankvnk 0:630b4da97968 895 } while ((retval.width * retval.bits/8 + retval.pad)%4 != 0);
frankvnk 0:630b4da97968 896 return retval;
frankvnk 0:630b4da97968 897
frankvnk 0:630b4da97968 898 }