generated from Embedded_Projects/Fire_RT1021_EVK_Template
212 lines
5.4 KiB
C
212 lines
5.4 KiB
C
|
|
/* FreeRTOS */
|
|
#include "FreeRTOS.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
/* LVGL */
|
|
#include "lv_demos.h"
|
|
#include "lvgl.h"
|
|
|
|
/* LCD */
|
|
#include "epd-spi/panel/lcd_tk0096f611.h"
|
|
|
|
/* Sensors */
|
|
#include "imsensors/touch/tp_it7259.h"
|
|
|
|
/* App */
|
|
#include "app_impl_lcd.h"
|
|
#include "app_impl_sensors.h"
|
|
#include "app_lvgl.h"
|
|
|
|
#define APP_LVGL_LCD_DIR (LCD_ST7789_DIR_0)
|
|
#define APP_LVGL_LCD_BUF_SIZE (160 * 20)
|
|
|
|
static lcd_st7789_t s_lcd = {
|
|
.cb =
|
|
{
|
|
.write_command_cb = app_lcd_impl_write_command,
|
|
.write_data_cb = app_lcd_impl_write_data,
|
|
.delay_cb = app_lcd_impl_delay,
|
|
},
|
|
};
|
|
|
|
static ims_it7259_t s_tp = {
|
|
.cb =
|
|
{
|
|
.i2c_xfer = app_impl_sensors_i2c_xfer,
|
|
.delay = app_impl_sensors_delay,
|
|
},
|
|
.pdev = (void *)0x46U, /* Address */
|
|
};
|
|
|
|
static SemaphoreHandle_t s_lvgl_semphr = NULL;
|
|
|
|
static uint16_t s_lcd_buffer[APP_LVGL_LCD_BUF_SIZE];
|
|
|
|
static uint32_t app_lvgl_get_tick_cb(void);
|
|
static void app_lvgl_lcd_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map);
|
|
static void app_lvgl_tp_read_cb(lv_indev_t *indev, lv_indev_data_t *data);
|
|
static void app_lvgl_task(void *arguments);
|
|
|
|
int app_lvgl_init(void) {
|
|
s_lvgl_semphr = xSemaphoreCreateBinary();
|
|
if (s_lvgl_semphr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
xSemaphoreGive(s_lvgl_semphr);
|
|
|
|
app_lcd_impl_init(NULL);
|
|
lcd_st7789_init(&s_lcd, &lcd_tk0096_panel_config);
|
|
lcd_st7789_set_direction(&s_lcd, APP_LVGL_LCD_DIR);
|
|
lcd_st7789_set_pixel_format(&s_lcd, LCD_ST7789_RGB565);
|
|
lcd_st7789_enable_display(&s_lcd, true);
|
|
|
|
app_impl_sensors_init();
|
|
|
|
ims_it7259_init(&s_tp);
|
|
|
|
lv_init();
|
|
|
|
lv_tick_set_cb(app_lvgl_get_tick_cb);
|
|
|
|
uint16_t hor_res;
|
|
uint16_t ver_res;
|
|
|
|
if (s_lcd.direction == LCD_ST7789_DIR_0 || s_lcd.direction == LCD_ST7789_DIR_180) {
|
|
hor_res = lcd_tk0096_panel_config.size_x;
|
|
ver_res = lcd_tk0096_panel_config.size_y;
|
|
} else {
|
|
hor_res = lcd_tk0096_panel_config.size_y;
|
|
ver_res = lcd_tk0096_panel_config.size_x;
|
|
}
|
|
|
|
lv_display_t *display = lv_display_create(hor_res, ver_res);
|
|
if (display == NULL) {
|
|
goto deinit_lv_exit;
|
|
}
|
|
|
|
lv_display_set_flush_cb(display, app_lvgl_lcd_flush_cb);
|
|
lv_display_set_buffers(display, s_lcd_buffer, NULL, sizeof(s_lcd_buffer), LV_DISPLAY_RENDER_MODE_PARTIAL);
|
|
|
|
lv_indev_t *indev = lv_indev_create();
|
|
if (indev == NULL) {
|
|
goto destroy_display_exit;
|
|
}
|
|
|
|
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
|
lv_indev_set_read_cb(indev, app_lvgl_tp_read_cb);
|
|
|
|
lv_demo_widgets();
|
|
|
|
if (xTaskCreate(app_lvgl_task, "LVGL", 2048, NULL, 3, NULL) != pdPASS) {
|
|
goto destroy_indev_exit;
|
|
}
|
|
|
|
return 0;
|
|
|
|
destroy_indev_exit:
|
|
lv_indev_delete(indev);
|
|
|
|
destroy_display_exit:
|
|
lv_display_delete(display);
|
|
|
|
deinit_lv_exit:
|
|
lv_deinit();
|
|
vSemaphoreDelete(s_lvgl_semphr);
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool app_lvgl_lock(uint32_t timeout_ms) {
|
|
if (xSemaphoreTake(s_lvgl_semphr, pdMS_TO_TICKS(timeout_ms)) != pdPASS) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void app_lvgl_unlock(void) {
|
|
xSemaphoreGive(s_lvgl_semphr);
|
|
}
|
|
|
|
static uint32_t app_lvgl_get_tick_cb(void) {
|
|
return xTaskGetTickCount();
|
|
}
|
|
|
|
static void app_lvgl_lcd_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
|
|
epd_coord_t coord = {
|
|
.x_start = area->x1,
|
|
.x_end = area->x2,
|
|
.y_start = area->y1,
|
|
.y_end = area->y2,
|
|
};
|
|
|
|
lv_draw_sw_rgb565_swap(px_map, (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1));
|
|
|
|
lcd_st7789_load(&s_lcd, &coord, px_map);
|
|
|
|
lv_display_flush_ready(disp);
|
|
}
|
|
|
|
static void app_lvgl_tp_read_cb(lv_indev_t *indev, lv_indev_data_t *data) {
|
|
ims_it7259_point_t touch_points[3];
|
|
uint8_t num_points = 3;
|
|
bool track_found = false;
|
|
|
|
ims_ret_t ret = ims_it7259_read_points(&s_tp, &num_points, touch_points);
|
|
if (ret != IMS_SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < num_points; i++) {
|
|
if (touch_points[i].id != 0) {
|
|
continue;
|
|
}
|
|
|
|
if (touch_points[i].pres < IT7259_PRES_LIGHT) {
|
|
continue;
|
|
}
|
|
|
|
track_found = true;
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
|
|
switch (s_lcd.direction) {
|
|
case LCD_ST7789_DIR_0:
|
|
data->point.x = (s_tp.resolution_x - 1) - touch_points->pos_x;
|
|
data->point.y = (s_tp.resolution_y - 1) - touch_points->pos_y;
|
|
break;
|
|
case LCD_ST7789_DIR_90:
|
|
data->point.x = (s_tp.resolution_y - 1) - touch_points->pos_y;
|
|
data->point.y = touch_points->pos_x;
|
|
break;
|
|
case LCD_ST7789_DIR_180:
|
|
data->point.x = touch_points->pos_x;
|
|
data->point.y = touch_points->pos_y;
|
|
break;
|
|
|
|
case LCD_ST7789_DIR_270:
|
|
data->point.x = touch_points->pos_y;
|
|
data->point.y = (s_tp.resolution_x - 1) - touch_points->pos_x;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!track_found) {
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
|
}
|
|
}
|
|
|
|
static void app_lvgl_task(void *arguments) {
|
|
for (;;) {
|
|
if (app_lvgl_lock(portMAX_DELAY)) {
|
|
lv_task_handler();
|
|
app_lvgl_unlock();
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(5));
|
|
}
|
|
} |