components/tft/tftspi.c

changeset 0
b74b0e4902c3
child 34
5c92103c5e72
equal deleted inserted replaced
-1:000000000000 0:b74b0e4902c3
1 /*
2 * Author: LoBo (loboris@gmail.com, loboris.github)
3 *
4 * Module supporting SPI TFT displays based on ILI9341 & ILI9488 controllers
5 *
6 * HIGH SPEED LOW LEVEL DISPLAY FUNCTIONS
7 * USING DIRECT or DMA SPI TRANSFER MODEs
8 *
9 */
10
11 #include <string.h>
12 #include "tftspi.h"
13 #include "esp_system.h"
14 #include "freertos/task.h"
15 #include "esp_heap_caps.h"
16 #include "soc/spi_reg.h"
17
18 // ====================================================
19 // ==== Global variables, default values ==============
20
21 // Converts colors to grayscale if set to 1
22 uint8_t gray_scale = 0;
23 // Spi clock for reading data from display memory in Hz
24 uint32_t max_rdclock = 8000000;
25
26 // Default display dimensions
27 int _width = DEFAULT_TFT_DISPLAY_WIDTH;
28 int _height = DEFAULT_TFT_DISPLAY_HEIGHT;
29
30 // Display type, DISP_TYPE_ILI9488 or DISP_TYPE_ILI9341
31 uint8_t tft_disp_type = DEFAULT_DISP_TYPE;
32
33 // Spi device handles for display and touch screen
34 spi_lobo_device_handle_t disp_spi = NULL;
35 spi_lobo_device_handle_t ts_spi = NULL;
36
37 // ====================================================
38
39
40 static color_t *trans_cline = NULL;
41 static uint8_t _dma_sending = 0;
42
43 // RGB to GRAYSCALE constants
44 // 0.2989 0.5870 0.1140
45 #define GS_FACT_R 0.2989
46 #define GS_FACT_G 0.4870
47 #define GS_FACT_B 0.2140
48
49
50
51 // ==== Functions =====================
52
53 //------------------------------------------------------
54 esp_err_t IRAM_ATTR wait_trans_finish(uint8_t free_line)
55 {
56 // Wait for SPI bus ready
57 while (disp_spi->host->hw->cmd.usr);
58 if ((free_line) && (trans_cline)) {
59 free(trans_cline);
60 trans_cline = NULL;
61 }
62 if (_dma_sending) {
63 //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset.
64 if (disp_spi->host->dma_chan) spi_lobo_dmaworkaround_idle(disp_spi->host->dma_chan);
65
66 // Reset DMA
67 disp_spi->host->hw->dma_conf.val |= SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
68 disp_spi->host->hw->dma_out_link.start=0;
69 disp_spi->host->hw->dma_in_link.start=0;
70 disp_spi->host->hw->dma_conf.val &= ~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST);
71 disp_spi->host->hw->dma_conf.out_data_burst_en=1;
72 _dma_sending = 0;
73 }
74 return ESP_OK;
75 }
76
77 //-------------------------------
78 esp_err_t IRAM_ATTR disp_select()
79 {
80 wait_trans_finish(1);
81 return spi_lobo_device_select(disp_spi, 0);
82 }
83
84 //---------------------------------
85 esp_err_t IRAM_ATTR disp_deselect()
86 {
87 wait_trans_finish(1);
88 return spi_lobo_device_deselect(disp_spi);
89 }
90
91 //---------------------------------------------------------------------------------------------------
92 static void IRAM_ATTR _spi_transfer_start(spi_lobo_device_handle_t spi_dev, int wrbits, int rdbits) {
93 // Load send buffer
94 spi_dev->host->hw->user.usr_mosi_highpart = 0;
95 spi_dev->host->hw->mosi_dlen.usr_mosi_dbitlen = wrbits-1;
96 spi_dev->host->hw->user.usr_mosi = 1;
97 if (rdbits) {
98 spi_dev->host->hw->miso_dlen.usr_miso_dbitlen = rdbits;
99 spi_dev->host->hw->user.usr_miso = 1;
100 }
101 else {
102 spi_dev->host->hw->miso_dlen.usr_miso_dbitlen = 0;
103 spi_dev->host->hw->user.usr_miso = 0;
104 }
105 // Start transfer
106 spi_dev->host->hw->cmd.usr = 1;
107 // Wait for SPI bus ready
108 while (spi_dev->host->hw->cmd.usr);
109 }
110
111 // Send 1 byte display command, display must be selected
112 //------------------------------------------------
113 void IRAM_ATTR disp_spi_transfer_cmd(int8_t cmd) {
114 // Wait for SPI bus ready
115 while (disp_spi->host->hw->cmd.usr);
116
117 // Set DC to 0 (command mode);
118 gpio_set_level(PIN_NUM_DC, 0);
119
120 disp_spi->host->hw->data_buf[0] = (uint32_t)cmd;
121 _spi_transfer_start(disp_spi, 8, 0);
122 }
123
124 // Send command with data to display, display must be selected
125 //----------------------------------------------------------------------------------
126 void IRAM_ATTR disp_spi_transfer_cmd_data(int8_t cmd, uint8_t *data, uint32_t len) {
127 // Wait for SPI bus ready
128 while (disp_spi->host->hw->cmd.usr);
129
130 // Set DC to 0 (command mode);
131 gpio_set_level(PIN_NUM_DC, 0);
132
133 disp_spi->host->hw->data_buf[0] = (uint32_t)cmd;
134 _spi_transfer_start(disp_spi, 8, 0);
135
136 if ((len == 0) || (data == NULL)) return;
137
138 // Set DC to 1 (data mode);
139 gpio_set_level(PIN_NUM_DC, 1);
140
141 uint8_t idx=0, bidx=0;
142 uint32_t bits=0;
143 uint32_t count=0;
144 uint32_t wd = 0;
145 while (count < len) {
146 // get data byte from buffer
147 wd |= (uint32_t)data[count] << bidx;
148 count++;
149 bits += 8;
150 bidx += 8;
151 if (count == len) {
152 disp_spi->host->hw->data_buf[idx] = wd;
153 break;
154 }
155 if (bidx == 32) {
156 disp_spi->host->hw->data_buf[idx] = wd;
157 idx++;
158 bidx = 0;
159 wd = 0;
160 }
161 if (idx == 16) {
162 // SPI buffer full, send data
163 _spi_transfer_start(disp_spi, bits, 0);
164
165 bits = 0;
166 idx = 0;
167 bidx = 0;
168 }
169 }
170 if (bits > 0) _spi_transfer_start(disp_spi, bits, 0);
171 }
172
173 // Set the address window for display write & read commands, display must be selected
174 //---------------------------------------------------------------------------------------------------
175 static void IRAM_ATTR disp_spi_transfer_addrwin(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2) {
176 uint32_t wd;
177
178 taskDISABLE_INTERRUPTS();
179 // Wait for SPI bus ready
180 while (disp_spi->host->hw->cmd.usr);
181 gpio_set_level(PIN_NUM_DC, 0);
182
183 disp_spi->host->hw->data_buf[0] = (uint32_t)TFT_CASET;
184 disp_spi->host->hw->user.usr_mosi_highpart = 0;
185 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 7;
186 disp_spi->host->hw->user.usr_mosi = 1;
187 disp_spi->host->hw->miso_dlen.usr_miso_dbitlen = 0;
188 disp_spi->host->hw->user.usr_miso = 0;
189
190 disp_spi->host->hw->cmd.usr = 1; // Start transfer
191
192 wd = (uint32_t)(x1>>8);
193 wd |= (uint32_t)(x1&0xff) << 8;
194 wd |= (uint32_t)(x2>>8) << 16;
195 wd |= (uint32_t)(x2&0xff) << 24;
196
197 while (disp_spi->host->hw->cmd.usr); // wait transfer end
198 gpio_set_level(PIN_NUM_DC, 1);
199 disp_spi->host->hw->data_buf[0] = wd;
200 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 31;
201 disp_spi->host->hw->cmd.usr = 1; // Start transfer
202
203 while (disp_spi->host->hw->cmd.usr);
204 gpio_set_level(PIN_NUM_DC, 0);
205 disp_spi->host->hw->data_buf[0] = (uint32_t)TFT_PASET;
206 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 7;
207 disp_spi->host->hw->cmd.usr = 1; // Start transfer
208
209 wd = (uint32_t)(y1>>8);
210 wd |= (uint32_t)(y1&0xff) << 8;
211 wd |= (uint32_t)(y2>>8) << 16;
212 wd |= (uint32_t)(y2&0xff) << 24;
213
214 while (disp_spi->host->hw->cmd.usr);
215 gpio_set_level(PIN_NUM_DC, 1);
216
217 disp_spi->host->hw->data_buf[0] = wd;
218 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 31;
219 disp_spi->host->hw->cmd.usr = 1; // Start transfer
220 while (disp_spi->host->hw->cmd.usr);
221 taskENABLE_INTERRUPTS();
222 }
223
224 // Convert color to gray scale
225 //----------------------------------------------
226 static color_t IRAM_ATTR color2gs(color_t color)
227 {
228 color_t _color;
229 float gs_clr = GS_FACT_R * color.r + GS_FACT_G * color.g + GS_FACT_B * color.b;
230 if (gs_clr > 255) gs_clr = 255;
231
232 _color.r = (uint8_t)gs_clr;
233 _color.g = (uint8_t)gs_clr;
234 _color.b = (uint8_t)gs_clr;
235
236 return _color;
237 }
238
239 // Set display pixel at given coordinates to given color
240 //------------------------------------------------------------------------
241 void IRAM_ATTR drawPixel(int16_t x, int16_t y, color_t color, uint8_t sel)
242 {
243 if (!(disp_spi->cfg.flags & LB_SPI_DEVICE_HALFDUPLEX)) return;
244
245 if (sel) {
246 if (disp_select()) return;
247 }
248 else wait_trans_finish(1);
249
250 uint32_t wd = 0;
251 color_t _color = color;
252 if (gray_scale) _color = color2gs(color);
253
254 taskDISABLE_INTERRUPTS();
255 disp_spi_transfer_addrwin(x, x+1, y, y+1);
256
257 // Send RAM WRITE command
258 gpio_set_level(PIN_NUM_DC, 0);
259 disp_spi->host->hw->data_buf[0] = (uint32_t)TFT_RAMWR;
260 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 7;
261 disp_spi->host->hw->cmd.usr = 1; // Start transfer
262 while (disp_spi->host->hw->cmd.usr); // Wait for SPI bus ready
263
264 wd = (uint32_t)_color.r;
265 wd |= (uint32_t)_color.g << 8;
266 wd |= (uint32_t)_color.b << 16;
267
268 // Set DC to 1 (data mode);
269 gpio_set_level(PIN_NUM_DC, 1);
270
271 disp_spi->host->hw->data_buf[0] = wd;
272 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 23;
273 disp_spi->host->hw->cmd.usr = 1; // Start transfer
274 while (disp_spi->host->hw->cmd.usr); // Wait for SPI bus ready
275
276 taskENABLE_INTERRUPTS();
277 if (sel) disp_deselect();
278 }
279
280 //-----------------------------------------------------------
281 static void IRAM_ATTR _dma_send(uint8_t *data, uint32_t size)
282 {
283 //Fill DMA descriptors
284 spi_lobo_dmaworkaround_transfer_active(disp_spi->host->dma_chan); //mark channel as active
285 spi_lobo_setup_dma_desc_links(disp_spi->host->dmadesc_tx, size, data, false);
286 disp_spi->host->hw->user.usr_mosi_highpart=0;
287 disp_spi->host->hw->dma_out_link.addr=(int)(&disp_spi->host->dmadesc_tx[0]) & 0xFFFFF;
288 disp_spi->host->hw->dma_out_link.start=1;
289 disp_spi->host->hw->user.usr_mosi_highpart=0;
290
291 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = (size * 8) - 1;
292
293 _dma_sending = 1;
294 // Start transfer
295 disp_spi->host->hw->cmd.usr = 1;
296 }
297
298 //---------------------------------------------------------------------------
299 static void IRAM_ATTR _direct_send(color_t *color, uint32_t len, uint8_t rep)
300 {
301 uint32_t cidx = 0; // color buffer index
302 uint32_t wd = 0;
303 int idx = 0;
304 int bits = 0;
305 int wbits = 0;
306
307 taskDISABLE_INTERRUPTS();
308 color_t _color = color[0];
309 if ((rep) && (gray_scale)) _color = color2gs(color[0]);
310
311 while (len) {
312 // ** Get color data from color buffer **
313 if (rep == 0) {
314 if (gray_scale) _color = color2gs(color[cidx]);
315 else _color = color[cidx];
316 }
317
318 wd |= (uint32_t)_color.r << wbits;
319 wbits += 8;
320 if (wbits == 32) {
321 bits += wbits;
322 wbits = 0;
323 disp_spi->host->hw->data_buf[idx++] = wd;
324 wd = 0;
325 }
326 wd |= (uint32_t)_color.g << wbits;
327 wbits += 8;
328 if (wbits == 32) {
329 bits += wbits;
330 wbits = 0;
331 disp_spi->host->hw->data_buf[idx++] = wd;
332 wd = 0;
333 }
334 wd |= (uint32_t)_color.b << wbits;
335 wbits += 8;
336 if (wbits == 32) {
337 bits += wbits;
338 wbits = 0;
339 disp_spi->host->hw->data_buf[idx++] = wd;
340 wd = 0;
341 }
342 len--; // Decrement colors counter
343 if (rep == 0) cidx++; // if not repeating color, increment color buffer index
344 }
345 if (bits) {
346 while (disp_spi->host->hw->cmd.usr); // Wait for SPI bus ready
347 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = bits-1; // set number of bits to be sent
348 disp_spi->host->hw->cmd.usr = 1; // Start transfer
349 }
350 taskENABLE_INTERRUPTS();
351 }
352
353 // ================================================================
354 // === Main function to send data to display ======================
355 // If rep==true: repeat sending color data to display 'len' times
356 // If rep==false: send 'len' color data from color buffer to display
357 // ** Device must already be selected and address window set **
358 // ================================================================
359 //----------------------------------------------------------------------------------------------
360 static void IRAM_ATTR _TFT_pushColorRep(color_t *color, uint32_t len, uint8_t rep, uint8_t wait)
361 {
362 if (len == 0) return;
363 if (!(disp_spi->cfg.flags & LB_SPI_DEVICE_HALFDUPLEX)) return;
364
365 // Send RAM WRITE command
366 gpio_set_level(PIN_NUM_DC, 0);
367 disp_spi->host->hw->data_buf[0] = (uint32_t)TFT_RAMWR;
368 disp_spi->host->hw->mosi_dlen.usr_mosi_dbitlen = 7;
369 disp_spi->host->hw->cmd.usr = 1; // Start transfer
370 while (disp_spi->host->hw->cmd.usr); // Wait for SPI bus ready
371
372 gpio_set_level(PIN_NUM_DC, 1); // Set DC to 1 (data mode);
373
374 if ((len*24) <= 512) {
375
376 _direct_send(color, len, rep);
377
378 }
379 else if (rep == 0) {
380 // ==== use DMA transfer ====
381 // ** Prepare data
382 if (gray_scale) {
383 for (int n=0; n<len; n++) {
384 color[n] = color2gs(color[n]);
385 }
386 }
387
388 _dma_send((uint8_t *)color, len*3);
389 }
390 else {
391 // ==== Repeat color, more than 512 bits total ====
392
393 color_t _color;
394 uint32_t buf_colors;
395 int buf_bytes, to_send;
396
397 /*
398 to_send = len;
399 while (to_send > 0) {
400 wait_trans_finish(0);
401 _direct_send(color, ((to_send > 21) ? 21 : to_send), rep);
402 to_send -= 21;
403 }
404 */
405
406 buf_colors = ((len > (_width*2)) ? (_width*2) : len);
407 buf_bytes = buf_colors * 3;
408
409 // Prepare color buffer of maximum 2 color lines
410 trans_cline = heap_caps_malloc(buf_bytes, MALLOC_CAP_DMA);
411 if (trans_cline == NULL) return;
412
413 // Prepare fill color
414 if (gray_scale) _color = color2gs(color[0]);
415 else _color = color[0];
416
417 // Fill color buffer with fill color
418 for (uint32_t i=0; i<buf_colors; i++) {
419 trans_cline[i] = _color;
420 }
421
422 // Send 'len' colors
423 to_send = len;
424 while (to_send > 0) {
425 wait_trans_finish(0);
426 _dma_send((uint8_t *)trans_cline, ((to_send > buf_colors) ? buf_bytes : (to_send*3)));
427 to_send -= buf_colors;
428 }
429 }
430
431 if (wait) wait_trans_finish(1);
432 }
433
434 // Write 'len' color data to TFT 'window' (x1,y2),(x2,y2)
435 //-------------------------------------------------------------------------------------------
436 void IRAM_ATTR TFT_pushColorRep(int x1, int y1, int x2, int y2, color_t color, uint32_t len)
437 {
438 if (disp_select() != ESP_OK) return;
439
440 // ** Send address window **
441 disp_spi_transfer_addrwin(x1, x2, y1, y2);
442
443 _TFT_pushColorRep(&color, len, 1, 1);
444
445 disp_deselect();
446 }
447
448 // Write 'len' color data to TFT 'window' (x1,y2),(x2,y2) from given buffer
449 // ** Device must already be selected **
450 //-----------------------------------------------------------------------------------
451 void IRAM_ATTR send_data(int x1, int y1, int x2, int y2, uint32_t len, color_t *buf)
452 {
453 // ** Send address window **
454 disp_spi_transfer_addrwin(x1, x2, y1, y2);
455 _TFT_pushColorRep(buf, len, 0, 0);
456 }
457
458 // Reads 'len' pixels/colors from the TFT's GRAM 'window'
459 // 'buf' is an array of bytes with 1st byte reserved for reading 1 dummy byte
460 // and the rest is actually an array of color_t values
461 //--------------------------------------------------------------------------------------------
462 int IRAM_ATTR read_data(int x1, int y1, int x2, int y2, int len, uint8_t *buf, uint8_t set_sp)
463 {
464 spi_lobo_transaction_t t;
465 uint32_t current_clock = 0;
466
467 memset(&t, 0, sizeof(t)); //Zero out the transaction
468 memset(buf, 0, len*sizeof(color_t));
469
470 if (set_sp) {
471 if (disp_deselect() != ESP_OK) return -1;
472 // Change spi clock if needed
473 current_clock = spi_lobo_get_speed(disp_spi);
474 if (max_rdclock < current_clock) spi_lobo_set_speed(disp_spi, max_rdclock);
475 }
476
477 if (disp_select() != ESP_OK) return -2;
478
479 // ** Send address window **
480 disp_spi_transfer_addrwin(x1, x2, y1, y2);
481
482 // ** GET pixels/colors **
483 disp_spi_transfer_cmd(TFT_RAMRD);
484
485 t.length=0; //Send nothing
486 t.tx_buffer=NULL;
487 t.rxlength=8*((len*3)+1); //Receive size in bits
488 t.rx_buffer=buf;
489 //t.user = (void*)1;
490
491 esp_err_t res = spi_lobo_transfer_data(disp_spi, &t); // Receive using direct mode
492
493 disp_deselect();
494
495 if (set_sp) {
496 // Restore spi clock if needed
497 if (max_rdclock < current_clock) spi_lobo_set_speed(disp_spi, current_clock);
498 }
499
500 return res;
501 }
502
503 // Reads one pixel/color from the TFT's GRAM at position (x,y)
504 //-----------------------------------------------
505 color_t IRAM_ATTR readPixel(int16_t x, int16_t y)
506 {
507 uint8_t color_buf[sizeof(color_t)+1] = {0};
508
509 read_data(x, y, x+1, y+1, 1, color_buf, 1);
510
511 color_t color;
512 color.r = color_buf[1];
513 color.g = color_buf[2];
514 color.b = color_buf[3];
515 return color;
516 }
517
518 // get 16-bit data from touch controller for specified type
519 // ** Touch device must already be selected **
520 //----------------------------------------
521 int IRAM_ATTR touch_get_data(uint8_t type)
522 {
523 /*
524 esp_err_t ret;
525 spi_lobo_transaction_t t;
526 memset(&t, 0, sizeof(t)); //Zero out the transaction
527 uint8_t rxdata[2] = {0};
528
529 // send command byte & receive 2 byte response
530 t.rxlength=8*2;
531 t.rx_buffer=&rxdata;
532 t.command = type;
533
534 ret = spi_lobo_transfer_data(ts_spi, &t); // Transmit using direct mode
535
536 if (ret != ESP_OK) res = -1;
537 res = (((int)(rxdata[0] << 8) | (int)(rxdata[1])) >> 4);
538 */
539 // spi_lobo_device_select(ts_spi, 0);
540
541 ts_spi->host->hw->data_buf[0] = type;
542 _spi_transfer_start(ts_spi, 24, 24);
543
544 // printf("touch_get_data(%02X) %06x %02x %02x %02x ", type, ts_spi->host->hw->data_buf[0],
545 // (ts_spi->host->hw->data_buf[0] & 0x0ff),
546 // (ts_spi->host->hw->data_buf[0] >> 11 & 0x0ff),
547 // (ts_spi->host->hw->data_buf[0] >> 19 & 0x0ff) );
548 uint16_t res = (uint16_t)(((ts_spi->host->hw->data_buf[0] >> 11 & 0x0ff) << 8) | (ts_spi->host->hw->data_buf[0] >> 19 & 0x0ff));
549 // printf("res=%d %04x\n", res, res);
550 // spi_lobo_device_deselect(ts_spi);
551 return res;
552 }
553
554 // ==== STMPE610 ===============================================================
555
556
557 // ----- STMPE610 --------------------------------------------------------------------------
558
559 // Send 1 byte display command, display must be selected
560 //---------------------------------------------------------
561 static void IRAM_ATTR stmpe610_write_reg(uint8_t reg, uint8_t val) {
562
563 spi_lobo_device_select(ts_spi, 0);
564
565 ts_spi->host->hw->data_buf[0] = (val << 8) | reg;
566 _spi_transfer_start(ts_spi, 16, 0);
567
568 spi_lobo_device_deselect(ts_spi);
569 }
570
571 //-----------------------------------------------
572 static uint8_t IRAM_ATTR stmpe610_read_byte(uint8_t reg) {
573 spi_lobo_device_select(ts_spi, 0);
574
575 ts_spi->host->hw->data_buf[0] = (reg << 8) | (reg | 0x80);
576 _spi_transfer_start(ts_spi, 16, 16);
577 uint8_t res = ts_spi->host->hw->data_buf[0] >> 8;
578
579 spi_lobo_device_deselect(ts_spi);
580 return res;
581 }
582
583 //-----------------------------------------
584 static uint16_t IRAM_ATTR stmpe610_read_word(uint8_t reg) {
585 spi_lobo_device_select(ts_spi, 0);
586
587 ts_spi->host->hw->data_buf[0] = ((((reg+1) << 8) | ((reg+1) | 0x80)) << 16) | (reg << 8) | (reg | 0x80);
588 _spi_transfer_start(ts_spi, 32, 32);
589 uint16_t res = (uint16_t)(ts_spi->host->hw->data_buf[0] & 0xFF00);
590 res |= (uint16_t)(ts_spi->host->hw->data_buf[0] >> 24);
591
592 spi_lobo_device_deselect(ts_spi);
593 return res;
594 }
595
596 //-----------------------
597 uint32_t stmpe610_getID()
598 {
599 uint16_t tid = stmpe610_read_word(0);
600 uint8_t tver = stmpe610_read_byte(2);
601 return (tid << 8) | tver;
602 }
603
604 //==================
605 void stmpe610_Init()
606 {
607 stmpe610_write_reg(STMPE610_REG_SYS_CTRL1, 0x02); // Software chip reset
608 vTaskDelay(10 / portTICK_RATE_MS);
609
610 stmpe610_write_reg(STMPE610_REG_SYS_CTRL2, 0x04); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on
611
612 stmpe610_write_reg(STMPE610_REG_INT_EN, 0x00); // Don't Interrupt on INT pin
613
614 stmpe610_write_reg(STMPE610_REG_ADC_CTRL1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce
615 vTaskDelay(2 / portTICK_RATE_MS);
616 stmpe610_write_reg(STMPE610_REG_ADC_CTRL2, 0x01); // ADC speed 3.25MHz
617 stmpe610_write_reg(STMPE610_REG_GPIO_AF, 0x00); // GPIO alternate function - OFF
618 stmpe610_write_reg(STMPE610_REG_TSC_CFG, 0xE3); // Averaging 8, touch detect delay 1ms, panel driver settling time 1ms
619 stmpe610_write_reg(STMPE610_REG_FIFO_TH, 0x01); // FIFO threshold = 1
620 stmpe610_write_reg(STMPE610_REG_FIFO_STA, 0x01); // FIFO reset enable
621 stmpe610_write_reg(STMPE610_REG_FIFO_STA, 0x00); // FIFO reset disable
622 stmpe610_write_reg(STMPE610_REG_TSC_FRACT_XYZ, 0x07); // Z axis data format
623 stmpe610_write_reg(STMPE610_REG_TSC_I_DRIVE, 0x01); // max 50mA touchscreen line current
624 stmpe610_write_reg(STMPE610_REG_TSC_CTRL, 0x30); // X&Y&Z, 16 reading window
625 stmpe610_write_reg(STMPE610_REG_TSC_CTRL, 0x31); // X&Y&Z, 16 reading window, TSC enable
626 stmpe610_write_reg(STMPE610_REG_INT_STA, 0xFF); // Clear all interrupts
627 stmpe610_write_reg(STMPE610_REG_INT_CTRL, 0x00); // Level interrupt, disable interrupts
628 }
629
630 //===========================================================
631 int stmpe610_get_touch(uint16_t *x, uint16_t *y, uint16_t *z)
632 {
633 if (!(stmpe610_read_byte(STMPE610_REG_TSC_CTRL) & 0x80)) return 0;
634
635 // Get touch data
636 uint8_t fifo_size = stmpe610_read_byte(STMPE610_REG_FIFO_SIZE);
637 while (fifo_size < 2) {
638 if (!(stmpe610_read_byte(STMPE610_REG_TSC_CTRL) & 0x80)) return 0;
639 fifo_size = stmpe610_read_byte(STMPE610_REG_FIFO_SIZE);
640 }
641 while (fifo_size > 120) {
642 if (!(stmpe610_read_byte(STMPE610_REG_TSC_CTRL) & 0x80)) return 0;
643 *x = stmpe610_read_word(STMPE610_REG_TSC_DATA_X);
644 *y = stmpe610_read_word(STMPE610_REG_TSC_DATA_Y);
645 *z = stmpe610_read_byte(STMPE610_REG_TSC_DATA_Z);
646 fifo_size = stmpe610_read_byte(STMPE610_REG_FIFO_SIZE);
647 }
648 for (uint8_t i=0; i < (fifo_size-1); i++) {
649 *x = stmpe610_read_word(STMPE610_REG_TSC_DATA_X);
650 *y = stmpe610_read_word(STMPE610_REG_TSC_DATA_Y);
651 *z = stmpe610_read_byte(STMPE610_REG_TSC_DATA_Z);
652 }
653
654 *x = 4096 - *x;
655 /*
656 // Clear the rest of the fifo
657 {
658 stmpe610_write_reg(STMPE610_REG_FIFO_STA, 0x01); // FIFO reset enable
659 stmpe610_write_reg(STMPE610_REG_FIFO_STA, 0x00); // FIFO reset disable
660 }
661 */
662 return 1;
663 }
664
665 // ==== STMPE610 ===========================================================================
666
667
668 // Find maximum spi clock for successful read from display RAM
669 // ** Must be used AFTER the display is initialized **
670 //======================
671 uint32_t find_rd_speed()
672 {
673 esp_err_t ret;
674 color_t color;
675 uint32_t max_speed = 1000000;
676 uint32_t change_speed, cur_speed;
677 int line_check;
678 color_t *color_line = NULL;
679 uint8_t *line_rdbuf = NULL;
680 uint8_t gs = gray_scale;
681
682 gray_scale = 0;
683 cur_speed = spi_lobo_get_speed(disp_spi);
684
685 color_line = malloc(_width*3);
686 if (color_line == NULL) goto exit;
687
688 line_rdbuf = malloc((_width*3)+1);
689 if (line_rdbuf == NULL) goto exit;
690
691 color_t *rdline = (color_t *)(line_rdbuf+1);
692
693 // Fill test line with colors
694 color = (color_t){0xEC,0xA8,0x74};
695 for (int x=0; x<_width; x++) {
696 color_line[x] = color;
697 }
698
699 // Find maximum read spi clock
700 for (uint32_t speed=2000000; speed<=cur_speed; speed += 1000000) {
701 change_speed = spi_lobo_set_speed(disp_spi, speed);
702 if (change_speed == 0) goto exit;
703
704 memset(line_rdbuf, 0, _width*sizeof(color_t)+1);
705
706 if (disp_select()) goto exit;
707 // Write color line
708 send_data(0, _height/2, _width-1, _height/2, _width, color_line);
709 if (disp_deselect()) goto exit;
710
711 // Read color line
712 ret = read_data(0, _height/2, _width-1, _height/2, _width, line_rdbuf, 0);
713
714 // Compare
715 line_check = 0;
716 if (ret == ESP_OK) {
717 for (int y=0; y<_width; y++) {
718 if ((color_line[y].r & 0xFC) != (rdline[y].r & 0xFC)) line_check = 1;
719 else if ((color_line[y].g & 0xFC) != (rdline[y].g & 0xFC)) line_check = 1;
720 else if ((color_line[y].b & 0xFC) != (rdline[y].b & 0xFC)) line_check = 1;
721 if (line_check) break;
722 }
723 }
724 else line_check = ret;
725
726 if (line_check) break;
727 max_speed = speed;
728 }
729
730 exit:
731 gray_scale = gs;
732 if (line_rdbuf) free(line_rdbuf);
733 if (color_line) free(color_line);
734
735 // restore spi clk
736 change_speed = spi_lobo_set_speed(disp_spi, cur_speed);
737
738 return max_speed;
739 }
740
741 //---------------------------------------------------------------------------
742 // Companion code to the initialization table.
743 // Reads and issues a series of LCD commands stored in byte array
744 //---------------------------------------------------------------------------
745 static void commandList(spi_lobo_device_handle_t spi, const uint8_t *addr) {
746 uint8_t numCommands, numArgs, cmd;
747 uint16_t ms;
748
749 numCommands = *addr++; // Number of commands to follow
750 while(numCommands--) { // For each command...
751 cmd = *addr++; // save command
752 numArgs = *addr++; // Number of args to follow
753 ms = numArgs & TFT_CMD_DELAY; // If high bit set, delay follows args
754 numArgs &= ~TFT_CMD_DELAY; // Mask out delay bit
755
756 disp_spi_transfer_cmd_data(cmd, (uint8_t *)addr, numArgs);
757
758 addr += numArgs;
759
760 if(ms) {
761 ms = *addr++; // Read post-command delay time (ms)
762 if(ms == 255) ms = 500; // If 255, delay for 500 ms
763 vTaskDelay(ms / portTICK_RATE_MS);
764 }
765 }
766 }
767
768 //==================================
769 void _tft_setRotation(uint8_t rot) {
770 uint8_t rotation = rot & 3; // can't be higher than 3
771 uint8_t send = 1;
772 uint8_t madctl = 0;
773 uint16_t tmp;
774
775 if ((rotation & 1)) {
776 // in landscape modes must be width > height
777 if (_width < _height) {
778 tmp = _width;
779 _width = _height;
780 _height = tmp;
781 }
782 }
783 else {
784 // in portrait modes must be width < height
785 if (_width > _height) {
786 tmp = _width;
787 _width = _height;
788 _height = tmp;
789 }
790 }
791 #if TFT_INVERT_ROTATION
792 switch (rotation) {
793 case PORTRAIT:
794 madctl = (MADCTL_MV | TFT_RGB_BGR);
795 break;
796 case LANDSCAPE:
797 madctl = (MADCTL_MX | TFT_RGB_BGR);
798 break;
799 case PORTRAIT_FLIP:
800 madctl = (MADCTL_MV | TFT_RGB_BGR);
801 break;
802 case LANDSCAPE_FLIP:
803 madctl = (MADCTL_MY | TFT_RGB_BGR);
804 break;
805 }
806 #elif TFT_INVERT_ROTATION1
807 switch (rotation) {
808 case PORTRAIT:
809 madctl = (MADCTL_MY | MADCTL_MX | TFT_RGB_BGR);
810 break;
811 case LANDSCAPE:
812 madctl = (MADCTL_MY | MADCTL_MV | TFT_RGB_BGR);
813 break;
814 case PORTRAIT_FLIP:
815 madctl = (TFT_RGB_BGR);
816 break;
817 case LANDSCAPE_FLIP:
818 madctl = (MADCTL_MX | MADCTL_MV | TFT_RGB_BGR);
819 break;
820 }
821 #elif TFT_INVERT_ROTATION2
822 switch (rotation) {
823 case PORTRAIT:
824 madctl = (MADCTL_MX | MADCTL_MV | TFT_RGB_BGR);
825 break;
826 case LANDSCAPE:
827 madctl = (TFT_RGB_BGR);
828 break;
829 case PORTRAIT_FLIP:
830 madctl = (MADCTL_MY | MADCTL_MV | TFT_RGB_BGR);
831 break;
832 case LANDSCAPE_FLIP:
833 madctl = (MADCTL_MY | MADCTL_MX | TFT_RGB_BGR);
834 break;
835 }
836 #else
837 switch (rotation) {
838 case PORTRAIT:
839 madctl = (MADCTL_MX | TFT_RGB_BGR);
840 break;
841 case LANDSCAPE:
842 madctl = (MADCTL_MV | TFT_RGB_BGR);
843 break;
844 case PORTRAIT_FLIP:
845 madctl = (MADCTL_MY | TFT_RGB_BGR);
846 break;
847 case LANDSCAPE_FLIP:
848 madctl = (MADCTL_MX | MADCTL_MY | MADCTL_MV | TFT_RGB_BGR);
849 break;
850 }
851 #endif
852 if (send) {
853 if (disp_select() == ESP_OK) {
854 disp_spi_transfer_cmd_data(TFT_MADCTL, &madctl, 1);
855 disp_deselect();
856 }
857 }
858
859 }
860
861 //=================
862 void TFT_PinsInit()
863 {
864 // Route all used pins to GPIO control
865 gpio_pad_select_gpio(PIN_NUM_CS);
866 gpio_pad_select_gpio(PIN_NUM_MISO);
867 gpio_pad_select_gpio(PIN_NUM_MOSI);
868 gpio_pad_select_gpio(PIN_NUM_CLK);
869 gpio_pad_select_gpio(PIN_NUM_DC);
870
871 gpio_set_direction(PIN_NUM_MISO, GPIO_MODE_INPUT);
872 gpio_set_pull_mode(PIN_NUM_MISO, GPIO_PULLUP_ONLY);
873 gpio_set_direction(PIN_NUM_CS, GPIO_MODE_OUTPUT);
874 gpio_set_direction(PIN_NUM_MOSI, GPIO_MODE_OUTPUT);
875 gpio_set_direction(PIN_NUM_CLK, GPIO_MODE_OUTPUT);
876 gpio_set_direction(PIN_NUM_DC, GPIO_MODE_OUTPUT);
877 gpio_set_level(PIN_NUM_DC, 0);
878 #if USE_TOUCH
879 gpio_pad_select_gpio(PIN_NUM_TCS);
880 gpio_set_direction(PIN_NUM_TCS, GPIO_MODE_OUTPUT);
881 #endif
882 #if PIN_NUM_BCKL
883 gpio_pad_select_gpio(PIN_NUM_BCKL);
884 gpio_set_direction(PIN_NUM_BCKL, GPIO_MODE_OUTPUT);
885 gpio_set_level(PIN_NUM_BCKL, PIN_BCKL_OFF);
886 #endif
887
888 #if PIN_NUM_RST
889 gpio_pad_select_gpio(PIN_NUM_RST);
890 gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT);
891 gpio_set_level(PIN_NUM_RST, 0);
892 #endif
893 }
894
895 // Initialize the display
896 // ====================
897 void TFT_display_init()
898 {
899 esp_err_t ret;
900
901 #if PIN_NUM_RST
902 //Reset the display
903 gpio_set_level(PIN_NUM_RST, 0);
904 vTaskDelay(20 / portTICK_RATE_MS);
905 gpio_set_level(PIN_NUM_RST, 1);
906 vTaskDelay(150 / portTICK_RATE_MS);
907 #endif
908
909 ret = disp_select();
910 assert(ret==ESP_OK);
911 //Send all the initialization commands
912 if (tft_disp_type == DISP_TYPE_ILI9341) {
913 commandList(disp_spi, ILI9341_init);
914 }
915 else if (tft_disp_type == DISP_TYPE_ILI9488) {
916 commandList(disp_spi, ILI9488_init);
917 }
918 else if (tft_disp_type == DISP_TYPE_ST7789V) {
919 commandList(disp_spi, ST7789V_init);
920 }
921 else if (tft_disp_type == DISP_TYPE_ST7735) {
922 commandList(disp_spi, STP7735_init);
923 }
924 else if (tft_disp_type == DISP_TYPE_ST7735R) {
925 commandList(disp_spi, STP7735R_init);
926 commandList(disp_spi, Rcmd2green);
927 commandList(disp_spi, Rcmd3);
928 }
929 else if (tft_disp_type == DISP_TYPE_ST7735B) {
930 commandList(disp_spi, STP7735R_init);
931 commandList(disp_spi, Rcmd2red);
932 commandList(disp_spi, Rcmd3);
933 uint8_t dt = 0xC0;
934 disp_spi_transfer_cmd_data(TFT_MADCTL, &dt, 1);
935 }
936 else assert(0);
937
938 ret = disp_deselect();
939 assert(ret==ESP_OK);
940
941 // Clear screen
942 _tft_setRotation(PORTRAIT);
943 TFT_pushColorRep(0, 0, _width-1, _height-1, (color_t){0,0,0}, (uint32_t)(_height*_width));
944
945 ///Enable backlight
946 #if PIN_NUM_BCKL
947 gpio_set_level(PIN_NUM_BCKL, PIN_BCKL_ON);
948 #endif
949 }
950
951

mercurial