Release 0.2.3: fix local song HKTK load/play and keep tone map logs.
Use 41KB preset buffer with compressed 2.bin, expert/normal StartWithNote path, Flash Map address logs, and ship flash-mode/hub assets plus flash helpers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c4852aca5d
commit
4544f8706a
128
APP/app_log.c
128
APP/app_log.c
|
|
@ -14,13 +14,15 @@ static char s_debug_level = 'D';
|
|||
static char s_cmd_buf[48];
|
||||
static uint8_t s_cmd_len;
|
||||
|
||||
/* RTT 二进制烧录:将 ui0902_res.bin 写到 W25Q128 @ UI0902_RES_BASE */
|
||||
/* RTT 二进制烧录:写到 W25Q128(ui0902 或本地曲目) */
|
||||
static uint8_t s_flash_mode;
|
||||
static uint32_t s_flash_base;
|
||||
static uint32_t s_flash_addr;
|
||||
static uint32_t s_flash_remain;
|
||||
static uint32_t s_flash_last_sector;
|
||||
static uint16_t s_flash_page_len;
|
||||
static uint8_t s_flash_page[256];
|
||||
static char s_flash_ok_tag[24];
|
||||
|
||||
uint8_t app_log_flash_busy(void)
|
||||
{
|
||||
|
|
@ -61,7 +63,7 @@ static void app_log_flash_feed(const uint8_t *data, unsigned len)
|
|||
unsigned i;
|
||||
|
||||
for (i = 0; i < len && s_flash_remain > 0U; i++) {
|
||||
if (s_flash_page_len == 0U && s_flash_addr == UI0902_RES_BASE && i == 0U) {
|
||||
if (s_flash_page_len == 0U && s_flash_addr == s_flash_base && i == 0U) {
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "FLASH_RX\n");
|
||||
}
|
||||
s_flash_page[s_flash_page_len++] = data[i];
|
||||
|
|
@ -73,34 +75,42 @@ static void app_log_flash_feed(const uint8_t *data, unsigned len)
|
|||
|
||||
if (s_flash_remain == 0U && s_flash_mode) {
|
||||
s_flash_mode = 0U;
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "FLASH_UI0902_OK\n");
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, s_flash_ok_tag);
|
||||
UI_DrawModeSelectScreen();
|
||||
}
|
||||
}
|
||||
|
||||
static void app_log_flash_start(uint32_t size)
|
||||
static void app_log_flash_start_at(uint32_t base, uint32_t size, const char *go_tag, const char *ok_tag)
|
||||
{
|
||||
char msg[64];
|
||||
char msg[80];
|
||||
|
||||
if (size == 0U || size > (2U * 1024U * 1024U)) {
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "FLASH_UI0902_ERR size\n");
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "FLASH_ERR size\n");
|
||||
return;
|
||||
}
|
||||
|
||||
s_flash_mode = 1U;
|
||||
s_flash_addr = UI0902_RES_BASE;
|
||||
s_flash_base = base;
|
||||
s_flash_addr = base;
|
||||
s_flash_remain = size;
|
||||
s_flash_last_sector = 0xFFFFFFFFUL;
|
||||
s_flash_page_len = 0U;
|
||||
s_cmd_len = 0U;
|
||||
s_cmd_buf[0] = '\0';
|
||||
strncpy(s_flash_ok_tag, ok_tag, sizeof(s_flash_ok_tag) - 1U);
|
||||
s_flash_ok_tag[sizeof(s_flash_ok_tag) - 1U] = '\0';
|
||||
|
||||
snprintf(msg, sizeof(msg),
|
||||
"FLASH_UI0902_GO base=0x%08lX size=%lu\n",
|
||||
(unsigned long)UI0902_RES_BASE, (unsigned long)size);
|
||||
"%s base=0x%08lX size=%lu\n",
|
||||
go_tag, (unsigned long)base, (unsigned long)size);
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, msg);
|
||||
}
|
||||
|
||||
static void app_log_flash_start(uint32_t size)
|
||||
{
|
||||
app_log_flash_start_at(UI0902_RES_BASE, size, "FLASH_UI0902_GO", "FLASH_UI0902_OK\n");
|
||||
}
|
||||
|
||||
static void app_log_slot_store(const char *line)
|
||||
{
|
||||
uint16_t idx = s_head;
|
||||
|
|
@ -264,6 +274,106 @@ uint8_t app_log_try_command(const char *cmd)
|
|||
app_log_flash_start(size);
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "flash haitian ", 14) == 0) {
|
||||
uint32_t size = (uint32_t)strtoul(cmd + 14, NULL, 10);
|
||||
app_log_flash_start_at(FLASH_ADDR_SONG_HAITIAN, size,
|
||||
"FLASH_HAITIAN_GO", "FLASH_HAITIAN_OK\n");
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "tone status", 11) == 0) {
|
||||
uint8_t hdr[16];
|
||||
uint8_t name[40];
|
||||
uint8_t cur_hdr[16];
|
||||
char *pname;
|
||||
char line[192];
|
||||
const char *map;
|
||||
W25Q128_Read(hdr, FLASH_ADDR_SONG_HAITIAN, 16);
|
||||
W25Q128_Read(name, FLASH_ADDR_SONG_HAITIAN + 1280 + 4, 32);
|
||||
name[32] = 0;
|
||||
W25Q128_Read(cur_hdr, (uint32_t)ADDRESS, 16);
|
||||
pname = AutoBandTop1_GetPresetName();
|
||||
if (ADDRESS == EXTFLASH_BIN1_RHYTHM_ADDR)
|
||||
map = "BIN1_RHYTHM";
|
||||
else if (ADDRESS == EXTFLASH_BIN2_SONG_HAITIAN_ADDR)
|
||||
map = "BIN2_SONG_HAITIAN";
|
||||
else if (ADDRESS == EXTFLASH_BIN3_UNIVERSAL_ADDR)
|
||||
map = "BIN3_UNIVERSAL";
|
||||
else
|
||||
map = "UNKNOWN";
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE tab=%u sw=%u addr=0x%08lX map=%s songidx=%u rhyt=%u\n",
|
||||
(unsigned)mGuiData[GUI_TAB_INDEX].Current,
|
||||
(unsigned)mGuiData[GUI_AUTOBAND_SW].Current,
|
||||
(unsigned long)ADDRESS, map,
|
||||
(unsigned)ParamGuiData[EXPRESS_MODE_PARAM].Current,
|
||||
(unsigned)ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE map BIN1=0x%08lX BIN2=0x%08lX BIN3=0x%08lX\n",
|
||||
(unsigned long)EXTFLASH_BIN1_RHYTHM_ADDR,
|
||||
(unsigned long)EXTFLASH_BIN2_SONG_HAITIAN_ADDR,
|
||||
(unsigned long)EXTFLASH_BIN3_UNIVERSAL_ADDR);
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE @ADDRESS magic=%02X%02X%02X%02X cnt=%lu\n",
|
||||
cur_hdr[0], cur_hdr[1], cur_hdr[2], cur_hdr[3],
|
||||
(unsigned long)(cur_hdr[12] | (cur_hdr[13] << 8) |
|
||||
(cur_hdr[14] << 16) | (cur_hdr[15] << 24)));
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE @BIN2 magic=%02X%02X%02X%02X max=%lu cnt=%lu name=%.16s\n",
|
||||
hdr[0], hdr[1], hdr[2], hdr[3],
|
||||
(unsigned long)(hdr[8] | (hdr[9] << 8) | (hdr[10] << 16) | (hdr[11] << 24)),
|
||||
(unsigned long)(hdr[12] | (hdr[13] << 8) | (hdr[14] << 16) | (hdr[15] << 24)),
|
||||
(char *)name);
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE loaded name=%s count=%d\n",
|
||||
pname ? pname : "(null)",
|
||||
AutoBandTop1_GetPresetItemCount());
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "tone reload", 11) == 0) {
|
||||
char line[96];
|
||||
UI_ReloadTonePreset();
|
||||
snprintf(line, sizeof(line),
|
||||
"TONE_RELOAD addr=0x%08lX name=%s\n",
|
||||
(unsigned long)ADDRESS,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "(null)");
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "tone local", 10) == 0) {
|
||||
char line[128];
|
||||
int ret;
|
||||
mGuiData[GUI_TAB_INDEX].Current = 1; /* 专业 */
|
||||
mGuiData[GUI_AUTOBAND_SW].Current = 1; /* 本地曲目 */
|
||||
ParamGuiData[EXPRESS_MODE_PARAM].Current = 0;
|
||||
UI_ApplyToneAddress();
|
||||
AutoBandTop1_Stop();
|
||||
StartFlag = 0;
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(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,
|
||||
(unsigned long)EXTFLASH_BIN2_SONG_HAITIAN_ADDR,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "(null)",
|
||||
AutoBandTop1_GetPresetItemCount(),
|
||||
(ADDRESS == EXTFLASH_BIN2_SONG_HAITIAN_ADDR) ? "OK" : "MISMATCH");
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, line);
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "tone pick", 9) == 0) {
|
||||
/* 模拟专业+本地曲目拨片(无和弦板) */
|
||||
mGuiData[GUI_TAB_INDEX].Current = 1;
|
||||
mGuiData[GUI_AUTOBAND_SW].Current = 1;
|
||||
KEY_ID_1629 = 0; /* 走默认和弦兜底 */
|
||||
StartFlag = 0;
|
||||
Pick_Handle();
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "TONE_PICK_DONE\n");
|
||||
return 1U;
|
||||
}
|
||||
if (strncmp(cmd, "flash erase chip", 16) == 0) {
|
||||
SEGGER_RTT_WriteString(APP_LOG_RTT_CHANNEL, "FLASH_ERASE_BEGIN\n");
|
||||
LOG_I("FLASH", "W25Q128 chip erase start");
|
||||
|
|
|
|||
|
|
@ -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,2}; /* major.minor.patch — 0.2.2: BT persist, settings icon focus, auto-off UI */
|
||||
const uint8_t Version[3] = {0,2,3}; /* major.minor.patch — 0.2.3: local song HKTK load/play + tone addr logs */
|
||||
|
||||
uint8_t Led = 8;
|
||||
bool PressFlag = 0;
|
||||
|
|
@ -775,21 +775,48 @@ void Pick_Handle()
|
|||
break;
|
||||
|
||||
case 2:
|
||||
if(StartFlag == 0) //当播放了之后,拨片不再起作用
|
||||
/* 普通:节奏/本地曲目均用 StartWithNote;切库后允许再次拨片起奏 */
|
||||
if (StartFlag == 0 || mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
{
|
||||
StartFlag = 1;
|
||||
AutoBandTop1_Stop();
|
||||
AutoBandTop1_SetLoopMode(0,1);
|
||||
AutoBandTop1_SetRunVar(mGuiData[GUI_PLAY_SECTION].Current);
|
||||
/* 起调必须用 0x3C+移调;勿用和弦音区 MIDI(如 48),否则本地曲目起奏异常 */
|
||||
midi = 0x3C + mGuiData[GUI_TRANSPOSE].Current;
|
||||
AutoBandTop1_StartWithNote(midi);
|
||||
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
LOG_I("pick", "local/normal root=%u name=%s", midi,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?");
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
StartFlag = 1;
|
||||
AutoBandTop1_SetPiecePlayMode(1,0,1920);
|
||||
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
|
||||
AutoBandTop1_SetLoopMode(0,1);
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
{
|
||||
/* 本地曲目:与普通模式同一套起奏(0x3C 根音 + 和弦音) */
|
||||
AutoBandTop1_Stop();
|
||||
AutoBandTop1_SetLoopMode(0,1);
|
||||
AutoBandTop1_SetRunVar(mGuiData[GUI_PLAY_SECTION].Current);
|
||||
midi = 0x3C + mGuiData[GUI_TRANSPOSE].Current;
|
||||
AutoBandTop1_StartWithNote(midi);
|
||||
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
|
||||
LOG_I("pick", "local/expert root=%u name=%s sw=%u tab=%u",
|
||||
midi,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
(unsigned)mGuiData[GUI_AUTOBAND_SW].Current,
|
||||
(unsigned)mGuiData[GUI_TAB_INDEX].Current);
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoBandTop1_SetPiecePlayMode(1,0,1920);
|
||||
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
|
||||
AutoBandTop1_SetLoopMode(0,1);
|
||||
LOG_I("pick", "expert/rhythm piece name=%s",
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?");
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
StartFlag = 1;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "includes.h"
|
||||
MidiFifoSeq_t m_MidiSendFifo;
|
||||
#define PRESET_BUFFER_SIZE (1024*40)
|
||||
#define PRESET_BUFFER_SIZE (1024*41) /* 2s.res compressed HKTK preset 39760 bytes */
|
||||
static int m_presetCount = 0;
|
||||
static uint8_t pStoreBuffer[PRESET_BUFFER_SIZE];
|
||||
//static uint8_t* pStoreBuffer;
|
||||
|
|
@ -76,9 +76,60 @@ static void Func_CallBack_PitchWheel(int channel,int cc,int value)
|
|||
mymidififo_InQueue(&m_MidiSendFifo,&midimsg);
|
||||
}
|
||||
|
||||
/* Flash Map 0903:对照 ExtFlash_Tone_Addr.h / Doc/.../FLASH_MAP.txt */
|
||||
static const char *ToneFlashMapBank(uint32_t abs)
|
||||
{
|
||||
if (abs >= EXTFLASH_BIN1_RHYTHM_ADDR &&
|
||||
abs < EXTFLASH_BIN1_RHYTHM_ADDR + EXTFLASH_BIN1_RHYTHM_SIZE)
|
||||
return "BIN1_RHYTHM";
|
||||
if (abs >= EXTFLASH_BIN2_SONG_HAITIAN_ADDR &&
|
||||
abs < EXTFLASH_BIN2_SONG_HAITIAN_ADDR + EXTFLASH_BIN2_SONG_HAITIAN_SIZE)
|
||||
return "BIN2_SONG_HAITIAN";
|
||||
if (abs >= EXTFLASH_BIN3_UNIVERSAL_ADDR &&
|
||||
abs < EXTFLASH_BIN3_UNIVERSAL_ADDR + EXTFLASH_BIN3_UNIVERSAL_SIZE)
|
||||
return "BIN3_UNIVERSAL";
|
||||
if (abs >= FLASH_ADDR_AUTOBAND_LEGACY &&
|
||||
abs < FLASH_ADDR_AUTOBAND_LEGACY + 0x10000UL)
|
||||
return "LEGACY_AUTOBAND";
|
||||
return "OUT_OF_MAP";
|
||||
}
|
||||
|
||||
static uint32_t s_flash_rd_last_base = 0xFFFFFFFFu;
|
||||
static uint16_t s_flash_rd_log_cnt = 0;
|
||||
|
||||
static int Func_CallBack_ReadFlash(int address,int length,uint8_t* pOutput)
|
||||
{
|
||||
W25Q128_Read(pOutput, (uint32_t)ADDRESS+address, length);
|
||||
uint32_t base = (uint32_t)ADDRESS;
|
||||
uint32_t abs = base + (uint32_t)address;
|
||||
const char *bank;
|
||||
|
||||
if (base != s_flash_rd_last_base) {
|
||||
s_flash_rd_last_base = base;
|
||||
s_flash_rd_log_cnt = 0;
|
||||
LOG_I("FLASH_RD", "bank base=0x%08X map=%s (BIN1=0x%08X BIN2=0x%08X BIN3=0x%08X)",
|
||||
(unsigned)base,
|
||||
ToneFlashMapBank(base),
|
||||
(unsigned)EXTFLASH_BIN1_RHYTHM_ADDR,
|
||||
(unsigned)EXTFLASH_BIN2_SONG_HAITIAN_ADDR,
|
||||
(unsigned)EXTFLASH_BIN3_UNIVERSAL_ADDR);
|
||||
}
|
||||
|
||||
bank = ToneFlashMapBank(abs);
|
||||
/* 加载阶段打印前若干次 + 每次 offset==0;避免播放期刷屏 */
|
||||
if (s_flash_rd_log_cnt < 16u || address == 0) {
|
||||
LOG_I("FLASH_RD", "abs=0x%08X off=%d len=%d map=%s",
|
||||
(unsigned)abs, address, length, bank);
|
||||
if (s_flash_rd_log_cnt < 0xFFFFu)
|
||||
s_flash_rd_log_cnt++;
|
||||
if (s_flash_rd_log_cnt == 16u)
|
||||
LOG_I("FLASH_RD", "further reads omitted (same base)");
|
||||
} else if (bank[0] == 'O') {
|
||||
/* 读到 Map 外:始终告警 */
|
||||
LOG_W("FLASH_RD", "OUT_OF_MAP abs=0x%08X off=%d len=%d base=0x%08X",
|
||||
(unsigned)abs, address, length, (unsigned)base);
|
||||
}
|
||||
|
||||
W25Q128_Read(pOutput, abs, length);
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
|
|
@ -97,11 +148,14 @@ void App_Auto_Init(void)
|
|||
int ret = AutoBandTop1_LoadPresetItemFromFlash(0);
|
||||
if (ret != 0)
|
||||
{
|
||||
LOG_E("AUTO", "LoadPreset fail ret=%d addr=0x%08X",
|
||||
ret, (unsigned)ADDRESS);
|
||||
LOG_E("AUTO", "LoadPreset fail ret=%d addr=0x%08X map=%s",
|
||||
ret, (unsigned)ADDRESS, ToneFlashMapBank((uint32_t)ADDRESS));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_I("AUTO", "LoadPreset ok name=%s addr=0x%08X map=%s",
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
(unsigned)ADDRESS, ToneFlashMapBank((uint32_t)ADDRESS));
|
||||
AutoBandTop1_ChangeBPM(mGuiData[1].Current);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,12 +178,21 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
show_Param(&UI_Label[GUI_MODE_PARAM], pCurData);
|
||||
|
||||
UI_ApplyToneAddress();
|
||||
int ret = 0;
|
||||
if (tab == 0)
|
||||
AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
else if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[EXPRESS_MODE_PARAM].Current);
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[EXPRESS_MODE_PARAM].Current);
|
||||
else
|
||||
AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
ret = AutoBandTop1_LoadPresetItemFromFlash(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);
|
||||
else
|
||||
LOG_I("tone", "load preset ok tab=%d sw=%d name=%s addr=0x%08X",
|
||||
tab, mGuiData[GUI_AUTOBAND_SW].Current,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
(unsigned)ADDRESS);
|
||||
|
||||
if (tab == 0)
|
||||
nvm->param.Param3 = ParamGuiData[ALL_MODE_PARAM].Current;
|
||||
|
|
@ -216,7 +225,11 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
/* 万能无节奏/本地 TAB,忽略该触控 */
|
||||
if (mGuiData[GUI_TAB_INDEX].Current == 0)
|
||||
return;
|
||||
if (mGuiData[ID].Current == value)
|
||||
return;
|
||||
mGuiData[ID].Current = value;
|
||||
StartFlag = 0;
|
||||
AutoBandTop1_Stop();
|
||||
UI_ReloadTonePreset();
|
||||
if (!UI_SetFocus(GUI_MODE_PARAM))
|
||||
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM],&mGuiData[GUI_MODE_PARAM]);
|
||||
|
|
|
|||
|
|
@ -112,36 +112,66 @@ void CallUI_RestoreSelect(void) {
|
|||
/* 音师:万能→3.bin;普通/专业:节奏→1.bin、本地曲目→2.bin */
|
||||
void UI_ApplyToneAddress(void)
|
||||
{
|
||||
uint32_t expect = 0;
|
||||
const char *map_name = "?";
|
||||
|
||||
switch (mGuiData[GUI_TAB_INDEX].Current)
|
||||
{
|
||||
case 0: /* 万能:和弦走向库 */
|
||||
ADDRESS = FLASH_ADDR_MODE_UNIVERSAL;
|
||||
return;
|
||||
expect = EXTFLASH_BIN3_UNIVERSAL_ADDR;
|
||||
map_name = "BIN3_UNIVERSAL";
|
||||
break;
|
||||
case 1: /* 专业 */
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current) {
|
||||
ADDRESS = FLASH_ADDR_SONG_HAITIAN;
|
||||
else
|
||||
expect = EXTFLASH_BIN2_SONG_HAITIAN_ADDR;
|
||||
map_name = "BIN2_SONG_HAITIAN";
|
||||
} else {
|
||||
ADDRESS = FLASH_ADDR_MODE_EXPERT;
|
||||
return;
|
||||
expect = EXTFLASH_BIN1_RHYTHM_ADDR;
|
||||
map_name = "BIN1_RHYTHM";
|
||||
}
|
||||
break;
|
||||
case 2: /* 普通 */
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current) {
|
||||
ADDRESS = FLASH_ADDR_SONG_HAITIAN;
|
||||
else
|
||||
expect = EXTFLASH_BIN2_SONG_HAITIAN_ADDR;
|
||||
map_name = "BIN2_SONG_HAITIAN";
|
||||
} else {
|
||||
ADDRESS = FLASH_ADDR_MODE_NORMAL;
|
||||
return;
|
||||
expect = EXTFLASH_BIN1_RHYTHM_ADDR;
|
||||
map_name = "BIN1_RHYTHM";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ADDRESS = FLASH_ADDR_MODE_UNIVERSAL;
|
||||
return;
|
||||
expect = EXTFLASH_BIN3_UNIVERSAL_ADDR;
|
||||
map_name = "BIN3_UNIVERSAL";
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_I("tone", "ADDRESS=0x%08X map=%s expect=0x%08X tab=%u sw=%u %s",
|
||||
(unsigned)ADDRESS, map_name, (unsigned)expect,
|
||||
(unsigned)mGuiData[GUI_TAB_INDEX].Current,
|
||||
(unsigned)mGuiData[GUI_AUTOBAND_SW].Current,
|
||||
(ADDRESS == expect) ? "OK" : "MISMATCH");
|
||||
}
|
||||
|
||||
void UI_ReloadTonePreset(void)
|
||||
{
|
||||
UI_ApplyToneAddress();
|
||||
/* 换库前先停,避免播放中改 relocate 指针 */
|
||||
AutoBandTop1_Stop();
|
||||
StartFlag = 0;
|
||||
/* 万能:和弦走向 */
|
||||
if (mGuiData[GUI_TAB_INDEX].Current == 0)
|
||||
{
|
||||
AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[ALL_MODE_PARAM].Current);
|
||||
LOG_I("tone", "load universal idx=%d ret=%d name=%s addr=0x%08X map=BIN3@0x%08X",
|
||||
ParamGuiData[ALL_MODE_PARAM].Current, ret,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
(unsigned)ADDRESS, (unsigned)EXTFLASH_BIN3_UNIVERSAL_ADDR);
|
||||
return;
|
||||
}
|
||||
/* 普通/专业:本地曲目或节奏类型 */
|
||||
|
|
@ -151,7 +181,18 @@ 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;
|
||||
AutoBandTop1_LoadPresetItemFromFlash(local->Current);
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(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,
|
||||
(unsigned)EXTFLASH_BIN2_SONG_HAITIAN_ADDR);
|
||||
else
|
||||
LOG_I("tone", "local song idx=%d name=%s addr=0x%08X map=BIN2@0x%08X %s",
|
||||
local->Current,
|
||||
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
|
||||
(unsigned)ADDRESS,
|
||||
(unsigned)EXTFLASH_BIN2_SONG_HAITIAN_ADDR,
|
||||
(ADDRESS == EXTFLASH_BIN2_SONG_HAITIAN_ADDR) ? "OK" : "MISMATCH");
|
||||
{
|
||||
int bin_n = AutoBandTop1_GetPresetItemCount();
|
||||
if (bin_n != LOCAL_SONG_COUNT)
|
||||
|
|
@ -159,7 +200,16 @@ void UI_ReloadTonePreset(void)
|
|||
}
|
||||
return;
|
||||
}
|
||||
AutoBandTop1_LoadPresetItemFromFlash(ParamGuiData[SONG_MODE_PARAM].Current);
|
||||
{
|
||||
int ret = AutoBandTop1_LoadPresetItemFromFlash(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() : "?",
|
||||
(unsigned)ADDRESS,
|
||||
(unsigned)EXTFLASH_BIN1_RHYTHM_ADDR,
|
||||
(ADDRESS == EXTFLASH_BIN1_RHYTHM_ADDR) ? "OK" : "MISMATCH");
|
||||
(void)ret;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t s_ui_focus_id = UI_FOCUS_NONE;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
#define EXTFLASH_BIN1_RHYTHM_SIZE 530317UL
|
||||
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_ADDR 0x0009D07DUL
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_SIZE 46474UL
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_SIZE 41040UL
|
||||
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_ADDR 0x000A8607UL
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_ADDR 0x000A70CDUL
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_SIZE 31854UL
|
||||
|
||||
/* Convenience aliases used by UI ADDRESS */
|
||||
|
|
@ -35,8 +35,8 @@
|
|||
/* Legacy AutoBand bank — not repacked in 0903; left unchanged in firmware */
|
||||
#define FLASH_ADDR_AUTOBAND_LEGACY 0x0009EB5FUL
|
||||
|
||||
#define EXTFLASH_TONE_PACK_END 0x000B0275UL
|
||||
#define EXTFLASH_TONE_PACK_SIZE 721525UL
|
||||
#define EXTFLASH_TONE_PACK_END 0x000AED3BUL
|
||||
#define EXTFLASH_TONE_PACK_SIZE 716091UL
|
||||
#define UI0902_RES_BASE_SAFE_GAP (0x00100000UL - EXTFLASH_TONE_PACK_END)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
|
||||
* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
|
||||
*/
|
||||
#define RT_HEAP_SIZE (20*1024)
|
||||
#define RT_HEAP_SIZE (19*1024) /* 20KB-1KB to fit 41KB preset buffer in 96KB RAM */
|
||||
static rt_uint8_t rt_heap[RT_HEAP_SIZE];
|
||||
|
||||
RT_WEAK void *rt_heap_begin_get(void)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
import subprocess, shutil, os, time
|
||||
|
||||
base = os.path.join(r"C:\Users\qjyu\Documents\SoundWalker", "一诺国际吉他",
|
||||
r"Code\YNGJ-GT1-M - AT32F403ARCT7")
|
||||
stage = r"C:\Temp\k1flash"
|
||||
os.makedirs(stage, exist_ok=True)
|
||||
|
||||
out_src = os.path.join(base, r"project\IAR_V7.4\YNGJ-GT1-M\Exe\YNGJ-GT1-M.out")
|
||||
out_dst = os.path.join(stage, "YNGJ-GT1-M.out")
|
||||
with open(out_src, "rb") as a, open(out_dst, "wb") as b:
|
||||
shutil.copyfileobj(a, b)
|
||||
print("copied", os.path.getsize(out_dst), flush=True)
|
||||
|
||||
gen_src = os.path.join(base, r"project\IAR_V7.4\settings\YNGJ-GT1-M.YNGJ-GT1-M.general.xcl")
|
||||
drv_src = os.path.join(base, r"project\IAR_V7.4\settings\YNGJ-GT1-M.YNGJ-GT1-M.driver.xcl")
|
||||
lines = open(gen_src, encoding="utf-8", errors="replace").read().splitlines()
|
||||
new = []
|
||||
for ln in lines:
|
||||
new.append(f'"{out_dst}" ' if (".out" in ln and "YNGJ" in ln) else ln)
|
||||
open(os.path.join(stage, "general.xcl"), "w", encoding="utf-8", newline="\n").write("\n".join(new) + "\n")
|
||||
shutil.copy2(drv_src, os.path.join(stage, "driver.xcl"))
|
||||
|
||||
for n in ("cspybat.exe", "CSpyBat.exe", "JLink.exe", "IarIdePm.exe",
|
||||
"JLinkGUIServer.exe", "JLinkRTTClient.exe", "JFlash.exe"):
|
||||
subprocess.run(["taskkill", "/F", "/IM", n], capture_output=True)
|
||||
time.sleep(1.5)
|
||||
|
||||
# Force Artery AT32F403ACx (RCT7) — avoid Cortex-M4 / wrong-chip popup
|
||||
drv_path = os.path.join(stage, "driver.xcl")
|
||||
drv_lines = open(drv_path, encoding="utf-8", errors="replace").read().splitlines()
|
||||
forced = []
|
||||
for ln in drv_lines:
|
||||
if ln.strip().startswith("--jlink_device"):
|
||||
continue
|
||||
forced.append(ln)
|
||||
forced.append('--jlink_device=AT32F403AC')
|
||||
open(drv_path, "w", encoding="utf-8", newline="\n").write("\n".join(forced) + "\n")
|
||||
print("driver device forced: AT32F403AC", flush=True)
|
||||
|
||||
cspy = r"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.3\common\bin\cspybat.exe"
|
||||
cmd = [cspy, "-f", os.path.join(stage, "general.xcl"),
|
||||
f"--debug_file={out_dst}", "--download_only", "--backend",
|
||||
"-f", drv_path]
|
||||
logp = os.path.join(stage, "cspy.log")
|
||||
print("cspybat start (AT32F403AC / FlashAT32F403ARCT7)", flush=True)
|
||||
with open(logp, "w", encoding="utf-8", errors="replace") as log:
|
||||
r = subprocess.run(cmd, stdout=log, stderr=subprocess.STDOUT, timeout=180)
|
||||
print("cspy exit", r.returncode, flush=True)
|
||||
print(open(logp, encoding="utf-8", errors="replace").read()[-2000:])
|
||||
if r.returncode != 0:
|
||||
raise SystemExit(r.returncode)
|
||||
|
||||
jlink = r"C:\Program Files\SEGGER\JLink_V818\JLink.exe"
|
||||
reset = os.path.join(base, r"tools\reset_run.jlink")
|
||||
print("reset AT32F403AC", flush=True)
|
||||
subprocess.run([jlink, "-Device", "AT32F403AC", "-If", "SWD",
|
||||
"-Speed", "4000", "-AutoConnect", "1",
|
||||
"-CommandFile", reset], capture_output=True, timeout=30)
|
||||
time.sleep(3)
|
||||
print("Done", flush=True)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
gImage_mixer 34x33
|
||||
gImage_SystemSetting 33x33
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 415 B |
Binary file not shown.
|
After Width: | Height: | Size: 550 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
|
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Flash Doc/音色文件/0907/2.res (or --bin) to W25Q128 @ FLASH_ADDR_SONG_HAITIAN via RTT."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
DEFAULT_DEVICES = ("Cortex-M4", "AT32F403AC", "AT32F403A")
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
REPO = os.path.dirname(os.path.dirname(ROOT))
|
||||
DEFAULT_BIN = os.path.join(REPO, "Doc", "音色文件", "0907", "2.res")
|
||||
FLASH_ADDR_SONG_HAITIAN = 0x0009D07D
|
||||
|
||||
|
||||
def connect_jlink(device: str):
|
||||
import pylink
|
||||
|
||||
jlink = pylink.JLink()
|
||||
jlink.open()
|
||||
try:
|
||||
jlink.exec_command("HideDeviceSelection = 1")
|
||||
except Exception:
|
||||
pass
|
||||
jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
|
||||
|
||||
last_error = None
|
||||
for candidate in (device, *DEFAULT_DEVICES):
|
||||
try:
|
||||
try:
|
||||
jlink.exec_command(f"Device = {candidate}")
|
||||
except Exception:
|
||||
pass
|
||||
jlink.connect(candidate)
|
||||
print(f"Connected as {candidate}")
|
||||
return jlink
|
||||
except Exception as exc:
|
||||
last_error = exc
|
||||
jlink.close()
|
||||
raise SystemExit(f"Failed to connect J-Link: {last_error}")
|
||||
|
||||
|
||||
def find_rtt_control_block(jlink, ram_base: int = 0x20000000, ram_size: int = 0x18000):
|
||||
needle = b"SEGGER RTT"
|
||||
chunk = 0x1000
|
||||
was_halted = jlink.halted()
|
||||
if not was_halted:
|
||||
jlink.halt()
|
||||
try:
|
||||
for off in range(0, ram_size, chunk):
|
||||
data = bytes(jlink.memory_read8(ram_base + off, min(chunk, ram_size - off)))
|
||||
idx = data.find(needle)
|
||||
if idx >= 0:
|
||||
return ram_base + off + idx
|
||||
finally:
|
||||
if not was_halted:
|
||||
if hasattr(jlink, "restart"):
|
||||
jlink.restart()
|
||||
else:
|
||||
jlink.go()
|
||||
time.sleep(0.1)
|
||||
return None
|
||||
|
||||
|
||||
def rtt_read_text(jlink, timeout_s: float = 0.2) -> str:
|
||||
deadline = time.time() + timeout_s
|
||||
chunks: list[bytes] = []
|
||||
while time.time() < deadline:
|
||||
try:
|
||||
data = bytes(jlink.rtt_read(0, 512) or [])
|
||||
except Exception:
|
||||
data = b""
|
||||
if data:
|
||||
chunks.append(data)
|
||||
deadline = time.time() + timeout_s
|
||||
else:
|
||||
time.sleep(0.02)
|
||||
return b"".join(chunks).decode("ascii", errors="replace")
|
||||
|
||||
|
||||
def wait_for(jlink, marker: str, timeout_s: float = 30.0) -> str:
|
||||
deadline = time.time() + timeout_s
|
||||
buf = ""
|
||||
while time.time() < deadline:
|
||||
buf += rtt_read_text(jlink, 0.15)
|
||||
if marker in buf:
|
||||
return buf
|
||||
raise SystemExit(f"Timeout waiting for {marker!r}\n--- RTT ---\n{buf[-800:]}")
|
||||
|
||||
|
||||
def send_bytes(jlink, payload: bytes) -> None:
|
||||
off = 0
|
||||
while off < len(payload):
|
||||
try:
|
||||
n = jlink.rtt_write(0, list(payload[off : off + 64]))
|
||||
except Exception:
|
||||
time.sleep(0.05)
|
||||
continue
|
||||
if n is None or n <= 0:
|
||||
time.sleep(0.02)
|
||||
continue
|
||||
off += n
|
||||
|
||||
|
||||
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")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.isfile(args.bin):
|
||||
raise SystemExit(f"missing bin: {args.bin}")
|
||||
|
||||
data = open(args.bin, "rb").read()
|
||||
size = len(data)
|
||||
print(f"bin={args.bin} size={size} addr=0x{FLASH_ADDR_SONG_HAITIAN:08X}")
|
||||
|
||||
jlink = connect_jlink(args.device)
|
||||
try:
|
||||
cb = find_rtt_control_block(jlink)
|
||||
if cb is None:
|
||||
raise SystemExit("RTT control block not found")
|
||||
print(f"RTT CB @ 0x{cb:08X}")
|
||||
jlink.rtt_start(cb)
|
||||
time.sleep(0.3)
|
||||
_ = rtt_read_text(jlink, 0.3)
|
||||
|
||||
if not args.no_reset:
|
||||
print("hardware reset...")
|
||||
jlink.reset(halt=False)
|
||||
time.sleep(3.5)
|
||||
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 haitian {size}\n".encode("ascii")
|
||||
send_bytes(jlink, cmd)
|
||||
print("sent flash command, waiting GO...")
|
||||
log = wait_for(jlink, "FLASH_HAITIAN_GO", 20.0)
|
||||
print(log.strip().splitlines()[-1])
|
||||
time.sleep(0.2)
|
||||
|
||||
chunk = 256
|
||||
sent = 0
|
||||
t0 = time.time()
|
||||
receiving = False
|
||||
while sent < size:
|
||||
end = min(sent + chunk, size)
|
||||
send_bytes(jlink, data[sent:end])
|
||||
sent = end
|
||||
log = wait_for(jlink, "FLASH_ACK", 60.0)
|
||||
if (not receiving) and ("FLASH_RX" in log or "FLASH_ACK" in log):
|
||||
receiving = True
|
||||
print("device receiving...")
|
||||
if "FLASH_HAITIAN_OK" in log:
|
||||
print(log.strip().splitlines()[-1])
|
||||
print("Done. Local song bank updated.")
|
||||
return
|
||||
if sent % (4 * 1024) == 0 or sent == size:
|
||||
elapsed = time.time() - t0
|
||||
print(f" {sent}/{size} ({100.0 * sent / size:.1f}%) {elapsed:.1f}s")
|
||||
|
||||
log = wait_for(jlink, "FLASH_HAITIAN_OK", 60.0)
|
||||
print(log.strip().splitlines()[-1])
|
||||
print("Done. Local song bank updated.")
|
||||
finally:
|
||||
try:
|
||||
jlink.rtt_stop()
|
||||
except Exception:
|
||||
pass
|
||||
jlink.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -25,7 +25,7 @@ MAP_TXT = REPO / "Doc" / "音色文件" / "0903" / "FLASH_MAP.txt"
|
|||
IAP_DIR = REPO / "升级" / "MCU主控升级"
|
||||
OUT_ROOT = REPO / "tools" / "out"
|
||||
|
||||
FW_VER = "0.2.2"
|
||||
FW_VER = "0.2.3"
|
||||
TONE_RES_VER = "0903"
|
||||
UI0902_RES_BASE = 0x00100000
|
||||
|
||||
|
|
@ -126,8 +126,8 @@ def main() -> None:
|
|||
"",
|
||||
"外部 Flash 分区:",
|
||||
" 0x00000000 音色/充电图 (toneRes)",
|
||||
" logo pad + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin + 3.bin",
|
||||
" 0x00100000 UI0902 图片 (模式选择大图、全屏开机 Logo、设置/调音台素材等)",
|
||||
" logo pad + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin(HKTK/2s) + 3.bin",
|
||||
" 0x00100000 UI0902 图片 (模式选择、开机 Logo、充电、烧录模式、设置/调音台等)",
|
||||
"",
|
||||
f" {comb_name} size={comb_dst.stat().st_size} @ 0x00000000",
|
||||
f" sha256={sha256(comb_dst)}",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
HideDeviceSelection 1
|
||||
si SWD
|
||||
speed 4000
|
||||
device Cortex-M4
|
||||
|
|
|
|||
Loading…
Reference in New Issue