K1Guitar/UI/UI_Idle.c

303 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "includes.h"
uint8_t CurrentMode = 0;
void RGB_Y_TO_R()
{
app_tm1629_all_on(LED_COLOR_YELL);
rt_thread_delay(1000);
app_tm1629_all_on(LED_COLOR_R);
}
void RGB_Y_TO_G()
{
app_tm1629_all_on(LED_COLOR_YELL);
rt_thread_delay(1000);
app_tm1629_all_on(LED_COLOR_G);
}
#define UI_MODE_SCREEN_WIDTH 240
#define UI_MODE_SCREEN_HEIGHT 320
extern bool InModeFlag;
/* 0902-01行高88、行距92顶边与模式主页移调/速度(CARD_Y=48)对齐,分割线居中 */
#define UI0902_MODE_ROW_X 9
#define UI0902_MODE_ROW_W 222
#define UI0902_MODE_ROW_H 88
#define UI0902_MODE_ROW_Y0 UI0902_CARD_Y /* 48与移调/速度顶对齐 */
#define UI0902_MODE_ROW_DY 92 /* 48 / 140 / 232 */
/* 模式页不显示焦点:三行均用未选中资源;单击直接进入 */
static const uint32_t s_mode_row_addr[3] = {
UI0902_ROW_UNIVERSAL_NOT_ADDR, /* 0 万能 */
UI0902_ROW_NORMAL_NOT_ADDR, /* 1 普通 */
UI0902_ROW_EXPERT_NOT_ADDR, /* 2 专业 */
};
static void UI_ModeSelect_DrawButtons(void)
{
uint8_t i;
for (i = 0; i < 3; i++) {
uint16_t y = (uint16_t)(UI0902_MODE_ROW_Y0 + i * UI0902_MODE_ROW_DY);
LCD_WR_PIC_FROM_FLASH(UI0902_MODE_ROW_X, y,
UI0902_MODE_ROW_W, UI0902_MODE_ROW_H,
s_mode_row_addr[i]);
}
}
void UI_ReturnToModeSelect(void)
{
StartFlag = 0;
InModeFlag = false;
AutoBandTop1_Stop();
CallUI_Idle();
UI_DrawModeSelectScreen();
}
void UI_DrawModeSelectScreen(void)
{
UI_ClearFocus();
pCurrentTouch_Area = Touch_ModeSelect_Areas;
LCD_FillByColor(0, 0, 240, 320, UI0902_BG_COLOR);
label_top();
UI_ModeSelect_DrawButtons();
/* 设计稿 0902-01模式选择页无底部三栏导航仅三行模式按钮 */
}
const Touch_AreaTypeDef Touch_ModeSelect_Areas[] = {
/* Flag=按钮序号(0万能/1普通/2专业)ID=进入 TAB。全宽便于命中Y 与 MODE_ROW_* 一致 */
{ 0, 239, 48, 135, 0, 0, 0, NULL },
{ 0, 239, 140, 227, 1, 0, 2, NULL },
{ 0, 239, 232, 319, 2, 0, 1, NULL },
};
#define TOUCH_AREA_MODE_SELECT_NUM (sizeof(Touch_ModeSelect_Areas)/sizeof(Touch_AreaTypeDef))
/* Timbre_index <20><><EFBFBD><EFBFBD> midi_tables.h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
extern uint8_t channel;
extern uint8_t level;
extern bool powon;
extern bool InModeFlag;
extern int16_t MIC_VOL_MAP[11];
extern int8_t delta;
extern STRING_MIDI USE_MIDI;
void LoadConfig(void)
{
SendProgramChangeMidiEvent(0,Timbre_index[mGuiData[GUI_TIMBRE_SELECT].Current]);
uint8_t val_127 = (faders[0].val * 127) / 10;
SendVolumeChangeMidiEvent(1,val_127);
SendVolumeChangeMidiEvent(2,val_127);
SendVolumeChangeMidiEvent(3,val_127);
SendVolumeChangeMidiEvent(4,val_127);
SendVolumeChangeMidiEvent(5,val_127);
SendVolumeChangeMidiEvent(6,val_127);
SendVolumeChangeMidiEvent(7,val_127);
SendVolumeChangeMidiEvent(8,val_127);
SendVolumeChangeMidiEvent(9,val_127);
SendVolumeChangeMidiEvent(10,val_127);
SendVolumeChangeMidiEvent(11,val_127);
SendVolumeChangeMidiEvent(12,val_127);
SendVolumeChangeMidiEvent(13,val_127);
SendVolumeChangeMidiEvent(14,val_127);
SendVolumeChangeMidiEvent(15,val_127);
SendVolumeChangeMidiEvent(0,(faders[1].val * 127) / 10);
AW816_Set_Volume(MIC_VOL_MAP[faders[2].val]);
AW816_Set_Reverb(faders[3].val * 10);
}
void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex)
{
(void)areaIndex;
(void)FLAG;
StartTask();
/* ID 为 TAB 索引0=万能(Song) 1=专业(Expert) 2=普通(Free) */
mGuiData[GUI_TAB_INDEX].Current = ID;
InModeFlag = true;
/* 进入子页后抑制残留按下,否则易误触底栏 GUI_TAB_INDEX(id=5)→设置 */
app_touch_suppress(500);
/* DSP 已就绪:再下发音色 + 调音台音量(与关机前 NVM/faders 一致) */
LoadConfig();
switch (ID)
{
case 0: /* 万能 → 3.bin / 本地→2.bin */
MenuPage_SongMode_Proc(); /* Init 设 TAB 并 Reload */
break;
case 1: /* 专业 → 1.bin / 本地→2.bin */
MenuPage_ExpertMode_Proc();
break;
case 2: /* 普通 → 1.bin */
MenuPage_FreeMode_Proc();
break;
default:
break;
}
}
extern uint8_t bat_init_done;
void IdleProcess(DisplayTaskMessage_Type msg)
{
uint8_t vol;
switch (msg.MessageType)
{
case MSG_ID_POWER_ON :
LCD_BLK_Set();
LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_BOOT_LOGO_W, UI0902_BOOT_LOGO_H,
UI0902_BOOT_LOGO_ADDR);
BSP_SelectAdcChannel(6);
/* 让出 CPU避免忙等卡住触摸/主循环线程 */
rt_thread_mdelay(1000);
LoadConfig();
vol = ADC_ReadChannel(ADC_CHANNEL_1)>>5;
app_adc_sync_volume(vol);
Send_volume(vol);
UI_DrawModeSelectScreen();
TM1629D_AllLedOn(LED_COLOR_G);
TM1629D_UpdateDisplay(0);
StartTouchTask();
StartScanTask();
/* Dream 上电稍后可能忽略首包 SysEx再发主音量 + 调音台(保持关机前设置)。
* 此时扫描任务已启动、模拟开关在轮询,不可现场重读 ADC会串通道
* 统一用 MasterVolume_Reapply 取扫描任务维护的最近一次有效音量 */
rt_thread_mdelay(400);
MasterVolume_Reapply();
LoadConfig();
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY);
break;
case MSG_ID_POWER_OFF:
/* 无 Type-C整机关机熄屏有 Type-C 时随后 POWOFF_CHARG 会再亮充电图 */
LCD_BLK_Clr();
LCD_WR_REG(0x28); /* Display OFF */
LCD_FillByColor(0, 0, 240, 320, BLACK);
break;
case MSG_ID_CHARG:
Show_Battery_Icon(msg.ID);
break;
case MSG_ID_TOUCH:
{
if (!powon)
break; /* 软关机已停触摸;兜底勿进模式选择 */
static uint32_t s_last_enter_ms;
uint32_t now = rt_tick_get() * 1000U / RT_TICK_PER_SECOND;
uint8_t hit = 0U;
for(uint8_t k=0; k<TOUCH_AREA_MODE_SELECT_NUM; k++)
{
if( msg.HiByte >= Touch_ModeSelect_Areas[k].x_min && msg.HiByte <= Touch_ModeSelect_Areas[k].x_max &&
msg.LoByte >= Touch_ModeSelect_Areas[k].y_min && msg.LoByte <= Touch_ModeSelect_Areas[k].y_max )
{
hit = 1U;
LOG_I("UI", "mode_select hit area=%u row=%u x=%u y=%u",
(unsigned)k,
(unsigned)Touch_ModeSelect_Areas[k].Flag,
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
/* 单击直接进入对应模式主页 */
if (now - s_last_enter_ms < 300U)
break;
s_last_enter_ms = now;
Touch_Mode_Select_Action(Touch_ModeSelect_Areas[k].Flag,
Touch_ModeSelect_Areas[k].ID, k);
break;
}
}
if (!hit) {
LOG_I("UI", "mode_select miss x=%u y=%u",
(unsigned)msg.HiByte, (unsigned)msg.LoByte);
}
}
break;
case MSG_ID_TOUCH_LONG_REPEAT:
/* 模式页暂无长按动作 */
break;
case MSG_ID_BATTERY_VALUE:
Draw_Status_Battery_Icon(msg.ID);
break;
case MSG_ID_POWOFF_CHARG:
{
static bool s_charge_ui_drawn = false;
if(!s_charge_ui_drawn)
{
uint8_t peek[4];
BSP_MainPowerEnable(1);
LCD_WR_REG(0x29); /* Display on */
/* 先铺设计底色,避免外置 Flash 未烧充电图时整屏 0xFF 灰底 */
LCD_FillByColor(0, 0, 240, 320, UI0902_BG_COLOR);
W25Q128_Read(peek, UI0902_CHARGE_SCREEN_ADDR, 4);
if (peek[0] != 0xFF || peek[1] != 0xFF)
{
/* 0904 全屏充电画面UI0902 @ CHARGE_SCREEN% 由固件叠画 */
LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_CHARGE_SCREEN_W, UI0902_CHARGE_SCREEN_H,
UI0902_CHARGE_SCREEN_ADDR);
}
else
{
/* 资源未烧录时的兜底:圆环闪电(需稍后 flash ui0902 */
Draw_Charging_Icon(120, 150, 2, 0x3D7F);
LOG_W("UI", "charge flash empty @0x%08lX — flash ui0902",
(unsigned long)UI0902_CHARGE_SCREEN_ADDR);
}
LCD_BLK_Set();
s_charge_ui_drawn = true;
}
if(usb_charging_state)
{
/* MiSans Semibold 位图:数字与 % 同高对齐,对齐 0904 设计 */
char digits[4];
uint8_t n, i;
uint16_t total_w = g_ChargePctPercent.w;
uint16_t x, y = 266;
uint8_t pct = msg.ID;
if (pct > 100)
pct = 100;
n = (uint8_t)sprintf(digits, "%u", (unsigned)pct);
for (i = 0; i < n; i++)
total_w = (uint16_t)(total_w + g_ChargePctDigits[digits[i] - '0'].w);
LCD_FillByColor(40, 262, 200, 290, UI0902_BG_COLOR);
x = (uint16_t)((240 - total_w) / 2);
for (i = 0; i < n; i++)
{
const ChargePctGlyph *g = &g_ChargePctDigits[digits[i] - '0'];
LCD_WR_PIC_Trans(x, y, g->w, g->h, g->data, BLACK);
x = (uint16_t)(x + g->w);
}
LCD_WR_PIC_Trans(x, y, g_ChargePctPercent.w, g_ChargePctPercent.h,
g_ChargePctPercent.data, BLACK);
}
else
{
/* 关机充电中拔掉:熄屏,允许下次再进充电页 */
LCD_BLK_Clr();
LCD_FillByColor(0, 0, 240, 320, BLACK);
BSP_MainPowerEnable(0);
s_charge_ui_drawn = false;
}
}
break;
case MSG_ID_EC_VOL:
{
/* 主音量已在 MainTask 下发;此处只刷新条 */
level = msg.HiByte;
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY);
ResetAutoPowerCount();
}
break;
}
}