Repo for ESP32 Weather Station Development
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

948 lignes
29KB

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