Add CYD photo album with jpg/png/gif viewer and sample assets.

Ship TF-card album UI, half-res decode canvas, prebuilt firmware, and documented flash/upload workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-19 18:07:56 +08:00
commit 99618a46b0
35 changed files with 3211 additions and 0 deletions

1127
include/lv_conf.h Normal file

File diff suppressed because it is too large Load Diff

21
include/photo_list.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <stdint.h>
static constexpr int PHOTO_MAX = 64;
static constexpr int PHOTO_PATH_MAX = 96;
enum PhotoKind : uint8_t {
PHOTO_JPG = 0,
PHOTO_PNG = 1,
PHOTO_GIF = 2,
};
struct PhotoEntry {
char path[PHOTO_PATH_MAX];
PhotoKind kind;
};
uint16_t photo_list_count();
const PhotoEntry *photo_list_get(uint16_t index);
uint16_t photo_list_scan(); // returns count

22
include/photo_view.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <lvgl.h>
#include <stdint.h>
#include "photo_list.h"
bool photo_view_init();
void photo_view_deinit();
// Decode entry into half-res RGB565 canvas (160x120, shown 2x).
bool photo_view_show(const PhotoEntry *entry);
const lv_image_dsc_t *photo_view_dsc();
uint16_t photo_view_canvas_w();
uint16_t photo_view_canvas_h();
uint16_t photo_view_img_w();
uint16_t photo_view_img_h();
bool photo_view_is_gif();
// Advance GIF frame if due; returns true when pixels changed.
bool photo_view_gif_tick();

24
include/pins.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
// CYD ESP32-2432S028R
#define TFT_BL_PIN 21
// TF / microSD (VSPI;触摸用 SoftSPI,不抢总线)
#define SD_MISO 19
#define SD_MOSI 23
#define SD_SCK 18
#define SD_CS 5
#define SPEAKER_PIN 26
#define CYD_TOUCH_IRQ 36
#define CYD_TOUCH_MOSI 32
#define CYD_TOUCH_MISO 39
#define CYD_TOUCH_CLK 25
#define CYD_TOUCH_CS 33
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
#define UI_HOR_RES 320
#define UI_VER_RES 240

21
include/sd_info.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <Arduino.h>
struct SdCardInfo {
bool mounted;
bool present;
const char *type;
const char *filesystem;
uint64_t card_bytes;
uint64_t total_bytes;
uint64_t used_bytes;
uint64_t free_bytes;
uint32_t root_files;
String error;
};
bool sd_init();
void sd_deinit();
SdCardInfo sd_read_info();
String format_bytes(uint64_t bytes);

7
include/sd_put.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <Arduino.h>
// 串口协议: "#PUT <path> <bytes>\n" -> READY -> raw -> DONE/FAIL
// 在 loop 里调用;返回 true 表示刚处理完一次传输
bool sd_put_poll();

12
include/touch.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <lvgl.h>
#include <stdint.h>
void touch_init();
void touch_read_cb(lv_indev_t *indev, lv_indev_data_t *data);
// 调试:最近一次触点(物理 / LVGL 旋转后逻辑)
extern int16_t g_dbg_phys_x, g_dbg_phys_y;
extern int16_t g_dbg_logic_x, g_dbg_logic_y;
extern bool g_dbg_touch_down;

9
include/ui.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include "sd_info.h"
#include <stdint.h>
void ui_create();
void ui_update(const SdCardInfo &info);
void ui_tick();
void ui_reload_album(); // rescan TF and show current / first photo