Lib for the new LCD Display with ILI9341 controller Modified for huge fonts (>255 bytes/char). Needs modified font.h files with 2-byte size parameter. Window size is set on a per-character basis to minimise the number of pixels written (speed-up, plus better detection of whether one last character will fit on the current line). NUCLEO & NXP DMA-enabled versions are modified but untested.

Dependents:   Mandelbrot

Fork of SPI_TFT_ILI9341 by Peter Drescher

Committer:
dreschpe
Date:
Sun Jun 22 21:44:00 2014 +0000
Revision:
8:07ad6a48a85d
Parent:
7:4c30bea883bc
Special Nucleo L152 version of TFT Lib

Who changed what in which revision?

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