From 6ce5d7a4532751357cde0978cc8d4cea66cdc440 Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Sat, 10 Oct 2026 17:24:16 +0800 Subject: [PATCH] fix(audio): hold mode entry until the sound board finishes init Dream power-up now overlaps the boot light show. Mode keys, the pick, and side keys stay ignored until MIDI config has been sent, so a fast tap cannot play before the board is ready. Co-authored-by: Cursor --- Global/Global.c | 29 ++++++++++++++++++++++++----- Global/Global.h | 3 ++- UI/UI_Idle.c | 10 ++++++++-- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Global/Global.c b/Global/Global.c index 47d9984..790e33d 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -111,7 +111,7 @@ int16_t MIC_VOL_MAP[11]= {-9000,-7000,-5000,-3000,-1000,1000,3000,5000,7000,9000 uint8_t TOUCH_AREA_NUM = (sizeof(Touch_Areas)/sizeof(Touch_AreaTypeDef)); -const uint8_t Version[3] = {0,2,49}; /* major.minor.patch — 0.2.49: 曲目默认 BPM;出厂项与关机记忆 */ +const uint8_t Version[3] = {0,2,50}; /* major.minor.patch — 0.2.50: 音源板未就绪前不进模式起奏 */ uint8_t Led = 8; bool PressFlag = 0; @@ -230,12 +230,17 @@ static void PowerOff_EmergencyReset(void) nvic_system_reset(); } +/* 音源板初始化完成前为 0。彩灯与上电并行,模式键在置 1 之前忽略 */ +static volatile uint8_t s_audio_bringup_req = 0; +static volatile uint8_t s_audio_ready = 0; + void System_PowerOn(void) { LOG_I("PWR", "power_on begin"); /* 软关机不复位 MCU:清掉上次会话演奏状态,默认当前调一级大和弦(C 调=do mi sol) */ StartFlag = 0; InModeFlag = false; /* 停在模式选择,禁止拨片/侧面键起奏 */ + s_audio_ready = 0; /* 弦音色、移调跨开关机保留。节奏/曲目/走向/段落/蓝牙/BPM 每次开机回默认 */ Session_ApplyPowerOnDefaults(); Accomp_ApplyDefaultIChord(); @@ -286,14 +291,19 @@ static void Power_QuiesceForCharge(const char *where) Power_LogRails(where); } -/* UI 播完开机彩灯后请求;由主循环执行,避免功放 I2C 堵死触摸 */ -static volatile uint8_t s_audio_bringup_req = 0; - +/* UI 在彩灯开始时请求;由主循环执行,避免功放 I2C 堵死触摸。 + * 彩灯约 1.1s 与音源板上电重叠。s_audio_ready 置位前不进演奏模式。 */ void System_RequestAudioBringUp(void) { + s_audio_ready = 0; s_audio_bringup_req = 1; } +uint8_t Audio_IsReady(void) +{ + return s_audio_ready; +} + /* 低于等于 6.8V:充电画面亮 10s 后关屏,充电继续 */ #define CHARGE_BL_LOW_MS 10000u static uint32_t s_charge_bl_off_at = 0; @@ -387,6 +397,9 @@ void System_AudioBringUp_Poll(void) return; MasterVolume_Reapply(); LoadConfig(); + if (!powon) + return; + s_audio_ready = 1; MainTask_Sendmsg(MSG_ID_EC_VOL, app_adc_get_volume(), level, 0); LOG_I("PWR", "periph ready + BT UART recv started"); } @@ -402,6 +415,7 @@ static void PowerOff(void) LOG_I("PWR", "power_off begin"); powon = false; /* 更新关机标志 */ + s_audio_ready = 0; InModeFlag = false; /* 软关机后勿残留进模式,避免再开机模式选择页拨片起奏 */ s_pwr_off_grace_ms = 0u; /* 主路径已接管,取消紧急倒计时 */ StopFullTask(); @@ -1046,7 +1060,7 @@ void ADC_IN1_KEY_Handle(uint8_t key,bool on) /* 侧面键按压/释放均为用户操作 */ ResetAutoPowerCount(); /* 模式选择页:侧面键不得起奏 */ - if (!InModeFlag) + if (!InModeFlag || !Audio_IsReady()) return; /* 万能:前奏/间奏/尾奏/断奏无响应(含 App 06 指令) */ if (mGuiData[GUI_TAB_INDEX].Current == 0) @@ -1697,6 +1711,11 @@ void Pick_Handle() LOG_I("pick", "abort: not in mode"); return; } + if (!Audio_IsReady()) + { + LOG_I("pick", "abort: audio not ready"); + return; + } /* 空库/加载失败时禁止起奏:否则 TMR6 ISR 内 AutoBand 可能 HardFault, * LCD 卡死且主循环 Power_Key_Scan 不再跑 → 只能 RESET */ diff --git a/Global/Global.h b/Global/Global.h index b592edb..6a76a6d 100644 --- a/Global/Global.h +++ b/Global/Global.h @@ -180,9 +180,10 @@ void Power_Key_ConsumePress(void); void PowerOff_CutRails(void); void AutoPowerOff_Scan(void); void System_PowerOn(void); -/* Logo 与开机彩灯结束后再开 12V / Dream / 功放(主循环执行,不堵 UI) */ +/* 彩灯一开始就请求上电;主循环执行,不堵 UI。未就绪前禁止进模式起奏 */ void System_RequestAudioBringUp(void); void System_AudioBringUp_Poll(void); +uint8_t Audio_IsReady(void); void Power_ChargeIdle_LogPoll(void); /* 高于 6.8V:充电页背光保持;低于等于 6.8V:亮 10s 后关屏。拔电时复位倒计时。 */ void Power_ChargeBacklightSteady(void); diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index 8c38071..97e24b7 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -140,6 +140,12 @@ void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex) UI_StatusBar_ToggleBluetooth(); return; } + /* 音源板初始化要到秒级。没就绪就进模式,LoadConfig/拨片会打出不对的声音 */ + if (!Audio_IsReady()) + { + LOG_I("UI", "mode enter deferred: audio not ready"); + return; + } StartTask(); /* ID 为 TAB 索引:0=万能(Song) 1=专业(Expert) 2=普通(Free) */ mGuiData[GUI_TAB_INDEX].Current = ID; @@ -181,7 +187,8 @@ void IdleProcess(DisplayTaskMessage_Type msg) LCD_WR_REG(0x29); /* Display ON */ s_charge_ui_drawn = false; LCD_BLK_Set(); - /* 彩灯期间必须停在 Logo。此阶段 12V/Dream/功放尚未打开 */ + /* 彩灯与音源板上电并行。主循环初始化期间模式键先忽略 */ + System_RequestAudioBringUp(); LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_BOOT_LOGO_W, UI0902_BOOT_LOGO_H, UI0902_BOOT_LOGO_ADDR); UI_BootLedShow(); @@ -190,7 +197,6 @@ void IdleProcess(DisplayTaskMessage_Type msg) /* 先启动触摸再返回,功放初始化改到主循环,避免 UI 堵在 I2C 里点击无响应 */ StartTouchTask(); StartScanTask(); - System_RequestAudioBringUp(); Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY); break;