fix: keep power key alive on hang; refuse play when tone pack missing
TMR7 high-prio watchdog and fault-loop emergency cut/reset so soft-off still works if the main loop or AutoBand ISR dies; skip start when preset load fails. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
f8aeb4fb7c
commit
d06e44bcb3
|
|
@ -142,6 +142,11 @@ void app_log_write(char level, const char *cat, const char *fmt, ...)
|
|||
va_list ap;
|
||||
int n;
|
||||
|
||||
/* TMR6 1ms ISR 会经 AutoBand NoteOn 回调进来:禁止在中断里 take mutex / 打 RTT */
|
||||
if (rt_interrupt_get_nest() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == 'D' && s_debug_level != 'D') {
|
||||
return;
|
||||
}
|
||||
|
|
@ -387,7 +392,7 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
UI_ApplyToneAddress();
|
||||
AutoBandTop1_Stop();
|
||||
StartFlag = 0;
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(0);
|
||||
ret = App_Auto_LoadPresetFromFlash(0);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE_LOCAL ret=%d addr=0x%08lX map=BIN2@0x%08lX name=%s count=%d %s\n",
|
||||
ret, (unsigned long)ADDRESS,
|
||||
|
|
@ -416,7 +421,7 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
if (count > 0 && (int)idx >= count)
|
||||
idx = (unsigned)(count - 1);
|
||||
ParamGuiData[SONG_MODE_PARAM].Current = (uint8_t)idx;
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash((int)idx);
|
||||
ret = App_Auto_LoadPresetFromFlash((int)idx);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE_BIN1 ret=%d idx=%u addr=0x%08lX map=BIN1@0x%08lX name=%s count=%d %s\n",
|
||||
ret, idx, (unsigned long)ADDRESS,
|
||||
|
|
@ -445,7 +450,7 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
if (count > 0 && (int)idx >= count)
|
||||
idx = (unsigned)(count - 1);
|
||||
ParamGuiData[EXPRESS_MODE_PARAM].Current = (uint8_t)idx;
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash((int)idx);
|
||||
ret = App_Auto_LoadPresetFromFlash((int)idx);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE_BIN2 ret=%d idx=%u addr=0x%08lX map=BIN2@0x%08lX name=%s count=%d %s\n",
|
||||
ret, idx, (unsigned long)ADDRESS,
|
||||
|
|
@ -474,7 +479,7 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
if (count > 0 && (int)idx >= count)
|
||||
idx = (unsigned)(count - 1);
|
||||
ParamGuiData[ALL_MODE_PARAM].Current = (uint8_t)idx;
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash((int)idx);
|
||||
ret = App_Auto_LoadPresetFromFlash((int)idx);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE_BIN3 ret=%d idx=%u addr=0x%08lX map=BIN3@0x%08lX name=%s count=%d %s\n",
|
||||
ret, idx, (unsigned long)ADDRESS,
|
||||
|
|
@ -502,7 +507,7 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
UI_ApplyToneAddress();
|
||||
AutoBandTop1_Stop();
|
||||
StartFlag = 0;
|
||||
(void)AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
(void)App_Auto_LoadPresetFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
KEY_ID_1629 = 0;
|
||||
PressFlag = 0;
|
||||
Pick_Handle();
|
||||
|
|
|
|||
134
Global/Global.c
134
Global/Global.c
|
|
@ -101,7 +101,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,10}; /* major.minor.patch — 0.2.10: tone 0914 (BIN3 after 2.bin); autoclose label 关闭 */
|
||||
const uint8_t Version[3] = {0,2,11}; /* major.minor.patch — 0.2.11: power-key watchdog + refuse play on bad tone pack */
|
||||
|
||||
uint8_t Led = 8;
|
||||
bool PressFlag = 0;
|
||||
|
|
@ -159,8 +159,9 @@ void BLTask_Sendmsg(uint16_t ID, uint16_t ID2, uint16_t HiByte, uint16_t LoByte)
|
|||
|
||||
#define KEY_PRESS_LEVEL RESET
|
||||
|
||||
#define PWR_ON_HOLD_MS 3000 /* 关机态长按 3s → 开机 */
|
||||
#define PWR_OFF_HOLD_MS 2000 /* 开机态长按 2s → 关机 */
|
||||
#define PWR_ON_HOLD_MS 3000 /* 关机态长按 3s → 开机 */
|
||||
#define PWR_OFF_HOLD_MS 2000 /* 开机态长按 2s → 关机 */
|
||||
#define PWR_OFF_GRACE_MS 1500 /* 请求优雅关机后,超时仍未切轨则紧急断电+复位 */
|
||||
|
||||
|
||||
typedef enum
|
||||
|
|
@ -176,10 +177,37 @@ static uint32_t pwr_press_tick = 0;
|
|||
/* 当前开关机状态(UI_Idle.c 等 extern 引用) */
|
||||
bool powon = false;
|
||||
|
||||
/* 电源轨是否已切断(优雅关机与紧急关机共用;ISR 依此判断是否还需强切) */
|
||||
static volatile uint8_t s_pwr_rails_cut = 0;
|
||||
/* TMR7:关机长按已触发请求后的紧急倒计时(ms) */
|
||||
static volatile uint16_t s_pwr_off_grace_ms = 0;
|
||||
|
||||
/* ==================== 开机/关机动作 ==================== */
|
||||
|
||||
/* 仅 GPIO/背光:可在 ISR / HardFault 中调用,禁止 RTOS/Flash/日志 */
|
||||
void PowerOff_CutRails(void)
|
||||
{
|
||||
s_pwr_rails_cut = 1u;
|
||||
powon = false;
|
||||
LCD_BLK_Clr();
|
||||
BSP_MainPowerEnable(0);
|
||||
BSP_DreamCorePowerEnable(0);
|
||||
BSP_HT7178PowerEnable(0);
|
||||
BSP_BlueToothPowerEnable(0);
|
||||
}
|
||||
|
||||
static void PowerOff_EmergencyReset(void)
|
||||
{
|
||||
PowerOff_CutRails();
|
||||
/* 主循环已死时无法画充电页:复位后按 USB 状态进充电/待机 */
|
||||
nvic_system_reset();
|
||||
}
|
||||
|
||||
void System_PowerOn(void)
|
||||
{
|
||||
LOG_I("PWR", "power_on begin");
|
||||
s_pwr_rails_cut = 0u;
|
||||
s_pwr_off_grace_ms = 0u;
|
||||
/* 控制电源硬件;蓝牙按 NVM/系统设置开关恢复,勿强制常开 */
|
||||
BSP_MainPowerEnable(1);
|
||||
BSP_DreamCorePowerEnable(1);
|
||||
|
|
@ -213,6 +241,7 @@ static void PowerOff(void)
|
|||
|
||||
LOG_I("PWR", "power_off begin");
|
||||
powon = false; /* 更新关机标志 */
|
||||
s_pwr_off_grace_ms = 0u; /* 主路径已接管,取消紧急倒计时 */
|
||||
StopFullTask();
|
||||
|
||||
/* 关机前把当前调音台推子与蓝牙开关写入 NVM,保证再次开机保持 */
|
||||
|
|
@ -234,13 +263,9 @@ static void PowerOff(void)
|
|||
app_tm1629_all_off();
|
||||
|
||||
app_tm1617_off();
|
||||
/* 关掉主电源/音源/功放/蓝牙;MCU 仍跑以便长按开机与 Type-C 检测 */
|
||||
BSP_MainPowerEnable(0);
|
||||
BSP_DreamCorePowerEnable(0);
|
||||
BSP_HT7178PowerEnable(0);
|
||||
/* BT 最后关:给已排队的 UART4 ACK(如 05 00)留出模组转发窗口 */
|
||||
/* BT 先留窗口转发已排队 ACK,再切全部电源轨 */
|
||||
rt_thread_mdelay(30);
|
||||
BSP_BlueToothPowerEnable(0);
|
||||
PowerOff_CutRails();
|
||||
CurrUIProcress = IdleProcess;
|
||||
MainTask_Sendmsg(MSG_ID_POWER_OFF, 0, 0, 0);
|
||||
LOG_I("PWR", "power_off done (soft-off)");
|
||||
|
|
@ -271,6 +296,9 @@ static volatile uint8_t s_sys_poweroff_req = 0;
|
|||
void System_RequestPowerOff(void)
|
||||
{
|
||||
s_sys_poweroff_req = 1;
|
||||
/* 主循环若已卡死:TMR7 紧急倒计时仍会强切电源 */
|
||||
if (s_pwr_off_grace_ms == 0u && !s_pwr_rails_cut)
|
||||
s_pwr_off_grace_ms = PWR_OFF_GRACE_MS;
|
||||
}
|
||||
void System_PowerOff_Poll(void)
|
||||
{
|
||||
|
|
@ -282,6 +310,77 @@ void System_PowerOff_Poll(void)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TMR7 1ms(优先级高于伴奏 TMR6):与主循环解耦的关机键扫描。
|
||||
* 正常:请求优雅关机;超时未切轨 → 紧急断电并复位。
|
||||
*/
|
||||
void Power_Key_IsrTick(void)
|
||||
{
|
||||
static uint16_t isr_hold_ms = 0;
|
||||
static uint8_t isr_fired = 0;
|
||||
flag_status st = BSP_GetPowerKey();
|
||||
|
||||
if (st == KEY_PRESS_LEVEL)
|
||||
{
|
||||
if (isr_hold_ms < 60000u)
|
||||
isr_hold_ms++;
|
||||
}
|
||||
else
|
||||
{
|
||||
isr_hold_ms = 0;
|
||||
isr_fired = 0;
|
||||
}
|
||||
|
||||
/* 仅处理「开机态关机」;开机仍由主循环负责(需完整外设初始化) */
|
||||
if (powon && !isr_fired && isr_hold_ms >= PWR_OFF_HOLD_MS)
|
||||
{
|
||||
isr_fired = 1;
|
||||
System_RequestPowerOff();
|
||||
}
|
||||
|
||||
if (s_pwr_off_grace_ms > 0u)
|
||||
{
|
||||
s_pwr_off_grace_ms--;
|
||||
if (s_pwr_off_grace_ms == 0u && !s_pwr_rails_cut)
|
||||
PowerOff_EmergencyReset();
|
||||
}
|
||||
}
|
||||
|
||||
/* HardFault / MemManage / BusFault / UsageFault:死循环中仍可长按关机 */
|
||||
void Power_Key_FaultLoop(void)
|
||||
{
|
||||
uint32_t hold = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (BSP_GetPowerKey() == KEY_PRESS_LEVEL)
|
||||
{
|
||||
hold++;
|
||||
if (hold >= PWR_OFF_HOLD_MS)
|
||||
{
|
||||
PowerOff_EmergencyReset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hold = 0;
|
||||
}
|
||||
Delay_us(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t Power_HardFault_Hook(void *context)
|
||||
{
|
||||
(void)context;
|
||||
Power_Key_FaultLoop();
|
||||
return -RT_ERROR; /* 不可达 */
|
||||
}
|
||||
|
||||
void Power_Key_WatchdogInit(void)
|
||||
{
|
||||
rt_hw_exception_install(Power_HardFault_Hook);
|
||||
wk_tmr7_pwrkey_init();
|
||||
}
|
||||
|
||||
void Power_Key_Scan()
|
||||
{
|
||||
flag_status status = BSP_GetPowerKey();
|
||||
|
|
@ -340,19 +439,13 @@ void Power_Key_Scan()
|
|||
}
|
||||
holdtick = now - pwr_press_tick;
|
||||
|
||||
/* 用 powon 区分:关机长按 3s 开机,开机长按 2s 关机 */
|
||||
/* 关机长按 3s 开机;开机态关机改由 TMR7 ISR(主循环卡死仍可关) */
|
||||
if(powon == false && holdtick >= PWR_ON_HOLD_MS)
|
||||
{
|
||||
LOG_I("PWR", "key power_on hold=%u", (unsigned)holdtick);
|
||||
PowerOn();
|
||||
pwr_key_state = KEY_STATE_NONE;
|
||||
}
|
||||
else if(powon == true && holdtick >= PWR_OFF_HOLD_MS)
|
||||
{
|
||||
LOG_I("PWR", "key power_off hold=%u", (unsigned)holdtick);
|
||||
PowerOff();
|
||||
pwr_key_state = KEY_STATE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_STATE_NONE:
|
||||
|
|
@ -814,6 +907,15 @@ void Pick_Handle()
|
|||
uint8_t note_cnt = 0;
|
||||
uint8_t chord_id = KEY_ID_1629;
|
||||
|
||||
/* 空库/加载失败时禁止起奏:否则 TMR6 ISR 内 AutoBand 可能 HardFault,
|
||||
* LCD 卡死且主循环 Power_Key_Scan 不再跑 → 只能 RESET */
|
||||
if (!App_Auto_IsPresetReady())
|
||||
{
|
||||
LOG_E("pick", "abort: preset not ready tab=%u addr=0x%08X",
|
||||
(unsigned)mGuiData[GUI_TAB_INDEX].Current, (unsigned)ADDRESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏;
|
||||
* 普通模式除外——必须左手按住指板再拨,不做一级兜底 */
|
||||
if (mGuiData[GUI_TAB_INDEX].Current != 2 &&
|
||||
|
|
|
|||
|
|
@ -166,6 +166,10 @@ extern uint8_t KEY_ID_1629;
|
|||
|
||||
extern bool powon;
|
||||
void Power_Key_Scan(void);
|
||||
void Power_Key_IsrTick(void);
|
||||
void Power_Key_FaultLoop(void);
|
||||
void Power_Key_WatchdogInit(void);
|
||||
void PowerOff_CutRails(void);
|
||||
void AutoPowerOff_Scan(void);
|
||||
void System_PowerOn(void);
|
||||
void System_RequestPowerOff(void);
|
||||
|
|
|
|||
|
|
@ -416,6 +416,31 @@ static const char *ToneFlashMapBank(uint32_t abs)
|
|||
|
||||
static uint32_t s_flash_rd_last_base = 0xFFFFFFFFu;
|
||||
static uint16_t s_flash_rd_log_cnt = 0;
|
||||
/* 最近一次 LoadPreset 是否成功;失败时禁止拨片起奏(防空库 + TMR6 ISR 崩) */
|
||||
static volatile uint8_t s_preset_ready = 0;
|
||||
|
||||
int App_Auto_LoadPresetFromFlash(int presetIndex)
|
||||
{
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(presetIndex);
|
||||
if (ret == 0)
|
||||
{
|
||||
const char *name = AutoBandTop1_GetPresetName();
|
||||
int count = AutoBandTop1_GetPresetItemCount();
|
||||
s_preset_ready = (count > 0 && name != NULL && name[0] != '\0') ? 1u : 0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_preset_ready = 0u;
|
||||
AutoBandTop1_Stop();
|
||||
StartFlag = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t App_Auto_IsPresetReady(void)
|
||||
{
|
||||
return s_preset_ready;
|
||||
}
|
||||
|
||||
static int Func_CallBack_ReadFlash(int address,int length,uint8_t* pOutput)
|
||||
{
|
||||
|
|
@ -468,7 +493,7 @@ void App_Auto_Init(void)
|
|||
AutoBandTop1_RegisterReadFlashCallback(Func_CallBack_ReadFlash);
|
||||
m_presetCount = AutoBandTop1_GetPresetItemCount();
|
||||
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(0);
|
||||
int ret = App_Auto_LoadPresetFromFlash(0);
|
||||
if (ret != 0)
|
||||
{
|
||||
uint8_t hdr[16];
|
||||
|
|
|
|||
|
|
@ -8,9 +8,14 @@
|
|||
#ifndef APP_AUTO_H_
|
||||
#define APP_AUTO_H_
|
||||
#include "mymidififo1.h"
|
||||
#include <stdint.h>
|
||||
|
||||
extern void App_Auto_Init(void);
|
||||
|
||||
/* 统一加载入口:记录成功/失败,失败时 Stop,避免空库起奏进 ISR 崩溃 */
|
||||
int App_Auto_LoadPresetFromFlash(int presetIndex);
|
||||
uint8_t App_Auto_IsPresetReady(void);
|
||||
|
||||
extern MidiFifoSeq_t m_MidiSendFifo;
|
||||
|
||||
#endif /* APP_AUTO_H_ */
|
||||
|
|
|
|||
|
|
@ -180,11 +180,11 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
UI_ApplyToneAddress();
|
||||
int ret = 0;
|
||||
if (tab == 0)
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
else if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[EXPRESS_MODE_PARAM].Current);
|
||||
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[EXPRESS_MODE_PARAM].Current);
|
||||
else
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
ret = App_Auto_LoadPresetFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
if (ret != 0)
|
||||
LOG_E("tone", "load preset failed tab=%d sw=%d ret=%d addr=0x%08X",
|
||||
tab, mGuiData[GUI_AUTOBAND_SW].Current, ret, (unsigned)ADDRESS);
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ void UI_ReloadTonePreset(void)
|
|||
/* 万能:和弦走向 */
|
||||
if (mGuiData[GUI_TAB_INDEX].Current == 0)
|
||||
{
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
int ret = App_Auto_LoadPresetFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
if (ret != 0)
|
||||
{
|
||||
uint8_t hdr[16];
|
||||
|
|
@ -197,7 +197,7 @@ void UI_ReloadTonePreset(void)
|
|||
local->Max = (LOCAL_SONG_COUNT > 0) ? (uint16_t)(LOCAL_SONG_COUNT - 1) : 0;
|
||||
if (local->Current > local->Max)
|
||||
local->Current = local->Max;
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(local->Current);
|
||||
int ret = App_Auto_LoadPresetFromFlash(local->Current);
|
||||
if (ret != 0)
|
||||
LOG_E("tone", "load local song idx=%d failed ret=%d addr=0x%08X map=BIN2@0x%08X",
|
||||
local->Current, ret, (unsigned)ADDRESS,
|
||||
|
|
@ -217,7 +217,7 @@ void UI_ReloadTonePreset(void)
|
|||
return;
|
||||
}
|
||||
{
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
int ret = App_Auto_LoadPresetFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
LOG_I("tone", "load rhythm idx=%d ret=%d name=%s addr=0x%08X map=BIN1@0x%08X %s",
|
||||
ParamGuiData[SONG_MODE_PARAM].Current, ret,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ void wk_tmr6_1ms_init(void);
|
|||
void wk_tmr6_1ms_tick(void);
|
||||
uint32_t wk_tmr6_tick_get(void);
|
||||
|
||||
/* TMR7 1ms:关机键看门狗(优先级高于 TMR6,主循环卡死仍可关) */
|
||||
void wk_tmr7_pwrkey_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@
|
|||
|
||||
/* private includes ----------------------------------------------------------*/
|
||||
/* add user code begin private includes */
|
||||
|
||||
/* 关机键看门狗:与 Global.c 解耦声明,避免 int.c 拉全量 includes */
|
||||
void Power_Key_IsrTick(void);
|
||||
void Power_Key_FaultLoop(void);
|
||||
/* add user code end private includes */
|
||||
|
||||
/* private typedef -----------------------------------------------------------*/
|
||||
|
|
@ -110,16 +112,7 @@ void NMI_Handler(void)
|
|||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* add user code begin MemoryManagement_IRQ 0 */
|
||||
|
||||
/* add user code end MemoryManagement_IRQ 0 */
|
||||
/* go to infinite loop when memory manage exception occurs */
|
||||
while (1)
|
||||
{
|
||||
/* add user code begin W1_MemoryManagement_IRQ 0 */
|
||||
|
||||
/* add user code end W1_MemoryManagement_IRQ 0 */
|
||||
}
|
||||
Power_Key_FaultLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -129,16 +122,7 @@ void MemManage_Handler(void)
|
|||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* add user code begin BusFault_IRQ 0 */
|
||||
|
||||
/* add user code end BusFault_IRQ 0 */
|
||||
/* go to infinite loop when bus fault exception occurs */
|
||||
while (1)
|
||||
{
|
||||
/* add user code begin W1_BusFault_IRQ 0 */
|
||||
|
||||
/* add user code end W1_BusFault_IRQ 0 */
|
||||
}
|
||||
Power_Key_FaultLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -148,16 +132,7 @@ void BusFault_Handler(void)
|
|||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* add user code begin UsageFault_IRQ 0 */
|
||||
|
||||
/* add user code end UsageFault_IRQ 0 */
|
||||
/* go to infinite loop when usage fault exception occurs */
|
||||
while (1)
|
||||
{
|
||||
/* add user code begin W1_UsageFault_IRQ 0 */
|
||||
|
||||
/* add user code end W1_UsageFault_IRQ 0 */
|
||||
}
|
||||
Power_Key_FaultLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -241,6 +216,15 @@ void TMR6_GLOBAL_IRQHandler(void)
|
|||
//rt_os_tick_callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TMR7:关机键看门狗(先于伴奏 TMR6 响应,主循环死锁仍可关)
|
||||
*/
|
||||
void TMR7_GLOBAL_IRQHandler(void)
|
||||
{
|
||||
tmr_flag_clear(TMR7, TMR_OVF_FLAG);
|
||||
Power_Key_IsrTick();
|
||||
}
|
||||
|
||||
/* add user code begin 1 */
|
||||
|
||||
/* add user code end 1 */
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ int main(void)
|
|||
drv_nvm_init();
|
||||
TaskInit();
|
||||
timer_init();
|
||||
/* 关机键看门狗:TMR7 + HardFault hook,与主循环/伴奏 ISR 解耦 */
|
||||
Power_Key_WatchdogInit();
|
||||
InitMenuUI();
|
||||
BSP_HT7178PowerEnable (1);
|
||||
BSP_ChargerEnable(1);
|
||||
|
|
|
|||
|
|
@ -174,3 +174,16 @@ void wk_tmr6_1ms_init(void)
|
|||
tmr_counter_enable(TMR6, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TMR7 1ms:仅扫关机键(抢占优先级 1,高于 TMR6=5 / 伴奏库)
|
||||
*/
|
||||
void wk_tmr7_pwrkey_init(void)
|
||||
{
|
||||
crm_periph_clock_enable(CRM_TMR7_PERIPH_CLOCK, TRUE);
|
||||
tmr_base_init(TMR7, 999, 239);
|
||||
tmr_flag_clear(TMR7, TMR_OVF_FLAG);
|
||||
tmr_interrupt_enable(TMR7, TMR_OVF_INT, TRUE);
|
||||
nvic_irq_enable(TMR7_GLOBAL_IRQn, 1, 0);
|
||||
tmr_counter_enable(TMR7, TRUE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ TONE_HDR = PROJ / "project" / "inc" / "ExtFlash_Tone_Addr.h"
|
|||
IAP_DIR = REPO / "升级" / "MCU主控升级"
|
||||
OUT_ROOT = REPO / "tools" / "out"
|
||||
|
||||
FW_VER = "0.2.10"
|
||||
FW_VER = "0.2.11"
|
||||
UI0902_RES_BASE = 0x00100000
|
||||
BOOT_FLASH_ADDR = 0x08000000
|
||||
APP_FLASH_ADDR = 0x08008000
|
||||
|
|
@ -135,12 +135,11 @@ def main() -> None:
|
|||
raise SystemExit(f"missing Boot bin: {BOOT_BIN}")
|
||||
if not EXE_BIN.is_file():
|
||||
raise SystemExit(f"missing MCU bin: {EXE_BIN}")
|
||||
if not TONE_BIN.is_file():
|
||||
# fallback legacy alias written by packer
|
||||
tone_bin = TONE_BIN
|
||||
if not tone_bin.is_file():
|
||||
legacy = PROJ / "tools" / "out" / "extflash_tone_0903.bin"
|
||||
if legacy.is_file():
|
||||
global TONE_BIN
|
||||
TONE_BIN = legacy
|
||||
tone_bin = legacy
|
||||
else:
|
||||
raise SystemExit(f"missing tone pack: {TONE_BIN} (run pack_extflash_tone_0903.py)")
|
||||
if not UI0902_BIN.is_file():
|
||||
|
|
@ -165,7 +164,7 @@ def main() -> None:
|
|||
shutil.rmtree(pkg)
|
||||
pkg.mkdir(parents=True)
|
||||
|
||||
tone_data = TONE_BIN.read_bytes()
|
||||
tone_data = tone_bin.read_bytes()
|
||||
verify_tone_layout(tone_data)
|
||||
ui_data = UI0902_BIN.read_bytes()
|
||||
if len(ui_data) < 1024:
|
||||
|
|
|
|||
Loading…
Reference in New Issue