1 /**
2  * @file lv_tft_espi.cpp
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_tft_espi.h"
10 #if LV_USE_TFT_ESPI
11 
12 #include <TFT_eSPI.h>
13 
14 /*********************
15  *      DEFINES
16  *********************/
17 
18 /**********************
19  *      TYPEDEFS
20  **********************/
21 typedef struct {
22     TFT_eSPI * tft;
23 } lv_tft_espi_t;
24 
25 /**********************
26  *  STATIC PROTOTYPES
27  **********************/
28 static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
29 static void resolution_changed_event_cb(lv_event_t * e);
30 
31 /**********************
32  *  STATIC VARIABLES
33  **********************/
34 
35 /**********************
36  *      MACROS
37  **********************/
38 
39 /**********************
40  *   GLOBAL FUNCTIONS
41  **********************/
42 
lv_tft_espi_create(uint32_t hor_res,uint32_t ver_res,void * buf,uint32_t buf_size_bytes)43 lv_display_t * lv_tft_espi_create(uint32_t hor_res, uint32_t ver_res, void * buf, uint32_t buf_size_bytes)
44 {
45     lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_malloc_zeroed(sizeof(lv_tft_espi_t));
46     LV_ASSERT_MALLOC(dsc);
47     if(dsc == NULL) return NULL;
48 
49     lv_display_t * disp = lv_display_create(hor_res, ver_res);
50     if(disp == NULL) {
51         lv_free(dsc);
52         return NULL;
53     }
54 
55     dsc->tft = new TFT_eSPI(hor_res, ver_res);
56     dsc->tft->begin();          /* TFT init */
57     dsc->tft->setRotation(0);
58     lv_display_set_driver_data(disp, (void *)dsc);
59     lv_display_set_flush_cb(disp, flush_cb);
60     lv_display_add_event_cb(disp, resolution_changed_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
61     lv_display_set_buffers(disp, (void *)buf, NULL, buf_size_bytes, LV_DISPLAY_RENDER_MODE_PARTIAL);
62     return disp;
63 }
64 
65 /**********************
66  *   STATIC FUNCTIONS
67  **********************/
68 
flush_cb(lv_display_t * disp,const lv_area_t * area,uint8_t * px_map)69 static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
70 {
71     lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp);
72 
73     uint32_t w = (area->x2 - area->x1 + 1);
74     uint32_t h = (area->y2 - area->y1 + 1);
75 
76     dsc->tft->startWrite();
77     dsc->tft->setAddrWindow(area->x1, area->y1, w, h);
78     dsc->tft->pushColors((uint16_t *)px_map, w * h, true);
79     dsc->tft->endWrite();
80 
81     lv_display_flush_ready(disp);
82 
83 }
84 
resolution_changed_event_cb(lv_event_t * e)85 static void resolution_changed_event_cb(lv_event_t * e)
86 {
87     lv_display_t * disp = (lv_display_t *)lv_event_get_target(e);
88     lv_tft_espi_t * dsc = (lv_tft_espi_t *)lv_display_get_driver_data(disp);
89     int32_t hor_res = lv_display_get_horizontal_resolution(disp);
90     int32_t ver_res = lv_display_get_vertical_resolution(disp);
91     lv_display_rotation_t rot = lv_display_get_rotation(disp);
92 
93     /* handle rotation */
94     switch(rot) {
95         case LV_DISPLAY_ROTATION_0:
96             dsc->tft->setRotation(0);   /* Portrait orientation */
97             break;
98         case LV_DISPLAY_ROTATION_90:
99             dsc->tft->setRotation(1);   /* Landscape orientation */
100             break;
101         case LV_DISPLAY_ROTATION_180:
102             dsc->tft->setRotation(2);   /* Portrait orientation, flipped */
103             break;
104         case LV_DISPLAY_ROTATION_270:
105             dsc->tft->setRotation(3);   /* Landscape orientation, flipped */
106             break;
107     }
108 }
109 
110 #endif /*LV_USE_TFT_ESPI*/
111