修复了屏幕颜色异常问题
This commit is contained in:
@@ -113,9 +113,9 @@ static const control_plane_key_config_t s_key_configs[] = {
|
|||||||
.long_press_ms = CONFIG_TQ_KEY_LONG_PRESS_MS,
|
.long_press_ms = CONFIG_TQ_KEY_LONG_PRESS_MS,
|
||||||
.double_click_ms = CONFIG_TQ_KEY_DOUBLE_CLICK_MS,
|
.double_click_ms = CONFIG_TQ_KEY_DOUBLE_CLICK_MS,
|
||||||
.emit_press_release = true,
|
.emit_press_release = true,
|
||||||
.enable_short_press = false,
|
.enable_short_press = true,
|
||||||
.enable_long_press = false,
|
.enable_long_press = false,
|
||||||
.enable_double_click = false,
|
.enable_double_click = true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.key_id = CONTROL_PLANE_KEY_ID_SW2,
|
.key_id = CONTROL_PLANE_KEY_ID_SW2,
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONTROL_PLANE_PTT_HOLD_STEP_MS 80
|
#define CONTROL_PLANE_PTT_HOLD_STEP_MS 80
|
||||||
|
#define CONTROL_PLANE_PTT_HOLD_START_DELAY_MS 320
|
||||||
#define CONTROL_PLANE_PTT_HOLD_TASK_STACK 4096
|
#define CONTROL_PLANE_PTT_HOLD_TASK_STACK 4096
|
||||||
#define CONTROL_PLANE_PTT_HOLD_TASK_PRIORITY 4
|
#define CONTROL_PLANE_PTT_HOLD_TASK_PRIORITY 4
|
||||||
|
|
||||||
@@ -117,6 +118,14 @@ static void control_plane_ptt_hold_task(void *arg)
|
|||||||
(void)arg;
|
(void)arg;
|
||||||
ESP_LOGI(TAG, "PTT hold task started");
|
ESP_LOGI(TAG, "PTT hold task started");
|
||||||
bool start_requested = false;
|
bool start_requested = false;
|
||||||
|
uint32_t waited_ms = 0;
|
||||||
|
|
||||||
|
while (s_ptt_hold_active &&
|
||||||
|
!s_stop_requested &&
|
||||||
|
waited_ms < CONTROL_PLANE_PTT_HOLD_START_DELAY_MS) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(CONTROL_PLANE_PTT_HOLD_STEP_MS));
|
||||||
|
waited_ms += CONTROL_PLANE_PTT_HOLD_STEP_MS;
|
||||||
|
}
|
||||||
|
|
||||||
while (s_ptt_hold_active && !s_stop_requested) {
|
while (s_ptt_hold_active && !s_stop_requested) {
|
||||||
if (!control_plane_is_sta_connected()) {
|
if (!control_plane_is_sta_connected()) {
|
||||||
@@ -223,6 +232,18 @@ static void control_plane_dispatch_key_event(const control_plane_key_event_t *ev
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CONTROL_PLANE_KEY_EVENT_DOUBLE_CLICK: {
|
||||||
|
const domain_expression_request_t request = {
|
||||||
|
.id = DOMAIN_EXPRESSION_MUYU,
|
||||||
|
.trigger = DOMAIN_EXPRESSION_TRIGGER_PTT_DOUBLE_CLICK,
|
||||||
|
};
|
||||||
|
esp_err_t expr_err = domain_runtime_request_expression(&request);
|
||||||
|
if (expr_err != ESP_OK && expr_err != ESP_ERR_INVALID_STATE) {
|
||||||
|
ESP_LOGW(TAG, "PTT double-click expression failed: %s", esp_err_to_name(expr_err));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ typedef enum {
|
|||||||
DOMAIN_EXPRESSION_WIFI_DISCONNECTED,
|
DOMAIN_EXPRESSION_WIFI_DISCONNECTED,
|
||||||
DOMAIN_EXPRESSION_WEALTH_SPIN,
|
DOMAIN_EXPRESSION_WEALTH_SPIN,
|
||||||
DOMAIN_EXPRESSION_WEALTH_DIRECTION,
|
DOMAIN_EXPRESSION_WEALTH_DIRECTION,
|
||||||
|
DOMAIN_EXPRESSION_MUYU,
|
||||||
} domain_expression_id_t;
|
} domain_expression_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -98,6 +99,7 @@ typedef enum {
|
|||||||
DOMAIN_EXPRESSION_TRIGGER_WIFI_RECONNECTED,
|
DOMAIN_EXPRESSION_TRIGGER_WIFI_RECONNECTED,
|
||||||
DOMAIN_EXPRESSION_TRIGGER_MODEL_DIRECTION,
|
DOMAIN_EXPRESSION_TRIGGER_MODEL_DIRECTION,
|
||||||
DOMAIN_EXPRESSION_TRIGGER_DAILY_FORTUNE,
|
DOMAIN_EXPRESSION_TRIGGER_DAILY_FORTUNE,
|
||||||
|
DOMAIN_EXPRESSION_TRIGGER_PTT_DOUBLE_CLICK,
|
||||||
} domain_expression_trigger_t;
|
} domain_expression_trigger_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ static const char *TAG = "domain_rt_adapters";
|
|||||||
|
|
||||||
static const uint8_t s_server_error_frame_order[] = {0, 1, 2, 1, 0};
|
static const uint8_t s_server_error_frame_order[] = {0, 1, 2, 1, 0};
|
||||||
static const uint8_t s_wifi_disconnected_frame_order[] = {0, 1, 2, 3, 2, 1, 0};
|
static const uint8_t s_wifi_disconnected_frame_order[] = {0, 1, 2, 3, 2, 1, 0};
|
||||||
|
static const uint8_t s_basic_face_frame_order[] = {0, 1, 2};
|
||||||
|
static const uint8_t s_muyu_frame_order[] = {0, 1, 2, 1};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wealth-direction reveal asset directories, indexed parallel to the direction
|
* Wealth-direction reveal asset directories, indexed parallel to the direction
|
||||||
@@ -119,10 +121,15 @@ static const domain_expression_catalog_entry_t s_expression_catalog[] = {
|
|||||||
{
|
{
|
||||||
.id = DOMAIN_EXPRESSION_IDLE,
|
.id = DOMAIN_EXPRESSION_IDLE,
|
||||||
.platform_request = {
|
.platform_request = {
|
||||||
.kind = PLATFORM_LCD_PRESENTATION_IDLE,
|
.kind = PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
|
||||||
.priority = 120,
|
.priority = 120,
|
||||||
.interrupt_current = true,
|
.interrupt_current = true,
|
||||||
.return_to_idle = false,
|
.return_to_idle = false,
|
||||||
|
.asset_dir = "jichubiaoqing",
|
||||||
|
.frame_order = s_basic_face_frame_order,
|
||||||
|
.frame_order_count = sizeof(s_basic_face_frame_order) / sizeof(s_basic_face_frame_order[0]),
|
||||||
|
.repeat_count = 0,
|
||||||
|
.frame_ms = 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -175,6 +182,21 @@ static const domain_expression_catalog_entry_t s_expression_catalog[] = {
|
|||||||
.frame_ms = DOMAIN_WEALTH_DIRECTION_FRAME_MS,
|
.frame_ms = DOMAIN_WEALTH_DIRECTION_FRAME_MS,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = DOMAIN_EXPRESSION_MUYU,
|
||||||
|
.platform_request = {
|
||||||
|
.kind = PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
|
||||||
|
.priority = 125,
|
||||||
|
.interrupt_current = true,
|
||||||
|
.return_to_idle = true,
|
||||||
|
.asset_dir = "muyu",
|
||||||
|
.frame_order = s_muyu_frame_order,
|
||||||
|
.frame_order_count = sizeof(s_muyu_frame_order) / sizeof(s_muyu_frame_order[0]),
|
||||||
|
.repeat_count = 25,
|
||||||
|
.frame_ms = 50,
|
||||||
|
.duration_ms = 10000,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void snapshot_domain_wifi_behavior_hooks(domain_wifi_behavior_hooks_t *out_hooks)
|
static void snapshot_domain_wifi_behavior_hooks(domain_wifi_behavior_hooks_t *out_hooks)
|
||||||
|
|||||||
@@ -63,6 +63,19 @@ target_add_binary_data(${COMPONENT_LIB}
|
|||||||
BINARY
|
BINARY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
foreach(lcd_rle_asset
|
||||||
|
jichubiaoqing0
|
||||||
|
jichubiaoqing1
|
||||||
|
jichubiaoqing2
|
||||||
|
muyu0
|
||||||
|
muyu1
|
||||||
|
muyu2)
|
||||||
|
target_add_binary_data(${COMPONENT_LIB}
|
||||||
|
"assets/lcd/${lcd_rle_asset}.rle"
|
||||||
|
BINARY
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
set(platform_audio_prompt_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/assets/audio_prompts")
|
set(platform_audio_prompt_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/assets/audio_prompts")
|
||||||
set(platform_asset_image_dir "${CMAKE_CURRENT_BINARY_DIR}/asset_image")
|
set(platform_asset_image_dir "${CMAKE_CURRENT_BINARY_DIR}/asset_image")
|
||||||
set(platform_asset_stage_stamp "${CMAKE_CURRENT_BINARY_DIR}/asset_image.stamp")
|
set(platform_asset_stage_stamp "${CMAKE_CURRENT_BINARY_DIR}/asset_image.stamp")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 248 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 249 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 250 KiB |
@@ -361,6 +361,7 @@ typedef struct {
|
|||||||
size_t frame_order_count;
|
size_t frame_order_count;
|
||||||
uint16_t repeat_count;
|
uint16_t repeat_count;
|
||||||
uint32_t frame_ms;
|
uint32_t frame_ms;
|
||||||
|
uint32_t duration_ms;
|
||||||
} platform_lcd_presentation_request_t;
|
} platform_lcd_presentation_request_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ typedef struct {
|
|||||||
#define LCD_DIRECT_DEFAULT_ICON_COUNT 5U
|
#define LCD_DIRECT_DEFAULT_ICON_COUNT 5U
|
||||||
|
|
||||||
const lcd_direct_image_t *lcd_direct_default_image(void);
|
const lcd_direct_image_t *lcd_direct_default_image(void);
|
||||||
|
const lcd_direct_image_t *lcd_direct_asset_frame(const char *asset_dir, uint8_t frame_index);
|
||||||
const lcd_direct_icon_t *lcd_direct_icon(uint16_t icon_id);
|
const lcd_direct_icon_t *lcd_direct_icon(uint16_t icon_id);
|
||||||
const lcd_direct_icon_draw_t *lcd_direct_default_icon_sequence(size_t *out_count);
|
const lcd_direct_icon_draw_t *lcd_direct_default_icon_sequence(size_t *out_count);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#define LCD_CMD_MADCTL 0x36
|
#define LCD_CMD_MADCTL 0x36
|
||||||
#define LCD_CMD_RAMCTRL 0xB0
|
#define LCD_CMD_RAMCTRL 0xB0
|
||||||
#define LCD_RAMCTRL_LE_BIT (1U << 3)
|
|
||||||
|
|
||||||
static const char *TAG = "lcd_direct";
|
static const char *TAG = "lcd_direct";
|
||||||
|
|
||||||
@@ -43,8 +42,11 @@ typedef struct {
|
|||||||
bool interrupt_current;
|
bool interrupt_current;
|
||||||
bool return_to_idle;
|
bool return_to_idle;
|
||||||
char asset_dir[PLATFORM_LCD_PRESENTATION_ASSET_DIR_MAX];
|
char asset_dir[PLATFORM_LCD_PRESENTATION_ASSET_DIR_MAX];
|
||||||
|
uint8_t frame_order[PLATFORM_LCD_PRESENTATION_FRAME_ORDER_MAX];
|
||||||
|
size_t frame_order_count;
|
||||||
uint16_t repeat_count;
|
uint16_t repeat_count;
|
||||||
uint32_t frame_ms;
|
uint32_t frame_ms;
|
||||||
|
uint32_t duration_ms;
|
||||||
} lcd_direct_request_t;
|
} lcd_direct_request_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -84,6 +86,8 @@ static uint32_t s_completion_count;
|
|||||||
static portMUX_TYPE s_state_lock = portMUX_INITIALIZER_UNLOCKED;
|
static portMUX_TYPE s_state_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
static uint16_t s_line_buffer[LCD_DIRECT_PIXELS_PER_TRANSFER];
|
static uint16_t s_line_buffer[LCD_DIRECT_PIXELS_PER_TRANSFER];
|
||||||
|
|
||||||
|
static void lcd_direct_signal_completion(void);
|
||||||
|
|
||||||
static uint16_t lcd_direct_swap_color(uint16_t color)
|
static uint16_t lcd_direct_swap_color(uint16_t color)
|
||||||
{
|
{
|
||||||
#if CONFIG_TQ_SCREEN_SWAP_COLOR_BYTES
|
#if CONFIG_TQ_SCREEN_SWAP_COLOR_BYTES
|
||||||
@@ -166,11 +170,7 @@ static esp_err_t lcd_direct_panel_init(void)
|
|||||||
#else
|
#else
|
||||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_TQ_SCREEN_SWAP_COLOR_BYTES
|
|
||||||
.data_endian = LCD_RGB_DATA_ENDIAN_LITTLE,
|
|
||||||
#else
|
|
||||||
.data_endian = LCD_RGB_DATA_ENDIAN_BIG,
|
.data_endian = LCD_RGB_DATA_ENDIAN_BIG,
|
||||||
#endif
|
|
||||||
.bits_per_pixel = 16,
|
.bits_per_pixel = 16,
|
||||||
};
|
};
|
||||||
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_st7789(s_panel_io, &panel_config, &s_panel),
|
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_st7789(s_panel_io, &panel_config, &s_panel),
|
||||||
@@ -207,9 +207,6 @@ static esp_err_t lcd_direct_panel_init(void)
|
|||||||
madctl |= 0x08;
|
madctl |= 0x08;
|
||||||
#endif
|
#endif
|
||||||
uint8_t ramctrl[] = {0x00, 0xF0};
|
uint8_t ramctrl[] = {0x00, 0xF0};
|
||||||
#if CONFIG_TQ_SCREEN_SWAP_COLOR_BYTES
|
|
||||||
ramctrl[1] |= LCD_RAMCTRL_LE_BIT;
|
|
||||||
#endif
|
|
||||||
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(s_panel_io, LCD_CMD_MADCTL, &madctl, 1),
|
ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(s_panel_io, LCD_CMD_MADCTL, &madctl, 1),
|
||||||
TAG,
|
TAG,
|
||||||
"panel MADCTL failed");
|
"panel MADCTL failed");
|
||||||
@@ -333,25 +330,6 @@ static void lcd_direct_overlay_icons(uint16_t *pixel_buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_direct_overlay_boot_marker(uint16_t *pixel_buffer, uint16_t row_start, uint16_t row_count)
|
|
||||||
{
|
|
||||||
const uint16_t marker_color = lcd_direct_swap_color(0xFFFF);
|
|
||||||
const uint16_t row_end = row_start + row_count;
|
|
||||||
|
|
||||||
for (uint16_t y = row_start; y < row_end; ++y) {
|
|
||||||
uint16_t local_y = y - row_start;
|
|
||||||
for (uint16_t x = 0; x < LCD_DIRECT_WIDTH; ++x) {
|
|
||||||
const bool border = y < 2U || y >= (LCD_DIRECT_HEIGHT - 2U) ||
|
|
||||||
x < 2U || x >= (LCD_DIRECT_WIDTH - 2U);
|
|
||||||
const bool center_line = (x >= 158U && x <= 161U && y >= 100U && y <= 140U) ||
|
|
||||||
(y >= 118U && y <= 121U && x >= 140U && x <= 180U);
|
|
||||||
if (border || center_line) {
|
|
||||||
pixel_buffer[(uint32_t)local_y * LCD_DIRECT_WIDTH + x] = marker_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
||||||
const lcd_direct_icon_draw_t *icons,
|
const lcd_direct_icon_draw_t *icons,
|
||||||
size_t icon_count)
|
size_t icon_count)
|
||||||
@@ -399,7 +377,6 @@ static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lcd_direct_overlay_icons(s_line_buffer, row_start, row_count, icons, icon_count);
|
lcd_direct_overlay_icons(s_line_buffer, row_start, row_count, icons, icon_count);
|
||||||
lcd_direct_overlay_boot_marker(s_line_buffer, row_start, row_count);
|
|
||||||
ESP_RETURN_ON_ERROR(lcd_direct_draw_rows(row_start, row_count),
|
ESP_RETURN_ON_ERROR(lcd_direct_draw_rows(row_start, row_count),
|
||||||
TAG,
|
TAG,
|
||||||
"write image pixels failed");
|
"write image pixels failed");
|
||||||
@@ -408,12 +385,169 @@ static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t lcd_direct_draw_default_image(void)
|
static esp_err_t lcd_direct_draw_asset_sequence_once(const lcd_direct_request_t *request)
|
||||||
{
|
{
|
||||||
size_t icon_count = 0;
|
ESP_RETURN_ON_FALSE(request != NULL,
|
||||||
const lcd_direct_icon_draw_t *icons = lcd_direct_default_icon_sequence(&icon_count);
|
ESP_ERR_INVALID_ARG,
|
||||||
ESP_LOGI(TAG, "Drawing default LCD image icons=%u", (unsigned)icon_count);
|
TAG,
|
||||||
return lcd_direct_draw_rle_image(lcd_direct_default_image(), icons, icon_count);
|
"invalid asset request");
|
||||||
|
|
||||||
|
const size_t frame_count = request->frame_order_count > 0U ? request->frame_order_count : 1U;
|
||||||
|
for (size_t i = 0; i < frame_count; ++i) {
|
||||||
|
bool stop = false;
|
||||||
|
portENTER_CRITICAL(&s_state_lock);
|
||||||
|
stop = s_stop_requested || s_pending_valid;
|
||||||
|
portEXIT_CRITICAL(&s_state_lock);
|
||||||
|
if (stop) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t frame_index = request->frame_order_count > 0U ? request->frame_order[i] : (uint8_t)i;
|
||||||
|
const lcd_direct_image_t *frame = lcd_direct_asset_frame(request->asset_dir, frame_index);
|
||||||
|
ESP_RETURN_ON_FALSE(frame != NULL,
|
||||||
|
ESP_ERR_NOT_FOUND,
|
||||||
|
TAG,
|
||||||
|
"LCD asset frame not found asset=%s frame=%u",
|
||||||
|
request->asset_dir,
|
||||||
|
(unsigned)frame_index);
|
||||||
|
|
||||||
|
ESP_RETURN_ON_ERROR(lcd_direct_draw_rle_image(frame, NULL, 0),
|
||||||
|
TAG,
|
||||||
|
"draw asset frame failed");
|
||||||
|
|
||||||
|
const uint32_t frame_ms = request->frame_ms > 0U ? request->frame_ms : 100U;
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(frame_ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t lcd_direct_draw_asset_sequence_for_duration(const lcd_direct_request_t *request,
|
||||||
|
TickType_t start_tick,
|
||||||
|
TickType_t duration_ticks)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(request != NULL,
|
||||||
|
ESP_ERR_INVALID_ARG,
|
||||||
|
TAG,
|
||||||
|
"invalid timed asset request");
|
||||||
|
|
||||||
|
const size_t frame_count = request->frame_order_count > 0U ? request->frame_order_count : 1U;
|
||||||
|
while ((xTaskGetTickCount() - start_tick) < duration_ticks) {
|
||||||
|
for (size_t i = 0; i < frame_count; ++i) {
|
||||||
|
bool stop = false;
|
||||||
|
portENTER_CRITICAL(&s_state_lock);
|
||||||
|
stop = s_stop_requested || s_pending_valid;
|
||||||
|
portEXIT_CRITICAL(&s_state_lock);
|
||||||
|
if (stop) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t frame_index = request->frame_order_count > 0U ? request->frame_order[i] : (uint8_t)i;
|
||||||
|
const lcd_direct_image_t *frame = lcd_direct_asset_frame(request->asset_dir, frame_index);
|
||||||
|
ESP_RETURN_ON_FALSE(frame != NULL,
|
||||||
|
ESP_ERR_NOT_FOUND,
|
||||||
|
TAG,
|
||||||
|
"LCD asset frame not found asset=%s frame=%u",
|
||||||
|
request->asset_dir,
|
||||||
|
(unsigned)frame_index);
|
||||||
|
|
||||||
|
ESP_RETURN_ON_ERROR(lcd_direct_draw_rle_image(frame, NULL, 0),
|
||||||
|
TAG,
|
||||||
|
"draw timed asset frame failed");
|
||||||
|
|
||||||
|
const TickType_t now = xTaskGetTickCount();
|
||||||
|
const TickType_t elapsed_ticks = now - start_tick;
|
||||||
|
if (elapsed_ticks >= duration_ticks) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t frame_ms = request->frame_ms > 0U ? request->frame_ms : 100U;
|
||||||
|
const TickType_t frame_ticks = pdMS_TO_TICKS(frame_ms);
|
||||||
|
const TickType_t remaining_ticks = duration_ticks - elapsed_ticks;
|
||||||
|
vTaskDelay(frame_ticks < remaining_ticks ? frame_ticks : remaining_ticks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t lcd_direct_play_asset_sequence(const lcd_direct_request_t *request)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(request != NULL,
|
||||||
|
ESP_ERR_INVALID_ARG,
|
||||||
|
TAG,
|
||||||
|
"invalid asset sequence");
|
||||||
|
|
||||||
|
if (request->asset_dir[0] == '\0' ||
|
||||||
|
lcd_direct_asset_frame(request->asset_dir,
|
||||||
|
request->frame_order_count > 0U ? request->frame_order[0] : 0U) == NULL) {
|
||||||
|
ESP_LOGW(TAG, "LCD asset sequence unavailable, fallback to basic face asset=%s", request->asset_dir);
|
||||||
|
const lcd_direct_request_t fallback = {
|
||||||
|
.kind = PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
|
||||||
|
.asset_dir = "jichubiaoqing",
|
||||||
|
.frame_order = {0, 1, 2},
|
||||||
|
.frame_order_count = 3,
|
||||||
|
.repeat_count = 1,
|
||||||
|
.frame_ms = 100,
|
||||||
|
};
|
||||||
|
esp_err_t fallback_err = lcd_direct_draw_asset_sequence_once(&fallback);
|
||||||
|
if (fallback_err == ESP_OK && request->repeat_count > 0U) {
|
||||||
|
lcd_direct_signal_completion();
|
||||||
|
}
|
||||||
|
return fallback_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request->duration_ms > 0U) {
|
||||||
|
const TickType_t start_tick = xTaskGetTickCount();
|
||||||
|
const TickType_t duration_ticks = pdMS_TO_TICKS(request->duration_ms);
|
||||||
|
esp_err_t err = lcd_direct_draw_asset_sequence_for_duration(request, start_tick, duration_ticks);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
lcd_direct_signal_completion();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t remaining = request->repeat_count;
|
||||||
|
do {
|
||||||
|
esp_err_t err = lcd_direct_draw_asset_sequence_once(request);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (request->repeat_count > 0U) {
|
||||||
|
remaining--;
|
||||||
|
}
|
||||||
|
} while (request->repeat_count == 0U || remaining > 0U);
|
||||||
|
|
||||||
|
lcd_direct_signal_completion();
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t lcd_direct_play_basic_face_until_pending(void)
|
||||||
|
{
|
||||||
|
const lcd_direct_request_t request = {
|
||||||
|
.kind = PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE,
|
||||||
|
.asset_dir = "jichubiaoqing",
|
||||||
|
.frame_order = {0, 1, 2},
|
||||||
|
.frame_order_count = 3,
|
||||||
|
.repeat_count = 0,
|
||||||
|
.frame_ms = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
bool stop = false;
|
||||||
|
portENTER_CRITICAL(&s_state_lock);
|
||||||
|
stop = s_stop_requested || s_pending_valid;
|
||||||
|
portEXIT_CRITICAL(&s_state_lock);
|
||||||
|
if (stop) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t err = lcd_direct_draw_asset_sequence_once(&request);
|
||||||
|
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_direct_signal_completion(void)
|
static void lcd_direct_signal_completion(void)
|
||||||
@@ -486,8 +620,6 @@ void lcd_direct_start_render_loop(void)
|
|||||||
portEXIT_CRITICAL(&s_state_lock);
|
portEXIT_CRITICAL(&s_state_lock);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Direct LCD render loop started");
|
ESP_LOGI(TAG, "Direct LCD render loop started");
|
||||||
esp_err_t default_draw_err = lcd_direct_draw_default_image();
|
|
||||||
ESP_LOGI(TAG, "Direct LCD default image draw result=%s", esp_err_to_name(default_draw_err));
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
@@ -503,13 +635,33 @@ void lcd_direct_start_render_loop(void)
|
|||||||
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||||
esp_err_t draw_err = ESP_OK;
|
esp_err_t draw_err = ESP_OK;
|
||||||
if (request.kind == PLATFORM_LCD_PRESENTATION_IDLE) {
|
if (request.kind == PLATFORM_LCD_PRESENTATION_IDLE) {
|
||||||
draw_err = lcd_direct_draw_default_image();
|
draw_err = lcd_direct_play_basic_face_until_pending();
|
||||||
|
} else if (request.kind == PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE) {
|
||||||
|
draw_err = lcd_direct_play_asset_sequence(&request);
|
||||||
|
if (draw_err == ESP_OK && request.return_to_idle) {
|
||||||
|
lcd_direct_request_t idle = {
|
||||||
|
.kind = PLATFORM_LCD_PRESENTATION_IDLE,
|
||||||
|
};
|
||||||
|
portENTER_CRITICAL(&s_state_lock);
|
||||||
|
s_pending = idle;
|
||||||
|
s_pending_valid = true;
|
||||||
|
portEXIT_CRITICAL(&s_state_lock);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
draw_err = lcd_direct_draw_test_pattern(&request);
|
draw_err = lcd_direct_draw_test_pattern(&request);
|
||||||
}
|
}
|
||||||
xSemaphoreGive(s_lock);
|
xSemaphoreGive(s_lock);
|
||||||
if (draw_err == ESP_OK && request.repeat_count > 0U) {
|
if (draw_err != ESP_OK && draw_err != ESP_ERR_INVALID_STATE) {
|
||||||
lcd_direct_signal_completion();
|
ESP_LOGW(TAG, "LCD presentation draw failed: %s", esp_err_to_name(draw_err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||||
|
esp_err_t idle_err = lcd_direct_play_basic_face_until_pending();
|
||||||
|
xSemaphoreGive(s_lock);
|
||||||
|
if (idle_err != ESP_OK && idle_err != ESP_ERR_INVALID_STATE) {
|
||||||
|
ESP_LOGW(TAG, "LCD idle draw failed: %s", esp_err_to_name(idle_err));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,10 +739,18 @@ esp_err_t lcd_direct_request_presentation(const platform_lcd_presentation_reques
|
|||||||
.return_to_idle = request->return_to_idle,
|
.return_to_idle = request->return_to_idle,
|
||||||
.repeat_count = request->repeat_count,
|
.repeat_count = request->repeat_count,
|
||||||
.frame_ms = request->frame_ms,
|
.frame_ms = request->frame_ms,
|
||||||
|
.duration_ms = request->duration_ms,
|
||||||
};
|
};
|
||||||
if (request->asset_dir != NULL) {
|
if (request->asset_dir != NULL) {
|
||||||
strlcpy(copied.asset_dir, request->asset_dir, sizeof(copied.asset_dir));
|
strlcpy(copied.asset_dir, request->asset_dir, sizeof(copied.asset_dir));
|
||||||
}
|
}
|
||||||
|
if (request->frame_order != NULL && request->frame_order_count > 0U) {
|
||||||
|
copied.frame_order_count = request->frame_order_count;
|
||||||
|
if (copied.frame_order_count > PLATFORM_LCD_PRESENTATION_FRAME_ORDER_MAX) {
|
||||||
|
copied.frame_order_count = PLATFORM_LCD_PRESENTATION_FRAME_ORDER_MAX;
|
||||||
|
}
|
||||||
|
memcpy(copied.frame_order, request->frame_order, copied.frame_order_count);
|
||||||
|
}
|
||||||
|
|
||||||
TaskHandle_t task = NULL;
|
TaskHandle_t task = NULL;
|
||||||
portENTER_CRITICAL(&s_state_lock);
|
portENTER_CRITICAL(&s_state_lock);
|
||||||
|
|||||||
@@ -1,19 +1,79 @@
|
|||||||
/* Generated from D:\Code\chaowan\lcd(1)\lcd\lcd\main\eye_image.c buyunqian1. */
|
|
||||||
#include "lcd_direct_assets.h"
|
#include "lcd_direct_assets.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern const uint8_t _binary_buyunqian1_rle_start[] asm("_binary_buyunqian1_rle_start");
|
extern const uint8_t _binary_buyunqian1_rle_start[] asm("_binary_buyunqian1_rle_start");
|
||||||
extern const uint8_t _binary_buyunqian1_rle_end[] asm("_binary_buyunqian1_rle_end");
|
extern const uint8_t _binary_buyunqian1_rle_end[] asm("_binary_buyunqian1_rle_end");
|
||||||
|
extern const uint8_t _binary_jichubiaoqing0_rle_start[] asm("_binary_jichubiaoqing0_rle_start");
|
||||||
|
extern const uint8_t _binary_jichubiaoqing1_rle_start[] asm("_binary_jichubiaoqing1_rle_start");
|
||||||
|
extern const uint8_t _binary_jichubiaoqing2_rle_start[] asm("_binary_jichubiaoqing2_rle_start");
|
||||||
|
extern const uint8_t _binary_muyu0_rle_start[] asm("_binary_muyu0_rle_start");
|
||||||
|
extern const uint8_t _binary_muyu1_rle_start[] asm("_binary_muyu1_rle_start");
|
||||||
|
extern const uint8_t _binary_muyu2_rle_start[] asm("_binary_muyu2_rle_start");
|
||||||
|
|
||||||
static const lcd_direct_image_t s_default_image = {
|
static const lcd_direct_image_t s_default_image = {
|
||||||
.runs = (const lcd_direct_rle_run_t *)_binary_buyunqian1_rle_start,
|
.runs = (const lcd_direct_rle_run_t *)_binary_buyunqian1_rle_start,
|
||||||
.run_count = 72552U,
|
.run_count = 72552U,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const lcd_direct_image_t s_basic_face_frames[] = {
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing0_rle_start,
|
||||||
|
.run_count = 5893U,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing1_rle_start,
|
||||||
|
.run_count = 4581U,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing2_rle_start,
|
||||||
|
.run_count = 3651U,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const lcd_direct_image_t s_muyu_frames[] = {
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_muyu0_rle_start,
|
||||||
|
.run_count = 63459U,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_muyu1_rle_start,
|
||||||
|
.run_count = 63665U,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.runs = (const lcd_direct_rle_run_t *)_binary_muyu2_rle_start,
|
||||||
|
.run_count = 63894U,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const lcd_direct_image_t *lcd_direct_default_image(void)
|
const lcd_direct_image_t *lcd_direct_default_image(void)
|
||||||
{
|
{
|
||||||
return &s_default_image;
|
return &s_default_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lcd_direct_image_t *lcd_direct_asset_frame(const char *asset_dir, uint8_t frame_index)
|
||||||
|
{
|
||||||
|
if (asset_dir == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(asset_dir, "jichubiaoqing") == 0) {
|
||||||
|
if (frame_index < sizeof(s_basic_face_frames) / sizeof(s_basic_face_frames[0])) {
|
||||||
|
return &s_basic_face_frames[frame_index];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(asset_dir, "muyu") == 0) {
|
||||||
|
if (frame_index < sizeof(s_muyu_frames) / sizeof(s_muyu_frames[0])) {
|
||||||
|
return &s_muyu_frames[frame_index];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const lcd_direct_icon_t *lcd_direct_icon(uint16_t icon_id)
|
const lcd_direct_icon_t *lcd_direct_icon(uint16_t icon_id)
|
||||||
{
|
{
|
||||||
(void)icon_id;
|
(void)icon_id;
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ menu "Example Configuration"
|
|||||||
|
|
||||||
config TQ_KEY_DOUBLE_CLICK_MS
|
config TQ_KEY_DOUBLE_CLICK_MS
|
||||||
int "Key double-click threshold (ms)"
|
int "Key double-click threshold (ms)"
|
||||||
default 300
|
default 450
|
||||||
range 100 1000
|
range 100 1000
|
||||||
depends on TQ_KEY_INPUT_ENABLE
|
depends on TQ_KEY_INPUT_ENABLE
|
||||||
help
|
help
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ CONFIG_TQ_KEY_IRQ_QUEUE_LEN=16
|
|||||||
CONFIG_TQ_KEY_INPUT_POLL_MS=20
|
CONFIG_TQ_KEY_INPUT_POLL_MS=20
|
||||||
CONFIG_TQ_KEY_DEBOUNCE_INTERVAL_MS=20
|
CONFIG_TQ_KEY_DEBOUNCE_INTERVAL_MS=20
|
||||||
CONFIG_TQ_KEY_LONG_PRESS_MS=800
|
CONFIG_TQ_KEY_LONG_PRESS_MS=800
|
||||||
CONFIG_TQ_KEY_DOUBLE_CLICK_MS=300
|
CONFIG_TQ_KEY_DOUBLE_CLICK_MS=450
|
||||||
|
|
||||||
# Internal DMA-capable SRAM budget. TLS/auth/fortune flows, hardware AES DMA
|
# Internal DMA-capable SRAM budget. TLS/auth/fortune flows, hardware AES DMA
|
||||||
# bounce buffers, LCD DMA, and worker task stacks all need internal-only memory.
|
# bounce buffers, LCD DMA, and worker task stacks all need internal-only memory.
|
||||||
|
|||||||
Reference in New Issue
Block a user