Lib for the new LCD Display with ILI9341 controller

Dependencies:   TFT_fonts

Dependents:   Sensor

Fork of SPI_TFT_ILI9341 by Peter Drescher

Committer:
wolfsberger
Date:
Tue Apr 05 14:00:25 2016 +0000
Revision:
17:77f9f262e449
Parent:
15:1895f6598fea
-

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 12:98cc5c193ecd 1 /* mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller
dreschpe 12:98cc5c193ecd 2 * Copyright (c) 2013, 2014 Peter Drescher - DC2PD
dreschpe 12:98cc5c193ecd 3 * Special version for STM Nucleo -L152
dreschpe 12:98cc5c193ecd 4 *
dreschpe 12:98cc5c193ecd 5 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dreschpe 12:98cc5c193ecd 6 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dreschpe 12:98cc5c193ecd 7 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dreschpe 12:98cc5c193ecd 8 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dreschpe 12:98cc5c193ecd 9 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dreschpe 12:98cc5c193ecd 10 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dreschpe 12:98cc5c193ecd 11 * THE SOFTWARE.
dreschpe 12:98cc5c193ecd 12 */
dreschpe 12:98cc5c193ecd 13
dreschpe 12:98cc5c193ecd 14 // 24.06.14 initial version
dreschpe 12:98cc5c193ecd 15 // 25.06.14 add Nucleo F103RB
dreschpe 12:98cc5c193ecd 16
dreschpe 12:98cc5c193ecd 17 // only include this file if target is L152 or F103RB :
dreschpe 12:98cc5c193ecd 18 #if defined TARGET_NUCLEO_L152RE || defined TARGET_NUCLEO_F103RB
dreschpe 12:98cc5c193ecd 19
dreschpe 12:98cc5c193ecd 20 #include "SPI_TFT_ILI9341.h"
dreschpe 12:98cc5c193ecd 21 #include "mbed.h"
dreschpe 12:98cc5c193ecd 22
dreschpe 12:98cc5c193ecd 23 #if defined TARGET_NUCLEO_L152RE
dreschpe 12:98cc5c193ecd 24 #include "stm32l1xx_dma.h"
dreschpe 12:98cc5c193ecd 25 #define use_ram
dreschpe 12:98cc5c193ecd 26 #endif
dreschpe 12:98cc5c193ecd 27
dreschpe 12:98cc5c193ecd 28 #if defined TARGET_NUCLEO_F103RB
dreschpe 12:98cc5c193ecd 29 #include "stm32f10x_dma.h"
dreschpe 12:98cc5c193ecd 30 #endif
dreschpe 12:98cc5c193ecd 31
dreschpe 12:98cc5c193ecd 32 #define BPP 16 // Bits per pixel
dreschpe 12:98cc5c193ecd 33
dreschpe 12:98cc5c193ecd 34 //extern Serial pc;
dreschpe 12:98cc5c193ecd 35 //extern DigitalOut xx; // debug !!
dreschpe 12:98cc5c193ecd 36
dreschpe 12:98cc5c193ecd 37 DMA_InitTypeDef DMA_InitStructure;
dreschpe 12:98cc5c193ecd 38
dreschpe 12:98cc5c193ecd 39
dreschpe 12:98cc5c193ecd 40 SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name)
dreschpe 12:98cc5c193ecd 41 : GraphicsDisplay(name), SPI(mosi,miso,sclk,NC), _cs(cs), _reset(reset), _dc(dc)
dreschpe 12:98cc5c193ecd 42 {
dreschpe 12:98cc5c193ecd 43
dreschpe 12:98cc5c193ecd 44 format(8,3); // 8 bit spi mode 3
wolfsberger 14:a01f09a0dc25 45 frequency(18000000); // 10 Mhz SPI clock : result 2 / 4 = 8
dreschpe 12:98cc5c193ecd 46 orientation = 0;
dreschpe 12:98cc5c193ecd 47 char_x = 0;
dreschpe 12:98cc5c193ecd 48 if(_spi.spi == SPI_1){ // test which SPI is in use
dreschpe 12:98cc5c193ecd 49 spi_num = 1;
dreschpe 12:98cc5c193ecd 50 }
dreschpe 12:98cc5c193ecd 51 if(_spi.spi == SPI_2){
dreschpe 12:98cc5c193ecd 52 spi_num = 2;
dreschpe 12:98cc5c193ecd 53 }
dreschpe 12:98cc5c193ecd 54 #ifdef SPI_3 // there is no SPI 3 on all devices
dreschpe 12:98cc5c193ecd 55 if(_spi.spi == SPI_3){
dreschpe 12:98cc5c193ecd 56 spi_num = 3;
dreschpe 12:98cc5c193ecd 57 }
dreschpe 12:98cc5c193ecd 58 #endif
dreschpe 12:98cc5c193ecd 59 tft_reset();
dreschpe 12:98cc5c193ecd 60 }
dreschpe 12:98cc5c193ecd 61
dreschpe 12:98cc5c193ecd 62 // we define a fast write to the SPI port
dreschpe 12:98cc5c193ecd 63 // we use the bit banding address to get the flag without masking
dreschpe 12:98cc5c193ecd 64
dreschpe 12:98cc5c193ecd 65 #define bit_SPI1_txe *((volatile unsigned int *)0x42260104)
dreschpe 12:98cc5c193ecd 66 #define SPI1_DR *((volatile unsigned int *)0x4001300C)
dreschpe 12:98cc5c193ecd 67 #define bit_SPI2_txe *((volatile unsigned int *)0x42070104)
dreschpe 12:98cc5c193ecd 68 #define SPI2_DR *((volatile unsigned int *)0x4000380C)
dreschpe 12:98cc5c193ecd 69 #define bit_SPI3_txe *((volatile unsigned int *)0x42078104)
dreschpe 12:98cc5c193ecd 70 #define SPI3_DR *((volatile unsigned int *)0x40003C0C)
dreschpe 12:98cc5c193ecd 71
dreschpe 12:98cc5c193ecd 72 void SPI_TFT_ILI9341::f_write(int data){
dreschpe 12:98cc5c193ecd 73
dreschpe 12:98cc5c193ecd 74 switch(spi_num){ // used SPI port
dreschpe 12:98cc5c193ecd 75 case (1):
dreschpe 12:98cc5c193ecd 76 while(bit_SPI1_txe == 0); // wait for SPI1->SR TXE flag
dreschpe 12:98cc5c193ecd 77 SPI1_DR = data;
dreschpe 12:98cc5c193ecd 78 break;
dreschpe 12:98cc5c193ecd 79
dreschpe 12:98cc5c193ecd 80 case (2):
dreschpe 12:98cc5c193ecd 81 while( bit_SPI2_txe == 0); // wait for SPI2->SR TXE flag
dreschpe 12:98cc5c193ecd 82 SPI2_DR = data;
dreschpe 12:98cc5c193ecd 83 break;
dreschpe 12:98cc5c193ecd 84
dreschpe 12:98cc5c193ecd 85 case (3):
dreschpe 12:98cc5c193ecd 86 while( bit_SPI3_txe == 0); // wait for SPI3->SR TXE flag
dreschpe 12:98cc5c193ecd 87 SPI3_DR = data;
dreschpe 12:98cc5c193ecd 88 break;
dreschpe 12:98cc5c193ecd 89
dreschpe 12:98cc5c193ecd 90 }
dreschpe 12:98cc5c193ecd 91 }
dreschpe 12:98cc5c193ecd 92
dreschpe 12:98cc5c193ecd 93 // wait for SPI not busy
dreschpe 12:98cc5c193ecd 94 // we have to wait for the last bit to switch the cs off
dreschpe 12:98cc5c193ecd 95 // we use the bit banding address to get the flag without masking
dreschpe 12:98cc5c193ecd 96
dreschpe 12:98cc5c193ecd 97 #define bit_SPI1_bsy *((volatile unsigned int *)0x4226011C)
dreschpe 12:98cc5c193ecd 98 #define bit_SPI2_bsy *((volatile unsigned int *)0x4207011C)
dreschpe 12:98cc5c193ecd 99 #define bit_SPI3_bsy *((volatile unsigned int *)0x4207811C)
dreschpe 12:98cc5c193ecd 100
dreschpe 12:98cc5c193ecd 101 void inline SPI_TFT_ILI9341::spi_bsy(void){
dreschpe 12:98cc5c193ecd 102 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 103 case (1):
dreschpe 12:98cc5c193ecd 104 while(bit_SPI1_bsy == 1); // SPI1->SR bit 7
dreschpe 12:98cc5c193ecd 105 break;
dreschpe 12:98cc5c193ecd 106
dreschpe 12:98cc5c193ecd 107 case (2):
dreschpe 12:98cc5c193ecd 108 while(bit_SPI2_bsy == 1); // SPI2->SR bit 7
dreschpe 12:98cc5c193ecd 109 break;
dreschpe 12:98cc5c193ecd 110
dreschpe 12:98cc5c193ecd 111 case (3):
dreschpe 12:98cc5c193ecd 112 while(bit_SPI3_bsy == 1); // SPI2->SR bit 7
dreschpe 12:98cc5c193ecd 113 break;
dreschpe 12:98cc5c193ecd 114 }
dreschpe 12:98cc5c193ecd 115 }
dreschpe 12:98cc5c193ecd 116
dreschpe 12:98cc5c193ecd 117
dreschpe 12:98cc5c193ecd 118 // switch fast between 8 and 16 bit mode
dreschpe 12:98cc5c193ecd 119 #define bit_SPI1_dff *((volatile unsigned int *)0x4226002C)
dreschpe 12:98cc5c193ecd 120 #define bit_SPI2_dff *((volatile unsigned int *)0x4207002C)
dreschpe 12:98cc5c193ecd 121 #define bit_SPI3_dff *((volatile unsigned int *)0x4207802C)
dreschpe 12:98cc5c193ecd 122 void SPI_TFT_ILI9341::spi_16(bool s){
dreschpe 12:98cc5c193ecd 123 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 124 case(1):
dreschpe 12:98cc5c193ecd 125 if(s) bit_SPI1_dff = 1; // switch to 16 bit Mode
dreschpe 12:98cc5c193ecd 126 else bit_SPI1_dff = 0; // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 127 break;
dreschpe 12:98cc5c193ecd 128
dreschpe 12:98cc5c193ecd 129 case(2):
dreschpe 12:98cc5c193ecd 130 if(s) bit_SPI2_dff = 1; // switch to 16 bit Mode
dreschpe 12:98cc5c193ecd 131 else bit_SPI2_dff = 0; // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 132 break;
dreschpe 12:98cc5c193ecd 133
dreschpe 12:98cc5c193ecd 134 case(3):
dreschpe 12:98cc5c193ecd 135 if(s) bit_SPI3_dff = 1; // switch to 16 bit Mode
dreschpe 12:98cc5c193ecd 136 else bit_SPI3_dff = 0; // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 137 break;
dreschpe 12:98cc5c193ecd 138 }
dreschpe 12:98cc5c193ecd 139 }
dreschpe 12:98cc5c193ecd 140
dreschpe 12:98cc5c193ecd 141
dreschpe 12:98cc5c193ecd 142 int SPI_TFT_ILI9341::width()
dreschpe 12:98cc5c193ecd 143 {
dreschpe 12:98cc5c193ecd 144 if (orientation == 0 || orientation == 2) return 240;
dreschpe 12:98cc5c193ecd 145 else return 320;
dreschpe 12:98cc5c193ecd 146 }
dreschpe 12:98cc5c193ecd 147
dreschpe 12:98cc5c193ecd 148
dreschpe 12:98cc5c193ecd 149 int SPI_TFT_ILI9341::height()
dreschpe 12:98cc5c193ecd 150 {
dreschpe 12:98cc5c193ecd 151 if (orientation == 0 || orientation == 2) return 320;
dreschpe 12:98cc5c193ecd 152 else return 240;
dreschpe 12:98cc5c193ecd 153 }
dreschpe 12:98cc5c193ecd 154
dreschpe 12:98cc5c193ecd 155
dreschpe 12:98cc5c193ecd 156 void SPI_TFT_ILI9341::set_orientation(unsigned int o)
dreschpe 12:98cc5c193ecd 157 {
dreschpe 12:98cc5c193ecd 158 orientation = o;
dreschpe 12:98cc5c193ecd 159 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL
dreschpe 12:98cc5c193ecd 160 switch (orientation) {
dreschpe 12:98cc5c193ecd 161 case 0:
dreschpe 12:98cc5c193ecd 162 f_write(0x48);
dreschpe 12:98cc5c193ecd 163 break;
dreschpe 12:98cc5c193ecd 164 case 1:
dreschpe 12:98cc5c193ecd 165 f_write(0x28);
dreschpe 12:98cc5c193ecd 166 break;
dreschpe 12:98cc5c193ecd 167 case 2:
dreschpe 12:98cc5c193ecd 168 f_write(0x88);
dreschpe 12:98cc5c193ecd 169 break;
dreschpe 12:98cc5c193ecd 170 case 3:
dreschpe 12:98cc5c193ecd 171 f_write(0xE8);
dreschpe 12:98cc5c193ecd 172 break;
dreschpe 12:98cc5c193ecd 173 }
dreschpe 12:98cc5c193ecd 174 spi_bsy(); // wait for end of transfer
dreschpe 12:98cc5c193ecd 175 _cs = 1;
dreschpe 12:98cc5c193ecd 176 WindowMax();
dreschpe 12:98cc5c193ecd 177 }
dreschpe 12:98cc5c193ecd 178
dreschpe 12:98cc5c193ecd 179
dreschpe 12:98cc5c193ecd 180 // write command to tft register
dreschpe 12:98cc5c193ecd 181 // use fast command
dreschpe 12:98cc5c193ecd 182 void SPI_TFT_ILI9341::wr_cmd(unsigned char cmd)
dreschpe 12:98cc5c193ecd 183 {
dreschpe 12:98cc5c193ecd 184 _dc = 0;
dreschpe 12:98cc5c193ecd 185 _cs = 0;
dreschpe 12:98cc5c193ecd 186 f_write(cmd);
dreschpe 12:98cc5c193ecd 187 spi_bsy();
dreschpe 12:98cc5c193ecd 188 _dc = 1;
dreschpe 12:98cc5c193ecd 189 }
dreschpe 12:98cc5c193ecd 190
dreschpe 12:98cc5c193ecd 191 void SPI_TFT_ILI9341::wr_dat(unsigned char dat)
dreschpe 12:98cc5c193ecd 192 {
dreschpe 12:98cc5c193ecd 193 f_write(dat);
dreschpe 12:98cc5c193ecd 194 spi_bsy(); // wait for SPI send
dreschpe 12:98cc5c193ecd 195 }
dreschpe 12:98cc5c193ecd 196
dreschpe 12:98cc5c193ecd 197 // the ILI9341 can read
dreschpe 12:98cc5c193ecd 198 char SPI_TFT_ILI9341::rd_byte(unsigned char cmd)
dreschpe 12:98cc5c193ecd 199 {
dreschpe 12:98cc5c193ecd 200 // has to change !!
dreschpe 12:98cc5c193ecd 201 return(0);
dreschpe 12:98cc5c193ecd 202 }
dreschpe 12:98cc5c193ecd 203
dreschpe 12:98cc5c193ecd 204 // read 32 bit
dreschpe 12:98cc5c193ecd 205 int SPI_TFT_ILI9341::rd_32(unsigned char cmd)
dreschpe 12:98cc5c193ecd 206 {
dreschpe 12:98cc5c193ecd 207 // has to change !!!
dreschpe 12:98cc5c193ecd 208 return(0);
dreschpe 12:98cc5c193ecd 209 }
dreschpe 12:98cc5c193ecd 210
dreschpe 12:98cc5c193ecd 211 int SPI_TFT_ILI9341::Read_ID(void){
dreschpe 12:98cc5c193ecd 212 int r;
dreschpe 12:98cc5c193ecd 213 r = rd_byte(0x0A);
dreschpe 12:98cc5c193ecd 214 r = rd_byte(0x0A);
dreschpe 12:98cc5c193ecd 215 r = rd_byte(0x0A);
dreschpe 12:98cc5c193ecd 216 r = rd_byte(0x0A);
dreschpe 12:98cc5c193ecd 217 return(r);
dreschpe 12:98cc5c193ecd 218 }
dreschpe 12:98cc5c193ecd 219
dreschpe 12:98cc5c193ecd 220 // Init code based on MI0283QT datasheet
dreschpe 12:98cc5c193ecd 221 // this code is called only at start
dreschpe 12:98cc5c193ecd 222 // no need to be optimized
dreschpe 12:98cc5c193ecd 223
dreschpe 12:98cc5c193ecd 224 void SPI_TFT_ILI9341::tft_reset()
dreschpe 12:98cc5c193ecd 225 {
dreschpe 12:98cc5c193ecd 226 _cs = 1; // cs high
dreschpe 12:98cc5c193ecd 227 _dc = 1; // dc high
dreschpe 12:98cc5c193ecd 228 _reset = 0; // display reset
dreschpe 12:98cc5c193ecd 229
dreschpe 12:98cc5c193ecd 230 wait_us(50);
dreschpe 12:98cc5c193ecd 231 _reset = 1; // end hardware reset
dreschpe 12:98cc5c193ecd 232 wait_ms(5);
dreschpe 12:98cc5c193ecd 233
dreschpe 12:98cc5c193ecd 234 wr_cmd(0x01); // SW reset
dreschpe 12:98cc5c193ecd 235 wait_ms(5);
dreschpe 12:98cc5c193ecd 236 wr_cmd(0x28); // display off
dreschpe 12:98cc5c193ecd 237
dreschpe 12:98cc5c193ecd 238 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 12:98cc5c193ecd 239 wr_cmd(0xCF);
dreschpe 12:98cc5c193ecd 240 f_write(0x00);
dreschpe 12:98cc5c193ecd 241 f_write(0x83);
dreschpe 12:98cc5c193ecd 242 f_write(0x30);
dreschpe 12:98cc5c193ecd 243 spi_bsy();
dreschpe 12:98cc5c193ecd 244 _cs = 1;
dreschpe 12:98cc5c193ecd 245
dreschpe 12:98cc5c193ecd 246 wr_cmd(0xED);
dreschpe 12:98cc5c193ecd 247 f_write(0x64);
dreschpe 12:98cc5c193ecd 248 f_write(0x03);
dreschpe 12:98cc5c193ecd 249 f_write(0x12);
dreschpe 12:98cc5c193ecd 250 f_write(0x81);
dreschpe 12:98cc5c193ecd 251 spi_bsy();
dreschpe 12:98cc5c193ecd 252 _cs = 1;
dreschpe 12:98cc5c193ecd 253
dreschpe 12:98cc5c193ecd 254 wr_cmd(0xE8);
dreschpe 12:98cc5c193ecd 255 f_write(0x85);
dreschpe 12:98cc5c193ecd 256 f_write(0x01);
dreschpe 12:98cc5c193ecd 257 f_write(0x79);
dreschpe 12:98cc5c193ecd 258 spi_bsy();
dreschpe 12:98cc5c193ecd 259 _cs = 1;
dreschpe 12:98cc5c193ecd 260
dreschpe 12:98cc5c193ecd 261 wr_cmd(0xCB);
dreschpe 12:98cc5c193ecd 262 f_write(0x39);
dreschpe 12:98cc5c193ecd 263 f_write(0x2C);
dreschpe 12:98cc5c193ecd 264 f_write(0x00);
dreschpe 12:98cc5c193ecd 265 f_write(0x34);
dreschpe 12:98cc5c193ecd 266 f_write(0x02);
dreschpe 12:98cc5c193ecd 267 spi_bsy();
dreschpe 12:98cc5c193ecd 268 _cs = 1;
dreschpe 12:98cc5c193ecd 269
dreschpe 12:98cc5c193ecd 270 wr_cmd(0xF7);
dreschpe 12:98cc5c193ecd 271 f_write(0x20);
dreschpe 12:98cc5c193ecd 272 spi_bsy();
dreschpe 12:98cc5c193ecd 273 _cs = 1;
dreschpe 12:98cc5c193ecd 274
dreschpe 12:98cc5c193ecd 275 wr_cmd(0xEA);
dreschpe 12:98cc5c193ecd 276 f_write(0x00);
dreschpe 12:98cc5c193ecd 277 f_write(0x00);
dreschpe 12:98cc5c193ecd 278 spi_bsy();
dreschpe 12:98cc5c193ecd 279 _cs = 1;
dreschpe 12:98cc5c193ecd 280
dreschpe 12:98cc5c193ecd 281 wr_cmd(0xC0); // POWER_CONTROL_1
dreschpe 12:98cc5c193ecd 282 f_write(0x26);
dreschpe 12:98cc5c193ecd 283 spi_bsy();
dreschpe 12:98cc5c193ecd 284 _cs = 1;
dreschpe 12:98cc5c193ecd 285
dreschpe 12:98cc5c193ecd 286 wr_cmd(0xC1); // POWER_CONTROL_2
dreschpe 12:98cc5c193ecd 287 f_write(0x11);
dreschpe 12:98cc5c193ecd 288 spi_bsy();
dreschpe 12:98cc5c193ecd 289 _cs = 1;
dreschpe 12:98cc5c193ecd 290
dreschpe 12:98cc5c193ecd 291 wr_cmd(0xC5); // VCOM_CONTROL_1
dreschpe 12:98cc5c193ecd 292 f_write(0x35);
dreschpe 12:98cc5c193ecd 293 f_write(0x3E);
dreschpe 12:98cc5c193ecd 294 spi_bsy();
dreschpe 12:98cc5c193ecd 295 _cs = 1;
dreschpe 12:98cc5c193ecd 296
dreschpe 12:98cc5c193ecd 297 wr_cmd(0xC7); // VCOM_CONTROL_2
dreschpe 12:98cc5c193ecd 298 f_write(0xBE);
dreschpe 12:98cc5c193ecd 299 spi_bsy();
dreschpe 12:98cc5c193ecd 300 _cs = 1;
dreschpe 12:98cc5c193ecd 301
dreschpe 12:98cc5c193ecd 302 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL
dreschpe 12:98cc5c193ecd 303 f_write(0x48);
dreschpe 12:98cc5c193ecd 304 spi_bsy();
dreschpe 12:98cc5c193ecd 305 _cs = 1;
dreschpe 12:98cc5c193ecd 306
dreschpe 12:98cc5c193ecd 307 wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET
dreschpe 12:98cc5c193ecd 308 f_write(0x55); // 16 bit pixel
dreschpe 12:98cc5c193ecd 309 spi_bsy();
dreschpe 12:98cc5c193ecd 310 _cs = 1;
dreschpe 12:98cc5c193ecd 311
dreschpe 12:98cc5c193ecd 312 wr_cmd(0xB1); // Frame Rate
dreschpe 12:98cc5c193ecd 313 f_write(0x00);
dreschpe 12:98cc5c193ecd 314 f_write(0x1B);
dreschpe 12:98cc5c193ecd 315 spi_bsy();
dreschpe 12:98cc5c193ecd 316 _cs = 1;
dreschpe 12:98cc5c193ecd 317
dreschpe 12:98cc5c193ecd 318 wr_cmd(0xF2); // Gamma Function Disable
dreschpe 12:98cc5c193ecd 319 f_write(0x08);
dreschpe 12:98cc5c193ecd 320 spi_bsy();
dreschpe 12:98cc5c193ecd 321 _cs = 1;
dreschpe 12:98cc5c193ecd 322
dreschpe 12:98cc5c193ecd 323 wr_cmd(0x26);
dreschpe 12:98cc5c193ecd 324 f_write(0x01); // gamma set for curve 01/2/04/08
dreschpe 12:98cc5c193ecd 325 spi_bsy();
dreschpe 12:98cc5c193ecd 326 _cs = 1;
dreschpe 12:98cc5c193ecd 327
dreschpe 12:98cc5c193ecd 328 wr_cmd(0xE0); // positive gamma correction
dreschpe 12:98cc5c193ecd 329 f_write(0x1F);
dreschpe 12:98cc5c193ecd 330 f_write(0x1A);
dreschpe 12:98cc5c193ecd 331 f_write(0x18);
dreschpe 12:98cc5c193ecd 332 f_write(0x0A);
dreschpe 12:98cc5c193ecd 333 f_write(0x0F);
dreschpe 12:98cc5c193ecd 334 f_write(0x06);
dreschpe 12:98cc5c193ecd 335 f_write(0x45);
dreschpe 12:98cc5c193ecd 336 f_write(0x87);
dreschpe 12:98cc5c193ecd 337 f_write(0x32);
dreschpe 12:98cc5c193ecd 338 f_write(0x0A);
dreschpe 12:98cc5c193ecd 339 f_write(0x07);
dreschpe 12:98cc5c193ecd 340 f_write(0x02);
dreschpe 12:98cc5c193ecd 341 f_write(0x07);
dreschpe 12:98cc5c193ecd 342 f_write(0x05);
dreschpe 12:98cc5c193ecd 343 f_write(0x00);
dreschpe 12:98cc5c193ecd 344 spi_bsy();
dreschpe 12:98cc5c193ecd 345 _cs = 1;
dreschpe 12:98cc5c193ecd 346
dreschpe 12:98cc5c193ecd 347 wr_cmd(0xE1); // negativ gamma correction
dreschpe 12:98cc5c193ecd 348 f_write(0x00);
dreschpe 12:98cc5c193ecd 349 f_write(0x25);
dreschpe 12:98cc5c193ecd 350 f_write(0x27);
dreschpe 12:98cc5c193ecd 351 f_write(0x05);
dreschpe 12:98cc5c193ecd 352 f_write(0x10);
dreschpe 12:98cc5c193ecd 353 f_write(0x09);
dreschpe 12:98cc5c193ecd 354 f_write(0x3A);
dreschpe 12:98cc5c193ecd 355 f_write(0x78);
dreschpe 12:98cc5c193ecd 356 f_write(0x4D);
dreschpe 12:98cc5c193ecd 357 f_write(0x05);
dreschpe 12:98cc5c193ecd 358 f_write(0x18);
dreschpe 12:98cc5c193ecd 359 f_write(0x0D);
dreschpe 12:98cc5c193ecd 360 f_write(0x38);
dreschpe 12:98cc5c193ecd 361 f_write(0x3A);
dreschpe 12:98cc5c193ecd 362 f_write(0x1F);
dreschpe 12:98cc5c193ecd 363 spi_bsy();
dreschpe 12:98cc5c193ecd 364 _cs = 1;
dreschpe 12:98cc5c193ecd 365
dreschpe 12:98cc5c193ecd 366 WindowMax ();
dreschpe 12:98cc5c193ecd 367
dreschpe 12:98cc5c193ecd 368 //wr_cmd(0x34); // tearing effect off
dreschpe 12:98cc5c193ecd 369 //_cs = 1;
dreschpe 12:98cc5c193ecd 370
dreschpe 12:98cc5c193ecd 371 //wr_cmd(0x35); // tearing effect on
dreschpe 12:98cc5c193ecd 372 //_cs = 1;
dreschpe 12:98cc5c193ecd 373
dreschpe 12:98cc5c193ecd 374 wr_cmd(0xB7); // entry mode
dreschpe 12:98cc5c193ecd 375 f_write(0x07);
dreschpe 12:98cc5c193ecd 376 spi_bsy();
dreschpe 12:98cc5c193ecd 377 _cs = 1;
dreschpe 12:98cc5c193ecd 378
dreschpe 12:98cc5c193ecd 379 wr_cmd(0xB6); // display function control
dreschpe 12:98cc5c193ecd 380 f_write(0x0A);
dreschpe 12:98cc5c193ecd 381 f_write(0x82);
dreschpe 12:98cc5c193ecd 382 f_write(0x27);
dreschpe 12:98cc5c193ecd 383 f_write(0x00);
dreschpe 12:98cc5c193ecd 384 spi_bsy();
dreschpe 12:98cc5c193ecd 385 _cs = 1;
wolfsberger 15:1895f6598fea 386
dreschpe 12:98cc5c193ecd 387 wr_cmd(0x11); // sleep out
dreschpe 12:98cc5c193ecd 388 spi_bsy();
dreschpe 12:98cc5c193ecd 389 _cs = 1;
dreschpe 12:98cc5c193ecd 390
dreschpe 12:98cc5c193ecd 391 wait_ms(100);
dreschpe 12:98cc5c193ecd 392
dreschpe 12:98cc5c193ecd 393 wr_cmd(0x29); // display on
dreschpe 12:98cc5c193ecd 394 spi_bsy();
dreschpe 12:98cc5c193ecd 395 _cs = 1;
dreschpe 12:98cc5c193ecd 396
dreschpe 12:98cc5c193ecd 397 wait_ms(100);
dreschpe 12:98cc5c193ecd 398
dreschpe 12:98cc5c193ecd 399 // Configure the DMA controller init-structure
dreschpe 12:98cc5c193ecd 400 DMA_StructInit(&DMA_InitStructure);
dreschpe 12:98cc5c193ecd 401 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 402 case (1):
dreschpe 12:98cc5c193ecd 403 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // SPI1 and SPI2 are using DMA 1
dreschpe 12:98cc5c193ecd 404 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1->DR);
dreschpe 12:98cc5c193ecd 405 break;
dreschpe 12:98cc5c193ecd 406 case (2):
dreschpe 12:98cc5c193ecd 407 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // SPI1 and SPI2 are using DMA 1
dreschpe 12:98cc5c193ecd 408 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI2->DR);
dreschpe 12:98cc5c193ecd 409 break;
dreschpe 12:98cc5c193ecd 410 case (3):
dreschpe 12:98cc5c193ecd 411 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); // SPI3 is using DMA 2
dreschpe 12:98cc5c193ecd 412 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI3->DR);
dreschpe 12:98cc5c193ecd 413 break;
dreschpe 12:98cc5c193ecd 414 }
dreschpe 12:98cc5c193ecd 415 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
dreschpe 12:98cc5c193ecd 416 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
dreschpe 12:98cc5c193ecd 417 DMA_InitStructure.DMA_BufferSize = 0;
dreschpe 12:98cc5c193ecd 418 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dreschpe 12:98cc5c193ecd 419 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dreschpe 12:98cc5c193ecd 420 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dreschpe 12:98cc5c193ecd 421 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
dreschpe 12:98cc5c193ecd 422 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
dreschpe 12:98cc5c193ecd 423 }
dreschpe 12:98cc5c193ecd 424
dreschpe 12:98cc5c193ecd 425
dreschpe 12:98cc5c193ecd 426 // speed optimized
dreschpe 12:98cc5c193ecd 427 // write direct to SPI1 register !
dreschpe 12:98cc5c193ecd 428 void SPI_TFT_ILI9341::pixel(int x, int y, int color)
dreschpe 12:98cc5c193ecd 429 {
dreschpe 12:98cc5c193ecd 430 wr_cmd(0x2A);
dreschpe 12:98cc5c193ecd 431 spi_16(1); // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 432 f_write(x);
dreschpe 12:98cc5c193ecd 433 spi_bsy();
dreschpe 12:98cc5c193ecd 434 _cs = 1;
dreschpe 12:98cc5c193ecd 435
dreschpe 12:98cc5c193ecd 436 spi_16(0); // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 437 wr_cmd(0x2B);
dreschpe 12:98cc5c193ecd 438 spi_16(1);
dreschpe 12:98cc5c193ecd 439 f_write(y);
dreschpe 12:98cc5c193ecd 440 spi_bsy();
dreschpe 12:98cc5c193ecd 441 _cs = 1;
dreschpe 12:98cc5c193ecd 442 spi_16(0);
dreschpe 12:98cc5c193ecd 443
dreschpe 12:98cc5c193ecd 444 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 445 spi_16(1);
dreschpe 12:98cc5c193ecd 446 f_write(color);
dreschpe 12:98cc5c193ecd 447 spi_bsy();
dreschpe 12:98cc5c193ecd 448 _cs = 1;
dreschpe 12:98cc5c193ecd 449 spi_16(0);
dreschpe 12:98cc5c193ecd 450 }
dreschpe 12:98cc5c193ecd 451
dreschpe 12:98cc5c193ecd 452 // optimized
dreschpe 12:98cc5c193ecd 453 // write direct to SPI1 register !
dreschpe 12:98cc5c193ecd 454 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
dreschpe 12:98cc5c193ecd 455 {
dreschpe 12:98cc5c193ecd 456 wr_cmd(0x2A);
dreschpe 12:98cc5c193ecd 457 spi_16(1);
dreschpe 12:98cc5c193ecd 458 f_write(x);
dreschpe 12:98cc5c193ecd 459 f_write(x+w-1);
dreschpe 12:98cc5c193ecd 460 spi_bsy();
dreschpe 12:98cc5c193ecd 461 _cs = 1;
dreschpe 12:98cc5c193ecd 462 spi_16(0);
dreschpe 12:98cc5c193ecd 463
dreschpe 12:98cc5c193ecd 464 wr_cmd(0x2B);
dreschpe 12:98cc5c193ecd 465 spi_16(1);
dreschpe 12:98cc5c193ecd 466 f_write(y) ;
dreschpe 12:98cc5c193ecd 467 f_write(y+h-1);
dreschpe 12:98cc5c193ecd 468 spi_bsy();
dreschpe 12:98cc5c193ecd 469 _cs = 1;
dreschpe 12:98cc5c193ecd 470 spi_16(0);
dreschpe 12:98cc5c193ecd 471 }
dreschpe 12:98cc5c193ecd 472
dreschpe 12:98cc5c193ecd 473
dreschpe 12:98cc5c193ecd 474 void SPI_TFT_ILI9341::WindowMax (void)
dreschpe 12:98cc5c193ecd 475 {
dreschpe 12:98cc5c193ecd 476 window (0, 0, width(), height());
dreschpe 12:98cc5c193ecd 477 }
dreschpe 12:98cc5c193ecd 478
dreschpe 12:98cc5c193ecd 479 // optimized
dreschpe 12:98cc5c193ecd 480 // use DMA to transfer pixel data to the screen
dreschpe 12:98cc5c193ecd 481 void SPI_TFT_ILI9341::cls (void)
dreschpe 12:98cc5c193ecd 482 {
dreschpe 12:98cc5c193ecd 483 // we can use the fillrect function
dreschpe 12:98cc5c193ecd 484 fillrect(0,0,width()-1,height()-1,_background);
dreschpe 12:98cc5c193ecd 485 }
dreschpe 12:98cc5c193ecd 486
dreschpe 12:98cc5c193ecd 487 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color)
dreschpe 12:98cc5c193ecd 488 {
dreschpe 12:98cc5c193ecd 489
dreschpe 12:98cc5c193ecd 490 int x = -r, y = 0, err = 2-2*r, e2;
dreschpe 12:98cc5c193ecd 491 do {
dreschpe 12:98cc5c193ecd 492 pixel(x0-x, y0+y,color);
dreschpe 12:98cc5c193ecd 493 pixel(x0+x, y0+y,color);
dreschpe 12:98cc5c193ecd 494 pixel(x0+x, y0-y,color);
dreschpe 12:98cc5c193ecd 495 pixel(x0-x, y0-y,color);
dreschpe 12:98cc5c193ecd 496 e2 = err;
dreschpe 12:98cc5c193ecd 497 if (e2 <= y) {
dreschpe 12:98cc5c193ecd 498 err += ++y*2+1;
dreschpe 12:98cc5c193ecd 499 if (-x == y && e2 <= x) e2 = 0;
dreschpe 12:98cc5c193ecd 500 }
dreschpe 12:98cc5c193ecd 501 if (e2 > x) err += ++x*2+1;
dreschpe 12:98cc5c193ecd 502 } while (x <= 0);
dreschpe 12:98cc5c193ecd 503 }
dreschpe 12:98cc5c193ecd 504
dreschpe 12:98cc5c193ecd 505 void SPI_TFT_ILI9341::fillcircle(int x0, int y0, int r, int color)
dreschpe 12:98cc5c193ecd 506 {
dreschpe 12:98cc5c193ecd 507 int x = -r, y = 0, err = 2-2*r, e2;
dreschpe 12:98cc5c193ecd 508 do {
dreschpe 12:98cc5c193ecd 509 vline(x0-x, y0-y, y0+y, color);
dreschpe 12:98cc5c193ecd 510 vline(x0+x, y0-y, y0+y, color);
dreschpe 12:98cc5c193ecd 511 e2 = err;
dreschpe 12:98cc5c193ecd 512 if (e2 <= y) {
dreschpe 12:98cc5c193ecd 513 err += ++y*2+1;
dreschpe 12:98cc5c193ecd 514 if (-x == y && e2 <= x) e2 = 0;
dreschpe 12:98cc5c193ecd 515 }
dreschpe 12:98cc5c193ecd 516 if (e2 > x) err += ++x*2+1;
dreschpe 12:98cc5c193ecd 517 } while (x <= 0);
dreschpe 12:98cc5c193ecd 518 }
dreschpe 12:98cc5c193ecd 519
dreschpe 12:98cc5c193ecd 520
dreschpe 12:98cc5c193ecd 521 // optimized for speed
dreschpe 12:98cc5c193ecd 522 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
dreschpe 12:98cc5c193ecd 523 {
dreschpe 12:98cc5c193ecd 524 int w,j;
dreschpe 12:98cc5c193ecd 525 w = x1 - x0 + 1;
dreschpe 12:98cc5c193ecd 526 window(x0,y,w,1);
dreschpe 12:98cc5c193ecd 527 _dc = 0;
dreschpe 12:98cc5c193ecd 528 _cs = 0;
dreschpe 12:98cc5c193ecd 529 f_write(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 530 spi_bsy();
dreschpe 12:98cc5c193ecd 531 _dc = 1;
dreschpe 12:98cc5c193ecd 532 spi_16(1);
dreschpe 12:98cc5c193ecd 533
dreschpe 12:98cc5c193ecd 534 for (j=0; j<w; j++) {
dreschpe 12:98cc5c193ecd 535 f_write(color);
dreschpe 12:98cc5c193ecd 536 }
dreschpe 12:98cc5c193ecd 537 spi_bsy();
dreschpe 12:98cc5c193ecd 538 spi_16(0);
dreschpe 12:98cc5c193ecd 539 _cs = 1;
dreschpe 12:98cc5c193ecd 540 WindowMax();
dreschpe 12:98cc5c193ecd 541 return;
dreschpe 12:98cc5c193ecd 542 }
dreschpe 12:98cc5c193ecd 543
dreschpe 12:98cc5c193ecd 544 // optimized for speed
dreschpe 12:98cc5c193ecd 545 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
dreschpe 12:98cc5c193ecd 546 {
dreschpe 12:98cc5c193ecd 547 int h,y;
dreschpe 12:98cc5c193ecd 548 h = y1 - y0 + 1;
dreschpe 12:98cc5c193ecd 549 window(x,y0,1,h);
dreschpe 12:98cc5c193ecd 550 _dc = 0;
dreschpe 12:98cc5c193ecd 551 _cs = 0;
dreschpe 12:98cc5c193ecd 552 f_write(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 553 spi_bsy();
dreschpe 12:98cc5c193ecd 554 _dc = 1;
dreschpe 12:98cc5c193ecd 555 spi_16(1);
dreschpe 12:98cc5c193ecd 556 // switch to 16 bit Mode 3
dreschpe 12:98cc5c193ecd 557 for (y=0; y<h; y++) {
dreschpe 12:98cc5c193ecd 558 f_write(color);
dreschpe 12:98cc5c193ecd 559 }
dreschpe 12:98cc5c193ecd 560 spi_bsy();
dreschpe 12:98cc5c193ecd 561 spi_16(0);
dreschpe 12:98cc5c193ecd 562 _cs = 1;
dreschpe 12:98cc5c193ecd 563 WindowMax();
dreschpe 12:98cc5c193ecd 564 return;
dreschpe 12:98cc5c193ecd 565 }
dreschpe 12:98cc5c193ecd 566
dreschpe 12:98cc5c193ecd 567
dreschpe 12:98cc5c193ecd 568 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 569 {
dreschpe 12:98cc5c193ecd 570 //WindowMax();
dreschpe 12:98cc5c193ecd 571 int dx = 0, dy = 0;
dreschpe 12:98cc5c193ecd 572 int dx_sym = 0, dy_sym = 0;
dreschpe 12:98cc5c193ecd 573 int dx_x2 = 0, dy_x2 = 0;
dreschpe 12:98cc5c193ecd 574 int di = 0;
dreschpe 12:98cc5c193ecd 575
dreschpe 12:98cc5c193ecd 576 dx = x1-x0;
dreschpe 12:98cc5c193ecd 577 dy = y1-y0;
dreschpe 12:98cc5c193ecd 578
dreschpe 12:98cc5c193ecd 579 if (dx == 0) { /* vertical line */
dreschpe 12:98cc5c193ecd 580 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 12:98cc5c193ecd 581 else vline(x0,y1,y0,color);
dreschpe 12:98cc5c193ecd 582 return;
dreschpe 12:98cc5c193ecd 583 }
dreschpe 12:98cc5c193ecd 584
dreschpe 12:98cc5c193ecd 585 if (dx > 0) {
dreschpe 12:98cc5c193ecd 586 dx_sym = 1;
dreschpe 12:98cc5c193ecd 587 } else {
dreschpe 12:98cc5c193ecd 588 dx_sym = -1;
dreschpe 12:98cc5c193ecd 589 }
dreschpe 12:98cc5c193ecd 590 if (dy == 0) { /* horizontal line */
dreschpe 12:98cc5c193ecd 591 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 12:98cc5c193ecd 592 else hline(x1,x0,y0,color);
dreschpe 12:98cc5c193ecd 593 return;
dreschpe 12:98cc5c193ecd 594 }
dreschpe 12:98cc5c193ecd 595
dreschpe 12:98cc5c193ecd 596 if (dy > 0) {
dreschpe 12:98cc5c193ecd 597 dy_sym = 1;
dreschpe 12:98cc5c193ecd 598 } else {
dreschpe 12:98cc5c193ecd 599 dy_sym = -1;
dreschpe 12:98cc5c193ecd 600 }
dreschpe 12:98cc5c193ecd 601
dreschpe 12:98cc5c193ecd 602 dx = dx_sym*dx;
dreschpe 12:98cc5c193ecd 603 dy = dy_sym*dy;
dreschpe 12:98cc5c193ecd 604
dreschpe 12:98cc5c193ecd 605 dx_x2 = dx*2;
dreschpe 12:98cc5c193ecd 606 dy_x2 = dy*2;
dreschpe 12:98cc5c193ecd 607
dreschpe 12:98cc5c193ecd 608 if (dx >= dy) {
dreschpe 12:98cc5c193ecd 609 di = dy_x2 - dx;
dreschpe 12:98cc5c193ecd 610 while (x0 != x1) {
dreschpe 12:98cc5c193ecd 611
dreschpe 12:98cc5c193ecd 612 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 613 x0 += dx_sym;
dreschpe 12:98cc5c193ecd 614 if (di<0) {
dreschpe 12:98cc5c193ecd 615 di += dy_x2;
dreschpe 12:98cc5c193ecd 616 } else {
dreschpe 12:98cc5c193ecd 617 di += dy_x2 - dx_x2;
dreschpe 12:98cc5c193ecd 618 y0 += dy_sym;
dreschpe 12:98cc5c193ecd 619 }
dreschpe 12:98cc5c193ecd 620 }
dreschpe 12:98cc5c193ecd 621 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 622 } else {
dreschpe 12:98cc5c193ecd 623 di = dx_x2 - dy;
dreschpe 12:98cc5c193ecd 624 while (y0 != y1) {
dreschpe 12:98cc5c193ecd 625 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 626 y0 += dy_sym;
dreschpe 12:98cc5c193ecd 627 if (di < 0) {
dreschpe 12:98cc5c193ecd 628 di += dx_x2;
dreschpe 12:98cc5c193ecd 629 } else {
dreschpe 12:98cc5c193ecd 630 di += dx_x2 - dy_x2;
dreschpe 12:98cc5c193ecd 631 x0 += dx_sym;
dreschpe 12:98cc5c193ecd 632 }
dreschpe 12:98cc5c193ecd 633 }
dreschpe 12:98cc5c193ecd 634 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 635 }
dreschpe 12:98cc5c193ecd 636 return;
dreschpe 12:98cc5c193ecd 637 }
dreschpe 12:98cc5c193ecd 638
dreschpe 12:98cc5c193ecd 639
dreschpe 12:98cc5c193ecd 640 void SPI_TFT_ILI9341::rect(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 641 {
dreschpe 12:98cc5c193ecd 642
dreschpe 12:98cc5c193ecd 643 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 12:98cc5c193ecd 644 else hline(x1,x0,y0,color);
dreschpe 12:98cc5c193ecd 645
dreschpe 12:98cc5c193ecd 646 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 12:98cc5c193ecd 647 else vline(x0,y1,y0,color);
dreschpe 12:98cc5c193ecd 648
dreschpe 12:98cc5c193ecd 649 if (x1 > x0) hline(x0,x1,y1,color);
dreschpe 12:98cc5c193ecd 650 else hline(x1,x0,y1,color);
dreschpe 12:98cc5c193ecd 651
dreschpe 12:98cc5c193ecd 652 if (y1 > y0) vline(x1,y0,y1,color);
dreschpe 12:98cc5c193ecd 653 else vline(x1,y1,y0,color);
dreschpe 12:98cc5c193ecd 654
dreschpe 12:98cc5c193ecd 655 return;
dreschpe 12:98cc5c193ecd 656 }
dreschpe 12:98cc5c193ecd 657
dreschpe 12:98cc5c193ecd 658
dreschpe 12:98cc5c193ecd 659
dreschpe 12:98cc5c193ecd 660 // optimized for speed
dreschpe 12:98cc5c193ecd 661 // use DMA
dreschpe 12:98cc5c193ecd 662 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 663 {
dreschpe 12:98cc5c193ecd 664
dreschpe 12:98cc5c193ecd 665 int h = y1 - y0 + 1;
dreschpe 12:98cc5c193ecd 666 int w = x1 - x0 + 1;
dreschpe 12:98cc5c193ecd 667 int pixel = h * w;
dreschpe 12:98cc5c193ecd 668 unsigned int dma_transfer;
dreschpe 12:98cc5c193ecd 669 window(x0,y0,w,h);
dreschpe 12:98cc5c193ecd 670
dreschpe 12:98cc5c193ecd 671 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 672 spi_16(1);
dreschpe 12:98cc5c193ecd 673 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &color;
dreschpe 12:98cc5c193ecd 674 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
dreschpe 12:98cc5c193ecd 675
dreschpe 12:98cc5c193ecd 676 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 677 case (1):
dreschpe 12:98cc5c193ecd 678 DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 679 do{
dreschpe 12:98cc5c193ecd 680 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 681 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 682 pixel = 0;
dreschpe 12:98cc5c193ecd 683 }
dreschpe 12:98cc5c193ecd 684 else {
dreschpe 12:98cc5c193ecd 685 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 686 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 687 }
dreschpe 12:98cc5c193ecd 688 DMA_SetCurrDataCounter(DMA1_Channel3, dma_transfer);
dreschpe 12:98cc5c193ecd 689 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 690 DMA_Cmd(DMA1_Channel3, ENABLE);
dreschpe 12:98cc5c193ecd 691 while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 692 DMA_Cmd(DMA1_Channel3, DISABLE);
dreschpe 12:98cc5c193ecd 693 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 694 break;
dreschpe 12:98cc5c193ecd 695
dreschpe 12:98cc5c193ecd 696 case (2):
dreschpe 12:98cc5c193ecd 697 DMA_Init(DMA1_Channel5, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 698 do{
dreschpe 12:98cc5c193ecd 699 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 700 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 701 pixel = 0;
dreschpe 12:98cc5c193ecd 702 }
dreschpe 12:98cc5c193ecd 703 else {
dreschpe 12:98cc5c193ecd 704 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 705 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 706 }
dreschpe 12:98cc5c193ecd 707 DMA_SetCurrDataCounter(DMA1_Channel5, dma_transfer);
dreschpe 12:98cc5c193ecd 708 SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 709 DMA_Cmd(DMA1_Channel5, ENABLE);
dreschpe 12:98cc5c193ecd 710 while(DMA_GetCurrDataCounter(DMA1_Channel5) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 711 DMA_Cmd(DMA1_Channel5, DISABLE);
dreschpe 12:98cc5c193ecd 712 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 713 break;
dreschpe 12:98cc5c193ecd 714
dreschpe 12:98cc5c193ecd 715 case (3):
dreschpe 12:98cc5c193ecd 716 DMA_Init(DMA2_Channel2, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 717 do{
dreschpe 12:98cc5c193ecd 718 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 719 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 720 pixel = 0;
dreschpe 12:98cc5c193ecd 721 }
dreschpe 12:98cc5c193ecd 722 else {
dreschpe 12:98cc5c193ecd 723 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 724 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 725 }
dreschpe 12:98cc5c193ecd 726 DMA_SetCurrDataCounter(DMA2_Channel2, dma_transfer);
dreschpe 12:98cc5c193ecd 727 SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 728 DMA_Cmd(DMA2_Channel2, ENABLE);
dreschpe 12:98cc5c193ecd 729 while(DMA_GetCurrDataCounter(DMA2_Channel2) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 730 DMA_Cmd(DMA2_Channel2, DISABLE);
dreschpe 12:98cc5c193ecd 731 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 732 break;
dreschpe 12:98cc5c193ecd 733 }
dreschpe 12:98cc5c193ecd 734 spi_bsy();
dreschpe 12:98cc5c193ecd 735 spi_16(0);
dreschpe 12:98cc5c193ecd 736 _cs = 1;
dreschpe 12:98cc5c193ecd 737 WindowMax();
dreschpe 12:98cc5c193ecd 738 return;
dreschpe 12:98cc5c193ecd 739 }
dreschpe 12:98cc5c193ecd 740
dreschpe 12:98cc5c193ecd 741 void SPI_TFT_ILI9341::locate(int x, int y)
dreschpe 12:98cc5c193ecd 742 {
dreschpe 12:98cc5c193ecd 743 char_x = x;
dreschpe 12:98cc5c193ecd 744 char_y = y;
dreschpe 12:98cc5c193ecd 745 }
dreschpe 12:98cc5c193ecd 746
dreschpe 12:98cc5c193ecd 747 int SPI_TFT_ILI9341::columns()
dreschpe 12:98cc5c193ecd 748 {
dreschpe 12:98cc5c193ecd 749 return width() / font[1];
dreschpe 12:98cc5c193ecd 750 }
dreschpe 12:98cc5c193ecd 751
dreschpe 12:98cc5c193ecd 752
dreschpe 12:98cc5c193ecd 753 int SPI_TFT_ILI9341::rows()
dreschpe 12:98cc5c193ecd 754 {
dreschpe 12:98cc5c193ecd 755 return height() / font[2];
dreschpe 12:98cc5c193ecd 756 }
dreschpe 12:98cc5c193ecd 757
dreschpe 12:98cc5c193ecd 758
dreschpe 12:98cc5c193ecd 759 int SPI_TFT_ILI9341::_putc(int value)
dreschpe 12:98cc5c193ecd 760 {
dreschpe 12:98cc5c193ecd 761 if (value == '\n') { // new line
dreschpe 12:98cc5c193ecd 762 char_x = 0;
dreschpe 12:98cc5c193ecd 763 char_y = char_y + font[2];
dreschpe 12:98cc5c193ecd 764 if (char_y >= height() - font[2]) {
dreschpe 12:98cc5c193ecd 765 char_y = 0;
dreschpe 12:98cc5c193ecd 766 }
dreschpe 12:98cc5c193ecd 767 } else {
dreschpe 12:98cc5c193ecd 768 character(char_x, char_y, value);
dreschpe 12:98cc5c193ecd 769 }
dreschpe 12:98cc5c193ecd 770 return value;
dreschpe 12:98cc5c193ecd 771 }
dreschpe 12:98cc5c193ecd 772
dreschpe 12:98cc5c193ecd 773
dreschpe 12:98cc5c193ecd 774 // speed optimized
dreschpe 12:98cc5c193ecd 775 // will use dma
dreschpe 12:98cc5c193ecd 776 void SPI_TFT_ILI9341::character(int x, int y, int c)
dreschpe 12:98cc5c193ecd 777 {
dreschpe 12:98cc5c193ecd 778 unsigned int hor,vert,offset,bpl,j,i,b;
dreschpe 12:98cc5c193ecd 779 unsigned char* zeichen;
dreschpe 12:98cc5c193ecd 780 unsigned char z,w;
dreschpe 12:98cc5c193ecd 781 #ifdef use_ram
dreschpe 12:98cc5c193ecd 782 unsigned int pixel;
dreschpe 12:98cc5c193ecd 783 unsigned int p;
dreschpe 12:98cc5c193ecd 784 unsigned int dma_count,dma_off;
dreschpe 12:98cc5c193ecd 785 uint16_t *buffer;
dreschpe 12:98cc5c193ecd 786 #endif
dreschpe 12:98cc5c193ecd 787
dreschpe 12:98cc5c193ecd 788 if ((c < 31) || (c > 127)) return; // test char range
dreschpe 12:98cc5c193ecd 789
dreschpe 12:98cc5c193ecd 790 // read font parameter from start of array
dreschpe 12:98cc5c193ecd 791 offset = font[0]; // bytes / char
dreschpe 12:98cc5c193ecd 792 hor = font[1]; // get hor size of font
dreschpe 12:98cc5c193ecd 793 vert = font[2]; // get vert size of font
dreschpe 12:98cc5c193ecd 794 bpl = font[3]; // bytes per line
dreschpe 12:98cc5c193ecd 795
dreschpe 12:98cc5c193ecd 796 if (char_x + hor > width()) {
dreschpe 12:98cc5c193ecd 797 char_x = 0;
dreschpe 12:98cc5c193ecd 798 char_y = char_y + vert;
dreschpe 12:98cc5c193ecd 799 if (char_y >= height() - font[2]) {
dreschpe 12:98cc5c193ecd 800 char_y = 0;
dreschpe 12:98cc5c193ecd 801 }
dreschpe 12:98cc5c193ecd 802 }
dreschpe 12:98cc5c193ecd 803 window(char_x, char_y,hor,vert); // setup char box
dreschpe 12:98cc5c193ecd 804 wr_cmd(0x2C);
dreschpe 12:98cc5c193ecd 805 spi_16(1); // switch to 16 bit Mode
dreschpe 12:98cc5c193ecd 806 #ifdef use_ram
dreschpe 12:98cc5c193ecd 807 pixel = hor * vert; // calculate buffer size
dreschpe 12:98cc5c193ecd 808 buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the font
dreschpe 12:98cc5c193ecd 809 if(buffer != NULL) { // there is memory space -> use dma
dreschpe 12:98cc5c193ecd 810 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 12:98cc5c193ecd 811 w = zeichen[0]; // width of actual char
dreschpe 12:98cc5c193ecd 812 p = 0;
dreschpe 12:98cc5c193ecd 813 // construct the font into the buffer
dreschpe 12:98cc5c193ecd 814 for (j=0; j<vert; j++) { // vert line
dreschpe 12:98cc5c193ecd 815 for (i=0; i<hor; i++) { // horz line
dreschpe 12:98cc5c193ecd 816 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 12:98cc5c193ecd 817 b = 1 << (j & 0x07);
dreschpe 12:98cc5c193ecd 818 if (( z & b ) == 0x00) {
dreschpe 12:98cc5c193ecd 819 buffer[p] = _background;
dreschpe 12:98cc5c193ecd 820 } else {
dreschpe 12:98cc5c193ecd 821 buffer[p] = _foreground;
dreschpe 12:98cc5c193ecd 822 }
dreschpe 12:98cc5c193ecd 823 p++;
dreschpe 12:98cc5c193ecd 824 }
dreschpe 12:98cc5c193ecd 825 }
dreschpe 12:98cc5c193ecd 826 // copy the buffer with DMA SPI to display
dreschpe 12:98cc5c193ecd 827 dma_off = 0; // offset for DMA transfer
dreschpe 12:98cc5c193ecd 828 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) (buffer + dma_off);
dreschpe 12:98cc5c193ecd 829 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
dreschpe 12:98cc5c193ecd 830
dreschpe 12:98cc5c193ecd 831 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 832 case (1):
dreschpe 12:98cc5c193ecd 833 DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 834 // start DMA
dreschpe 12:98cc5c193ecd 835 do {
dreschpe 12:98cc5c193ecd 836 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 837 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 838 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 839 } else {
dreschpe 12:98cc5c193ecd 840 dma_count = pixel;
dreschpe 12:98cc5c193ecd 841 pixel = 0;
dreschpe 12:98cc5c193ecd 842 }
dreschpe 12:98cc5c193ecd 843 DMA_SetCurrDataCounter(DMA1_Channel3, dma_count);
dreschpe 12:98cc5c193ecd 844 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 845 DMA_Cmd(DMA1_Channel3, ENABLE);
dreschpe 12:98cc5c193ecd 846 while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 847 DMA_Cmd(DMA1_Channel3, DISABLE);
dreschpe 12:98cc5c193ecd 848 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 849 break;
dreschpe 12:98cc5c193ecd 850
dreschpe 12:98cc5c193ecd 851 case (2):
dreschpe 12:98cc5c193ecd 852 DMA_Init(DMA1_Channel5, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 853 // start DMA
dreschpe 12:98cc5c193ecd 854 do {
dreschpe 12:98cc5c193ecd 855 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 856 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 857 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 858 } else {
dreschpe 12:98cc5c193ecd 859 dma_count = pixel;
dreschpe 12:98cc5c193ecd 860 pixel = 0;
dreschpe 12:98cc5c193ecd 861 }
dreschpe 12:98cc5c193ecd 862 DMA_SetCurrDataCounter(DMA1_Channel5, dma_count);
dreschpe 12:98cc5c193ecd 863 SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 864 DMA_Cmd(DMA1_Channel5, ENABLE);
dreschpe 12:98cc5c193ecd 865 while(DMA_GetCurrDataCounter(DMA1_Channel5) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 866 DMA_Cmd(DMA1_Channel5, DISABLE);
dreschpe 12:98cc5c193ecd 867 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 868 break;
dreschpe 12:98cc5c193ecd 869
dreschpe 12:98cc5c193ecd 870 case (3):
dreschpe 12:98cc5c193ecd 871 DMA_Init(DMA2_Channel2, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 872 // start DMA
dreschpe 12:98cc5c193ecd 873 do {
dreschpe 12:98cc5c193ecd 874 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 875 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 876 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 877 } else {
dreschpe 12:98cc5c193ecd 878 dma_count = pixel;
dreschpe 12:98cc5c193ecd 879 pixel = 0;
dreschpe 12:98cc5c193ecd 880 }
dreschpe 12:98cc5c193ecd 881 DMA_SetCurrDataCounter(DMA2_Channel2, dma_count);
dreschpe 12:98cc5c193ecd 882 SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 883 DMA_Cmd(DMA2_Channel2, ENABLE);
dreschpe 12:98cc5c193ecd 884 while(DMA_GetCurrDataCounter(DMA2_Channel2) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 885 DMA_Cmd(DMA2_Channel2, DISABLE);
dreschpe 12:98cc5c193ecd 886 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 887 break;
dreschpe 12:98cc5c193ecd 888
dreschpe 12:98cc5c193ecd 889 }
dreschpe 12:98cc5c193ecd 890 spi_bsy();
dreschpe 12:98cc5c193ecd 891 free ((uint16_t *) buffer);
dreschpe 12:98cc5c193ecd 892 spi_16(0);
dreschpe 12:98cc5c193ecd 893 }
dreschpe 12:98cc5c193ecd 894
dreschpe 12:98cc5c193ecd 895 else{
dreschpe 12:98cc5c193ecd 896 #endif
dreschpe 12:98cc5c193ecd 897 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 12:98cc5c193ecd 898 w = zeichen[0]; // width of actual char
dreschpe 12:98cc5c193ecd 899 for (j=0; j<vert; j++) { // vert line
dreschpe 12:98cc5c193ecd 900 for (i=0; i<hor; i++) { // horz line
dreschpe 12:98cc5c193ecd 901 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 12:98cc5c193ecd 902 b = 1 << (j & 0x07);
dreschpe 12:98cc5c193ecd 903 if (( z & b ) == 0x00) {
dreschpe 12:98cc5c193ecd 904 f_write(_background);
dreschpe 12:98cc5c193ecd 905 } else {
dreschpe 12:98cc5c193ecd 906 f_write(_foreground);
dreschpe 12:98cc5c193ecd 907 }
dreschpe 12:98cc5c193ecd 908 }
dreschpe 12:98cc5c193ecd 909 }
dreschpe 12:98cc5c193ecd 910 spi_bsy();
dreschpe 12:98cc5c193ecd 911 _cs = 1;
dreschpe 12:98cc5c193ecd 912 spi_16(0);
dreschpe 12:98cc5c193ecd 913 #ifdef use_ram
dreschpe 12:98cc5c193ecd 914 }
dreschpe 12:98cc5c193ecd 915 #endif
dreschpe 12:98cc5c193ecd 916 _cs = 1;
dreschpe 12:98cc5c193ecd 917 WindowMax();
dreschpe 12:98cc5c193ecd 918 if ((w + 2) < hor) { // x offset to next char
dreschpe 12:98cc5c193ecd 919 char_x += w + 2;
dreschpe 12:98cc5c193ecd 920 } else char_x += hor;
dreschpe 12:98cc5c193ecd 921 }
dreschpe 12:98cc5c193ecd 922
dreschpe 12:98cc5c193ecd 923
dreschpe 12:98cc5c193ecd 924 void SPI_TFT_ILI9341::set_font(unsigned char* f)
dreschpe 12:98cc5c193ecd 925 {
dreschpe 12:98cc5c193ecd 926 font = f;
dreschpe 12:98cc5c193ecd 927 }
dreschpe 12:98cc5c193ecd 928
dreschpe 12:98cc5c193ecd 929
dreschpe 12:98cc5c193ecd 930 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
dreschpe 12:98cc5c193ecd 931 {
dreschpe 12:98cc5c193ecd 932 unsigned int j;
dreschpe 12:98cc5c193ecd 933 int padd;
dreschpe 12:98cc5c193ecd 934 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
dreschpe 12:98cc5c193ecd 935
dreschpe 12:98cc5c193ecd 936 unsigned int i;
dreschpe 12:98cc5c193ecd 937
dreschpe 12:98cc5c193ecd 938 // the lines are padded to multiple of 4 bytes in a bitmap
dreschpe 12:98cc5c193ecd 939 padd = -1;
dreschpe 12:98cc5c193ecd 940 do {
dreschpe 12:98cc5c193ecd 941 padd ++;
dreschpe 12:98cc5c193ecd 942 } while (2*(w + padd)%4 != 0);
dreschpe 12:98cc5c193ecd 943 window(x, y, w, h);
dreschpe 12:98cc5c193ecd 944 bitmap_ptr += ((h - 1)* (w + padd));
dreschpe 12:98cc5c193ecd 945 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 946 spi_16(1);
dreschpe 12:98cc5c193ecd 947 for (j = 0; j < h; j++) { //Lines
dreschpe 12:98cc5c193ecd 948 for (i = 0; i < w; i++) { // one line
dreschpe 12:98cc5c193ecd 949 f_write(*bitmap_ptr); // one line
dreschpe 12:98cc5c193ecd 950 bitmap_ptr++;
dreschpe 12:98cc5c193ecd 951 }
dreschpe 12:98cc5c193ecd 952 bitmap_ptr -= 2*w;
dreschpe 12:98cc5c193ecd 953 bitmap_ptr -= padd;
dreschpe 12:98cc5c193ecd 954 }
dreschpe 12:98cc5c193ecd 955 spi_bsy();
dreschpe 12:98cc5c193ecd 956 _cs = 1;
dreschpe 12:98cc5c193ecd 957 spi_16(0);
dreschpe 12:98cc5c193ecd 958 WindowMax();
dreschpe 12:98cc5c193ecd 959 }
dreschpe 12:98cc5c193ecd 960
dreschpe 12:98cc5c193ecd 961
dreschpe 12:98cc5c193ecd 962 // local filesystem is not implemented but you can add a SD card to a different SPI
dreschpe 12:98cc5c193ecd 963
dreschpe 12:98cc5c193ecd 964 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
dreschpe 12:98cc5c193ecd 965 {
dreschpe 12:98cc5c193ecd 966
dreschpe 12:98cc5c193ecd 967 #define OffsetPixelWidth 18
dreschpe 12:98cc5c193ecd 968 #define OffsetPixelHeigh 22
dreschpe 12:98cc5c193ecd 969 #define OffsetFileSize 34
dreschpe 12:98cc5c193ecd 970 #define OffsetPixData 10
dreschpe 12:98cc5c193ecd 971 #define OffsetBPP 28
dreschpe 12:98cc5c193ecd 972
dreschpe 12:98cc5c193ecd 973 char filename[50];
dreschpe 12:98cc5c193ecd 974 unsigned char BMP_Header[54];
dreschpe 12:98cc5c193ecd 975 unsigned short BPP_t;
dreschpe 12:98cc5c193ecd 976 unsigned int PixelWidth,PixelHeigh,start_data;
dreschpe 12:98cc5c193ecd 977 unsigned int i,off;
dreschpe 12:98cc5c193ecd 978 int padd,j;
dreschpe 12:98cc5c193ecd 979 unsigned short *line;
dreschpe 12:98cc5c193ecd 980
dreschpe 12:98cc5c193ecd 981 // get the filename
dreschpe 12:98cc5c193ecd 982 i=0;
dreschpe 12:98cc5c193ecd 983 while (*Name_BMP!='\0') {
dreschpe 12:98cc5c193ecd 984 filename[i++]=*Name_BMP++;
dreschpe 12:98cc5c193ecd 985 }
dreschpe 12:98cc5c193ecd 986 filename[i] = 0;
dreschpe 12:98cc5c193ecd 987
dreschpe 12:98cc5c193ecd 988 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file
dreschpe 12:98cc5c193ecd 989 if (!Image) {
dreschpe 12:98cc5c193ecd 990 return(0); // error file not found !
dreschpe 12:98cc5c193ecd 991 }
dreschpe 12:98cc5c193ecd 992
dreschpe 12:98cc5c193ecd 993 fread(&BMP_Header[0],1,54,Image); // get the BMP Header
dreschpe 12:98cc5c193ecd 994
dreschpe 12:98cc5c193ecd 995 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
dreschpe 12:98cc5c193ecd 996 fclose(Image);
dreschpe 12:98cc5c193ecd 997 return(-1); // error no BMP file
dreschpe 12:98cc5c193ecd 998 }
dreschpe 12:98cc5c193ecd 999
dreschpe 12:98cc5c193ecd 1000 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
dreschpe 12:98cc5c193ecd 1001 if (BPP_t != 0x0010) {
dreschpe 12:98cc5c193ecd 1002 fclose(Image);
dreschpe 12:98cc5c193ecd 1003 return(-2); // error no 16 bit BMP
dreschpe 12:98cc5c193ecd 1004 }
dreschpe 12:98cc5c193ecd 1005
dreschpe 12:98cc5c193ecd 1006 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
dreschpe 12:98cc5c193ecd 1007 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
dreschpe 12:98cc5c193ecd 1008 if (PixelHeigh > height() + y || PixelWidth > width() + x) {
dreschpe 12:98cc5c193ecd 1009 fclose(Image);
dreschpe 12:98cc5c193ecd 1010 return(-3); // to big
dreschpe 12:98cc5c193ecd 1011 }
dreschpe 12:98cc5c193ecd 1012
dreschpe 12:98cc5c193ecd 1013 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
dreschpe 12:98cc5c193ecd 1014
dreschpe 12:98cc5c193ecd 1015 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
dreschpe 12:98cc5c193ecd 1016 if (line == NULL) {
dreschpe 12:98cc5c193ecd 1017 return(-4); // error no memory
dreschpe 12:98cc5c193ecd 1018 }
dreschpe 12:98cc5c193ecd 1019
dreschpe 12:98cc5c193ecd 1020 // the bmp lines are padded to multiple of 4 bytes
dreschpe 12:98cc5c193ecd 1021 padd = -1;
dreschpe 12:98cc5c193ecd 1022 do {
dreschpe 12:98cc5c193ecd 1023 padd ++;
dreschpe 12:98cc5c193ecd 1024 } while ((PixelWidth * 2 + padd)%4 != 0);
dreschpe 12:98cc5c193ecd 1025
dreschpe 12:98cc5c193ecd 1026 window(x, y,PixelWidth ,PixelHeigh);
dreschpe 12:98cc5c193ecd 1027 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 1028 spi_16(1);
dreschpe 12:98cc5c193ecd 1029 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
dreschpe 12:98cc5c193ecd 1030 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
dreschpe 12:98cc5c193ecd 1031 fseek(Image, off ,SEEK_SET);
dreschpe 12:98cc5c193ecd 1032 fread(line,1,PixelWidth * 2,Image); // read a line - slow
dreschpe 12:98cc5c193ecd 1033 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
dreschpe 12:98cc5c193ecd 1034 f_write(line[i]); // one 16 bit pixel
dreschpe 12:98cc5c193ecd 1035 }
dreschpe 12:98cc5c193ecd 1036 }
dreschpe 12:98cc5c193ecd 1037 spi_bsy();
dreschpe 12:98cc5c193ecd 1038 _cs = 1;
dreschpe 12:98cc5c193ecd 1039 spi_16(0);
dreschpe 12:98cc5c193ecd 1040 free (line);
dreschpe 12:98cc5c193ecd 1041 fclose(Image);
dreschpe 12:98cc5c193ecd 1042 WindowMax();
dreschpe 12:98cc5c193ecd 1043 return(1);
dreschpe 12:98cc5c193ecd 1044 }
dreschpe 12:98cc5c193ecd 1045
dreschpe 12:98cc5c193ecd 1046 #endif
dreschpe 12:98cc5c193ecd 1047