Lib for the new LCD Display with ILI9341 controller

Committer:
dreschpe
Date:
Wed Jun 25 07:54:58 2014 +0000
Revision:
12:98cc5c193ecd
Add fast Version for Nucleo F103

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
dreschpe 12:98cc5c193ecd 45 frequency(10000000); // 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
dreschpe 12:98cc5c193ecd 221 // Init code based on MI0283QT datasheet
dreschpe 12:98cc5c193ecd 222 // this code is called only at start
dreschpe 12:98cc5c193ecd 223 // no need to be optimized
dreschpe 12:98cc5c193ecd 224
dreschpe 12:98cc5c193ecd 225 void SPI_TFT_ILI9341::tft_reset()
dreschpe 12:98cc5c193ecd 226 {
dreschpe 12:98cc5c193ecd 227 _cs = 1; // cs high
dreschpe 12:98cc5c193ecd 228 _dc = 1; // dc high
dreschpe 12:98cc5c193ecd 229 _reset = 0; // display reset
dreschpe 12:98cc5c193ecd 230
dreschpe 12:98cc5c193ecd 231 wait_us(50);
dreschpe 12:98cc5c193ecd 232 _reset = 1; // end hardware reset
dreschpe 12:98cc5c193ecd 233 wait_ms(5);
dreschpe 12:98cc5c193ecd 234
dreschpe 12:98cc5c193ecd 235 wr_cmd(0x01); // SW reset
dreschpe 12:98cc5c193ecd 236 wait_ms(5);
dreschpe 12:98cc5c193ecd 237 wr_cmd(0x28); // display off
dreschpe 12:98cc5c193ecd 238
dreschpe 12:98cc5c193ecd 239 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 12:98cc5c193ecd 240 wr_cmd(0xCF);
dreschpe 12:98cc5c193ecd 241 f_write(0x00);
dreschpe 12:98cc5c193ecd 242 f_write(0x83);
dreschpe 12:98cc5c193ecd 243 f_write(0x30);
dreschpe 12:98cc5c193ecd 244 spi_bsy();
dreschpe 12:98cc5c193ecd 245 _cs = 1;
dreschpe 12:98cc5c193ecd 246
dreschpe 12:98cc5c193ecd 247 wr_cmd(0xED);
dreschpe 12:98cc5c193ecd 248 f_write(0x64);
dreschpe 12:98cc5c193ecd 249 f_write(0x03);
dreschpe 12:98cc5c193ecd 250 f_write(0x12);
dreschpe 12:98cc5c193ecd 251 f_write(0x81);
dreschpe 12:98cc5c193ecd 252 spi_bsy();
dreschpe 12:98cc5c193ecd 253 _cs = 1;
dreschpe 12:98cc5c193ecd 254
dreschpe 12:98cc5c193ecd 255 wr_cmd(0xE8);
dreschpe 12:98cc5c193ecd 256 f_write(0x85);
dreschpe 12:98cc5c193ecd 257 f_write(0x01);
dreschpe 12:98cc5c193ecd 258 f_write(0x79);
dreschpe 12:98cc5c193ecd 259 spi_bsy();
dreschpe 12:98cc5c193ecd 260 _cs = 1;
dreschpe 12:98cc5c193ecd 261
dreschpe 12:98cc5c193ecd 262 wr_cmd(0xCB);
dreschpe 12:98cc5c193ecd 263 f_write(0x39);
dreschpe 12:98cc5c193ecd 264 f_write(0x2C);
dreschpe 12:98cc5c193ecd 265 f_write(0x00);
dreschpe 12:98cc5c193ecd 266 f_write(0x34);
dreschpe 12:98cc5c193ecd 267 f_write(0x02);
dreschpe 12:98cc5c193ecd 268 spi_bsy();
dreschpe 12:98cc5c193ecd 269 _cs = 1;
dreschpe 12:98cc5c193ecd 270
dreschpe 12:98cc5c193ecd 271 wr_cmd(0xF7);
dreschpe 12:98cc5c193ecd 272 f_write(0x20);
dreschpe 12:98cc5c193ecd 273 spi_bsy();
dreschpe 12:98cc5c193ecd 274 _cs = 1;
dreschpe 12:98cc5c193ecd 275
dreschpe 12:98cc5c193ecd 276 wr_cmd(0xEA);
dreschpe 12:98cc5c193ecd 277 f_write(0x00);
dreschpe 12:98cc5c193ecd 278 f_write(0x00);
dreschpe 12:98cc5c193ecd 279 spi_bsy();
dreschpe 12:98cc5c193ecd 280 _cs = 1;
dreschpe 12:98cc5c193ecd 281
dreschpe 12:98cc5c193ecd 282 wr_cmd(0xC0); // POWER_CONTROL_1
dreschpe 12:98cc5c193ecd 283 f_write(0x26);
dreschpe 12:98cc5c193ecd 284 spi_bsy();
dreschpe 12:98cc5c193ecd 285 _cs = 1;
dreschpe 12:98cc5c193ecd 286
dreschpe 12:98cc5c193ecd 287 wr_cmd(0xC1); // POWER_CONTROL_2
dreschpe 12:98cc5c193ecd 288 f_write(0x11);
dreschpe 12:98cc5c193ecd 289 spi_bsy();
dreschpe 12:98cc5c193ecd 290 _cs = 1;
dreschpe 12:98cc5c193ecd 291
dreschpe 12:98cc5c193ecd 292 wr_cmd(0xC5); // VCOM_CONTROL_1
dreschpe 12:98cc5c193ecd 293 f_write(0x35);
dreschpe 12:98cc5c193ecd 294 f_write(0x3E);
dreschpe 12:98cc5c193ecd 295 spi_bsy();
dreschpe 12:98cc5c193ecd 296 _cs = 1;
dreschpe 12:98cc5c193ecd 297
dreschpe 12:98cc5c193ecd 298 wr_cmd(0xC7); // VCOM_CONTROL_2
dreschpe 12:98cc5c193ecd 299 f_write(0xBE);
dreschpe 12:98cc5c193ecd 300 spi_bsy();
dreschpe 12:98cc5c193ecd 301 _cs = 1;
dreschpe 12:98cc5c193ecd 302
dreschpe 12:98cc5c193ecd 303 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL
dreschpe 12:98cc5c193ecd 304 f_write(0x48);
dreschpe 12:98cc5c193ecd 305 spi_bsy();
dreschpe 12:98cc5c193ecd 306 _cs = 1;
dreschpe 12:98cc5c193ecd 307
dreschpe 12:98cc5c193ecd 308 wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET
dreschpe 12:98cc5c193ecd 309 f_write(0x55); // 16 bit pixel
dreschpe 12:98cc5c193ecd 310 spi_bsy();
dreschpe 12:98cc5c193ecd 311 _cs = 1;
dreschpe 12:98cc5c193ecd 312
dreschpe 12:98cc5c193ecd 313 wr_cmd(0xB1); // Frame Rate
dreschpe 12:98cc5c193ecd 314 f_write(0x00);
dreschpe 12:98cc5c193ecd 315 f_write(0x1B);
dreschpe 12:98cc5c193ecd 316 spi_bsy();
dreschpe 12:98cc5c193ecd 317 _cs = 1;
dreschpe 12:98cc5c193ecd 318
dreschpe 12:98cc5c193ecd 319 wr_cmd(0xF2); // Gamma Function Disable
dreschpe 12:98cc5c193ecd 320 f_write(0x08);
dreschpe 12:98cc5c193ecd 321 spi_bsy();
dreschpe 12:98cc5c193ecd 322 _cs = 1;
dreschpe 12:98cc5c193ecd 323
dreschpe 12:98cc5c193ecd 324 wr_cmd(0x26);
dreschpe 12:98cc5c193ecd 325 f_write(0x01); // gamma set for curve 01/2/04/08
dreschpe 12:98cc5c193ecd 326 spi_bsy();
dreschpe 12:98cc5c193ecd 327 _cs = 1;
dreschpe 12:98cc5c193ecd 328
dreschpe 12:98cc5c193ecd 329 wr_cmd(0xE0); // positive gamma correction
dreschpe 12:98cc5c193ecd 330 f_write(0x1F);
dreschpe 12:98cc5c193ecd 331 f_write(0x1A);
dreschpe 12:98cc5c193ecd 332 f_write(0x18);
dreschpe 12:98cc5c193ecd 333 f_write(0x0A);
dreschpe 12:98cc5c193ecd 334 f_write(0x0F);
dreschpe 12:98cc5c193ecd 335 f_write(0x06);
dreschpe 12:98cc5c193ecd 336 f_write(0x45);
dreschpe 12:98cc5c193ecd 337 f_write(0x87);
dreschpe 12:98cc5c193ecd 338 f_write(0x32);
dreschpe 12:98cc5c193ecd 339 f_write(0x0A);
dreschpe 12:98cc5c193ecd 340 f_write(0x07);
dreschpe 12:98cc5c193ecd 341 f_write(0x02);
dreschpe 12:98cc5c193ecd 342 f_write(0x07);
dreschpe 12:98cc5c193ecd 343 f_write(0x05);
dreschpe 12:98cc5c193ecd 344 f_write(0x00);
dreschpe 12:98cc5c193ecd 345 spi_bsy();
dreschpe 12:98cc5c193ecd 346 _cs = 1;
dreschpe 12:98cc5c193ecd 347
dreschpe 12:98cc5c193ecd 348 wr_cmd(0xE1); // negativ gamma correction
dreschpe 12:98cc5c193ecd 349 f_write(0x00);
dreschpe 12:98cc5c193ecd 350 f_write(0x25);
dreschpe 12:98cc5c193ecd 351 f_write(0x27);
dreschpe 12:98cc5c193ecd 352 f_write(0x05);
dreschpe 12:98cc5c193ecd 353 f_write(0x10);
dreschpe 12:98cc5c193ecd 354 f_write(0x09);
dreschpe 12:98cc5c193ecd 355 f_write(0x3A);
dreschpe 12:98cc5c193ecd 356 f_write(0x78);
dreschpe 12:98cc5c193ecd 357 f_write(0x4D);
dreschpe 12:98cc5c193ecd 358 f_write(0x05);
dreschpe 12:98cc5c193ecd 359 f_write(0x18);
dreschpe 12:98cc5c193ecd 360 f_write(0x0D);
dreschpe 12:98cc5c193ecd 361 f_write(0x38);
dreschpe 12:98cc5c193ecd 362 f_write(0x3A);
dreschpe 12:98cc5c193ecd 363 f_write(0x1F);
dreschpe 12:98cc5c193ecd 364 spi_bsy();
dreschpe 12:98cc5c193ecd 365 _cs = 1;
dreschpe 12:98cc5c193ecd 366
dreschpe 12:98cc5c193ecd 367 WindowMax ();
dreschpe 12:98cc5c193ecd 368
dreschpe 12:98cc5c193ecd 369 //wr_cmd(0x34); // tearing effect off
dreschpe 12:98cc5c193ecd 370 //_cs = 1;
dreschpe 12:98cc5c193ecd 371
dreschpe 12:98cc5c193ecd 372 //wr_cmd(0x35); // tearing effect on
dreschpe 12:98cc5c193ecd 373 //_cs = 1;
dreschpe 12:98cc5c193ecd 374
dreschpe 12:98cc5c193ecd 375 wr_cmd(0xB7); // entry mode
dreschpe 12:98cc5c193ecd 376 f_write(0x07);
dreschpe 12:98cc5c193ecd 377 spi_bsy();
dreschpe 12:98cc5c193ecd 378 _cs = 1;
dreschpe 12:98cc5c193ecd 379
dreschpe 12:98cc5c193ecd 380 wr_cmd(0xB6); // display function control
dreschpe 12:98cc5c193ecd 381 f_write(0x0A);
dreschpe 12:98cc5c193ecd 382 f_write(0x82);
dreschpe 12:98cc5c193ecd 383 f_write(0x27);
dreschpe 12:98cc5c193ecd 384 f_write(0x00);
dreschpe 12:98cc5c193ecd 385 spi_bsy();
dreschpe 12:98cc5c193ecd 386 _cs = 1;
dreschpe 12:98cc5c193ecd 387
dreschpe 12:98cc5c193ecd 388 wr_cmd(0x11); // sleep out
dreschpe 12:98cc5c193ecd 389 spi_bsy();
dreschpe 12:98cc5c193ecd 390 _cs = 1;
dreschpe 12:98cc5c193ecd 391
dreschpe 12:98cc5c193ecd 392 wait_ms(100);
dreschpe 12:98cc5c193ecd 393
dreschpe 12:98cc5c193ecd 394 wr_cmd(0x29); // display on
dreschpe 12:98cc5c193ecd 395 spi_bsy();
dreschpe 12:98cc5c193ecd 396 _cs = 1;
dreschpe 12:98cc5c193ecd 397
dreschpe 12:98cc5c193ecd 398 wait_ms(100);
dreschpe 12:98cc5c193ecd 399
dreschpe 12:98cc5c193ecd 400 // Configure the DMA controller init-structure
dreschpe 12:98cc5c193ecd 401 DMA_StructInit(&DMA_InitStructure);
dreschpe 12:98cc5c193ecd 402 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 403 case (1):
dreschpe 12:98cc5c193ecd 404 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // SPI1 and SPI2 are using DMA 1
dreschpe 12:98cc5c193ecd 405 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1->DR);
dreschpe 12:98cc5c193ecd 406 break;
dreschpe 12:98cc5c193ecd 407 case (2):
dreschpe 12:98cc5c193ecd 408 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // SPI1 and SPI2 are using DMA 1
dreschpe 12:98cc5c193ecd 409 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI2->DR);
dreschpe 12:98cc5c193ecd 410 break;
dreschpe 12:98cc5c193ecd 411 case (3):
dreschpe 12:98cc5c193ecd 412 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); // SPI3 is using DMA 2
dreschpe 12:98cc5c193ecd 413 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI3->DR);
dreschpe 12:98cc5c193ecd 414 break;
dreschpe 12:98cc5c193ecd 415 }
dreschpe 12:98cc5c193ecd 416 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
dreschpe 12:98cc5c193ecd 417 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
dreschpe 12:98cc5c193ecd 418 DMA_InitStructure.DMA_BufferSize = 0;
dreschpe 12:98cc5c193ecd 419 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dreschpe 12:98cc5c193ecd 420 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dreschpe 12:98cc5c193ecd 421 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dreschpe 12:98cc5c193ecd 422 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
dreschpe 12:98cc5c193ecd 423 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
dreschpe 12:98cc5c193ecd 424 }
dreschpe 12:98cc5c193ecd 425
dreschpe 12:98cc5c193ecd 426
dreschpe 12:98cc5c193ecd 427 // speed optimized
dreschpe 12:98cc5c193ecd 428 // write direct to SPI1 register !
dreschpe 12:98cc5c193ecd 429 void SPI_TFT_ILI9341::pixel(int x, int y, int color)
dreschpe 12:98cc5c193ecd 430 {
dreschpe 12:98cc5c193ecd 431 wr_cmd(0x2A);
dreschpe 12:98cc5c193ecd 432 spi_16(1); // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 433 f_write(x);
dreschpe 12:98cc5c193ecd 434 spi_bsy();
dreschpe 12:98cc5c193ecd 435 _cs = 1;
dreschpe 12:98cc5c193ecd 436
dreschpe 12:98cc5c193ecd 437 spi_16(0); // switch to 8 bit Mode
dreschpe 12:98cc5c193ecd 438 wr_cmd(0x2B);
dreschpe 12:98cc5c193ecd 439 spi_16(1);
dreschpe 12:98cc5c193ecd 440 f_write(y);
dreschpe 12:98cc5c193ecd 441 spi_bsy();
dreschpe 12:98cc5c193ecd 442 _cs = 1;
dreschpe 12:98cc5c193ecd 443 spi_16(0);
dreschpe 12:98cc5c193ecd 444
dreschpe 12:98cc5c193ecd 445 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 446 spi_16(1);
dreschpe 12:98cc5c193ecd 447 f_write(color);
dreschpe 12:98cc5c193ecd 448 spi_bsy();
dreschpe 12:98cc5c193ecd 449 _cs = 1;
dreschpe 12:98cc5c193ecd 450 spi_16(0);
dreschpe 12:98cc5c193ecd 451 }
dreschpe 12:98cc5c193ecd 452
dreschpe 12:98cc5c193ecd 453 // optimized
dreschpe 12:98cc5c193ecd 454 // write direct to SPI1 register !
dreschpe 12:98cc5c193ecd 455 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
dreschpe 12:98cc5c193ecd 456 {
dreschpe 12:98cc5c193ecd 457 wr_cmd(0x2A);
dreschpe 12:98cc5c193ecd 458 spi_16(1);
dreschpe 12:98cc5c193ecd 459 f_write(x);
dreschpe 12:98cc5c193ecd 460 f_write(x+w-1);
dreschpe 12:98cc5c193ecd 461 spi_bsy();
dreschpe 12:98cc5c193ecd 462 _cs = 1;
dreschpe 12:98cc5c193ecd 463 spi_16(0);
dreschpe 12:98cc5c193ecd 464
dreschpe 12:98cc5c193ecd 465 wr_cmd(0x2B);
dreschpe 12:98cc5c193ecd 466 spi_16(1);
dreschpe 12:98cc5c193ecd 467 f_write(y) ;
dreschpe 12:98cc5c193ecd 468 f_write(y+h-1);
dreschpe 12:98cc5c193ecd 469 spi_bsy();
dreschpe 12:98cc5c193ecd 470 _cs = 1;
dreschpe 12:98cc5c193ecd 471 spi_16(0);
dreschpe 12:98cc5c193ecd 472 }
dreschpe 12:98cc5c193ecd 473
dreschpe 12:98cc5c193ecd 474
dreschpe 12:98cc5c193ecd 475 void SPI_TFT_ILI9341::WindowMax (void)
dreschpe 12:98cc5c193ecd 476 {
dreschpe 12:98cc5c193ecd 477 window (0, 0, width(), height());
dreschpe 12:98cc5c193ecd 478 }
dreschpe 12:98cc5c193ecd 479
dreschpe 12:98cc5c193ecd 480 // optimized
dreschpe 12:98cc5c193ecd 481 // use DMA to transfer pixel data to the screen
dreschpe 12:98cc5c193ecd 482 void SPI_TFT_ILI9341::cls (void)
dreschpe 12:98cc5c193ecd 483 {
dreschpe 12:98cc5c193ecd 484 // we can use the fillrect function
dreschpe 12:98cc5c193ecd 485 fillrect(0,0,width()-1,height()-1,_background);
dreschpe 12:98cc5c193ecd 486 }
dreschpe 12:98cc5c193ecd 487
dreschpe 12:98cc5c193ecd 488 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color)
dreschpe 12:98cc5c193ecd 489 {
dreschpe 12:98cc5c193ecd 490
dreschpe 12:98cc5c193ecd 491 int x = -r, y = 0, err = 2-2*r, e2;
dreschpe 12:98cc5c193ecd 492 do {
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 pixel(x0-x, y0-y,color);
dreschpe 12:98cc5c193ecd 497 e2 = err;
dreschpe 12:98cc5c193ecd 498 if (e2 <= y) {
dreschpe 12:98cc5c193ecd 499 err += ++y*2+1;
dreschpe 12:98cc5c193ecd 500 if (-x == y && e2 <= x) e2 = 0;
dreschpe 12:98cc5c193ecd 501 }
dreschpe 12:98cc5c193ecd 502 if (e2 > x) err += ++x*2+1;
dreschpe 12:98cc5c193ecd 503 } while (x <= 0);
dreschpe 12:98cc5c193ecd 504 }
dreschpe 12:98cc5c193ecd 505
dreschpe 12:98cc5c193ecd 506 void SPI_TFT_ILI9341::fillcircle(int x0, int y0, int r, int color)
dreschpe 12:98cc5c193ecd 507 {
dreschpe 12:98cc5c193ecd 508 int x = -r, y = 0, err = 2-2*r, e2;
dreschpe 12:98cc5c193ecd 509 do {
dreschpe 12:98cc5c193ecd 510 vline(x0-x, y0-y, y0+y, color);
dreschpe 12:98cc5c193ecd 511 vline(x0+x, y0-y, y0+y, color);
dreschpe 12:98cc5c193ecd 512 e2 = err;
dreschpe 12:98cc5c193ecd 513 if (e2 <= y) {
dreschpe 12:98cc5c193ecd 514 err += ++y*2+1;
dreschpe 12:98cc5c193ecd 515 if (-x == y && e2 <= x) e2 = 0;
dreschpe 12:98cc5c193ecd 516 }
dreschpe 12:98cc5c193ecd 517 if (e2 > x) err += ++x*2+1;
dreschpe 12:98cc5c193ecd 518 } while (x <= 0);
dreschpe 12:98cc5c193ecd 519 }
dreschpe 12:98cc5c193ecd 520
dreschpe 12:98cc5c193ecd 521
dreschpe 12:98cc5c193ecd 522 // optimized for speed
dreschpe 12:98cc5c193ecd 523 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
dreschpe 12:98cc5c193ecd 524 {
dreschpe 12:98cc5c193ecd 525 int w,j;
dreschpe 12:98cc5c193ecd 526 w = x1 - x0 + 1;
dreschpe 12:98cc5c193ecd 527 window(x0,y,w,1);
dreschpe 12:98cc5c193ecd 528 _dc = 0;
dreschpe 12:98cc5c193ecd 529 _cs = 0;
dreschpe 12:98cc5c193ecd 530 f_write(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 531 spi_bsy();
dreschpe 12:98cc5c193ecd 532 _dc = 1;
dreschpe 12:98cc5c193ecd 533 spi_16(1);
dreschpe 12:98cc5c193ecd 534
dreschpe 12:98cc5c193ecd 535 for (j=0; j<w; j++) {
dreschpe 12:98cc5c193ecd 536 f_write(color);
dreschpe 12:98cc5c193ecd 537 }
dreschpe 12:98cc5c193ecd 538 spi_bsy();
dreschpe 12:98cc5c193ecd 539 spi_16(0);
dreschpe 12:98cc5c193ecd 540 _cs = 1;
dreschpe 12:98cc5c193ecd 541 WindowMax();
dreschpe 12:98cc5c193ecd 542 return;
dreschpe 12:98cc5c193ecd 543 }
dreschpe 12:98cc5c193ecd 544
dreschpe 12:98cc5c193ecd 545 // optimized for speed
dreschpe 12:98cc5c193ecd 546 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
dreschpe 12:98cc5c193ecd 547 {
dreschpe 12:98cc5c193ecd 548 int h,y;
dreschpe 12:98cc5c193ecd 549 h = y1 - y0 + 1;
dreschpe 12:98cc5c193ecd 550 window(x,y0,1,h);
dreschpe 12:98cc5c193ecd 551 _dc = 0;
dreschpe 12:98cc5c193ecd 552 _cs = 0;
dreschpe 12:98cc5c193ecd 553 f_write(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 554 spi_bsy();
dreschpe 12:98cc5c193ecd 555 _dc = 1;
dreschpe 12:98cc5c193ecd 556 spi_16(1);
dreschpe 12:98cc5c193ecd 557 // switch to 16 bit Mode 3
dreschpe 12:98cc5c193ecd 558 for (y=0; y<h; y++) {
dreschpe 12:98cc5c193ecd 559 f_write(color);
dreschpe 12:98cc5c193ecd 560 }
dreschpe 12:98cc5c193ecd 561 spi_bsy();
dreschpe 12:98cc5c193ecd 562 spi_16(0);
dreschpe 12:98cc5c193ecd 563 _cs = 1;
dreschpe 12:98cc5c193ecd 564 WindowMax();
dreschpe 12:98cc5c193ecd 565 return;
dreschpe 12:98cc5c193ecd 566 }
dreschpe 12:98cc5c193ecd 567
dreschpe 12:98cc5c193ecd 568
dreschpe 12:98cc5c193ecd 569 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 570 {
dreschpe 12:98cc5c193ecd 571 //WindowMax();
dreschpe 12:98cc5c193ecd 572 int dx = 0, dy = 0;
dreschpe 12:98cc5c193ecd 573 int dx_sym = 0, dy_sym = 0;
dreschpe 12:98cc5c193ecd 574 int dx_x2 = 0, dy_x2 = 0;
dreschpe 12:98cc5c193ecd 575 int di = 0;
dreschpe 12:98cc5c193ecd 576
dreschpe 12:98cc5c193ecd 577 dx = x1-x0;
dreschpe 12:98cc5c193ecd 578 dy = y1-y0;
dreschpe 12:98cc5c193ecd 579
dreschpe 12:98cc5c193ecd 580 if (dx == 0) { /* vertical line */
dreschpe 12:98cc5c193ecd 581 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 12:98cc5c193ecd 582 else vline(x0,y1,y0,color);
dreschpe 12:98cc5c193ecd 583 return;
dreschpe 12:98cc5c193ecd 584 }
dreschpe 12:98cc5c193ecd 585
dreschpe 12:98cc5c193ecd 586 if (dx > 0) {
dreschpe 12:98cc5c193ecd 587 dx_sym = 1;
dreschpe 12:98cc5c193ecd 588 } else {
dreschpe 12:98cc5c193ecd 589 dx_sym = -1;
dreschpe 12:98cc5c193ecd 590 }
dreschpe 12:98cc5c193ecd 591 if (dy == 0) { /* horizontal line */
dreschpe 12:98cc5c193ecd 592 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 12:98cc5c193ecd 593 else hline(x1,x0,y0,color);
dreschpe 12:98cc5c193ecd 594 return;
dreschpe 12:98cc5c193ecd 595 }
dreschpe 12:98cc5c193ecd 596
dreschpe 12:98cc5c193ecd 597 if (dy > 0) {
dreschpe 12:98cc5c193ecd 598 dy_sym = 1;
dreschpe 12:98cc5c193ecd 599 } else {
dreschpe 12:98cc5c193ecd 600 dy_sym = -1;
dreschpe 12:98cc5c193ecd 601 }
dreschpe 12:98cc5c193ecd 602
dreschpe 12:98cc5c193ecd 603 dx = dx_sym*dx;
dreschpe 12:98cc5c193ecd 604 dy = dy_sym*dy;
dreschpe 12:98cc5c193ecd 605
dreschpe 12:98cc5c193ecd 606 dx_x2 = dx*2;
dreschpe 12:98cc5c193ecd 607 dy_x2 = dy*2;
dreschpe 12:98cc5c193ecd 608
dreschpe 12:98cc5c193ecd 609 if (dx >= dy) {
dreschpe 12:98cc5c193ecd 610 di = dy_x2 - dx;
dreschpe 12:98cc5c193ecd 611 while (x0 != x1) {
dreschpe 12:98cc5c193ecd 612
dreschpe 12:98cc5c193ecd 613 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 614 x0 += dx_sym;
dreschpe 12:98cc5c193ecd 615 if (di<0) {
dreschpe 12:98cc5c193ecd 616 di += dy_x2;
dreschpe 12:98cc5c193ecd 617 } else {
dreschpe 12:98cc5c193ecd 618 di += dy_x2 - dx_x2;
dreschpe 12:98cc5c193ecd 619 y0 += dy_sym;
dreschpe 12:98cc5c193ecd 620 }
dreschpe 12:98cc5c193ecd 621 }
dreschpe 12:98cc5c193ecd 622 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 623 } else {
dreschpe 12:98cc5c193ecd 624 di = dx_x2 - dy;
dreschpe 12:98cc5c193ecd 625 while (y0 != y1) {
dreschpe 12:98cc5c193ecd 626 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 627 y0 += dy_sym;
dreschpe 12:98cc5c193ecd 628 if (di < 0) {
dreschpe 12:98cc5c193ecd 629 di += dx_x2;
dreschpe 12:98cc5c193ecd 630 } else {
dreschpe 12:98cc5c193ecd 631 di += dx_x2 - dy_x2;
dreschpe 12:98cc5c193ecd 632 x0 += dx_sym;
dreschpe 12:98cc5c193ecd 633 }
dreschpe 12:98cc5c193ecd 634 }
dreschpe 12:98cc5c193ecd 635 pixel(x0, y0, color);
dreschpe 12:98cc5c193ecd 636 }
dreschpe 12:98cc5c193ecd 637 return;
dreschpe 12:98cc5c193ecd 638 }
dreschpe 12:98cc5c193ecd 639
dreschpe 12:98cc5c193ecd 640
dreschpe 12:98cc5c193ecd 641 void SPI_TFT_ILI9341::rect(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 642 {
dreschpe 12:98cc5c193ecd 643
dreschpe 12:98cc5c193ecd 644 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 12:98cc5c193ecd 645 else hline(x1,x0,y0,color);
dreschpe 12:98cc5c193ecd 646
dreschpe 12:98cc5c193ecd 647 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 12:98cc5c193ecd 648 else vline(x0,y1,y0,color);
dreschpe 12:98cc5c193ecd 649
dreschpe 12:98cc5c193ecd 650 if (x1 > x0) hline(x0,x1,y1,color);
dreschpe 12:98cc5c193ecd 651 else hline(x1,x0,y1,color);
dreschpe 12:98cc5c193ecd 652
dreschpe 12:98cc5c193ecd 653 if (y1 > y0) vline(x1,y0,y1,color);
dreschpe 12:98cc5c193ecd 654 else vline(x1,y1,y0,color);
dreschpe 12:98cc5c193ecd 655
dreschpe 12:98cc5c193ecd 656 return;
dreschpe 12:98cc5c193ecd 657 }
dreschpe 12:98cc5c193ecd 658
dreschpe 12:98cc5c193ecd 659
dreschpe 12:98cc5c193ecd 660
dreschpe 12:98cc5c193ecd 661 // optimized for speed
dreschpe 12:98cc5c193ecd 662 // use DMA
dreschpe 12:98cc5c193ecd 663 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
dreschpe 12:98cc5c193ecd 664 {
dreschpe 12:98cc5c193ecd 665
dreschpe 12:98cc5c193ecd 666 int h = y1 - y0 + 1;
dreschpe 12:98cc5c193ecd 667 int w = x1 - x0 + 1;
dreschpe 12:98cc5c193ecd 668 int pixel = h * w;
dreschpe 12:98cc5c193ecd 669 unsigned int dma_transfer;
dreschpe 12:98cc5c193ecd 670 window(x0,y0,w,h);
dreschpe 12:98cc5c193ecd 671
dreschpe 12:98cc5c193ecd 672 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 673 spi_16(1);
dreschpe 12:98cc5c193ecd 674 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &color;
dreschpe 12:98cc5c193ecd 675 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
dreschpe 12:98cc5c193ecd 676
dreschpe 12:98cc5c193ecd 677 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 678 case (1):
dreschpe 12:98cc5c193ecd 679 DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 680 do{
dreschpe 12:98cc5c193ecd 681 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 682 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 683 pixel = 0;
dreschpe 12:98cc5c193ecd 684 }
dreschpe 12:98cc5c193ecd 685 else {
dreschpe 12:98cc5c193ecd 686 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 687 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 688 }
dreschpe 12:98cc5c193ecd 689 DMA_SetCurrDataCounter(DMA1_Channel3, dma_transfer);
dreschpe 12:98cc5c193ecd 690 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 691 DMA_Cmd(DMA1_Channel3, ENABLE);
dreschpe 12:98cc5c193ecd 692 while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 693 DMA_Cmd(DMA1_Channel3, DISABLE);
dreschpe 12:98cc5c193ecd 694 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 695 break;
dreschpe 12:98cc5c193ecd 696
dreschpe 12:98cc5c193ecd 697 case (2):
dreschpe 12:98cc5c193ecd 698 DMA_Init(DMA1_Channel5, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 699 do{
dreschpe 12:98cc5c193ecd 700 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 701 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 702 pixel = 0;
dreschpe 12:98cc5c193ecd 703 }
dreschpe 12:98cc5c193ecd 704 else {
dreschpe 12:98cc5c193ecd 705 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 706 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 707 }
dreschpe 12:98cc5c193ecd 708 DMA_SetCurrDataCounter(DMA1_Channel5, dma_transfer);
dreschpe 12:98cc5c193ecd 709 SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 710 DMA_Cmd(DMA1_Channel5, ENABLE);
dreschpe 12:98cc5c193ecd 711 while(DMA_GetCurrDataCounter(DMA1_Channel5) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 712 DMA_Cmd(DMA1_Channel5, DISABLE);
dreschpe 12:98cc5c193ecd 713 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 714 break;
dreschpe 12:98cc5c193ecd 715
dreschpe 12:98cc5c193ecd 716 case (3):
dreschpe 12:98cc5c193ecd 717 DMA_Init(DMA2_Channel2, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 718 do{
dreschpe 12:98cc5c193ecd 719 if(pixel < 0x10000) {
dreschpe 12:98cc5c193ecd 720 dma_transfer = pixel;
dreschpe 12:98cc5c193ecd 721 pixel = 0;
dreschpe 12:98cc5c193ecd 722 }
dreschpe 12:98cc5c193ecd 723 else {
dreschpe 12:98cc5c193ecd 724 dma_transfer = 0xffff;
dreschpe 12:98cc5c193ecd 725 pixel = pixel - 0xffff;
dreschpe 12:98cc5c193ecd 726 }
dreschpe 12:98cc5c193ecd 727 DMA_SetCurrDataCounter(DMA2_Channel2, dma_transfer);
dreschpe 12:98cc5c193ecd 728 SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 729 DMA_Cmd(DMA2_Channel2, ENABLE);
dreschpe 12:98cc5c193ecd 730 while(DMA_GetCurrDataCounter(DMA2_Channel2) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 731 DMA_Cmd(DMA2_Channel2, DISABLE);
dreschpe 12:98cc5c193ecd 732 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 733 break;
dreschpe 12:98cc5c193ecd 734 }
dreschpe 12:98cc5c193ecd 735 spi_bsy();
dreschpe 12:98cc5c193ecd 736 spi_16(0);
dreschpe 12:98cc5c193ecd 737 _cs = 1;
dreschpe 12:98cc5c193ecd 738 WindowMax();
dreschpe 12:98cc5c193ecd 739 return;
dreschpe 12:98cc5c193ecd 740 }
dreschpe 12:98cc5c193ecd 741
dreschpe 12:98cc5c193ecd 742 void SPI_TFT_ILI9341::locate(int x, int y)
dreschpe 12:98cc5c193ecd 743 {
dreschpe 12:98cc5c193ecd 744 char_x = x;
dreschpe 12:98cc5c193ecd 745 char_y = y;
dreschpe 12:98cc5c193ecd 746 }
dreschpe 12:98cc5c193ecd 747
dreschpe 12:98cc5c193ecd 748 int SPI_TFT_ILI9341::columns()
dreschpe 12:98cc5c193ecd 749 {
dreschpe 12:98cc5c193ecd 750 return width() / font[1];
dreschpe 12:98cc5c193ecd 751 }
dreschpe 12:98cc5c193ecd 752
dreschpe 12:98cc5c193ecd 753
dreschpe 12:98cc5c193ecd 754 int SPI_TFT_ILI9341::rows()
dreschpe 12:98cc5c193ecd 755 {
dreschpe 12:98cc5c193ecd 756 return height() / font[2];
dreschpe 12:98cc5c193ecd 757 }
dreschpe 12:98cc5c193ecd 758
dreschpe 12:98cc5c193ecd 759
dreschpe 12:98cc5c193ecd 760 int SPI_TFT_ILI9341::_putc(int value)
dreschpe 12:98cc5c193ecd 761 {
dreschpe 12:98cc5c193ecd 762 if (value == '\n') { // new line
dreschpe 12:98cc5c193ecd 763 char_x = 0;
dreschpe 12:98cc5c193ecd 764 char_y = char_y + font[2];
dreschpe 12:98cc5c193ecd 765 if (char_y >= height() - font[2]) {
dreschpe 12:98cc5c193ecd 766 char_y = 0;
dreschpe 12:98cc5c193ecd 767 }
dreschpe 12:98cc5c193ecd 768 } else {
dreschpe 12:98cc5c193ecd 769 character(char_x, char_y, value);
dreschpe 12:98cc5c193ecd 770 }
dreschpe 12:98cc5c193ecd 771 return value;
dreschpe 12:98cc5c193ecd 772 }
dreschpe 12:98cc5c193ecd 773
dreschpe 12:98cc5c193ecd 774
dreschpe 12:98cc5c193ecd 775 // speed optimized
dreschpe 12:98cc5c193ecd 776 // will use dma
dreschpe 12:98cc5c193ecd 777 void SPI_TFT_ILI9341::character(int x, int y, int c)
dreschpe 12:98cc5c193ecd 778 {
dreschpe 12:98cc5c193ecd 779 unsigned int hor,vert,offset,bpl,j,i,b;
dreschpe 12:98cc5c193ecd 780 unsigned char* zeichen;
dreschpe 12:98cc5c193ecd 781 unsigned char z,w;
dreschpe 12:98cc5c193ecd 782 #ifdef use_ram
dreschpe 12:98cc5c193ecd 783 unsigned int pixel;
dreschpe 12:98cc5c193ecd 784 unsigned int p;
dreschpe 12:98cc5c193ecd 785 unsigned int dma_count,dma_off;
dreschpe 12:98cc5c193ecd 786 uint16_t *buffer;
dreschpe 12:98cc5c193ecd 787 #endif
dreschpe 12:98cc5c193ecd 788
dreschpe 12:98cc5c193ecd 789 if ((c < 31) || (c > 127)) return; // test char range
dreschpe 12:98cc5c193ecd 790
dreschpe 12:98cc5c193ecd 791 // read font parameter from start of array
dreschpe 12:98cc5c193ecd 792 offset = font[0]; // bytes / char
dreschpe 12:98cc5c193ecd 793 hor = font[1]; // get hor size of font
dreschpe 12:98cc5c193ecd 794 vert = font[2]; // get vert size of font
dreschpe 12:98cc5c193ecd 795 bpl = font[3]; // bytes per line
dreschpe 12:98cc5c193ecd 796
dreschpe 12:98cc5c193ecd 797 if (char_x + hor > width()) {
dreschpe 12:98cc5c193ecd 798 char_x = 0;
dreschpe 12:98cc5c193ecd 799 char_y = char_y + vert;
dreschpe 12:98cc5c193ecd 800 if (char_y >= height() - font[2]) {
dreschpe 12:98cc5c193ecd 801 char_y = 0;
dreschpe 12:98cc5c193ecd 802 }
dreschpe 12:98cc5c193ecd 803 }
dreschpe 12:98cc5c193ecd 804 window(char_x, char_y,hor,vert); // setup char box
dreschpe 12:98cc5c193ecd 805 wr_cmd(0x2C);
dreschpe 12:98cc5c193ecd 806 spi_16(1); // switch to 16 bit Mode
dreschpe 12:98cc5c193ecd 807 #ifdef use_ram
dreschpe 12:98cc5c193ecd 808 pixel = hor * vert; // calculate buffer size
dreschpe 12:98cc5c193ecd 809 buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the font
dreschpe 12:98cc5c193ecd 810 if(buffer != NULL) { // there is memory space -> use dma
dreschpe 12:98cc5c193ecd 811 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 12:98cc5c193ecd 812 w = zeichen[0]; // width of actual char
dreschpe 12:98cc5c193ecd 813 p = 0;
dreschpe 12:98cc5c193ecd 814 // construct the font into the buffer
dreschpe 12:98cc5c193ecd 815 for (j=0; j<vert; j++) { // vert line
dreschpe 12:98cc5c193ecd 816 for (i=0; i<hor; i++) { // horz line
dreschpe 12:98cc5c193ecd 817 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 12:98cc5c193ecd 818 b = 1 << (j & 0x07);
dreschpe 12:98cc5c193ecd 819 if (( z & b ) == 0x00) {
dreschpe 12:98cc5c193ecd 820 buffer[p] = _background;
dreschpe 12:98cc5c193ecd 821 } else {
dreschpe 12:98cc5c193ecd 822 buffer[p] = _foreground;
dreschpe 12:98cc5c193ecd 823 }
dreschpe 12:98cc5c193ecd 824 p++;
dreschpe 12:98cc5c193ecd 825 }
dreschpe 12:98cc5c193ecd 826 }
dreschpe 12:98cc5c193ecd 827 // copy the buffer with DMA SPI to display
dreschpe 12:98cc5c193ecd 828 dma_off = 0; // offset for DMA transfer
dreschpe 12:98cc5c193ecd 829 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) (buffer + dma_off);
dreschpe 12:98cc5c193ecd 830 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
dreschpe 12:98cc5c193ecd 831
dreschpe 12:98cc5c193ecd 832 switch(spi_num){ // decide which SPI is to use
dreschpe 12:98cc5c193ecd 833 case (1):
dreschpe 12:98cc5c193ecd 834 DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 835 // start DMA
dreschpe 12:98cc5c193ecd 836 do {
dreschpe 12:98cc5c193ecd 837 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 838 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 839 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 840 } else {
dreschpe 12:98cc5c193ecd 841 dma_count = pixel;
dreschpe 12:98cc5c193ecd 842 pixel = 0;
dreschpe 12:98cc5c193ecd 843 }
dreschpe 12:98cc5c193ecd 844 DMA_SetCurrDataCounter(DMA1_Channel3, dma_count);
dreschpe 12:98cc5c193ecd 845 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 846 DMA_Cmd(DMA1_Channel3, ENABLE);
dreschpe 12:98cc5c193ecd 847 while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 848 DMA_Cmd(DMA1_Channel3, DISABLE);
dreschpe 12:98cc5c193ecd 849 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 850 break;
dreschpe 12:98cc5c193ecd 851
dreschpe 12:98cc5c193ecd 852 case (2):
dreschpe 12:98cc5c193ecd 853 DMA_Init(DMA1_Channel5, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 854 // start DMA
dreschpe 12:98cc5c193ecd 855 do {
dreschpe 12:98cc5c193ecd 856 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 857 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 858 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 859 } else {
dreschpe 12:98cc5c193ecd 860 dma_count = pixel;
dreschpe 12:98cc5c193ecd 861 pixel = 0;
dreschpe 12:98cc5c193ecd 862 }
dreschpe 12:98cc5c193ecd 863 DMA_SetCurrDataCounter(DMA1_Channel5, dma_count);
dreschpe 12:98cc5c193ecd 864 SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 865 DMA_Cmd(DMA1_Channel5, ENABLE);
dreschpe 12:98cc5c193ecd 866 while(DMA_GetCurrDataCounter(DMA1_Channel5) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 867 DMA_Cmd(DMA1_Channel5, DISABLE);
dreschpe 12:98cc5c193ecd 868 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 869 break;
dreschpe 12:98cc5c193ecd 870
dreschpe 12:98cc5c193ecd 871 case (3):
dreschpe 12:98cc5c193ecd 872 DMA_Init(DMA2_Channel2, &DMA_InitStructure); // init the DMA
dreschpe 12:98cc5c193ecd 873 // start DMA
dreschpe 12:98cc5c193ecd 874 do {
dreschpe 12:98cc5c193ecd 875 if (pixel > 0X10000) { // this is a giant font !
dreschpe 12:98cc5c193ecd 876 dma_count = 0Xffff;
dreschpe 12:98cc5c193ecd 877 pixel = pixel - 0Xffff;
dreschpe 12:98cc5c193ecd 878 } else {
dreschpe 12:98cc5c193ecd 879 dma_count = pixel;
dreschpe 12:98cc5c193ecd 880 pixel = 0;
dreschpe 12:98cc5c193ecd 881 }
dreschpe 12:98cc5c193ecd 882 DMA_SetCurrDataCounter(DMA2_Channel2, dma_count);
dreschpe 12:98cc5c193ecd 883 SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx,ENABLE);
dreschpe 12:98cc5c193ecd 884 DMA_Cmd(DMA2_Channel2, ENABLE);
dreschpe 12:98cc5c193ecd 885 while(DMA_GetCurrDataCounter(DMA2_Channel2) != 0); // wait for end of transfer
dreschpe 12:98cc5c193ecd 886 DMA_Cmd(DMA2_Channel2, DISABLE);
dreschpe 12:98cc5c193ecd 887 }while(pixel > 0);
dreschpe 12:98cc5c193ecd 888 break;
dreschpe 12:98cc5c193ecd 889
dreschpe 12:98cc5c193ecd 890 }
dreschpe 12:98cc5c193ecd 891 spi_bsy();
dreschpe 12:98cc5c193ecd 892 free ((uint16_t *) buffer);
dreschpe 12:98cc5c193ecd 893 spi_16(0);
dreschpe 12:98cc5c193ecd 894 }
dreschpe 12:98cc5c193ecd 895
dreschpe 12:98cc5c193ecd 896 else{
dreschpe 12:98cc5c193ecd 897 #endif
dreschpe 12:98cc5c193ecd 898 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 12:98cc5c193ecd 899 w = zeichen[0]; // width of actual char
dreschpe 12:98cc5c193ecd 900 for (j=0; j<vert; j++) { // vert line
dreschpe 12:98cc5c193ecd 901 for (i=0; i<hor; i++) { // horz line
dreschpe 12:98cc5c193ecd 902 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 12:98cc5c193ecd 903 b = 1 << (j & 0x07);
dreschpe 12:98cc5c193ecd 904 if (( z & b ) == 0x00) {
dreschpe 12:98cc5c193ecd 905 f_write(_background);
dreschpe 12:98cc5c193ecd 906 } else {
dreschpe 12:98cc5c193ecd 907 f_write(_foreground);
dreschpe 12:98cc5c193ecd 908 }
dreschpe 12:98cc5c193ecd 909 }
dreschpe 12:98cc5c193ecd 910 }
dreschpe 12:98cc5c193ecd 911 spi_bsy();
dreschpe 12:98cc5c193ecd 912 _cs = 1;
dreschpe 12:98cc5c193ecd 913 spi_16(0);
dreschpe 12:98cc5c193ecd 914 #ifdef use_ram
dreschpe 12:98cc5c193ecd 915 }
dreschpe 12:98cc5c193ecd 916 #endif
dreschpe 12:98cc5c193ecd 917 _cs = 1;
dreschpe 12:98cc5c193ecd 918 WindowMax();
dreschpe 12:98cc5c193ecd 919 if ((w + 2) < hor) { // x offset to next char
dreschpe 12:98cc5c193ecd 920 char_x += w + 2;
dreschpe 12:98cc5c193ecd 921 } else char_x += hor;
dreschpe 12:98cc5c193ecd 922 }
dreschpe 12:98cc5c193ecd 923
dreschpe 12:98cc5c193ecd 924
dreschpe 12:98cc5c193ecd 925 void SPI_TFT_ILI9341::set_font(unsigned char* f)
dreschpe 12:98cc5c193ecd 926 {
dreschpe 12:98cc5c193ecd 927 font = f;
dreschpe 12:98cc5c193ecd 928 }
dreschpe 12:98cc5c193ecd 929
dreschpe 12:98cc5c193ecd 930
dreschpe 12:98cc5c193ecd 931 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
dreschpe 12:98cc5c193ecd 932 {
dreschpe 12:98cc5c193ecd 933 unsigned int j;
dreschpe 12:98cc5c193ecd 934 int padd;
dreschpe 12:98cc5c193ecd 935 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
dreschpe 12:98cc5c193ecd 936
dreschpe 12:98cc5c193ecd 937 unsigned int i;
dreschpe 12:98cc5c193ecd 938
dreschpe 12:98cc5c193ecd 939 // the lines are padded to multiple of 4 bytes in a bitmap
dreschpe 12:98cc5c193ecd 940 padd = -1;
dreschpe 12:98cc5c193ecd 941 do {
dreschpe 12:98cc5c193ecd 942 padd ++;
dreschpe 12:98cc5c193ecd 943 } while (2*(w + padd)%4 != 0);
dreschpe 12:98cc5c193ecd 944 window(x, y, w, h);
dreschpe 12:98cc5c193ecd 945 bitmap_ptr += ((h - 1)* (w + padd));
dreschpe 12:98cc5c193ecd 946 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 947 spi_16(1);
dreschpe 12:98cc5c193ecd 948 for (j = 0; j < h; j++) { //Lines
dreschpe 12:98cc5c193ecd 949 for (i = 0; i < w; i++) { // one line
dreschpe 12:98cc5c193ecd 950 f_write(*bitmap_ptr); // one line
dreschpe 12:98cc5c193ecd 951 bitmap_ptr++;
dreschpe 12:98cc5c193ecd 952 }
dreschpe 12:98cc5c193ecd 953 bitmap_ptr -= 2*w;
dreschpe 12:98cc5c193ecd 954 bitmap_ptr -= padd;
dreschpe 12:98cc5c193ecd 955 }
dreschpe 12:98cc5c193ecd 956 spi_bsy();
dreschpe 12:98cc5c193ecd 957 _cs = 1;
dreschpe 12:98cc5c193ecd 958 spi_16(0);
dreschpe 12:98cc5c193ecd 959 WindowMax();
dreschpe 12:98cc5c193ecd 960 }
dreschpe 12:98cc5c193ecd 961
dreschpe 12:98cc5c193ecd 962
dreschpe 12:98cc5c193ecd 963 // local filesystem is not implemented but you can add a SD card to a different SPI
dreschpe 12:98cc5c193ecd 964
dreschpe 12:98cc5c193ecd 965 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
dreschpe 12:98cc5c193ecd 966 {
dreschpe 12:98cc5c193ecd 967
dreschpe 12:98cc5c193ecd 968 #define OffsetPixelWidth 18
dreschpe 12:98cc5c193ecd 969 #define OffsetPixelHeigh 22
dreschpe 12:98cc5c193ecd 970 #define OffsetFileSize 34
dreschpe 12:98cc5c193ecd 971 #define OffsetPixData 10
dreschpe 12:98cc5c193ecd 972 #define OffsetBPP 28
dreschpe 12:98cc5c193ecd 973
dreschpe 12:98cc5c193ecd 974 char filename[50];
dreschpe 12:98cc5c193ecd 975 unsigned char BMP_Header[54];
dreschpe 12:98cc5c193ecd 976 unsigned short BPP_t;
dreschpe 12:98cc5c193ecd 977 unsigned int PixelWidth,PixelHeigh,start_data;
dreschpe 12:98cc5c193ecd 978 unsigned int i,off;
dreschpe 12:98cc5c193ecd 979 int padd,j;
dreschpe 12:98cc5c193ecd 980 unsigned short *line;
dreschpe 12:98cc5c193ecd 981
dreschpe 12:98cc5c193ecd 982 // get the filename
dreschpe 12:98cc5c193ecd 983 i=0;
dreschpe 12:98cc5c193ecd 984 while (*Name_BMP!='\0') {
dreschpe 12:98cc5c193ecd 985 filename[i++]=*Name_BMP++;
dreschpe 12:98cc5c193ecd 986 }
dreschpe 12:98cc5c193ecd 987 filename[i] = 0;
dreschpe 12:98cc5c193ecd 988
dreschpe 12:98cc5c193ecd 989 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file
dreschpe 12:98cc5c193ecd 990 if (!Image) {
dreschpe 12:98cc5c193ecd 991 return(0); // error file not found !
dreschpe 12:98cc5c193ecd 992 }
dreschpe 12:98cc5c193ecd 993
dreschpe 12:98cc5c193ecd 994 fread(&BMP_Header[0],1,54,Image); // get the BMP Header
dreschpe 12:98cc5c193ecd 995
dreschpe 12:98cc5c193ecd 996 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
dreschpe 12:98cc5c193ecd 997 fclose(Image);
dreschpe 12:98cc5c193ecd 998 return(-1); // error no BMP file
dreschpe 12:98cc5c193ecd 999 }
dreschpe 12:98cc5c193ecd 1000
dreschpe 12:98cc5c193ecd 1001 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
dreschpe 12:98cc5c193ecd 1002 if (BPP_t != 0x0010) {
dreschpe 12:98cc5c193ecd 1003 fclose(Image);
dreschpe 12:98cc5c193ecd 1004 return(-2); // error no 16 bit BMP
dreschpe 12:98cc5c193ecd 1005 }
dreschpe 12:98cc5c193ecd 1006
dreschpe 12:98cc5c193ecd 1007 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
dreschpe 12:98cc5c193ecd 1008 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
dreschpe 12:98cc5c193ecd 1009 if (PixelHeigh > height() + y || PixelWidth > width() + x) {
dreschpe 12:98cc5c193ecd 1010 fclose(Image);
dreschpe 12:98cc5c193ecd 1011 return(-3); // to big
dreschpe 12:98cc5c193ecd 1012 }
dreschpe 12:98cc5c193ecd 1013
dreschpe 12:98cc5c193ecd 1014 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
dreschpe 12:98cc5c193ecd 1015
dreschpe 12:98cc5c193ecd 1016 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
dreschpe 12:98cc5c193ecd 1017 if (line == NULL) {
dreschpe 12:98cc5c193ecd 1018 return(-4); // error no memory
dreschpe 12:98cc5c193ecd 1019 }
dreschpe 12:98cc5c193ecd 1020
dreschpe 12:98cc5c193ecd 1021 // the bmp lines are padded to multiple of 4 bytes
dreschpe 12:98cc5c193ecd 1022 padd = -1;
dreschpe 12:98cc5c193ecd 1023 do {
dreschpe 12:98cc5c193ecd 1024 padd ++;
dreschpe 12:98cc5c193ecd 1025 } while ((PixelWidth * 2 + padd)%4 != 0);
dreschpe 12:98cc5c193ecd 1026
dreschpe 12:98cc5c193ecd 1027 window(x, y,PixelWidth ,PixelHeigh);
dreschpe 12:98cc5c193ecd 1028 wr_cmd(0x2C); // send pixel
dreschpe 12:98cc5c193ecd 1029 spi_16(1);
dreschpe 12:98cc5c193ecd 1030 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
dreschpe 12:98cc5c193ecd 1031 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
dreschpe 12:98cc5c193ecd 1032 fseek(Image, off ,SEEK_SET);
dreschpe 12:98cc5c193ecd 1033 fread(line,1,PixelWidth * 2,Image); // read a line - slow
dreschpe 12:98cc5c193ecd 1034 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
dreschpe 12:98cc5c193ecd 1035 f_write(line[i]); // one 16 bit pixel
dreschpe 12:98cc5c193ecd 1036 }
dreschpe 12:98cc5c193ecd 1037 }
dreschpe 12:98cc5c193ecd 1038 spi_bsy();
dreschpe 12:98cc5c193ecd 1039 _cs = 1;
dreschpe 12:98cc5c193ecd 1040 spi_16(0);
dreschpe 12:98cc5c193ecd 1041 free (line);
dreschpe 12:98cc5c193ecd 1042 fclose(Image);
dreschpe 12:98cc5c193ecd 1043 WindowMax();
dreschpe 12:98cc5c193ecd 1044 return(1);
dreschpe 12:98cc5c193ecd 1045 }
dreschpe 12:98cc5c193ecd 1046
dreschpe 12:98cc5c193ecd 1047 #endif
dreschpe 12:98cc5c193ecd 1048