ILI9341 display driver (with SPI DMA) for STM32F4 targets. Fork of https://os.mbed.com/users/beaglescout007/code/Nucleo_Ex06_EMU/file/3dac1f1bc9e0/TFT/. Added support for STM32F407 (Seeed Arch Max).

Dependents:   STM32F407VET6_Pong

Committer:
hudakz
Date:
Thu Apr 11 20:10:38 2019 +0000
Revision:
0:5c2870105122
Added support for STM32F407.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:5c2870105122 1 /*===================================================================*/
hudakz 0:5c2870105122 2 /* */
hudakz 0:5c2870105122 3 /* tft.cpp : TFT(ILI9341) function */
hudakz 0:5c2870105122 4 /* */
hudakz 0:5c2870105122 5 /* 2016/1/20 Racoon */
hudakz 0:5c2870105122 6 /* */
hudakz 0:5c2870105122 7 /*===================================================================*/
hudakz 0:5c2870105122 8 #include "mbed.h"
hudakz 0:5c2870105122 9 #include "tft.h"
hudakz 0:5c2870105122 10
hudakz 0:5c2870105122 11 DigitalOut cs(PB_7, PullUp); // TFT chipselect pin
hudakz 0:5c2870105122 12 DigitalOut dc(PB_6, PullUp); // TFT data command select pin
hudakz 0:5c2870105122 13 DigitalOut rst(PB_8, PullUp); // TFT reset pin
hudakz 0:5c2870105122 14
hudakz 0:5c2870105122 15 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 16 /* Write command */
hudakz 0:5c2870105122 17
hudakz 0:5c2870105122 18 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 19 void write_cmd(uint8_t cmd)
hudakz 0:5c2870105122 20 {
hudakz 0:5c2870105122 21 dc = 0;
hudakz 0:5c2870105122 22 spi_write(cmd);
hudakz 0:5c2870105122 23 }
hudakz 0:5c2870105122 24
hudakz 0:5c2870105122 25 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 26 /* Write data */
hudakz 0:5c2870105122 27
hudakz 0:5c2870105122 28 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 29 void write_data(uint8_t data)
hudakz 0:5c2870105122 30 {
hudakz 0:5c2870105122 31 dc = 1;
hudakz 0:5c2870105122 32 spi_write(data);
hudakz 0:5c2870105122 33 }
hudakz 0:5c2870105122 34
hudakz 0:5c2870105122 35 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 36 /* TFT reset */
hudakz 0:5c2870105122 37
hudakz 0:5c2870105122 38 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 39 void tft_reset()
hudakz 0:5c2870105122 40 {
hudakz 0:5c2870105122 41 wait_ms(200);
hudakz 0:5c2870105122 42 cs = 1;
hudakz 0:5c2870105122 43 dc = 1;
hudakz 0:5c2870105122 44 rst = 1;
hudakz 0:5c2870105122 45 wait_ms(200);
hudakz 0:5c2870105122 46 rst = 0;
hudakz 0:5c2870105122 47 wait_us(10);
hudakz 0:5c2870105122 48 rst = 1;
hudakz 0:5c2870105122 49 wait_ms(120);
hudakz 0:5c2870105122 50 cs = 0;
hudakz 0:5c2870105122 51 wait_ms(10);
hudakz 0:5c2870105122 52
hudakz 0:5c2870105122 53 write_cmd(0x3A); // Pixel Format
hudakz 0:5c2870105122 54 write_data(0x55); // 16bit Color
hudakz 0:5c2870105122 55 write_cmd(0xB1); // Frame Control
hudakz 0:5c2870105122 56 write_data(0);
hudakz 0:5c2870105122 57 write_data(0x1f);
hudakz 0:5c2870105122 58
hudakz 0:5c2870105122 59 write_cmd(0x36); // Memory Access Control
hudakz 0:5c2870105122 60 write_data(0xE8); // MY MX MV BGR
hudakz 0:5c2870105122 61 write_cmd(0x11); // Sleep Out
hudakz 0:5c2870105122 62 wait_ms(5);
hudakz 0:5c2870105122 63
hudakz 0:5c2870105122 64 write_cmd(0x29); // Display On
hudakz 0:5c2870105122 65 }
hudakz 0:5c2870105122 66
hudakz 0:5c2870105122 67 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 68 /* Set windows size, start memory write */
hudakz 0:5c2870105122 69
hudakz 0:5c2870105122 70 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 71 void tft_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
hudakz 0:5c2870105122 72 {
hudakz 0:5c2870105122 73 write_cmd(0x2A); // Column Address Set
hudakz 0:5c2870105122 74 write_data(x0 >> 8);
hudakz 0:5c2870105122 75 write_data(x0);
hudakz 0:5c2870105122 76 write_data(x1 >> 8);
hudakz 0:5c2870105122 77 write_data(x1);
hudakz 0:5c2870105122 78
hudakz 0:5c2870105122 79 write_cmd(0x2B); // Page Address Set
hudakz 0:5c2870105122 80 write_data(y0 >> 8);
hudakz 0:5c2870105122 81 write_data(y0);
hudakz 0:5c2870105122 82 write_data(y1 >> 8);
hudakz 0:5c2870105122 83 write_data(y1);
hudakz 0:5c2870105122 84
hudakz 0:5c2870105122 85 write_cmd(0x2C); // Memory Write
hudakz 0:5c2870105122 86 wait_us(20);
hudakz 0:5c2870105122 87
hudakz 0:5c2870105122 88 dc = 1;
hudakz 0:5c2870105122 89 }
hudakz 0:5c2870105122 90
hudakz 0:5c2870105122 91 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 92 /* Clear screen */
hudakz 0:5c2870105122 93
hudakz 0:5c2870105122 94 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 95 void tft_clear(uint16_t color)
hudakz 0:5c2870105122 96 {
hudakz 0:5c2870105122 97 uint16_t pixel[320];
hudakz 0:5c2870105122 98
hudakz 0:5c2870105122 99 tft_set_window(0, 0, TFT_WIDTH, TFT_HEIGHT);
hudakz 0:5c2870105122 100
hudakz 0:5c2870105122 101 //for (int i = 0; i < TFT_WIDTH * TFT_HEIGHT; ++i) {
hudakz 0:5c2870105122 102 //pixel[i++] = color;
hudakz 0:5c2870105122 103 //}
hudakz 0:5c2870105122 104
hudakz 0:5c2870105122 105
hudakz 0:5c2870105122 106 for (int i = 0; i < TFT_HEIGHT; i++) {
hudakz 0:5c2870105122 107 for (int j = 0; j < TFT_WIDTH; j++) {
hudakz 0:5c2870105122 108 pixel[j] = color;
hudakz 0:5c2870105122 109 }
hudakz 0:5c2870105122 110 HAL_SPI_Transmit(&SpiHandle, (uint8_t*)pixel, TFT_WIDTH * 2, 100);
hudakz 0:5c2870105122 111 }
hudakz 0:5c2870105122 112
hudakz 0:5c2870105122 113 }
hudakz 0:5c2870105122 114
hudakz 0:5c2870105122 115 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 116 /* Put char */
hudakz 0:5c2870105122 117
hudakz 0:5c2870105122 118 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 119 void tft_put_char(int x, int y, char chr, uint16_t color, uint16_t bgcolor)
hudakz 0:5c2870105122 120 {
hudakz 0:5c2870105122 121 if (chr < 0x20 || chr > 0x7f) {
hudakz 0:5c2870105122 122 chr = 0x3f;
hudakz 0:5c2870105122 123 }
hudakz 0:5c2870105122 124 else {
hudakz 0:5c2870105122 125 chr = (chr < 0x60) ? chr - 0x20 : chr - 0x40;
hudakz 0:5c2870105122 126 }
hudakz 0:5c2870105122 127
hudakz 0:5c2870105122 128 tft_set_window(x, y, x + 7, y + 6);
hudakz 0:5c2870105122 129
hudakz 0:5c2870105122 130 for (int dy = 0; dy < 7; ++dy) {
hudakz 0:5c2870105122 131 unsigned char img = chrimg[chr][dy];
hudakz 0:5c2870105122 132 for (int dx = 0; dx < 8; ++dx) {
hudakz 0:5c2870105122 133 if (img & 0x80) {
hudakz 0:5c2870105122 134 spi_writew(color);
hudakz 0:5c2870105122 135 }
hudakz 0:5c2870105122 136 else {
hudakz 0:5c2870105122 137 spi_writew(bgcolor);
hudakz 0:5c2870105122 138 }
hudakz 0:5c2870105122 139
hudakz 0:5c2870105122 140 img <<= 1;
hudakz 0:5c2870105122 141 }
hudakz 0:5c2870105122 142 }
hudakz 0:5c2870105122 143 }
hudakz 0:5c2870105122 144
hudakz 0:5c2870105122 145 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 146 /* Text out */
hudakz 0:5c2870105122 147
hudakz 0:5c2870105122 148 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 149 void tft_text(int x, int y, char* text, uint16_t color, uint16_t bgcolor)
hudakz 0:5c2870105122 150 {
hudakz 0:5c2870105122 151 while (*text != 0) {
hudakz 0:5c2870105122 152 tft_put_char(x, y, *text, color, bgcolor);
hudakz 0:5c2870105122 153 x += 8;
hudakz 0:5c2870105122 154 text++;
hudakz 0:5c2870105122 155 }
hudakz 0:5c2870105122 156 }
hudakz 0:5c2870105122 157
hudakz 0:5c2870105122 158 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 159 /* Horizontal Line */
hudakz 0:5c2870105122 160
hudakz 0:5c2870105122 161 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 162 void tft_hline(int x1, int y, int x2, uint16_t color)
hudakz 0:5c2870105122 163 {
hudakz 0:5c2870105122 164 uint16_t pixel[320];
hudakz 0:5c2870105122 165 int i = 0;
hudakz 0:5c2870105122 166
hudakz 0:5c2870105122 167 tft_set_window(x1, y, x2, y);
hudakz 0:5c2870105122 168
hudakz 0:5c2870105122 169 for (; x1 < x2; ++x1) {
hudakz 0:5c2870105122 170 //spi_writew(color);
hudakz 0:5c2870105122 171 pixel[i++] = color;
hudakz 0:5c2870105122 172 }
hudakz 0:5c2870105122 173 HAL_SPI_Transmit(&SpiHandle, (uint8_t*)pixel, (i - 1) * 2, 100);
hudakz 0:5c2870105122 174 }
hudakz 0:5c2870105122 175
hudakz 0:5c2870105122 176 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 177 /* Vertical Line */
hudakz 0:5c2870105122 178
hudakz 0:5c2870105122 179 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 180 void tft_vline(int x, int y1, int y2, uint16_t color)
hudakz 0:5c2870105122 181 {
hudakz 0:5c2870105122 182 uint16_t pixel[240];
hudakz 0:5c2870105122 183 int i = 0;
hudakz 0:5c2870105122 184
hudakz 0:5c2870105122 185 tft_set_window(x, y1, x, y2);
hudakz 0:5c2870105122 186
hudakz 0:5c2870105122 187 for (; y1 < y2; ++y1) {
hudakz 0:5c2870105122 188 //spi_writew(color);
hudakz 0:5c2870105122 189 pixel[i++] = color;
hudakz 0:5c2870105122 190 }
hudakz 0:5c2870105122 191 HAL_SPI_Transmit(&SpiHandle, (uint8_t*)pixel, (i - 1) * 2, 100);
hudakz 0:5c2870105122 192 }
hudakz 0:5c2870105122 193
hudakz 0:5c2870105122 194 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 195 /* Box */
hudakz 0:5c2870105122 196
hudakz 0:5c2870105122 197 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 198 void tft_box(int x1, int y1, int x2, int y2, uint16_t color)
hudakz 0:5c2870105122 199 {
hudakz 0:5c2870105122 200 tft_hline(x1, y1, x2, color);
hudakz 0:5c2870105122 201 tft_vline(x1, y1, y2, color);
hudakz 0:5c2870105122 202 tft_vline(x2, y1, y2, color);
hudakz 0:5c2870105122 203 tft_hline(x1, y2, x2, color);
hudakz 0:5c2870105122 204 }
hudakz 0:5c2870105122 205
hudakz 0:5c2870105122 206 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 207 /* Box Fill */
hudakz 0:5c2870105122 208
hudakz 0:5c2870105122 209 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 210 void tft_boxfill(int x1, int y1, int x2, int y2, uint16_t color)
hudakz 0:5c2870105122 211 {
hudakz 0:5c2870105122 212 uint16_t pixel[320];
hudakz 0:5c2870105122 213 int i;
hudakz 0:5c2870105122 214 int j;
hudakz 0:5c2870105122 215
hudakz 0:5c2870105122 216 tft_set_window(x1, y1, x2, y2);
hudakz 0:5c2870105122 217
hudakz 0:5c2870105122 218 //for (int i = 0; i < (x2 - x1 + 1) * (y2 - y1 + 1); ++i) {
hudakz 0:5c2870105122 219 //spi_writew(color);
hudakz 0:5c2870105122 220 //}
hudakz 0:5c2870105122 221
hudakz 0:5c2870105122 222 for (i = 0; i < (y2 - y1 + 1); i++) {
hudakz 0:5c2870105122 223 for (j = 0; j < (x2 - x1 + 1); j++) {
hudakz 0:5c2870105122 224 pixel[j] = color;
hudakz 0:5c2870105122 225 }
hudakz 0:5c2870105122 226 HAL_SPI_Transmit(&SpiHandle, (uint8_t*)pixel, (j - 1) * 2, 100);
hudakz 0:5c2870105122 227 }
hudakz 0:5c2870105122 228 }
hudakz 0:5c2870105122 229
hudakz 0:5c2870105122 230 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 231 /* Draw 4bit BMP */
hudakz 0:5c2870105122 232
hudakz 0:5c2870105122 233 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 234 bool draw_bmp_4bpp(const unsigned char* imgdata, int x, int y)
hudakz 0:5c2870105122 235 {
hudakz 0:5c2870105122 236 BITMAPFILEHEADER* bf = (BITMAPFILEHEADER*)imgdata;
hudakz 0:5c2870105122 237 BITMAPINFOHEADER* bi = (BITMAPINFOHEADER *) (imgdata + sizeof(BITMAPFILEHEADER));
hudakz 0:5c2870105122 238
hudakz 0:5c2870105122 239 if (bi->biBitCount != 4) {
hudakz 0:5c2870105122 240 return false;
hudakz 0:5c2870105122 241 }
hudakz 0:5c2870105122 242
hudakz 0:5c2870105122 243 unsigned char* pRGBPal = (unsigned char*)imgdata + sizeof(BITMAPFILEHEADER) + bi->biSize;
hudakz 0:5c2870105122 244 unsigned short palette[16];
hudakz 0:5c2870105122 245
hudakz 0:5c2870105122 246 for (int i = 0; pRGBPal < imgdata + bf->bfOffBits && i < 16; ++i) {
hudakz 0:5c2870105122 247 unsigned short r, g, b;
hudakz 0:5c2870105122 248 b = *pRGBPal++ >> 3;
hudakz 0:5c2870105122 249 g = *pRGBPal++ >> 2;
hudakz 0:5c2870105122 250 r = *pRGBPal++ >> 3;
hudakz 0:5c2870105122 251 pRGBPal++;
hudakz 0:5c2870105122 252 palette[i] = ((g & 7) << 13) | (b << 8) | (r << 3) | (g >> 3);
hudakz 0:5c2870105122 253 }
hudakz 0:5c2870105122 254
hudakz 0:5c2870105122 255 unsigned short HLine[320];
hudakz 0:5c2870105122 256 int linesize = (bi->biWidth / 2 + 3) & 0xfffc;
hudakz 0:5c2870105122 257
hudakz 0:5c2870105122 258 tft_set_window(x, y, x + bi->biWidth - 1, y + bi->biHeight - 1);
hudakz 0:5c2870105122 259
hudakz 0:5c2870105122 260 unsigned char* bmp;
hudakz 0:5c2870105122 261
hudakz 0:5c2870105122 262 for (int y = bi->biHeight - 1; y >= 0; --y) {
hudakz 0:5c2870105122 263 bmp = (unsigned char*)imgdata + bf->bfOffBits + y * linesize;
hudakz 0:5c2870105122 264
hudakz 0:5c2870105122 265 for (int x = 0; x < bi->biWidth; ++x) {
hudakz 0:5c2870105122 266 char pal;
hudakz 0:5c2870105122 267 if (x & 1) {
hudakz 0:5c2870105122 268 pal = *bmp & 0xf;
hudakz 0:5c2870105122 269 bmp++;
hudakz 0:5c2870105122 270 }
hudakz 0:5c2870105122 271 else {
hudakz 0:5c2870105122 272 pal = *bmp >> 4;
hudakz 0:5c2870105122 273 }
hudakz 0:5c2870105122 274
hudakz 0:5c2870105122 275 HLine[x] = palette[pal];
hudakz 0:5c2870105122 276 }
hudakz 0:5c2870105122 277
hudakz 0:5c2870105122 278 HAL_SPI_Transmit(&SpiHandle, (uint8_t*)HLine, bi->biWidth * 2, 100);
hudakz 0:5c2870105122 279 }
hudakz 0:5c2870105122 280
hudakz 0:5c2870105122 281 return true;
hudakz 0:5c2870105122 282 }
hudakz 0:5c2870105122 283
hudakz 0:5c2870105122 284 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 285 /* Initialize TFT */
hudakz 0:5c2870105122 286
hudakz 0:5c2870105122 287 /*-------------------------------------------------------------------*/
hudakz 0:5c2870105122 288 void tft_init(void)
hudakz 0:5c2870105122 289 {
hudakz 0:5c2870105122 290 spi_init();
hudakz 0:5c2870105122 291
hudakz 0:5c2870105122 292 tft_reset();
hudakz 0:5c2870105122 293 }