fix(boot): show the burn-mode title in white

The source picture painted the glyphs in the page background color, so the screen stayed black. Draw those strokes in white when the external image has no light pixels.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-26 13:11:17 +08:00
parent fa5aa85bee
commit 6f19486b16
4 changed files with 100 additions and 5 deletions

View File

@ -0,0 +1,27 @@
#ifndef BOOT_FLASH_MODE_INK_H
#define BOOT_FLASH_MODE_INK_H
#include <stdint.h>
/* 烧录模式.png 的白字笔画。原图把字画成页面底色,铺到黑底上就是黑屏。 */
#define BOOT_FLASH_INK_X 78
#define BOOT_FLASH_INK_Y 149
#define BOOT_FLASH_INK_W 86
#define BOOT_FLASH_INK_H 21
static const uint8_t boot_flash_ink[231] = {
0x1C,0x30,0x00,0x00,0x00,0x01,0x83,0x18,0x00,0x0E,0x40,0x1C,0x30,0x00,0xFF,0xFE,
0x01,0x83,0x18,0x00,0x0E,0xE0,0x1C,0x3F,0xF0,0xFF,0xFE,0x01,0xBF,0xFF,0x00,0x0E,
0x70,0x1D,0xFF,0xE0,0x00,0x06,0x01,0xBF,0xFF,0x00,0x0E,0x30,0xDF,0xFC,0x60,0x00,
0x06,0x0F,0xE3,0x18,0x3F,0xFF,0xF8,0x7E,0x1C,0xE0,0x7F,0xFE,0x0F,0xE0,0x00,0x3F,
0xFF,0xF8,0x7C,0x0F,0xC0,0x7F,0xFE,0x03,0x9F,0xFE,0x00,0x06,0x00,0x7C,0x0F,0x10,
0x00,0x06,0x03,0x9C,0x0E,0x00,0x06,0x00,0x7C,0xFF,0x31,0xFF,0xFF,0xC3,0x9F,0xFE,
0x00,0x06,0x00,0x7C,0xF3,0xF3,0xFF,0xFF,0xC7,0xDF,0xFE,0x3F,0xF6,0x00,0x1C,0x81,
0xE0,0x41,0xC1,0x07,0xF8,0x06,0x3F,0xF6,0x00,0x1C,0x00,0x40,0xE1,0xC3,0x0F,0xFF,
0xFE,0x03,0x86,0x00,0x1D,0xFF,0xF0,0x71,0xE7,0x8F,0x9F,0xFE,0x03,0x07,0x00,0x1F,
0xFF,0xF0,0x3B,0xFE,0x0D,0x80,0xC0,0x03,0x07,0x00,0x1E,0x33,0x00,0x1F,0xFC,0x09,
0xBF,0xFF,0x03,0x03,0x18,0x3F,0x33,0x10,0x7F,0xFC,0x01,0xBF,0xFF,0x03,0x03,0x18,
0x32,0x73,0x11,0xF9,0xCF,0x01,0x81,0xE0,0x07,0xFB,0x98,0x70,0x73,0x13,0xE1,0xC7,
0xC1,0x87,0xF8,0x3F,0xF9,0xD8,0x61,0xE3,0xF1,0x8F,0xC1,0xC1,0x9F,0x3F,0x3F,0x01,
0xF8,0x61,0xC1,0xF0,0x0F,0x80,0x01,0xBC,0x0F,0x00,0x00,0xF0,0x00,0x00,0x00,0x0F,
0x00,0x01,0xB0,0x02,0x00,0x00,0x20,
};
#endif

View File

@ -38,6 +38,7 @@
#include "Drv_TM1617_RGB.h" #include "Drv_TM1617_RGB.h"
#include "UI0902_Res_Addr.h" #include "UI0902_Res_Addr.h"
#include "drv_nvm.h" #include "drv_nvm.h"
#include "boot_flash_mode_ink.h"
/* private includes ----------------------------------------------------------*/ /* private includes ----------------------------------------------------------*/
/* add user code begin private includes */ /* add user code begin private includes */
@ -111,6 +112,40 @@ static uint8_t Boot_NvmUsbUpdateRequested(void)
return (nvm->data.param.UsbMode == NVM_USB_UPDATE) ? 1 : 0; return (nvm->data.param.UsbMode == NVM_USB_UPDATE) ? 1 : 0;
} }
/* 外部图把字画成了页面底色,铺出来是黑屏。字行中间有接近白色的像素才采用它。 */
static uint8_t Boot_FlashModeHasLight(void)
{
uint8_t row[172];
uint16_t i;
W25Q128_Read(row,
UI0902_FLASH_MODE_ADDR + (158ul * 240ul + 78ul) * 2ul,
(uint16_t)sizeof(row));
for (i = 0; i + 1u < sizeof(row); i += 2)
{
uint16_t c = (uint16_t)(((uint16_t)row[i] << 8) | row[i + 1]);
if (c >= 0xC618)
return 1;
}
return 0;
}
static void Boot_DrawFlashModeInk(void)
{
uint16_t row, col, stride;
LCD_FillByColor(0, 0, 240, 320, 0x0042);
stride = (uint16_t)((BOOT_FLASH_INK_W + 7u) >> 3);
for (row = 0; row < BOOT_FLASH_INK_H; row++)
{
const uint8_t *p = boot_flash_ink + (uint32_t)row * stride;
for (col = 0; col < BOOT_FLASH_INK_W; col++)
{
if (p[col >> 3] & (uint8_t)(0x80u >> (col & 7)))
LCD_DrawPoint((uint16_t)(BOOT_FLASH_INK_X + col),
(uint16_t)(BOOT_FLASH_INK_Y + row), WHITE);
}
}
}
static void Boot_NvmClearUsbUpdate(void) static void Boot_NvmClearUsbUpdate(void)
{ {
NvmData_Type tmp; NvmData_Type tmp;
@ -211,17 +246,15 @@ int main(void)
{ {
uint8_t peek[4]; uint8_t peek[4];
W25Q128_Read(peek, UI0902_FLASH_MODE_ADDR, 4); W25Q128_Read(peek, UI0902_FLASH_MODE_ADDR, 4);
if (!(peek[0] == 0xFF && peek[1] == 0xFF && peek[2] == 0xFF && peek[3] == 0xFF)) if (!(peek[0] == 0xFF && peek[1] == 0xFF && peek[2] == 0xFF && peek[3] == 0xFF) &&
Boot_FlashModeHasLight())
{ {
LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_FLASH_MODE_W, UI0902_FLASH_MODE_H, LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_FLASH_MODE_W, UI0902_FLASH_MODE_H,
UI0902_FLASH_MODE_ADDR); UI0902_FLASH_MODE_ADDR);
} }
else else
{ {
LCD_FillByColor(0, 0, 240, 320, BLACK); Boot_DrawFlashModeInk();
LCD_ShowChinese_AutoAlign(0, 240, 150,
(uint8_t *)"\xC9\xD5\xC2\xBC\xC4\xA3\xCA\xBD\x00",
LCD_ALIGN_CENTER, WHITE, BLACK, 0, 24);
} }
} }
/* 画面出来后再清标志,避免还没进烧录就被下一次复位跳回 App。 /* 画面出来后再清标志,避免还没进烧录就被下一次复位跳回 App。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -60,6 +60,39 @@ def rgba_to_rgb565(im):
return bytes(out), w, h return bytes(out), w, h
def flash_mode_on_page(im):
"""烧录模式导出把「烧录模式」画成页面底色、其余透明。
直接铺到黑底上整屏都是黑。这里把这些笔画改成白字,铺在页面底色上。
已经是白字的图不再改。
"""
rgba = im.convert("RGBA")
px = rgba.load()
w, h = rgba.size
light = 0
for y in range(h):
for x in range(w):
r, g, b, a = px[x, y]
if a >= 40 and (r + g + b) > 400:
light += 1
if light > 50:
return rgba
out = Image.new("RGBA", (w, h), PAGE_BG + (255,))
opx = out.load()
for y in range(h):
for x in range(w):
r, g, b, a = px[x, y]
if a < 8:
continue
opx[x, y] = (
(255 * a + PAGE_BG[0] * (255 - a)) // 255,
(255 * a + PAGE_BG[1] * (255 - a)) // 255,
(255 * a + PAGE_BG[2] * (255 - a)) // 255,
255,
)
return out
def rgba_to_rgb565_opaque(im): def rgba_to_rgb565_opaque(im):
"""Full-screen boot/charge/flash: keep dark bg; flatten RGBA onto black (not white). """Full-screen boot/charge/flash: keep dark bg; flatten RGBA onto black (not white).
@ -299,6 +332,8 @@ def main():
entries = {} entries = {}
for name, rel in EXTERNAL: for name, rel in EXTERNAL:
im = Image.open(SRC / rel) im = Image.open(SRC / rel)
if name == "FLASH_MODE":
im = flash_mode_on_page(im)
if name in ("ROW_UNIVERSAL_NOT", "ROW_UNIVERSAL_SEL", "ROW_NORMAL_NOT", "ROW_NORMAL_SEL", "ROW_EXPERT_NOT", "ROW_EXPERT_SEL"): if name in ("ROW_UNIVERSAL_NOT", "ROW_UNIVERSAL_SEL", "ROW_NORMAL_NOT", "ROW_NORMAL_SEL", "ROW_EXPERT_NOT", "ROW_EXPERT_SEL"):
im = im.resize(ROW_RESIZE, Image.LANCZOS) im = im.resize(ROW_RESIZE, Image.LANCZOS)
data, w, h = rgba_to_rgb565(im) data, w, h = rgba_to_rgb565(im)