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 <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-10-10 17:24:16 +08:00
parent cb6c2da5ce
commit 6ce5d7a453
3 changed files with 34 additions and 8 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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;