diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index 754c55c..cd05f8d 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -24,12 +24,12 @@ static uint8_t s_mode_select_focus = 0; extern bool InModeFlag; -/* 0902 设计稿:整行位图(背景+图标+文字+箭头)存外部 Flash,222x84 */ +/* 0902/0819:三行模式撑满状态栏下方至底边(无底栏),222x88 @ y=43/135/225 */ #define UI0902_MODE_ROW_X 9 #define UI0902_MODE_ROW_W 222 -#define UI0902_MODE_ROW_H 84 -#define UI0902_MODE_ROW_Y0 30 -#define UI0902_MODE_ROW_DY 86 +#define UI0902_MODE_ROW_H 88 +#define UI0902_MODE_ROW_Y0 43 +#define UI0902_MODE_ROW_DY 92 static const uint32_t s_mode_row_addr[3][2] = { { UI0902_ROW_UNIVERSAL_NOT_ADDR, UI0902_ROW_UNIVERSAL_SEL_ADDR }, /* 0 万能 */ @@ -89,17 +89,14 @@ void UI_DrawModeSelectScreen(void) LCD_FillByColor(0, 0, 240, 320, UI0902_BG_COLOR); label_top(); UI_ModeSelect_DrawButtons(); - Draw_Bottom_Bar(UI0902_NAV_MODE, 0); + /* 设计稿 0902-01:模式选择页无底部三栏导航,仅三行模式按钮 */ } const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = { - /* Flag=按钮序号(0万能/1普通/2专业);ID=进入 TAB */ - { 9, 231, 30, 114, 0, 0, 0, NULL }, - { 9, 231, 116, 200, 1, 0, 2, NULL }, - { 9, 231, 202, 286, 2, 0, 1, NULL }, - /* 底栏导航:设置 / 调音台(模式选择即本页) */ - { 0, 79, 287, 319, 0, UI0902_NAV_SETTING, GUI_NAV_BAR, NULL }, - { 80, 159, 287, 319, 0, UI0902_NAV_MIXER, GUI_NAV_BAR, NULL }, + /* Flag=按钮序号(0万能/1普通/2专业);ID=进入 TAB。三行撑满,无底栏 */ + { 9, 231, 43, 130, 0, 0, 0, NULL }, + { 9, 231, 135, 222, 1, 0, 2, NULL }, + { 9, 231, 225, 312, 2, 0, 1, NULL }, }; #define TOUCH_AREA_MODE_SELECT_NUM (sizeof(Touch_ModeSelect_Areas)/sizeof(Touch_AreaTypeDef)) @@ -229,13 +226,6 @@ void IdleProcess(DisplayTaskMessage_Type msg) msg.LoByte >= Touch_ModeSelect_Areas[k].y_min && msg.LoByte <= Touch_ModeSelect_Areas[k].y_max ) { hit = 1U; - if (Touch_ModeSelect_Areas[k].ID == GUI_NAV_BAR) { - if (Touch_ModeSelect_Areas[k].Value == UI0902_NAV_SETTING) - MenuPage_Setting_Proc(); - else if (Touch_ModeSelect_Areas[k].Value == UI0902_NAV_MIXER) - MenuPage_Mixer_Proc(); - break; - } uint8_t row = (uint8_t)Touch_ModeSelect_Areas[k].Flag; LOG_I("UI", "mode_select hit area=%u row=%u focus=%u x=%u y=%u", (unsigned)k, (unsigned)row, (unsigned)s_mode_select_focus, @@ -301,7 +291,7 @@ void IdleProcess(DisplayTaskMessage_Type msg) else if (vol <= 95) level = 3; else if (vol <= 115) level = 4; else level = 5; - Draw_Volume_Bar(55, 3, level, 1, WHITE, GRAY); + Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY); uint8_t mMasterSysExVolume[12] = { 0xF0, 0x41, 0x00, 0x42, 0x12, 0x40, 0x00, 0x04, 0x64, 0x00, 0x00,0xF7}; memset(mMasterSysExVolume+8,msg.ID,1); SendMidiDataToDreamDSP(mMasterSysExVolume,12); diff --git a/UI/UI_SongMode.c b/UI/UI_SongMode.c index ea81b3b..af1c58a 100644 --- a/UI/UI_SongMode.c +++ b/UI/UI_SongMode.c @@ -418,7 +418,7 @@ void UI_SongMode_Process(DisplayTaskMessage_Type msg) case MSG_ID_EC_VOL: Send_volume(msg.ID); - Draw_Volume_Bar(55, 3, msg.HiByte, 1, WHITE, GRAY); + Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, msg.HiByte, 1, WHITE, GRAY); break; case MSG_ID_TAP_SPEED: diff --git a/UI/UI_global.c b/UI/UI_global.c index d5e46be..e513e1e 100644 --- a/UI/UI_global.c +++ b/UI/UI_global.c @@ -175,11 +175,10 @@ uint8_t UI_SetFocus(uint8_t widget_id) void label_top() { - const uint16_t btn_color = /*DARKLGRAY*/0x2988; // 深灰�????? - //LCD_FillByColor(0,0,240,25,BLACK); + const uint16_t btn_color = /*DARKLGRAY*/0x2988; LCD_FillByColor(0, 0, 240, UI_STATUS_BAR_H, UI0902_BG_COLOR); - LCD_WR_PIC_Trans(8, 6, 20, 15, gImage_UI0902_Volume_20x15, BLACK); - Draw_Volume_Bar(55, 3, level, 1, WHITE, GRAY); + /* 仅一组动态音量条(音量图标素材本身也是竖条,不再叠绘以免双图标) */ + Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY); LCD_DrawLine(0, 26, 240, 26, btn_color); Show_BL_Icon(mGuiData[GUI_BL_SW].Current); Show_Battery_Icon(usb_charging_state); @@ -245,31 +244,49 @@ void UI_GotoCurrentModePage(void) } } -/* 蓝牙图标显示(占位) */ +/* 蓝牙图标:设计稿居中 */ void Show_BL_Icon(uint8_t value) { - if(value) + LCD_FillByColor(UI0902_BT_X, UI0902_BT_Y, + UI0902_BT_X + UI0902_BT_W - 1, + UI0902_BT_Y + UI0902_BT_H - 1, UI0902_BG_COLOR); + if (value) { - LCD_WR_PIC_Trans(36, 5, 11, 17, gImage_UI0902_Bluetooth_11x17, BLACK); + LCD_WR_PIC_Trans(UI0902_BT_X, UI0902_BT_Y, UI0902_BT_W, UI0902_BT_H, + gImage_UI0902_Bluetooth_11x17, BLACK); } - else - { - LCD_FillByColor(36, 5, 47, 22, UI0902_BG_COLOR); - } - BSP_BlueToothPowerEnable (value); + BSP_BlueToothPowerEnable(value); } void Draw_Status_Battery_Icon(uint8_t battery_percent) { + uint8_t Info[8]; uint16_t fill_w; - if (battery_percent > 100) battery_percent = 100; - LCD_FillByColor(UI0902_BATTERY_X, UI0902_BATTERY_Y, - UI0902_BATTERY_X + 29, UI0902_BATTERY_Y + 12, UI0902_BG_COLOR); + uint16_t text_w; + uint16_t bat_x; + uint16_t text_x; + uint16_t text_y; + + if (battery_percent > 100) + battery_percent = 100; + + sprintf((char *)Info, "%d%%", battery_percent); + text_w = (uint16_t)(strlen((char *)Info) * (UI0902_BATTERY_TEXT_SIZE / 2)); + bat_x = (uint16_t)(240 - UI0902_BATTERY_RIGHT_MARGIN - text_w + - UI0902_BATTERY_TEXT_GAP - UI0902_BATTERY_W); + text_x = (uint16_t)(bat_x + UI0902_BATTERY_W + UI0902_BATTERY_TEXT_GAP); + text_y = (uint16_t)((UI_STATUS_BAR_H - UI0902_BATTERY_TEXT_SIZE) / 2); + + LCD_FillByColor(bat_x > 2 ? (uint16_t)(bat_x - 2) : 0, 0, 240, UI_STATUS_BAR_H, + UI0902_BG_COLOR); + fill_w = (uint16_t)((22UL * battery_percent) / 100); - LCD_WR_PIC_ClipX(UI0902_BATTERY_X + 3, UI0902_BATTERY_Y + 2, 22, 9, fill_w, + LCD_WR_PIC_ClipX(bat_x + 3, UI0902_BATTERY_Y + 2, 22, 9, fill_w, gImage_UI0902_BatteryFill_22x9); - LCD_WR_PIC_Trans(UI0902_BATTERY_X, UI0902_BATTERY_Y, 29, 12, + LCD_WR_PIC_Trans(bat_x, UI0902_BATTERY_Y, UI0902_BATTERY_W, UI0902_BATTERY_H, gImage_UI0902_BatteryOutline_29x12, BLACK); + LCD_ShowString(text_x, text_y, Info, WHITE, UI0902_BG_COLOR, + UI0902_BATTERY_TEXT_SIZE, 0); } void Show_Battery_Icon(uint8_t flag) diff --git a/UI/UI_global.h b/UI/UI_global.h index c3fceb4..743c1f7 100644 --- a/UI/UI_global.h +++ b/UI/UI_global.h @@ -31,13 +31,24 @@ void CallUI_RestoreSelect(void); /* 0902 设计稿配色与底栏导航 */ #define UI0902_BG_COLOR 0x0042 /* #000813 页面背景 */ #define UI0902_ROW_BG 0x2147 /* #242B3A 列表行背景 */ -#define UI0902_BATTERY_X 203 +/* 0902 状态栏:左音量条 / 中蓝牙 / 右电池+百分比(对齐屏幕参考 0902-01) */ +#define UI0902_VOL_X 8 +#define UI0902_VOL_Y 3 +#define UI0902_BT_W 11 +#define UI0902_BT_H 17 +#define UI0902_BT_X ((240 - UI0902_BT_W) / 2) /* 居中 */ +#define UI0902_BT_Y 5 +#define UI0902_BATTERY_W 29 +#define UI0902_BATTERY_H 12 #define UI0902_BATTERY_Y 7 +#define UI0902_BATTERY_RIGHT_MARGIN 8 +#define UI0902_BATTERY_TEXT_GAP 4 +#define UI0902_BATTERY_TEXT_SIZE 16 #define UI0902_NAV_SETTING 0 /* 底栏位0:设置(设置页内为返回) */ #define UI0902_NAV_MIXER 1 /* 底栏位1:调音台 */ #define UI0902_NAV_MODE 2 /* 底栏位2:模式选择 */ #define UI0902_NAV_NONE 0xFF -/* 电量组在 Draw_Battery_Icon 内按右对齐重算;此值为允许的最左起点 */ +/* 旧几何电池(Draw_Battery_Icon)最左起点;0902 图电池用 Draw_Status_Battery_Icon */ #define UI_STATUS_BATTERY_X 150 #define UI_STATUS_BATTERY_H 11 #define UI_STATUS_BATTERY_Y ((UI_STATUS_BAR_H - UI_STATUS_BATTERY_H) / 2) diff --git a/device/LCD_ILI9341/Drv_ILI9341_Lcd_App.c b/device/LCD_ILI9341/Drv_ILI9341_Lcd_App.c index 0e345f0..3caba51 100644 --- a/device/LCD_ILI9341/Drv_ILI9341_Lcd_App.c +++ b/device/LCD_ILI9341/Drv_ILI9341_Lcd_App.c @@ -1780,7 +1780,7 @@ void Draw_Volume_Bar(uint16_t x, uint16_t y, uint8_t volume_level,uint8_t scale, } clear_w = (uint16_t)(w + gap) * bar_count - gap; - LCD_FillByColor(x, y, x + clear_w, y + max_h * scale, BLACK); + LCD_FillByColor(x, y, x + clear_w, y + max_h * scale, UI0902_BG_COLOR); if(volume_level == 0) { diff --git a/project/inc/UI0902_Res_Addr.h b/project/inc/UI0902_Res_Addr.h index 9c85fef..61bd7da 100644 --- a/project/inc/UI0902_Res_Addr.h +++ b/project/inc/UI0902_Res_Addr.h @@ -4,29 +4,29 @@ /* Auto-generated by tools/gen_ui0902_assets.py. W25Q128 resource map. */ #define UI0902_RES_BASE 0x00100000UL -#define UI0902_ROW_UNIVERSAL_NOT_ADDR (UI0902_RES_BASE + 0x000000UL) /* 37296 bytes */ +#define UI0902_ROW_UNIVERSAL_NOT_ADDR (UI0902_RES_BASE + 0x000000UL) /* 39072 bytes */ #define UI0902_ROW_UNIVERSAL_NOT_W 222 -#define UI0902_ROW_UNIVERSAL_NOT_H 84 +#define UI0902_ROW_UNIVERSAL_NOT_H 88 -#define UI0902_ROW_UNIVERSAL_SEL_ADDR (UI0902_RES_BASE + 0x00A000UL) /* 37296 bytes */ +#define UI0902_ROW_UNIVERSAL_SEL_ADDR (UI0902_RES_BASE + 0x00A000UL) /* 39072 bytes */ #define UI0902_ROW_UNIVERSAL_SEL_W 222 -#define UI0902_ROW_UNIVERSAL_SEL_H 84 +#define UI0902_ROW_UNIVERSAL_SEL_H 88 -#define UI0902_ROW_NORMAL_NOT_ADDR (UI0902_RES_BASE + 0x014000UL) /* 37296 bytes */ +#define UI0902_ROW_NORMAL_NOT_ADDR (UI0902_RES_BASE + 0x014000UL) /* 39072 bytes */ #define UI0902_ROW_NORMAL_NOT_W 222 -#define UI0902_ROW_NORMAL_NOT_H 84 +#define UI0902_ROW_NORMAL_NOT_H 88 -#define UI0902_ROW_NORMAL_SEL_ADDR (UI0902_RES_BASE + 0x01E000UL) /* 37296 bytes */ +#define UI0902_ROW_NORMAL_SEL_ADDR (UI0902_RES_BASE + 0x01E000UL) /* 39072 bytes */ #define UI0902_ROW_NORMAL_SEL_W 222 -#define UI0902_ROW_NORMAL_SEL_H 84 +#define UI0902_ROW_NORMAL_SEL_H 88 -#define UI0902_ROW_EXPERT_NOT_ADDR (UI0902_RES_BASE + 0x028000UL) /* 37296 bytes */ +#define UI0902_ROW_EXPERT_NOT_ADDR (UI0902_RES_BASE + 0x028000UL) /* 39072 bytes */ #define UI0902_ROW_EXPERT_NOT_W 222 -#define UI0902_ROW_EXPERT_NOT_H 84 +#define UI0902_ROW_EXPERT_NOT_H 88 -#define UI0902_ROW_EXPERT_SEL_ADDR (UI0902_RES_BASE + 0x032000UL) /* 37296 bytes */ +#define UI0902_ROW_EXPERT_SEL_ADDR (UI0902_RES_BASE + 0x032000UL) /* 39072 bytes */ #define UI0902_ROW_EXPERT_SEL_W 222 -#define UI0902_ROW_EXPERT_SEL_H 84 +#define UI0902_ROW_EXPERT_SEL_H 88 #define UI0902_ICON_UNIVERSAL_SEL_ADDR (UI0902_RES_BASE + 0x03C000UL) /* 2730 bytes */ #define UI0902_ICON_UNIVERSAL_SEL_W 39 diff --git a/tools/flash_ui0902_res.py b/tools/flash_ui0902_res.py index 6172c5c..d8294f7 100644 --- a/tools/flash_ui0902_res.py +++ b/tools/flash_ui0902_res.py @@ -102,6 +102,8 @@ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--bin", default=DEFAULT_BIN) parser.add_argument("--device", default="Cortex-M4") + parser.add_argument("--no-reset", action="store_true", + help="Skip hardware reset (device must already be running)") args = parser.parse_args() if not os.path.isfile(args.bin): @@ -121,45 +123,47 @@ def main() -> None: time.sleep(0.3) _ = rtt_read_text(jlink, 0.3) - # Hardware reset clears any stuck flash_mode from a previous attempt - print("hardware reset...") - jlink.reset(halt=False) - time.sleep(3.5) - # RTT CB may move after reboot — re-find - try: - jlink.rtt_stop() - except Exception: - pass - cb = find_rtt_control_block(jlink) - if cb is None: - raise SystemExit("RTT CB missing after reset") - print(f"RTT CB @ 0x{cb:08X}") - jlink.rtt_start(cb) - time.sleep(0.5) - _ = rtt_read_text(jlink, 0.5) + if not args.no_reset: + # Hardware reset clears any stuck flash_mode from a previous attempt + print("hardware reset...") + jlink.reset(halt=False) + time.sleep(3.5) + # RTT CB may move after reboot — re-find + try: + jlink.rtt_stop() + except Exception: + pass + cb = find_rtt_control_block(jlink) + if cb is None: + raise SystemExit("RTT CB missing after reset") + print(f"RTT CB @ 0x{cb:08X}") + jlink.rtt_start(cb) + time.sleep(0.5) + _ = rtt_read_text(jlink, 0.5) cmd = f"flash ui0902 {size}\n".encode("ascii") send_bytes(jlink, cmd) print("sent flash command, waiting GO...") - log = wait_for(jlink, "FLASH_UI0902_GO", 15.0) + log = wait_for(jlink, "FLASH_UI0902_GO", 20.0) print(log.strip().splitlines()[-1]) time.sleep(0.2) - # wait for first byte confirmation after starting transfer - chunk = 256 + # Smaller chunks + brief pause so erase/write can keep up with RTT down-buffer + chunk = 128 sent = 0 t0 = time.time() - # prime first page then expect FLASH_RX send_bytes(jlink, data[0:256]) sent = 256 - wait_for(jlink, "FLASH_RX", 15.0) + wait_for(jlink, "FLASH_RX", 20.0) print("device receiving...") while sent < size: end = min(sent + chunk, size) send_bytes(jlink, data[sent:end]) sent = end + if sent % 256 == 0: + time.sleep(0.002) if sent % 4096 == 0 or sent == size: - log = wait_for(jlink, "FLASH_ACK", 30.0) + log = wait_for(jlink, "FLASH_ACK", 60.0) if "FLASH_UI0902_OK" in log: print(log.strip().splitlines()[-1]) print("Done. Mode-select should redraw with new assets.") @@ -168,7 +172,7 @@ def main() -> None: elapsed = time.time() - t0 print(f" {sent}/{size} ({100.0 * sent / size:.1f}%) {elapsed:.1f}s") - log = wait_for(jlink, "FLASH_UI0902_OK", 30.0) + log = wait_for(jlink, "FLASH_UI0902_OK", 60.0) print(log.strip().splitlines()[-1]) print("Done. Mode-select should redraw with new assets.") finally: diff --git a/tools/gen_ui0902_assets.py b/tools/gen_ui0902_assets.py index 479cfcc..21ecaee 100644 --- a/tools/gen_ui0902_assets.py +++ b/tools/gen_ui0902_assets.py @@ -23,8 +23,8 @@ OUT_BIN = OUT / "ui0902_res.bin" RES_BASE = 0x00100000 # W25Q128 offset; avoids logo(0x0)/charge(0xCB70)/preset(<~0xA8B60) regions ALIGN = 0x1000 -# 222x89 rows do not fit 3x between status bar (26) and bottom bar (285); squash to 84px -ROW_RESIZE = (222, 84) +# 模式选择页无底栏:三行按设计稿 0902-01 撑满(约 y=43/135/225,高 88) +ROW_RESIZE = (222, 88) MISANS = r"c:\Users\qjyu\Documents\SoundWalker\一诺国际吉他\Doc\UI\MiSans\MiSans 字体\MiSans-Medium.ttf" PAGE_BG = (0, 8, 19) # #000813 diff --git a/tools/gen_ui0902_previews.py b/tools/gen_ui0902_previews.py index 53578a5..7a9ad0a 100644 --- a/tools/gen_ui0902_previews.py +++ b/tools/gen_ui0902_previews.py @@ -64,12 +64,11 @@ def text_center(d, cx, y, s, size, color=(255, 255, 255)): # ---------- 1. mode select ---------- p, d = new_page() draw_status_bar(p, d) -rows = [("04_模式图标/完整版/模式界面栏背景-17.png", 30), - ("04_模式图标/完整版/模式界面栏背景-18.png", 116), - ("04_模式图标/完整版/模式界面栏背景-20.png", 202)] +rows = [("04_模式图标/完整版/模式界面栏背景-19.png", 43), + ("04_模式图标/完整版/模式界面栏背景-17.png", 135), + ("04_模式图标/完整版/模式界面栏背景-18.png", 225)] for rel, y in rows: - paste_trans(p, load(rel).resize((222, 84), Image.LANCZOS), 9, y) -draw_bottom_bar(p, d, sel=2) + paste_trans(p, load(rel).resize((222, 88), Image.LANCZOS), 9, y) p.save(OUT / "preview_01_mode_select.png") # ---------- 2. mixer ----------