The code from https://github.com/vpcola/Nucleo

Committer:
sinrab
Date:
Wed Oct 08 11:00:24 2014 +0000
Revision:
0:5464d5e415e5
The code from https://github.com/vpcola/Nucleo

Who changed what in which revision?

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