Add optional cyd_35r (ESP32-3248S035) with 480x320 UI; default remains 2.8.

This commit is contained in:
2026-10-23 16:24:18 +08:00
parent 0dab8a97ab
commit f870f5cebb
4 changed files with 97 additions and 39 deletions

View File

@@ -1,9 +1,13 @@
# Rebuild (optional) and refresh firmware/cyd from PlatformIO build output.
# Usage:
# .\firmware\export_from_build.ps1
# .\firmware\export_from_build.ps1 -SkipBuild
# Export firmware bins from PlatformIO build.
# Default: 2.8" (cyd -> firmware/cyd)
# 3.5": .\firmware\export_from_build.ps1 -Env cyd_35r
# (only after: pio run -e cyd_35r)
param([switch]$SkipBuild)
param(
[switch]$SkipBuild,
[ValidateSet("cyd", "cyd_35r")]
[string]$Env = "cyd"
)
$ErrorActionPreference = "Stop"
$root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
@@ -12,17 +16,26 @@ Set-Location $root
$env:Path = "C:\Users\dsx2016\AppData\Local\Programs\Python\Python312\Scripts;" + $env:Path
if (-not $SkipBuild) {
pio run -e cyd
pio run -e $Env
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
$src = Join-Path $root ".pio\build\cyd"
$dst = Join-Path $root "firmware\cyd"
$src = Join-Path $root (".pio\build\" + $Env)
if ($Env -eq "cyd_35r") {
$dstName = "cyd_35r"
$boardLine = "board: ESP32-3248S035 (ST7796)"
$boardIdHint = "esp32-3248s035"
} else {
$dstName = "cyd"
$boardLine = "board: ESP32-2432S028R (ILI9341)"
$boardIdHint = "esp32-2432s028"
}
$dst = Join-Path $root ("firmware\" + $dstName)
New-Item -ItemType Directory -Force -Path $dst | Out-Null
foreach ($f in @("bootloader.bin", "partitions.bin", "firmware.bin")) {
$p = Join-Path $src $f
if (-not (Test-Path $p)) { Write-Error "Missing build artifact: $p" }
if (-not (Test-Path $p)) { Write-Error "Missing build artifact: $p — build with: pio run -e $Env" }
Copy-Item $p $dst -Force
}
@@ -32,17 +45,15 @@ if (-not (Test-Path $bootApp)) {
}
Copy-Item $bootApp (Join-Path $dst "boot_app0.bin") -Force
# Keep flash scripts if already present
$git = ""
try { $git = (git -C $root rev-parse --short HEAD).Trim() } catch { $git = "unknown" }
$date = Get-Date -Format "yyyy-MM-dd"
$hashes = Get-ChildItem (Join-Path $dst "*.bin") | Get-FileHash -Algorithm SHA256
$lines = @(
"name: CYD Photo album (cyd)",
"name: CYD phtotest ($dstName)",
"git: $git",
"date: $date",
"board: ESP32-2432S028R (ILI9341)",
"features: jpg/png/gif album, SoftSPI touch, TF card",
$boardLine,
"flash_size: 4MB",
"offsets:",
" 0x1000 bootloader.bin",
@@ -55,4 +66,22 @@ foreach ($h in $hashes) {
$lines += (" {0,-15} {1}" -f (Split-Path $h.Path -Leaf), $h.Hash)
}
$lines | Set-Content -Encoding utf8 (Join-Path $dst "VERSION.txt")
Write-Host "Exported -> $dst (git $git)"
# Keep / refresh meta.json boardId for catalog filtering
$metaPath = Join-Path $dst "meta.json"
if (Test-Path $metaPath) {
try {
$meta = Get-Content $metaPath -Raw | ConvertFrom-Json
$meta.boardId = $boardIdHint
if ($Env -eq "cyd_35r" -and $meta.name -notmatch "3\.5") {
$meta.name = ($meta.name -replace "\s*$","") + " (3.5\")"
}
$meta | ConvertTo-Json -Depth 8 | Set-Content -Encoding utf8 $metaPath
} catch {
Write-Host "meta.json update skipped: $_"
}
} elseif ($Env -eq "cyd_35r") {
Write-Host "Note: add firmware/cyd_35r/meta.json with boardId=$boardIdHint for the web catalog"
}
Write-Host "Exported -> $dst (env=$Env git=$git)"

View File

@@ -1,16 +1,20 @@
#pragma once
// CYD ESP32-2432S028R
// Board pins — 2.8" default; 3.5" when CYD_BOARD_3248S035 is set (env:cyd_35r)
#if defined(CYD_BOARD_3248S035)
#define TFT_BL_PIN 27
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
#define UI_HOR_RES 480
#define UI_VER_RES 320
#else
#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 SCREEN_WIDTH 240
#define SCREEN_HEIGHT 320
#define UI_HOR_RES 320
#define UI_VER_RES 240
#endif
#define CYD_TOUCH_IRQ 36
#define CYD_TOUCH_MOSI 32
@@ -18,7 +22,15 @@
#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
/* Map 320x240 design coordinates onto the active UI resolution (identity on 2.8"). */
#define UX(x) ((int)(((long)(x) * (UI_HOR_RES)) / 320))
#define UY(y) ((int)(((long)(y) * (UI_VER_RES)) / 240))
#define UW(w) UX(w)
#define UH(h) UY(h)
#define SD_MISO 19
#define SD_MOSI 23
#define SD_SCK 18
#define SD_CS 5
#define SPEAKER_PIN 26

View File

@@ -57,3 +57,20 @@ build_flags =
-I${PROJECT_DIR}/include
extra_scripts = pre:copy_lv_conf.py
; Optional 3.5" CYD ESP32-3248S035 (ST7796 resistive). Default remains [env:cyd].
; Build: pio run -e cyd_35r
[env:cyd_35r]
extends = env:cyd
build_flags =
${env:cyd.build_flags}
-UILI9341_2_DRIVER
-DST7796_DRIVER=1
-UTFT_WIDTH
-UTFT_HEIGHT
-DTFT_WIDTH=320
-DTFT_HEIGHT=480
-UTFT_BL
-DTFT_BL=27
-DCYD_BOARD_3248S035=1

View File

@@ -90,7 +90,7 @@ static void show_current() {
lv_image_set_pivot(img_photo, 0, 0);
lv_image_set_inner_align(img_photo, LV_IMAGE_ALIGN_STRETCH);
lv_obj_set_size(img_photo, UI_HOR_RES, UI_VER_RES);
lv_obj_align(img_photo, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_align(img_photo, LV_ALIGN_TOP_LEFT, UX(0), UY(0));
const lv_image_dsc_t *dsc = photo_view_dsc();
if (ok && dsc) {
@@ -183,7 +183,7 @@ void ui_create() {
// Full-screen tap zones (behind chrome)
lv_obj_t *tap = lv_obj_create(scr);
lv_obj_set_size(tap, UI_HOR_RES, UI_VER_RES);
lv_obj_set_pos(tap, 0, 0);
lv_obj_set_pos(tap, UX(0), UY(0));
lv_obj_set_style_bg_opa(tap, LV_OPA_TRANSP, 0);
lv_obj_set_style_border_width(tap, 0, 0);
lv_obj_set_style_pad_all(tap, 0, 0);
@@ -193,7 +193,7 @@ void ui_create() {
img_photo = lv_image_create(scr);
lv_obj_set_size(img_photo, UI_HOR_RES, UI_VER_RES);
lv_obj_align(img_photo, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_align(img_photo, LV_ALIGN_TOP_LEFT, UX(0), UY(0));
lv_image_set_scale(img_photo, LV_SCALE_NONE);
lv_image_set_inner_align(img_photo, LV_IMAGE_ALIGN_STRETCH);
lv_obj_set_style_bg_color(img_photo, lv_color_hex(0x000000), 0);
@@ -203,7 +203,7 @@ void ui_create() {
// Top bar
lv_obj_t *top = lv_obj_create(scr);
lv_obj_set_size(top, UI_HOR_RES, 28);
lv_obj_set_pos(top, 0, 0);
lv_obj_set_pos(top, UX(0), UY(0));
lv_obj_set_style_bg_color(top, lv_color_hex(COL_BG), 0);
lv_obj_set_style_bg_opa(top, LV_OPA_80, 0);
lv_obj_set_style_border_width(top, 0, 0);
@@ -216,19 +216,19 @@ void ui_create() {
lv_label_set_text(lbl_title, "ALBUM");
lv_obj_set_style_text_font(lbl_title, &lv_font_montserrat_16, 0);
lv_obj_set_style_text_color(lbl_title, lv_color_hex(COL_ACCENT), 0);
lv_obj_set_pos(lbl_title, 8, 5);
lv_obj_set_pos(lbl_title, UX(8), UY(5));
lbl_index = lv_label_create(top);
lv_label_set_text(lbl_index, "0/0");
lv_obj_set_style_text_font(lbl_index, &lv_font_montserrat_14, 0);
lv_obj_set_style_text_color(lbl_index, lv_color_hex(COL_INK), 0);
lv_obj_align(lbl_index, LV_ALIGN_TOP_MID, 0, 6);
lv_obj_align(lbl_index, LV_ALIGN_TOP_MID, UX(0), UY(6));
lbl_chip = lv_label_create(top);
lv_label_set_text(lbl_chip, "-");
lv_obj_set_style_text_font(lbl_chip, &lv_font_montserrat_14, 0);
lv_obj_set_style_text_color(lbl_chip, lv_color_hex(COL_MUTED), 0);
lv_obj_align(lbl_chip, LV_ALIGN_TOP_RIGHT, -8, 6);
lv_obj_align(lbl_chip, LV_ALIGN_TOP_RIGHT, UX(-8), UY(6));
// Bottom bar
lv_obj_t *bot = lv_obj_create(scr);
@@ -242,8 +242,8 @@ void ui_create() {
lv_obj_clear_flag(bot, LV_OBJ_FLAG_SCROLLABLE);
btn_prev = lv_button_create(bot);
lv_obj_set_pos(btn_prev, 8, 6);
lv_obj_set_size(btn_prev, 56, 28);
lv_obj_set_pos(btn_prev, UX(8), UY(6));
lv_obj_set_size(btn_prev, UW(56), UH(28));
lv_obj_add_flag(btn_prev, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(btn_prev, on_prev, LV_EVENT_CLICKED, nullptr);
style_btn(btn_prev, COL_BTN);
@@ -255,7 +255,7 @@ void ui_create() {
btn_next = lv_button_create(bot);
lv_obj_set_pos(btn_next, UI_HOR_RES - 64, 6);
lv_obj_set_size(btn_next, 56, 28);
lv_obj_set_size(btn_next, UW(56), UH(28));
lv_obj_add_flag(btn_next, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(btn_next, on_next, LV_EVENT_CLICKED, nullptr);
style_btn(btn_next, COL_BTN_HI);
@@ -271,13 +271,13 @@ void ui_create() {
lv_obj_set_width(lbl_name, UI_HOR_RES - 140);
lv_obj_set_style_text_font(lbl_name, &lv_font_montserrat_14, 0);
lv_obj_set_style_text_color(lbl_name, lv_color_hex(COL_INK), 0);
lv_obj_align(lbl_name, LV_ALIGN_TOP_MID, 0, 4);
lv_obj_align(lbl_name, LV_ALIGN_TOP_MID, UX(0), UY(4));
lbl_hint = lv_label_create(bot);
lv_label_set_text(lbl_hint, "Tap left/right");
lv_obj_set_style_text_font(lbl_hint, &lv_font_montserrat_14, 0);
lv_obj_set_style_text_color(lbl_hint, lv_color_hex(COL_MUTED), 0);
lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, 0, 20);
lv_obj_align(lbl_hint, LV_ALIGN_TOP_MID, UX(0), UY(20));
// Raise bars / buttons above tap target for hit testing
lv_obj_move_foreground(top);