LCD图片资源放入flash
This commit is contained in:
@@ -58,30 +58,28 @@ idf_component_register(
|
||||
${platform_priv_requires}
|
||||
)
|
||||
|
||||
target_add_binary_data(${COMPONENT_LIB}
|
||||
"assets/lcd/buyunqian1.rle"
|
||||
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_lcd_asset_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/assets/lcd")
|
||||
set(platform_asset_image_dir "${CMAKE_CURRENT_BINARY_DIR}/asset_image")
|
||||
set(platform_asset_stage_stamp "${CMAKE_CURRENT_BINARY_DIR}/asset_image.stamp")
|
||||
file(GLOB_RECURSE platform_audio_prompt_files CONFIGURE_DEPENDS
|
||||
"${platform_audio_prompt_src_dir}/*.opus"
|
||||
)
|
||||
set(platform_lcd_flash_assets
|
||||
buyunqian1
|
||||
jichubiaoqing0
|
||||
jichubiaoqing1
|
||||
jichubiaoqing2
|
||||
muyu0
|
||||
muyu1
|
||||
muyu2
|
||||
)
|
||||
set(platform_lcd_flash_asset_files)
|
||||
foreach(lcd_rle_asset IN LISTS platform_lcd_flash_assets)
|
||||
list(APPEND platform_lcd_flash_asset_files
|
||||
"${platform_lcd_asset_src_dir}/${lcd_rle_asset}.rle"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
set(platform_asset_stage_commands)
|
||||
foreach(audio_file IN LISTS platform_audio_prompt_files)
|
||||
@@ -93,6 +91,14 @@ foreach(audio_file IN LISTS platform_audio_prompt_files)
|
||||
"${platform_asset_image_dir}/audio_prompts/${audio_rel_path}"
|
||||
)
|
||||
endforeach()
|
||||
foreach(lcd_rle_asset IN LISTS platform_lcd_flash_assets)
|
||||
list(APPEND platform_asset_stage_commands
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${platform_asset_image_dir}/lcd"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${platform_lcd_asset_src_dir}/${lcd_rle_asset}.rle"
|
||||
"${platform_asset_image_dir}/lcd/${lcd_rle_asset}.rle"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${platform_asset_stage_stamp}"
|
||||
@@ -100,7 +106,9 @@ add_custom_command(
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${platform_asset_image_dir}"
|
||||
${platform_asset_stage_commands}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${platform_asset_stage_stamp}"
|
||||
DEPENDS ${platform_audio_prompt_files}
|
||||
DEPENDS
|
||||
${platform_audio_prompt_files}
|
||||
${platform_lcd_flash_asset_files}
|
||||
)
|
||||
|
||||
littlefs_create_partition_image(
|
||||
|
||||
@@ -15,6 +15,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
const lcd_direct_rle_run_t *runs;
|
||||
uint32_t run_count;
|
||||
const char *path;
|
||||
} lcd_direct_image_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
#include "lcd_direct.h"
|
||||
#include "lcd_direct_assets.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
@@ -85,6 +88,7 @@ static lcd_direct_request_t s_pending;
|
||||
static uint32_t s_completion_count;
|
||||
static portMUX_TYPE s_state_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
static uint16_t s_line_buffer[LCD_DIRECT_PIXELS_PER_TRANSFER];
|
||||
static lcd_direct_rle_run_t s_rle_file_chunk[128];
|
||||
|
||||
static void lcd_direct_signal_completion(void);
|
||||
|
||||
@@ -330,9 +334,9 @@ static void lcd_direct_overlay_icons(uint16_t *pixel_buffer,
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
||||
const lcd_direct_icon_draw_t *icons,
|
||||
size_t icon_count)
|
||||
static esp_err_t lcd_direct_draw_rle_memory_image(const lcd_direct_image_t *image,
|
||||
const lcd_direct_icon_draw_t *icons,
|
||||
size_t icon_count)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(image != NULL && image->runs != NULL,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
@@ -385,6 +389,112 @@ static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_draw_rle_file_image(const lcd_direct_image_t *image,
|
||||
const lcd_direct_icon_draw_t *icons,
|
||||
size_t icon_count)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(image != NULL && image->path != NULL,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"invalid file image");
|
||||
|
||||
errno = 0;
|
||||
int fd = open(image->path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ESP_LOGE(TAG, "open LCD asset failed path=%s errno=%d", image->path, errno);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
uint32_t run_index = 0;
|
||||
uint32_t chunk_index = 0;
|
||||
uint32_t chunk_count = 0;
|
||||
uint32_t run_remaining = 0;
|
||||
uint16_t run_color = 0;
|
||||
esp_err_t result = ESP_OK;
|
||||
|
||||
for (uint16_t row_start = 0; row_start < LCD_DIRECT_HEIGHT; row_start += LCD_DIRECT_ROWS_PER_TRANSFER) {
|
||||
uint16_t row_count = LCD_DIRECT_HEIGHT - row_start;
|
||||
if (row_count > LCD_DIRECT_ROWS_PER_TRANSFER) {
|
||||
row_count = LCD_DIRECT_ROWS_PER_TRANSFER;
|
||||
}
|
||||
|
||||
const uint32_t pixels_needed = (uint32_t)LCD_DIRECT_WIDTH * row_count;
|
||||
uint32_t buffered_pixels = 0;
|
||||
while (buffered_pixels < pixels_needed) {
|
||||
if (run_remaining == 0U) {
|
||||
if (run_index >= image->run_count) {
|
||||
break;
|
||||
}
|
||||
if (chunk_index >= chunk_count) {
|
||||
const size_t runs_left = image->run_count - run_index;
|
||||
const size_t runs_to_read = runs_left < (sizeof(s_rle_file_chunk) / sizeof(s_rle_file_chunk[0])) ?
|
||||
runs_left :
|
||||
(sizeof(s_rle_file_chunk) / sizeof(s_rle_file_chunk[0]));
|
||||
const size_t bytes_to_read = runs_to_read * sizeof(s_rle_file_chunk[0]);
|
||||
ssize_t bytes_read = read(fd, s_rle_file_chunk, bytes_to_read);
|
||||
if (bytes_read != (ssize_t)bytes_to_read) {
|
||||
ESP_LOGE(TAG,
|
||||
"read LCD asset failed path=%s requested=%u read=%d errno=%d",
|
||||
image->path,
|
||||
(unsigned)bytes_to_read,
|
||||
(int)bytes_read,
|
||||
errno);
|
||||
result = ESP_FAIL;
|
||||
goto out;
|
||||
}
|
||||
chunk_index = 0;
|
||||
chunk_count = runs_to_read;
|
||||
}
|
||||
|
||||
run_color = lcd_direct_swap_color(s_rle_file_chunk[chunk_index].color);
|
||||
run_remaining = s_rle_file_chunk[chunk_index].count;
|
||||
chunk_index++;
|
||||
run_index++;
|
||||
}
|
||||
|
||||
uint32_t pixels_to_copy = run_remaining;
|
||||
const uint32_t pixels_left = pixels_needed - buffered_pixels;
|
||||
if (pixels_to_copy > pixels_left) {
|
||||
pixels_to_copy = pixels_left;
|
||||
}
|
||||
for (uint32_t i = 0; i < pixels_to_copy; ++i) {
|
||||
s_line_buffer[buffered_pixels + i] = run_color;
|
||||
}
|
||||
buffered_pixels += pixels_to_copy;
|
||||
run_remaining -= pixels_to_copy;
|
||||
}
|
||||
|
||||
while (buffered_pixels < pixels_needed) {
|
||||
s_line_buffer[buffered_pixels++] = 0;
|
||||
}
|
||||
|
||||
lcd_direct_overlay_icons(s_line_buffer, row_start, row_count, icons, icon_count);
|
||||
result = lcd_direct_draw_rows(row_start, row_count);
|
||||
if (result != ESP_OK) {
|
||||
ESP_LOGE(TAG, "write image pixels failed path=%s", image->path);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_draw_rle_image(const lcd_direct_image_t *image,
|
||||
const lcd_direct_icon_draw_t *icons,
|
||||
size_t icon_count)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(image != NULL,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"invalid image");
|
||||
if (image->runs != NULL) {
|
||||
return lcd_direct_draw_rle_memory_image(image, icons, icon_count);
|
||||
}
|
||||
return lcd_direct_draw_rle_file_image(image, icons, icon_count);
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_draw_asset_sequence_once(const lcd_direct_request_t *request)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(request != NULL,
|
||||
|
||||
@@ -2,46 +2,39 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
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_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");
|
||||
#define LCD_ASSET_BASE_PATH "/littlefs/lcd/"
|
||||
|
||||
static const lcd_direct_image_t s_default_image = {
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_buyunqian1_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "buyunqian1.rle",
|
||||
.run_count = 72552U,
|
||||
};
|
||||
|
||||
static const lcd_direct_image_t s_basic_face_frames[] = {
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing0_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "jichubiaoqing0.rle",
|
||||
.run_count = 5893U,
|
||||
},
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing1_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "jichubiaoqing1.rle",
|
||||
.run_count = 4581U,
|
||||
},
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_jichubiaoqing2_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "jichubiaoqing2.rle",
|
||||
.run_count = 3651U,
|
||||
},
|
||||
};
|
||||
|
||||
static const lcd_direct_image_t s_muyu_frames[] = {
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_muyu0_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "muyu0.rle",
|
||||
.run_count = 63459U,
|
||||
},
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_muyu1_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "muyu1.rle",
|
||||
.run_count = 63665U,
|
||||
},
|
||||
{
|
||||
.runs = (const lcd_direct_rle_run_t *)_binary_muyu2_rle_start,
|
||||
.path = LCD_ASSET_BASE_PATH "muyu2.rle",
|
||||
.run_count = 63894U,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user