-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwho_lecd.c
142 lines (123 loc) · 3.8 KB
/
who_lecd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "who_lcd.h"
#include "esp_camera.h"
#include <string.h>
#include "logo_en_240x240_lcd.h"
static const char *TAG = "who_lcd";
static scr_driver_t g_lcd;
static scr_info_t g_lcd_info;
static QueueHandle_t xQueueFrameI = NULL;
static QueueHandle_t xQueueFrameO = NULL;
static bool gReturnFB = true;
static void task_process_handler(void *arg)
{
camera_fb_t *frame = NULL;
while (true)
{
if (xQueueReceive(xQueueFrameI, &frame, portMAX_DELAY))
{
g_lcd.draw_bitmap(0, 0, frame->width, frame->height, (uint16_t *)frame->buf);
if (xQueueFrameO)
{
xQueueSend(xQueueFrameO, &frame, portMAX_DELAY);
}
else if (gReturnFB)
{
esp_camera_fb_return(frame);
}
else
{
free(frame);
}
}
}
}
esp_err_t register_lcd(const QueueHandle_t frame_i, const QueueHandle_t frame_o, const bool return_fb)
{
spi_config_t bus_conf = {
.miso_io_num = BOARD_LCD_MISO,
.mosi_io_num = BOARD_LCD_MOSI,
.sclk_io_num = BOARD_LCD_SCK,
.max_transfer_sz = 2 * 240 * 240 + 10,
};
spi_bus_handle_t spi_bus = spi_bus_create(SPI2_HOST, &bus_conf);
scr_interface_spi_config_t spi_lcd_cfg = {
.spi_bus = spi_bus,
.pin_num_cs = BOARD_LCD_CS,
.pin_num_dc = BOARD_LCD_DC,
.clk_freq = 40 * 1000000,
.swap_data = 0,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_SPI, &spi_lcd_cfg, &iface_drv);
esp_err_t ret = scr_find_driver(SCREEN_CONTROLLER_ST7789, &g_lcd);
if (ESP_OK != ret)
{
return ret;
ESP_LOGE(TAG, "screen find failed");
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = BOARD_LCD_RST,
.pin_num_bckl = BOARD_LCD_BL,
.rst_active_level = 0,
.bckl_active_level = 0,
.offset_hor = 0,
.offset_ver = 0,
.width = 240,
.height = 240,
.rotate = 0,
};
ret = g_lcd.init(&lcd_cfg);
if (ESP_OK != ret)
{
return ESP_FAIL;
ESP_LOGE(TAG, "screen initialize failed");
}
g_lcd.get_info(&g_lcd_info);
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", g_lcd_info.name, g_lcd_info.width, g_lcd_info.height);
app_lcd_set_color(0x000000);
vTaskDelay(pdMS_TO_TICKS(200));
app_lcd_draw_wallpaper();
vTaskDelay(pdMS_TO_TICKS(200));
xQueueFrameI = frame_i;
xQueueFrameO = frame_o;
gReturnFB = return_fb;
xTaskCreatePinnedToCore(task_process_handler, TAG, 4 * 1024, NULL, 5, NULL, 0);
return ESP_OK;
}
void app_lcd_draw_wallpaper()
{
scr_info_t lcd_info;
g_lcd.get_info(&lcd_info);
uint16_t *pixels = (uint16_t *)heap_caps_malloc((logo_en_240x240_lcd_width * logo_en_240x240_lcd_height) * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
if (NULL == pixels)
{
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
memcpy(pixels, logo_en_240x240_lcd, (logo_en_240x240_lcd_width * logo_en_240x240_lcd_height) * sizeof(uint16_t));
g_lcd.draw_bitmap(0, 0, logo_en_240x240_lcd_width, logo_en_240x240_lcd_height, (uint16_t *)pixels);
heap_caps_free(pixels);
}
void app_lcd_set_color(int color)
{
scr_info_t lcd_info;
g_lcd.get_info(&lcd_info);
uint16_t *buffer = (uint16_t *)malloc(lcd_info.width * sizeof(uint16_t));
if (NULL == buffer)
{
ESP_LOGE(TAG, "Memory for bitmap is not enough");
}
else
{
for (size_t i = 0; i < lcd_info.width; i++)
{
buffer[i] = color;
}
for (int y = 0; y < lcd_info.height; y++)
{
g_lcd.draw_bitmap(0, y, lcd_info.width, 1, buffer);
}
free(buffer);
}
}