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:
Tue Mar 18 18:59:54 2014 +0000
Revision:
3:a016fe71ed72
Parent:
2:45a3c5aa99c3
Child:
4:2519f2e680af
Added KL25Z

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 3:a016fe71ed72 287 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 288 _spi.format(16,3);
frankvnk 3:a016fe71ed72 289 #endif
frankvnk 0:630b4da97968 290 int num = width()*height();
frankvnk 0:630b4da97968 291
frankvnk 0:630b4da97968 292 for( index = 0; index<num; index++ ) {
frankvnk 3:a016fe71ed72 293 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 294 _spi.fastWrite(_background);
frankvnk 3:a016fe71ed72 295 #else
frankvnk 3:a016fe71ed72 296 _spi.fastWrite(_background >> 8);
frankvnk 3:a016fe71ed72 297 _spi.fastWrite(_background & 0xFF);
frankvnk 3:a016fe71ed72 298 #endif
frankvnk 0:630b4da97968 299 }
frankvnk 0:630b4da97968 300 _spi.clearRX();
frankvnk 0:630b4da97968 301
frankvnk 3:a016fe71ed72 302 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 303 _spi.format(8,3);
frankvnk 3:a016fe71ed72 304 #endif
frankvnk 0:630b4da97968 305 _cs = 1;
frankvnk 0:630b4da97968 306 }
frankvnk 0:630b4da97968 307 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 308 else {
frankvnk 0:630b4da97968 309 int _orientation=orientation;
frankvnk 0:630b4da97968 310 set_orientation(backgroundOrientation);
frankvnk 0:630b4da97968 311 Bitmap(0,0,width(),height(),(unsigned char*) sector_start_adress[ 25 ]);
frankvnk 0:630b4da97968 312 set_orientation(_orientation);
frankvnk 0:630b4da97968 313 }
frankvnk 0:630b4da97968 314 #endif
frankvnk 0:630b4da97968 315 }
frankvnk 0:630b4da97968 316
frankvnk 0:630b4da97968 317 void SPI_TFT::hline(int x0, int x1, int y, int color)
frankvnk 0:630b4da97968 318 {
frankvnk 0:630b4da97968 319 unsigned int index=0;
frankvnk 0:630b4da97968 320 int w;
frankvnk 0:630b4da97968 321 w = x1 - x0 + 1;
frankvnk 0:630b4da97968 322 mod_orientation();
frankvnk 0:630b4da97968 323 window(x0,y,w,1);
frankvnk 0:630b4da97968 324 wr_cmd(0x22);
frankvnk 0:630b4da97968 325 _cs = 0;
frankvnk 0:630b4da97968 326 wr_dat_start();
frankvnk 0:630b4da97968 327
frankvnk 3:a016fe71ed72 328 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 329 _spi.format(16,3);
frankvnk 3:a016fe71ed72 330 #endif
frankvnk 0:630b4da97968 331 int num = x1-x0;
frankvnk 0:630b4da97968 332 for( index = 0; index<num; index++ ) {
frankvnk 3:a016fe71ed72 333 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 334 _spi.fastWrite(color);
frankvnk 3:a016fe71ed72 335 #else
frankvnk 3:a016fe71ed72 336 _spi.fastWrite(color >> 8);
frankvnk 3:a016fe71ed72 337 _spi.fastWrite(color & 0xFF);
frankvnk 3:a016fe71ed72 338 #endif
frankvnk 0:630b4da97968 339 }
frankvnk 0:630b4da97968 340 _spi.clearRX();
frankvnk 0:630b4da97968 341
frankvnk 3:a016fe71ed72 342 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 343 _spi.format(8,3);
frankvnk 3:a016fe71ed72 344 #endif
frankvnk 0:630b4da97968 345 _cs = 1;
frankvnk 0:630b4da97968 346 return;
frankvnk 0:630b4da97968 347 }
frankvnk 0:630b4da97968 348
frankvnk 0:630b4da97968 349 void SPI_TFT::vline(int x, int y0, int y1, int color)
frankvnk 0:630b4da97968 350 {
frankvnk 0:630b4da97968 351 unsigned int index=0;
frankvnk 0:630b4da97968 352 int h;
frankvnk 0:630b4da97968 353 h = y1 - y0 + 1;
frankvnk 0:630b4da97968 354 mod_orientation();
frankvnk 0:630b4da97968 355 window(x,y0,1,h);
frankvnk 0:630b4da97968 356 wr_cmd(0x22);
frankvnk 0:630b4da97968 357 _cs = 0;
frankvnk 0:630b4da97968 358 wr_dat_start();
frankvnk 3:a016fe71ed72 359 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 360 _spi.format(16,3);
frankvnk 3:a016fe71ed72 361 #endif
frankvnk 0:630b4da97968 362 int num = y1-y0;
frankvnk 0:630b4da97968 363 for( index = 0; index<num; index++ ) {
frankvnk 3:a016fe71ed72 364 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 365 _spi.fastWrite(color);
frankvnk 3:a016fe71ed72 366 #else
frankvnk 3:a016fe71ed72 367 _spi.fastWrite(color >> 8);
frankvnk 3:a016fe71ed72 368 _spi.fastWrite(color & 0xFF);
frankvnk 3:a016fe71ed72 369 #endif
frankvnk 0:630b4da97968 370 }
frankvnk 0:630b4da97968 371 _spi.clearRX();
frankvnk 3:a016fe71ed72 372 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 373 _spi.format(8,3);
frankvnk 3:a016fe71ed72 374 #endif
frankvnk 0:630b4da97968 375 _cs = 1;
frankvnk 0:630b4da97968 376 return;
frankvnk 0:630b4da97968 377 }
frankvnk 0:630b4da97968 378
frankvnk 0:630b4da97968 379 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color)
frankvnk 0:630b4da97968 380 {
frankvnk 0:630b4da97968 381 wr_reg(0x03, 0x1030);
frankvnk 0:630b4da97968 382 WindowMax();
frankvnk 0:630b4da97968 383 int dx = 0, dy = 0;
frankvnk 0:630b4da97968 384 int dx_sym = 0, dy_sym = 0;
frankvnk 0:630b4da97968 385 int dx_x2 = 0, dy_x2 = 0;
frankvnk 0:630b4da97968 386 int di = 0;
frankvnk 0:630b4da97968 387
frankvnk 0:630b4da97968 388 dx = x1-x0;
frankvnk 0:630b4da97968 389 dy = y1-y0;
frankvnk 0:630b4da97968 390
frankvnk 0:630b4da97968 391 if (dx == 0) { // vertical line
frankvnk 0:630b4da97968 392 if (y1 > y0) vline(x0,y0,y1,color);
frankvnk 0:630b4da97968 393 else vline(x0,y1,y0,color);
frankvnk 0:630b4da97968 394 return;
frankvnk 0:630b4da97968 395 }
frankvnk 0:630b4da97968 396
frankvnk 0:630b4da97968 397 if (dx > 0) {
frankvnk 0:630b4da97968 398 dx_sym = 1;
frankvnk 0:630b4da97968 399 } else {
frankvnk 0:630b4da97968 400 dx_sym = -1;
frankvnk 0:630b4da97968 401 }
frankvnk 0:630b4da97968 402 if (dy == 0) { // horizontal line
frankvnk 0:630b4da97968 403 if (x1 > x0) hline(x0,x1,y0,color);
frankvnk 0:630b4da97968 404 else hline(x1,x0,y0,color);
frankvnk 0:630b4da97968 405 return;
frankvnk 0:630b4da97968 406 }
frankvnk 0:630b4da97968 407
frankvnk 0:630b4da97968 408 if (dy > 0) {
frankvnk 0:630b4da97968 409 dy_sym = 1;
frankvnk 0:630b4da97968 410 } else {
frankvnk 0:630b4da97968 411 dy_sym = -1;
frankvnk 0:630b4da97968 412 }
frankvnk 0:630b4da97968 413
frankvnk 0:630b4da97968 414 dx = dx_sym*dx;
frankvnk 0:630b4da97968 415 dy = dy_sym*dy;
frankvnk 0:630b4da97968 416
frankvnk 0:630b4da97968 417 dx_x2 = dx*2;
frankvnk 0:630b4da97968 418 dy_x2 = dy*2;
frankvnk 0:630b4da97968 419
frankvnk 0:630b4da97968 420 if (dx >= dy) {
frankvnk 0:630b4da97968 421 di = dy_x2 - dx;
frankvnk 0:630b4da97968 422 while (x0 != x1) {
frankvnk 0:630b4da97968 423
frankvnk 0:630b4da97968 424 pixel(x0, y0, color);
frankvnk 0:630b4da97968 425 x0 += dx_sym;
frankvnk 0:630b4da97968 426 if (di<0) {
frankvnk 0:630b4da97968 427 di += dy_x2;
frankvnk 0:630b4da97968 428 } else {
frankvnk 0:630b4da97968 429 di += dy_x2 - dx_x2;
frankvnk 0:630b4da97968 430 y0 += dy_sym;
frankvnk 0:630b4da97968 431 }
frankvnk 0:630b4da97968 432 }
frankvnk 0:630b4da97968 433 pixel(x0, y0, color);
frankvnk 0:630b4da97968 434 } else {
frankvnk 0:630b4da97968 435 di = dx_x2 - dy;
frankvnk 0:630b4da97968 436 while (y0 != y1) {
frankvnk 0:630b4da97968 437 pixel(x0, y0, color);
frankvnk 0:630b4da97968 438 y0 += dy_sym;
frankvnk 0:630b4da97968 439 if (di < 0) {
frankvnk 0:630b4da97968 440 di += dx_x2;
frankvnk 0:630b4da97968 441 } else {
frankvnk 0:630b4da97968 442 di += dx_x2 - dy_x2;
frankvnk 0:630b4da97968 443 x0 += dx_sym;
frankvnk 0:630b4da97968 444 }
frankvnk 0:630b4da97968 445 }
frankvnk 0:630b4da97968 446 pixel(x0, y0, color);
frankvnk 0:630b4da97968 447 }
frankvnk 0:630b4da97968 448 return;
frankvnk 0:630b4da97968 449 }
frankvnk 0:630b4da97968 450
frankvnk 0:630b4da97968 451
frankvnk 0:630b4da97968 452 void SPI_TFT::rect(int x0, int y0, int w, int h, int color)
frankvnk 0:630b4da97968 453 {
frankvnk 0:630b4da97968 454 hline(x0,x0+w,y0,color);
frankvnk 0:630b4da97968 455 vline(x0,y0,y0+h,color);
frankvnk 0:630b4da97968 456 hline(x0,x0+w,y0+h,color);
frankvnk 0:630b4da97968 457 vline(x0+w,y0,y0+h,color);
frankvnk 0:630b4da97968 458
frankvnk 0:630b4da97968 459 return;
frankvnk 0:630b4da97968 460 }
frankvnk 0:630b4da97968 461
frankvnk 0:630b4da97968 462 void SPI_TFT::fillrect(int x0, int y0, int w, int h, int color)
frankvnk 0:630b4da97968 463 {
frankvnk 0:630b4da97968 464 unsigned long int index=0;
frankvnk 0:630b4da97968 465 if (w < 0) {
frankvnk 0:630b4da97968 466 x0 = x0 + w;
frankvnk 0:630b4da97968 467 w = -w;
frankvnk 0:630b4da97968 468 }
frankvnk 0:630b4da97968 469 if (h < 0) {
frankvnk 0:630b4da97968 470 y0 = y0 + h;
frankvnk 0:630b4da97968 471 h = -h;
frankvnk 0:630b4da97968 472 }
frankvnk 0:630b4da97968 473 mod_orientation();
frankvnk 0:630b4da97968 474 window(x0,y0,w,h);
frankvnk 0:630b4da97968 475 wr_cmd(0x22);
frankvnk 0:630b4da97968 476 _cs = 0;
frankvnk 0:630b4da97968 477 wr_dat_start();
frankvnk 3:a016fe71ed72 478 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 479 _spi.format(16,3);
frankvnk 3:a016fe71ed72 480 #endif
frankvnk 0:630b4da97968 481 int num = h*w;
frankvnk 0:630b4da97968 482 for( index = 0; index<num; index++ ) {
frankvnk 3:a016fe71ed72 483 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 484 _spi.fastWrite(color);
frankvnk 3:a016fe71ed72 485 #else
frankvnk 3:a016fe71ed72 486 _spi.fastWrite(color >> 8);
frankvnk 3:a016fe71ed72 487 _spi.fastWrite(color & 0xFF);
frankvnk 3:a016fe71ed72 488 #endif
frankvnk 0:630b4da97968 489 }
frankvnk 0:630b4da97968 490 _spi.clearRX();
frankvnk 3:a016fe71ed72 491 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 492 _spi.format(8,3);
frankvnk 3:a016fe71ed72 493 #endif
frankvnk 0:630b4da97968 494 _cs = 1;
frankvnk 0:630b4da97968 495 return;
frankvnk 0:630b4da97968 496 }
frankvnk 0:630b4da97968 497
frankvnk 0:630b4da97968 498 void SPI_TFT::draw_ellipse(int xc, int yc, int a, int b, unsigned int color)
frankvnk 0:630b4da97968 499 {
frankvnk 0:630b4da97968 500 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
frankvnk 0:630b4da97968 501 wr_reg(0x03, 0x1030);
frankvnk 0:630b4da97968 502 WindowMax();
frankvnk 0:630b4da97968 503 int x = 0, y = b;
frankvnk 0:630b4da97968 504 long a2 = (long)a*a, b2 = (long)b*b;
frankvnk 0:630b4da97968 505 long crit1 = -(a2/4 + a%2 + b2);
frankvnk 0:630b4da97968 506 long crit2 = -(b2/4 + b%2 + a2);
frankvnk 0:630b4da97968 507 long crit3 = -(b2/4 + b%2);
frankvnk 0:630b4da97968 508 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
frankvnk 0:630b4da97968 509 long dxt = 2*b2*x, dyt = -2*a2*y;
frankvnk 0:630b4da97968 510 long d2xt = 2*b2, d2yt = 2*a2;
frankvnk 0:630b4da97968 511
frankvnk 0:630b4da97968 512 while (y>=0 && x<=a) {
frankvnk 0:630b4da97968 513 pixel(xc+x, yc+y, color);
frankvnk 0:630b4da97968 514 if (x!=0 || y!=0)
frankvnk 0:630b4da97968 515 pixel(xc-x, yc-y, color);
frankvnk 0:630b4da97968 516 if (x!=0 && y!=0) {
frankvnk 0:630b4da97968 517 pixel(xc+x, yc-y, color);
frankvnk 0:630b4da97968 518 pixel(xc-x, yc+y, color);
frankvnk 0:630b4da97968 519 }
frankvnk 0:630b4da97968 520 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0
frankvnk 0:630b4da97968 521 t + a2*y <= crit3) // e(x+1/2,y) <= 0
frankvnk 0:630b4da97968 522 incx();
frankvnk 0:630b4da97968 523 else if (t - a2*y > crit2) // e(x+1/2,y-1) > 0
frankvnk 0:630b4da97968 524 incy();
frankvnk 0:630b4da97968 525 else {
frankvnk 0:630b4da97968 526 incx();
frankvnk 0:630b4da97968 527 incy();
frankvnk 0:630b4da97968 528 }
frankvnk 0:630b4da97968 529 }
frankvnk 0:630b4da97968 530 }
frankvnk 0:630b4da97968 531
frankvnk 0:630b4da97968 532 void SPI_TFT::fill_ellipse(int xc, int yc, int a, int b, unsigned int color)
frankvnk 0:630b4da97968 533 {
frankvnk 0:630b4da97968 534 /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */
frankvnk 0:630b4da97968 535 int x = 0, y = b;
frankvnk 0:630b4da97968 536 int rx = x, ry = y;
frankvnk 0:630b4da97968 537 unsigned int width = 1;
frankvnk 0:630b4da97968 538 unsigned int height = 1;
frankvnk 0:630b4da97968 539 long a2 = (long)a*a, b2 = (long)b*b;
frankvnk 0:630b4da97968 540 long crit1 = -(a2/4 + a%2 + b2);
frankvnk 0:630b4da97968 541 long crit2 = -(b2/4 + b%2 + a2);
frankvnk 0:630b4da97968 542 long crit3 = -(b2/4 + b%2);
frankvnk 0:630b4da97968 543 long t = -a2*y; // e(x+1/2,y-1/2) - (a^2+b^2)/4
frankvnk 0:630b4da97968 544 long dxt = 2*b2*x, dyt = -2*a2*y;
frankvnk 0:630b4da97968 545 long d2xt = 2*b2, d2yt = 2*a2;
frankvnk 0:630b4da97968 546
frankvnk 0:630b4da97968 547 if (b == 0) {
frankvnk 0:630b4da97968 548 fillrect(xc-a, yc, 2*a+1, 1, color);
frankvnk 0:630b4da97968 549 return;
frankvnk 0:630b4da97968 550 }
frankvnk 0:630b4da97968 551
frankvnk 0:630b4da97968 552 while (y>=0 && x<=a) {
frankvnk 0:630b4da97968 553 if (t + b2*x <= crit1 || // e(x+1,y-1/2) <= 0
frankvnk 0:630b4da97968 554 t + a2*y <= crit3) { // e(x+1/2,y) <= 0
frankvnk 0:630b4da97968 555 if (height == 1)
frankvnk 0:630b4da97968 556 ; // draw nothing
frankvnk 0:630b4da97968 557 else if (ry*2+1 > (height-1)*2) {
frankvnk 0:630b4da97968 558 fillrect(xc-rx, yc-ry, width, height-1, color);
frankvnk 0:630b4da97968 559 fillrect(xc-rx, yc+ry+1, width, 1-height, color);
frankvnk 0:630b4da97968 560 ry -= height-1;
frankvnk 0:630b4da97968 561 height = 1;
frankvnk 0:630b4da97968 562 } else {
frankvnk 0:630b4da97968 563 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 564 ry -= ry;
frankvnk 0:630b4da97968 565 height = 1;
frankvnk 0:630b4da97968 566 }
frankvnk 0:630b4da97968 567 incx();
frankvnk 0:630b4da97968 568 rx++;
frankvnk 0:630b4da97968 569 width += 2;
frankvnk 0:630b4da97968 570 } else if (t - a2*y > crit2) { // e(x+1/2,y-1) > 0
frankvnk 0:630b4da97968 571 incy();
frankvnk 0:630b4da97968 572 height++;
frankvnk 0:630b4da97968 573 } else {
frankvnk 0:630b4da97968 574 if (ry*2+1 > height*2) {
frankvnk 0:630b4da97968 575 fillrect(xc-rx, yc-ry, width, height, color);
frankvnk 0:630b4da97968 576 fillrect(xc-rx, yc+ry+1, width, -height, color);
frankvnk 0:630b4da97968 577 } else {
frankvnk 0:630b4da97968 578 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 579 }
frankvnk 0:630b4da97968 580 incx();
frankvnk 0:630b4da97968 581 incy();
frankvnk 0:630b4da97968 582 rx++;
frankvnk 0:630b4da97968 583 width += 2;
frankvnk 0:630b4da97968 584 ry -= height;
frankvnk 0:630b4da97968 585 height = 1;
frankvnk 0:630b4da97968 586 }
frankvnk 0:630b4da97968 587 }
frankvnk 0:630b4da97968 588
frankvnk 0:630b4da97968 589 if (ry > height) {
frankvnk 0:630b4da97968 590 fillrect(xc-rx, yc-ry, width, height, color);
frankvnk 0:630b4da97968 591 fillrect(xc-rx, yc+ry+1, width, -height, color);
frankvnk 0:630b4da97968 592 } else {
frankvnk 0:630b4da97968 593 fillrect(xc-rx, yc-ry, width, ry*2+1, color);
frankvnk 0:630b4da97968 594 }
frankvnk 0:630b4da97968 595 }
frankvnk 0:630b4da97968 596
frankvnk 0:630b4da97968 597
frankvnk 0:630b4da97968 598 void SPI_TFT::locate(int x, int y)
frankvnk 0:630b4da97968 599 {
frankvnk 0:630b4da97968 600 char_x = x;
frankvnk 0:630b4da97968 601 char_y = y;
frankvnk 0:630b4da97968 602 }
frankvnk 0:630b4da97968 603
frankvnk 0:630b4da97968 604 int SPI_TFT::columns()
frankvnk 0:630b4da97968 605 {
frankvnk 0:630b4da97968 606 return width() / font[1];
frankvnk 0:630b4da97968 607 }
frankvnk 0:630b4da97968 608
frankvnk 0:630b4da97968 609 int SPI_TFT::rows()
frankvnk 0:630b4da97968 610 {
frankvnk 0:630b4da97968 611 return height() / font[2];
frankvnk 0:630b4da97968 612 }
frankvnk 0:630b4da97968 613
frankvnk 0:630b4da97968 614 int SPI_TFT::_putc(int value)
frankvnk 0:630b4da97968 615 {
frankvnk 0:630b4da97968 616 if (value == '\n') { // new line
frankvnk 0:630b4da97968 617 char_x = 0;
frankvnk 0:630b4da97968 618 char_y = char_y + font[2];
frankvnk 0:630b4da97968 619 if (char_y >= height() - font[2]) {
frankvnk 0:630b4da97968 620 char_y = 0;
frankvnk 0:630b4da97968 621 }
frankvnk 0:630b4da97968 622 } else {
frankvnk 0:630b4da97968 623 character(char_x, char_y, value);
frankvnk 0:630b4da97968 624 }
frankvnk 0:630b4da97968 625 return value;
frankvnk 0:630b4da97968 626 }
frankvnk 0:630b4da97968 627
frankvnk 0:630b4da97968 628 void SPI_TFT::character(int x, int y, int c)
frankvnk 0:630b4da97968 629 {
frankvnk 0:630b4da97968 630 unsigned int hor,vert,offset,bpl,j,i,b;
frankvnk 0:630b4da97968 631 unsigned char* bitmap_char;
frankvnk 0:630b4da97968 632 unsigned char z,w;
frankvnk 0:630b4da97968 633
frankvnk 0:630b4da97968 634 if ((c < 31) || (c > 127)) return; // test char range
frankvnk 0:630b4da97968 635
frankvnk 0:630b4da97968 636 // read font parameter from start of array
frankvnk 0:630b4da97968 637 offset = font[0]; // bytes / char
frankvnk 0:630b4da97968 638 hor = font[1]; // get hor size of font
frankvnk 0:630b4da97968 639 vert = font[2]; // get vert size of font
frankvnk 0:630b4da97968 640 bpl = font[3]; // bytes per line
frankvnk 0:630b4da97968 641
frankvnk 0:630b4da97968 642 if (char_x + hor > width()) {
frankvnk 0:630b4da97968 643 char_x = 0;
frankvnk 0:630b4da97968 644 char_y = char_y + vert;
frankvnk 0:630b4da97968 645 if (char_y >= height() - font[2]) {
frankvnk 0:630b4da97968 646 char_y = 0;
frankvnk 0:630b4da97968 647 }
frankvnk 0:630b4da97968 648 }
frankvnk 0:630b4da97968 649 mod_orientation();
frankvnk 0:630b4da97968 650
frankvnk 0:630b4da97968 651 bitmap_char = &font[((c -32) * offset) + 4]; // start of char bitmap
frankvnk 0:630b4da97968 652 w = bitmap_char[0]; // width of actual char
frankvnk 2:45a3c5aa99c3 653 window(char_x, char_y,hor,vert); // char box
frankvnk 0:630b4da97968 654 wr_cmd(0x22);
frankvnk 0:630b4da97968 655 _cs = 0;
frankvnk 0:630b4da97968 656 wr_dat_start();
frankvnk 3:a016fe71ed72 657 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 658 _spi.format(16,3);
frankvnk 3:a016fe71ed72 659 #endif
frankvnk 0:630b4da97968 660 for (j=0; j<vert; j++) { // vert line
frankvnk 2:45a3c5aa99c3 661 for (i=0; i<hor; i++) { // horz line
frankvnk 0:630b4da97968 662 z = bitmap_char[bpl * i + ((j & 0xF8) >> 3)+1];
frankvnk 0:630b4da97968 663 b = 1 << (j & 0x07);
frankvnk 0:630b4da97968 664 if (( z & b ) == 0x00) {
frankvnk 0:630b4da97968 665 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 666 if (backgroundimage==false)
frankvnk 3:a016fe71ed72 667 {
frankvnk 0:630b4da97968 668 #endif
frankvnk 3:a016fe71ed72 669 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 670 _spi.fastWrite(_background);
frankvnk 3:a016fe71ed72 671 #else
frankvnk 3:a016fe71ed72 672 _spi.fastWrite(_background >> 8);
frankvnk 3:a016fe71ed72 673 _spi.fastWrite(_background & 0xFF);
frankvnk 3:a016fe71ed72 674 #endif
frankvnk 0:630b4da97968 675 #ifndef NO_FLASH_BUFFER
frankvnk 3:a016fe71ed72 676 }
frankvnk 0:630b4da97968 677 else
frankvnk 0:630b4da97968 678 {
frankvnk 0:630b4da97968 679 unsigned short *bitmap_ptr = (unsigned short *)sector_start_adress[ 25 ];
frankvnk 0:630b4da97968 680 int angle = (orientation - backgroundOrientation)%4; //Get the difference in orientation between background and current
frankvnk 0:630b4da97968 681 switch (angle) {
frankvnk 0:630b4da97968 682 case 0: //Same orientation
frankvnk 0:630b4da97968 683 bitmap_ptr += width() * (height()-(y+j+1))+x+i;
frankvnk 0:630b4da97968 684 break;
frankvnk 0:630b4da97968 685 case 1: //Rotated 1 (don't ask me which direction)
frankvnk 0:630b4da97968 686 bitmap_ptr += height() * (width()-(x+i+1))+height()-(y+j + 1);
frankvnk 0:630b4da97968 687 break;
frankvnk 0:630b4da97968 688 case 2: //Upside down
frankvnk 0:630b4da97968 689 bitmap_ptr += width() * (y+j)+width() - (x+i + 1);
frankvnk 0:630b4da97968 690 break;
frankvnk 0:630b4da97968 691 case 3: //Rotated 3
frankvnk 0:630b4da97968 692 bitmap_ptr += height() * (x+i)+y+j;
frankvnk 0:630b4da97968 693 break;
frankvnk 0:630b4da97968 694 default:
frankvnk 0:630b4da97968 695 break;
frankvnk 0:630b4da97968 696 }
frankvnk 0:630b4da97968 697
frankvnk 3:a016fe71ed72 698 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 699 _spi.fastWrite(*bitmap_ptr);
frankvnk 3:a016fe71ed72 700 #else
frankvnk 3:a016fe71ed72 701 _spi.fastWrite((*bitmap_ptr) >> 8);
frankvnk 3:a016fe71ed72 702 _spi.fastWrite((*bitmap_ptr) & 0xFF);
frankvnk 3:a016fe71ed72 703 #endif
frankvnk 0:630b4da97968 704 }
frankvnk 0:630b4da97968 705 #endif
frankvnk 0:630b4da97968 706 } else {
frankvnk 3:a016fe71ed72 707 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 708 _spi.fastWrite(_foreground);
frankvnk 3:a016fe71ed72 709 #else
frankvnk 3:a016fe71ed72 710 _spi.fastWrite(_foreground >> 8);
frankvnk 3:a016fe71ed72 711 _spi.fastWrite(_foreground & 0xFF);
frankvnk 3:a016fe71ed72 712 #endif
frankvnk 0:630b4da97968 713 }
frankvnk 0:630b4da97968 714 }
frankvnk 0:630b4da97968 715 }
frankvnk 0:630b4da97968 716 _spi.clearRX();
frankvnk 3:a016fe71ed72 717 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 718 _spi.format(8,3);
frankvnk 3:a016fe71ed72 719 #endif
frankvnk 0:630b4da97968 720 _cs = 1;
frankvnk 0:630b4da97968 721 if ((w + 2) < hor) { // x offset to next char
frankvnk 0:630b4da97968 722 char_x += w + 2;
frankvnk 0:630b4da97968 723 } else char_x += hor;
frankvnk 0:630b4da97968 724 }
frankvnk 0:630b4da97968 725
frankvnk 0:630b4da97968 726 void SPI_TFT::set_font(unsigned char* f)
frankvnk 0:630b4da97968 727 {
frankvnk 0:630b4da97968 728 font = f;
frankvnk 0:630b4da97968 729 }
frankvnk 0:630b4da97968 730
frankvnk 0:630b4da97968 731
frankvnk 0:630b4da97968 732 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
frankvnk 0:630b4da97968 733 {
frankvnk 0:630b4da97968 734 unsigned int i,j;
frankvnk 0:630b4da97968 735 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
frankvnk 0:630b4da97968 736 mod_orientation();
frankvnk 0:630b4da97968 737 window(x, y, w, h);
frankvnk 0:630b4da97968 738 wr_cmd(0x22);
frankvnk 0:630b4da97968 739 _cs = 0;
frankvnk 0:630b4da97968 740 wr_dat_start();
frankvnk 3:a016fe71ed72 741 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 742 _spi.format(16,3);
frankvnk 3:a016fe71ed72 743 #endif
frankvnk 0:630b4da97968 744 bitmap_ptr += ((h - 1)*w);
frankvnk 0:630b4da97968 745 for (j = 0; j < h; j++) { //Lines
frankvnk 0:630b4da97968 746 for (i = 0; i < w; i++) { // copy pixel data to TFT
frankvnk 3:a016fe71ed72 747 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 748 _spi.fastWrite(*bitmap_ptr); // one line
frankvnk 3:a016fe71ed72 749 #else
frankvnk 3:a016fe71ed72 750 _spi.fastWrite((*bitmap_ptr) >> 8);
frankvnk 3:a016fe71ed72 751 _spi.fastWrite((*bitmap_ptr) & 0xFF);
frankvnk 3:a016fe71ed72 752 #endif
frankvnk 0:630b4da97968 753 bitmap_ptr++;
frankvnk 0:630b4da97968 754 }
frankvnk 0:630b4da97968 755 bitmap_ptr -= 2*w;
frankvnk 0:630b4da97968 756 }
frankvnk 0:630b4da97968 757 _spi.clearRX();
frankvnk 3:a016fe71ed72 758 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 759 _spi.format(8,3);
frankvnk 3:a016fe71ed72 760 #endif
frankvnk 0:630b4da97968 761 _cs = 1;
frankvnk 0:630b4da97968 762 }
frankvnk 0:630b4da97968 763
frankvnk 0:630b4da97968 764 int SPI_TFT::Bitmap(unsigned int x, unsigned int y, const char *Name_BMP)
frankvnk 0:630b4da97968 765 {
frankvnk 0:630b4da97968 766 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
frankvnk 0:630b4da97968 767 mod_orientation();
frankvnk 0:630b4da97968 768
frankvnk 0:630b4da97968 769 bitmapData bmp = getBitmapData(Name_BMP);
frankvnk 0:630b4da97968 770 if (bmp.return_code != 1)
frankvnk 0:630b4da97968 771 return bmp.return_code;
frankvnk 0:630b4da97968 772
frankvnk 0:630b4da97968 773
frankvnk 0:630b4da97968 774 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line
frankvnk 0:630b4da97968 775 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short
frankvnk 0:630b4da97968 776
frankvnk 0:630b4da97968 777
frankvnk 0:630b4da97968 778 if ((bmp.height > height()+y) || (bmp.width > width()+x))
frankvnk 0:630b4da97968 779 return -3; //Size mismatch
frankvnk 0:630b4da97968 780
frankvnk 0:630b4da97968 781 if (line == NULL)
frankvnk 0:630b4da97968 782 return(-4); // error no memory
frankvnk 0:630b4da97968 783
frankvnk 0:630b4da97968 784
frankvnk 0:630b4da97968 785 for (int j = bmp.height-1; j >= 0; j--) { //Lines bottom up
frankvnk 0:630b4da97968 786 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line
frankvnk 0:630b4da97968 787 fseek(bmp.file, off ,SEEK_SET);
frankvnk 0:630b4da97968 788 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow !
frankvnk 0:630b4da97968 789
frankvnk 0:630b4da97968 790 //If 24 bit format, convert to 565
frankvnk 0:630b4da97968 791 if (bmp.bits == 24) {
frankvnk 0:630b4da97968 792 for (int i = 0; i<bmp.width; i++) {
frankvnk 0:630b4da97968 793 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]);
frankvnk 0:630b4da97968 794 }
frankvnk 0:630b4da97968 795 }
frankvnk 0:630b4da97968 796
frankvnk 0:630b4da97968 797 window(x, y+bmp.height - 1 - j,bmp.width ,1);
frankvnk 0:630b4da97968 798 wr_cmd(0x22);
frankvnk 0:630b4da97968 799
frankvnk 0:630b4da97968 800 _cs = 0;
frankvnk 0:630b4da97968 801 wr_dat_start();
frankvnk 3:a016fe71ed72 802 #ifndef SPI_8BIT
frankvnk 3:a016fe71ed72 803 _spi.format(16,3);
frankvnk 3:a016fe71ed72 804 #endif
frankvnk 0:630b4da97968 805 _spi.setFormat();
frankvnk 0:630b4da97968 806
frankvnk 0:630b4da97968 807 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT
frankvnk 3:a016fe71ed72 808 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 809 _spi.fastWrite(line_short[i]); // one line
frankvnk 3:a016fe71ed72 810 #else
frankvnk 3:a016fe71ed72 811 _spi.fastWrite(line_short[i] >> 8);
frankvnk 3:a016fe71ed72 812 _spi.fastWrite(line_short[i] & 0xFF);
frankvnk 3:a016fe71ed72 813 #endif
frankvnk 0:630b4da97968 814 }
frankvnk 0:630b4da97968 815
frankvnk 0:630b4da97968 816 _spi.clearRX();
frankvnk 3:a016fe71ed72 817 #ifndef SPI_8BIT
frankvnk 0:630b4da97968 818 _spi.format(8,3);
frankvnk 3:a016fe71ed72 819 #endif
frankvnk 0:630b4da97968 820 _cs = 1;
frankvnk 0:630b4da97968 821
frankvnk 0:630b4da97968 822 }
frankvnk 0:630b4da97968 823
frankvnk 0:630b4da97968 824
frankvnk 0:630b4da97968 825 free (line);
frankvnk 0:630b4da97968 826 fclose(bmp.file);
frankvnk 0:630b4da97968 827 WindowMax();
frankvnk 0:630b4da97968 828
frankvnk 0:630b4da97968 829 return(1);
frankvnk 0:630b4da97968 830 }
frankvnk 0:630b4da97968 831
frankvnk 0:630b4da97968 832 #ifndef NO_FLASH_BUFFER
frankvnk 0:630b4da97968 833
frankvnk 0:630b4da97968 834 int SPI_TFT::fileToFlash(const char *Name_BMP)
frankvnk 0:630b4da97968 835 {
frankvnk 0:630b4da97968 836 #define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
frankvnk 0:630b4da97968 837
frankvnk 0:630b4da97968 838 mod_orientation();
frankvnk 0:630b4da97968 839
frankvnk 0:630b4da97968 840 bitmapData bmp = getBitmapData(Name_BMP);
frankvnk 0:630b4da97968 841 if (bmp.return_code != 1)
frankvnk 0:630b4da97968 842 return bmp.return_code;
frankvnk 0:630b4da97968 843
frankvnk 0:630b4da97968 844
frankvnk 0:630b4da97968 845 unsigned char *line = (unsigned char *) malloc (bmp.bits/8 * bmp.width); // we need a buffer for a line
frankvnk 0:630b4da97968 846 unsigned short *line_short = (unsigned short*) (line); // Same one, addressed as short
frankvnk 0:630b4da97968 847
frankvnk 0:630b4da97968 848 unsigned short *flashSector = (unsigned short *) malloc (256); //And one to send to flash
frankvnk 0:630b4da97968 849
frankvnk 0:630b4da97968 850 if ((bmp.height != height()) || (bmp.width != width()))
frankvnk 0:630b4da97968 851 return -3; //Size mismatch
frankvnk 0:630b4da97968 852
frankvnk 0:630b4da97968 853 if ((line == NULL) || (flashSector == NULL))
frankvnk 0:630b4da97968 854 return(-4); // error no memory
frankvnk 0:630b4da97968 855
frankvnk 0:630b4da97968 856
frankvnk 0:630b4da97968 857 int flashPointer = 0, flashWrites = 0;
frankvnk 0:630b4da97968 858
frankvnk 0:630b4da97968 859 //Erase Flash that will be used:
frankvnk 0:630b4da97968 860 if ( iap.blank_check( 25, 29 ) == SECTOR_NOT_BLANK ) {
frankvnk 0:630b4da97968 861 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 862 iap.erase( 25, 29 );
frankvnk 0:630b4da97968 863 }
frankvnk 0:630b4da97968 864
frankvnk 0:630b4da97968 865 for (int j = 0; j < bmp.height; j++) { //Lines bottom up
frankvnk 0:630b4da97968 866 int off = j * (bmp.width * bmp.bits/8 + bmp.pad) + bmp.start_data; // start of line
frankvnk 0:630b4da97968 867 fseek(bmp.file, off ,SEEK_SET);
frankvnk 0:630b4da97968 868 fread(line,1,bmp.width * bmp.bits/8,bmp.file); // read a line - slow !
frankvnk 0:630b4da97968 869
frankvnk 0:630b4da97968 870 //If 24 bit format, do some processing
frankvnk 0:630b4da97968 871 if (bmp.bits == 24) {
frankvnk 0:630b4da97968 872 for (int i = 0; i<bmp.width; i++) {
frankvnk 0:630b4da97968 873 line_short[i] = RGB565CONVERT(line[3*i+2], line[3*i+1], line[3*i]);
frankvnk 0:630b4da97968 874 }
frankvnk 0:630b4da97968 875 }
frankvnk 0:630b4da97968 876
frankvnk 0:630b4da97968 877
frankvnk 0:630b4da97968 878 for (int i = 0; i < bmp.width; i++) { // copy pixel data to TFT
frankvnk 0:630b4da97968 879 flashSector[flashPointer] = line_short[i]; // one line
frankvnk 0:630b4da97968 880 flashPointer++;
frankvnk 0:630b4da97968 881
frankvnk 0:630b4da97968 882 //If flashpointer reached the end, write to flash
frankvnk 0:630b4da97968 883 if (flashPointer == 128) {
frankvnk 0:630b4da97968 884 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 885 iap.write((char *)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256);
frankvnk 0:630b4da97968 886 flashPointer = 0;
frankvnk 0:630b4da97968 887 flashWrites++;
frankvnk 0:630b4da97968 888 if (flashWrites == 1000)
frankvnk 0:630b4da97968 889 error("Too many flashwrites");
frankvnk 0:630b4da97968 890 }
frankvnk 0:630b4da97968 891 }
frankvnk 0:630b4da97968 892 }
frankvnk 0:630b4da97968 893 //write remaining data
frankvnk 0:630b4da97968 894 if (flashPointer!=0) {
frankvnk 0:630b4da97968 895 iap.prepare( 25, 29 );
frankvnk 0:630b4da97968 896 iap.write((char*)flashSector, sector_start_adress[ 25 ] + 256 * flashWrites, 256);
frankvnk 0:630b4da97968 897 flashPointer = 0;
frankvnk 0:630b4da97968 898 flashWrites++;
frankvnk 0:630b4da97968 899 if (flashWrites == 1000)
frankvnk 0:630b4da97968 900 error("Too many flashwrites");
frankvnk 0:630b4da97968 901 }
frankvnk 0:630b4da97968 902
frankvnk 0:630b4da97968 903
frankvnk 0:630b4da97968 904
frankvnk 0:630b4da97968 905 free (line);
frankvnk 0:630b4da97968 906 fclose(bmp.file);
frankvnk 0:630b4da97968 907 backgroundImage(true);
frankvnk 0:630b4da97968 908 backgroundOrientation = orientation;
frankvnk 0:630b4da97968 909 return(1);
frankvnk 0:630b4da97968 910 }
frankvnk 0:630b4da97968 911
frankvnk 0:630b4da97968 912 void SPI_TFT::backgroundImage( bool active) {
frankvnk 0:630b4da97968 913 backgroundimage = active;
frankvnk 0:630b4da97968 914 }
frankvnk 0:630b4da97968 915 #endif
frankvnk 0:630b4da97968 916
frankvnk 0:630b4da97968 917
frankvnk 0:630b4da97968 918 SPI_TFT::bitmapData SPI_TFT::getBitmapData(const char *Name_BMP){
frankvnk 0:630b4da97968 919 #define OffsetPixelWidth 18
frankvnk 0:630b4da97968 920 #define OffsetPixelHeigh 22
frankvnk 0:630b4da97968 921 #define OffsetFileSize 34
frankvnk 0:630b4da97968 922 #define OffsetPixData 10
frankvnk 0:630b4da97968 923 #define OffsetBPP 28
frankvnk 0:630b4da97968 924
frankvnk 0:630b4da97968 925
frankvnk 0:630b4da97968 926 bitmapData retval;
frankvnk 0:630b4da97968 927 retval.return_code = 1;
frankvnk 0:630b4da97968 928 unsigned char BMP_Header[54];
frankvnk 0:630b4da97968 929
frankvnk 0:630b4da97968 930 retval.file = fopen(Name_BMP, "rb"); // open the bmp file
frankvnk 0:630b4da97968 931 if (!retval.file) {
frankvnk 0:630b4da97968 932 retval.return_code = 0;
frankvnk 0:630b4da97968 933 return(retval); // error file not found !
frankvnk 0:630b4da97968 934 }
frankvnk 0:630b4da97968 935
frankvnk 0:630b4da97968 936 fread(&BMP_Header[0],1,54,retval.file); // get the BMP Header
frankvnk 0:630b4da97968 937
frankvnk 0:630b4da97968 938 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
frankvnk 0:630b4da97968 939 fclose(retval.file);
frankvnk 0:630b4da97968 940 retval.return_code = -1;
frankvnk 0:630b4da97968 941 return(retval); // error not a BMP file
frankvnk 0:630b4da97968 942 }
frankvnk 0:630b4da97968 943
frankvnk 0:630b4da97968 944 int BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
frankvnk 0:630b4da97968 945 if (BPP_t == 0x0010)
frankvnk 0:630b4da97968 946 retval.bits = 16;
frankvnk 0:630b4da97968 947 else if (BPP_t == 0x0018)
frankvnk 0:630b4da97968 948 retval.bits = 24;
frankvnk 0:630b4da97968 949 else {
frankvnk 0:630b4da97968 950 fclose(retval.file);
frankvnk 0:630b4da97968 951 retval.return_code = -2;
frankvnk 0:630b4da97968 952 return(retval); // error no 16/24 bit BMP
frankvnk 0:630b4da97968 953 }
frankvnk 0:630b4da97968 954
frankvnk 0:630b4da97968 955 retval.height = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
frankvnk 0:630b4da97968 956 retval.width = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
frankvnk 0:630b4da97968 957 if (retval.height > height()|| retval.width > width()) {
frankvnk 0:630b4da97968 958 fclose(retval.file);
frankvnk 0:630b4da97968 959 retval.return_code = -3;
frankvnk 0:630b4da97968 960 return(retval); // too big
frankvnk 0:630b4da97968 961 }
frankvnk 0:630b4da97968 962
frankvnk 0:630b4da97968 963
frankvnk 0:630b4da97968 964 retval.start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
frankvnk 0:630b4da97968 965
frankvnk 0:630b4da97968 966 // the bmp lines are padded to multiple of 4 bytes
frankvnk 0:630b4da97968 967 retval.pad = -1;
frankvnk 0:630b4da97968 968 do {
frankvnk 0:630b4da97968 969 retval.pad ++;
frankvnk 0:630b4da97968 970 } while ((retval.width * retval.bits/8 + retval.pad)%4 != 0);
frankvnk 0:630b4da97968 971 return retval;
frankvnk 0:630b4da97968 972
frankvnk 3:a016fe71ed72 973 }