save angle values

This commit is contained in:
Steven Dan
2026-04-23 23:35:51 +08:00
parent 3d488b39fe
commit 9796840c18
5 changed files with 271 additions and 5 deletions

View File

@@ -104,6 +104,13 @@ unsigned g_hid_expand_gain_request = (unsigned)-1;
// HID 0xB0 CMD_LMT_THRESHOLD到达时由eq.c设置button_task读取后保存到flash // HID 0xB0 CMD_LMT_THRESHOLD到达时由eq.c设置button_task读取后保存到flash
// 存储值为-threshold (0~35)-1 (0xFFFFFFFF) 表示无待处理请求 // 存储值为-threshold (0~35)-1 (0xFFFFFFFF) 表示无待处理请求
unsigned g_hid_lmt_threshold_request = (unsigned)-1; unsigned g_hid_lmt_threshold_request = (unsigned)-1;
// HID 0xB0 CMD_ANGLE到达时由eq.c设置button_task读取后保存到flash
// channel=0xFFFFFFFF 表示批量更新所有通道
#define EX3D_ANGLE_CHANNELS 8
unsigned g_hid_angle_values[EX3D_ANGLE_CHANNELS] = {0};
unsigned g_hid_angle_values_old[EX3D_ANGLE_CHANNELS] = { 315, 45, 0, 0, 225, 135, 270, 90 };
// HID 0x84 FACTORY_RESET命令到达时由eq.c设置button_task轮询后执行重启 // HID 0x84 FACTORY_RESET命令到达时由eq.c设置button_task轮询后执行重启
unsigned g_request_factory_reset = 0; unsigned g_request_factory_reset = 0;
uint32_t get_reference_time(); uint32_t get_reference_time();
@@ -112,6 +119,12 @@ unsigned g_dac_mode = 10;
unsigned g_new_dac_mode = 0; unsigned g_new_dac_mode = 0;
unsigned g_samfreq = 48000; unsigned g_samfreq = 48000;
unsigned g_dsd_mode = 0; unsigned g_dsd_mode = 0;
void save_value(unsigned char * unsafe path, unsigned char value);
unsigned char load_value(unsigned char * unsafe path);
void save_value32(unsigned char * unsafe path, unsigned value);
unsigned load_value32(unsigned char * unsafe path);
// mic detect events: mute_handler (tile[1]) → button_task (tile[0]) // mic detect events: mute_handler (tile[1]) → button_task (tile[0])
#define MIC_DET_MUTE 1 // mic插入或全拔出立即mute mic #define MIC_DET_MUTE 1 // mic插入或全拔出立即mute mic
#define MIC_DET_UNMUTE 2 // 插入1s后恢复mic音量 #define MIC_DET_UNMUTE 2 // 插入1s后恢复mic音量
@@ -122,6 +135,54 @@ unsafe chanend uc_audiohw; // tile[1] end: AudioHwConfig → button_task (tile[
#if HID_DFU_EN #if HID_DFU_EN
unsafe streaming chanend uc_dfu; // tile[1] send end: hid_button_task → button_task (tile[0]) unsafe streaming chanend uc_dfu; // tile[1] send end: hid_button_task → button_task (tile[0])
#endif #endif
static void ex3d_angle_load_defaults(unsigned angles[EX3D_ANGLE_CHANNELS])
{
angles[0] = 315;
angles[1] = 45;
angles[2] = 0;
angles[3] = 0;
angles[4] = 225;
angles[5] = 135;
angles[6] = 270;
angles[7] = 90;
}
static void ex3d_angle_make_path(unsigned channel, unsigned char path[6])
{
path[0] = 'x';
path[1] = '3';
path[2] = 'd';
path[3] = 'a';
path[4] = (unsigned char)('1' + channel);
path[5] = 0;
}
static void ex3d_angle_save_channel(unsigned channel, unsigned angle)
{
unsigned char path[6];
debug_printf("ex3d_angle_save_channel: %d, %d\n", channel, angle);
// 改动原因角度值改为单key一次写入32位减少4次拆分写入的flash调用提升效率并简化流程。
ex3d_angle_make_path(channel, path);
save_value32(path, angle);
}
static unsigned ex3d_angle_load_channel(unsigned channel, unsigned default_angle)
{
unsigned char path[6];
ex3d_angle_make_path(channel, path);
unsigned angle = load_value32(path);
if (angle == 0xFFFFFFFF) {
// 改动原因按用户要求去掉legacy迁移与归一化未初始化时直接使用并保存默认值流程最简。
ex3d_angle_save_channel(channel, default_angle);
return default_angle;
}
// debug_printf("ex3d_angle_load_channel: %d, %d\n", channel, angle);
// 改动原因按用户要求去掉normalize读取后直接返回原始32位角度值。
return angle;
}
// 改动原因添加增益模式和滤波器模式的请求变量用于HID命令设置模式 // 改动原因添加增益模式和滤波器模式的请求变量用于HID命令设置模式
unsigned g_request_game_mode = -1; unsigned g_request_game_mode = -1;
@@ -304,8 +365,6 @@ extern void dnr_set_strength_level(unsigned char strength);
extern void device_reboot(void); extern void device_reboot(void);
void save_value(unsigned char * unsafe path, unsigned char value);
unsigned char load_value(unsigned char * unsafe path);
enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6}; enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6};
@@ -448,6 +507,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
unsigned char mic_mute_path[] = "mic_mute"; unsigned char mic_mute_path[] = "mic_mute";
unsigned char hp_mute_path[] = "hp_mute"; unsigned char hp_mute_path[] = "hp_mute";
unsigned char monitor_sw_path[] = "monitor_sw"; unsigned char monitor_sw_path[] = "monitor_sw";
unsigned char dnr_strength_path[] = "dnr_strength";
unsigned host_os = OS_OTHERS; unsigned host_os = OS_OTHERS;
#if DNR_ENABLE #if DNR_ENABLE
unsigned dnr_init_flag = 0; unsigned dnr_init_flag = 0;
@@ -491,6 +551,19 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
} }
debug_printf("Loaded footstep gain from flash: %d, state=%d\n", saved_footstep, flag_footsteps_enhancement); debug_printf("Loaded footstep gain from flash: %d, state=%d\n", saved_footstep, flag_footsteps_enhancement);
} }
// 加载EX3D角度未初始化时写入默认值
{
unsigned ex3d_angles[EX3D_ANGLE_CHANNELS];
ex3d_angle_load_defaults(ex3d_angles);
for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i) {
g_hid_angle_values[i] = ex3d_angle_load_channel(i, ex3d_angles[i]);
// 改动原因:
// - g_hid_angle_values_old 用于后续“变更检测后再写flash”
// - 开机从flash加载角度后旧值必须与当前值对齐否则首次保存请求会把未变化通道也误判为变化。
g_hid_angle_values_old[i] = g_hid_angle_values[i];
}
}
#endif #endif
#if defined(UAC1_MODE) #if defined(UAC1_MODE)
@@ -504,7 +577,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
} }
if (host_os == OS_WIN) { if (host_os == OS_WIN) {
printf("Detected Windows OS (OS_WIN) saved_mode: %d\n", saved_mode); debug_printf("Detected Windows OS (OS_WIN) saved_mode: %d\n", saved_mode);
unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : MODE_F3_F4_FPS_UAC2; unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : MODE_F3_F4_FPS_UAC2;
SetRoleSwitchFlag(flag); SetRoleSwitchFlag(flag);
#ifndef DISABLE_REBOOT #ifndef DISABLE_REBOOT
@@ -636,6 +709,32 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
} }
debug_printf("Loaded monitor_switch from flash: %d\n", g_monitor_switch); debug_printf("Loaded monitor_switch from flash: %d\n", g_monitor_switch);
{
unsigned char saved_dnr = load_value(dnr_strength_path);
if (saved_dnr == 255) {
g_dnr_strength = 100;
dnr_strength_saved = 100;
flag_aidenoise_onoff = 1;
save_value(dnr_strength_path, (unsigned char)100);
} else if (saved_dnr == 0 || (saved_dnr <= 100 && (saved_dnr % 2) == 0)) {
g_dnr_strength = saved_dnr;
if (saved_dnr == 0) {
dnr_strength_saved = 100;
flag_aidenoise_onoff = 0;
} else {
dnr_strength_saved = saved_dnr;
flag_aidenoise_onoff = 1;
}
} else {
g_dnr_strength = 100;
dnr_strength_saved = 100;
flag_aidenoise_onoff = 1;
save_value(dnr_strength_path, (unsigned char)100);
}
debug_printf("Loaded dnr_strength from flash: current=%d saved=%d onoff=%d\n",
g_dnr_strength, dnr_strength_saved, flag_aidenoise_onoff);
}
// 从Flash恢复mic_mute状态默认关闭=未静音) // 从Flash恢复mic_mute状态默认关闭=未静音)
unsigned char saved_mic_mute = load_value(mic_mute_path); unsigned char saved_mic_mute = load_value(mic_mute_path);
if(saved_mic_mute == 1) if(saved_mic_mute == 1)
@@ -763,6 +862,15 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
debug_printf("Loaded lmt_threshold=%d from flash (raw=%d), sent to tile1\n", init_threshold, raw); debug_printf("Loaded lmt_threshold=%d from flash (raw=%d), sent to tile1\n", init_threshold, raw);
} }
// 同步EX3D角度到tile1
{
cc_mic_level <: 0xF9;
for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i) {
cc_mic_level <: g_hid_angle_values[i];
debug_printf("angle[%d] = %d\n", i, g_hid_angle_values[i]);
}
}
// 恢复脚步增强LED初始状态 // 恢复脚步增强LED初始状态
if (flag_footsteps_enhancement == 1) { if (flag_footsteps_enhancement == 1) {
led_on(&led_ctx, LED_FOOTSTEP_MODE); led_on(&led_ctx, LED_FOOTSTEP_MODE);
@@ -784,6 +892,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
led_on(&led_ctx, LED_ANC); led_on(&led_ctx, LED_ANC);
led_update_all(&led_ctx); led_update_all(&led_ctx);
dnr_set_mode(1); dnr_set_mode(1);
dnr_set_strength_level((unsigned char)g_dnr_strength);
} else {
led_off(&led_ctx, LED_ANC);
led_update_all(&led_ctx);
dnr_set_mode(1);
dnr_set_strength_level(0);
} }
#endif #endif
@@ -1511,6 +1625,20 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
} }
} }
} }
// HID 0xB0 CMD_ANGLE请求保存角度到flash
{
for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i)
{
// 改动原因按用户要求去掉normalize直接比较并保存原始角度值减少计算分支。
unsigned angle = g_hid_angle_values[i];
if (angle != g_hid_angle_values_old[i])
{
ex3d_angle_save_channel(i, angle);
g_hid_angle_values_old[i] = angle;
}
}
}
#endif #endif
mode_change = 0; mode_change = 0;
@@ -1974,8 +2102,9 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
dnr_strength_saved = new_strength; dnr_strength_saved = new_strength;
led_on(&led_ctx, LED_ANC); led_on(&led_ctx, LED_ANC);
} }
save_value(dnr_strength_path, (unsigned char)new_strength);
led_update_all(&led_ctx); led_update_all(&led_ctx);
debug_printf("HID SET_AI_NOISE_STRENGTH: strength=%d\n", new_strength); debug_printf("HID SET_AI_NOISE_STRENGTH: strength=%d, saved to flash\n", new_strength);
} }
} }

View File

@@ -44,9 +44,18 @@ unsigned g_mic_vol_cmd_pending = 0;
// 0xFA boot sync收到后置1ex3d_task用此标志决定是否保留boot sync的阈值 // 0xFA boot sync收到后置1ex3d_task用此标志决定是否保留boot sync的阈值
static volatile int g_boot_lmt_threshold_loaded = 0; static volatile int g_boot_lmt_threshold_loaded = 0;
static volatile int g_boot_footstep_expand_gain_loaded = 0; static volatile int g_boot_footstep_expand_gain_loaded = 0;
static volatile int g_boot_angle_loaded = 0;
// 改动原因修复“主机已通过CMD_ANGLE写入但随后启动阶段0xF9(来自flash旧值)又覆盖回默认角度”的竞态。
// 该标志在收到任意CMD_ANGLE写入后置1若置1则忽略后续0xF9覆盖确保“最后一次主机写入”为准。
static volatile int g_runtime_angle_written = 0;
// 改动原因修复0xF9角度同步与ex3d_task初始化的竞态。
// 当0xF9在ex3d_task初始化完成后才到达时旧逻辑只缓存不应用导致GET CMD_ANGLE仍返回默认值。
// 通过该标志判断EX3D是否已完成初始化若已完成则在收到0xF9时立即应用角度。
static volatile int g_ex3d_init_done = 0;
// audio_ex3d_init会覆盖Ex3dExpandGain为库默认值用此变量保存0xFD boot sync收到的值 // audio_ex3d_init会覆盖Ex3dExpandGain为库默认值用此变量保存0xFD boot sync收到的值
static volatile int32_t g_boot_footstep_expand_gain_value = 12; static volatile int32_t g_boot_footstep_expand_gain_value = 12;
static volatile int32_t g_boot_lmt_threshold_value = -5; static volatile int32_t g_boot_lmt_threshold_value = -5;
static volatile uint32_t g_boot_angle_values[8] = {315, 45, 0, 0, 225, 135, 270, 90};
chanend_t uc_ex3d_to_ubm, uc_eq_data; chanend_t uc_ex3d_to_ubm, uc_eq_data;
static unsigned ubm_sample_freq = 0; static unsigned ubm_sample_freq = 0;
@@ -83,6 +92,18 @@ unsigned g_mute_on_off_t0 = MUTE_OFF;
unsigned g_game_mode = 0; unsigned g_game_mode = 0;
static void ex3d_apply_boot_angles(void)
{
int apply_count = (NUM_USB_CHAN_OUT < 8) ? NUM_USB_CHAN_OUT : 8;
for (int i = 0; i < apply_count; ++i) {
uint32_t angle = g_boot_angle_values[i];
EX3D_VAngle[i] = (angle >> 16) & 0xFFFF;
EX3D_HAngle[i] = angle & 0xFFFF;
EX3DAudio_SetAngle(i + 1, EX3D_VAngle[i], EX3D_HAngle[i], (i == (apply_count - 1)));
debug_printf("ex3d_apply_boot_angles: %d, %d\n", EX3D_VAngle[i], EX3D_HAngle[i]);
}
}
// On UserBufferManagement Tile (1) // On UserBufferManagement Tile (1)
static unsigned frame_index = 0; static unsigned frame_index = 0;
//static unsigned dnr_frame_idx = 0; //static unsigned dnr_frame_idx = 0;
@@ -151,6 +172,14 @@ void UserBufferManagementInit(unsigned sampFreq)
debug_printf("audio_ex3d_change_parameter() error:%d\n\r", ret); debug_printf("audio_ex3d_change_parameter() error:%d\n\r", ret);
} else { } else {
debug_printf("audio_ex3d_change_parameter() success\n\r"); debug_printf("audio_ex3d_change_parameter() success\n\r");
}
// 改动原因修复“上电后GET CMD_ANGLE仍返回315”的问题。
// audio_ex3d_change_parameter 内部会把 EX3D_VAngle/EX3D_HAngle 重置为库默认值(315,45,...)
// 若 0xF9 已同步了 flash 中的角度(或主机期间已通过 CMD_ANGLE 改过),必须在此重新应用,
// 否则采样率切换/流启动时刚建立的角度会被静默覆盖,导致 GET 依旧读到默认值315。
if (g_boot_angle_loaded || g_runtime_angle_written) {
ex3d_apply_boot_angles();
debug_printf("UserBufferManagementInit: reapplied ex3d angles after change_parameter\n");
} }
// ② 预热:推一个零帧穿过 ex3d触发所有 worker 加载 + 首次同步 // ② 预热:推一个零帧穿过 ex3d触发所有 worker 加载 + 首次同步
chan_out_buf_word(uc_ex3d_to_ubm, (const uint32_t *)ubm_egress, chan_out_buf_word(uc_ex3d_to_ubm, (const uint32_t *)ubm_egress,
@@ -390,7 +419,7 @@ void hid_receive_task_in_c(unsigned char * RcvData, unsigned * SendData)
else new_mode = IR_GAME; else new_mode = IR_GAME;
SET_SHARED_GLOBAL(g_3d_on_off_t1, new_mode); SET_SHARED_GLOBAL(g_3d_on_off_t1, new_mode);
} }
printf("Set CMD_ONOFF : %u\r\n", pRcvBuf[1]); debug_printf("Set CMD_ONOFF : %u\r\n", pRcvBuf[1]);
} else { } else {
debug_printf("Get CMD_ONOFF : %u\r\n", bEX3D_On); debug_printf("Get CMD_ONOFF : %u\r\n", bEX3D_On);
pSendBuf[idx] = bEX3D_On; pSendBuf[idx] = bEX3D_On;
@@ -422,6 +451,10 @@ void hid_receive_task_in_c(unsigned char * RcvData, unsigned * SendData)
EX3D_VAngle[ChNum] = (angle >> 16) % 181; EX3D_VAngle[ChNum] = (angle >> 16) % 181;
EX3D_HAngle[ChNum] = (angle & 0xffff) % 360; EX3D_HAngle[ChNum] = (angle & 0xffff) % 360;
EX3DAudio_SetAngle(ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum], true); EX3DAudio_SetAngle(ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum], true);
// 改动原因记录“运行期角度已被主机改写”并同步缓存防止后续0xF9旧值覆盖。
g_boot_angle_values[ChNum] = ((uint32_t)EX3D_VAngle[ChNum] << 16) | (uint32_t)EX3D_HAngle[ChNum];
g_boot_angle_loaded = 1;
g_runtime_angle_written = 1;
debug_printf("[%s] Set angle ch%d-%d,%d\n",__FUNCTION__, ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum]); debug_printf("[%s] Set angle ch%d-%d,%d\n",__FUNCTION__, ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum]);
} else { } else {
uint8_t bApply = false; uint8_t bApply = false;
@@ -433,8 +466,13 @@ void hid_receive_task_in_c(unsigned char * RcvData, unsigned * SendData)
EX3D_HAngle[i] = (angle & 0xffff) % 360; EX3D_HAngle[i] = (angle & 0xffff) % 360;
if(i == (ChNum - 1)) bApply = true; if(i == (ChNum - 1)) bApply = true;
EX3DAudio_SetAngle(i+1, EX3D_VAngle[i], EX3D_HAngle[i], bApply); EX3DAudio_SetAngle(i+1, EX3D_VAngle[i], EX3D_HAngle[i], bApply);
// 改动原因批量写入时同样更新本地启动角度缓存避免0xF9旧值回灌。
g_boot_angle_values[i] = ((uint32_t)EX3D_VAngle[i] << 16) | (uint32_t)EX3D_HAngle[i];
debug_printf(" ch%d-%d,%d,", i+1, EX3D_VAngle[i], EX3D_HAngle[i]); debug_printf(" ch%d-%d,%d,", i+1, EX3D_VAngle[i], EX3D_HAngle[i]);
} }
// 改动原因批量写入成功后置位后续0xF9不再覆盖主机刚写的角度。
g_boot_angle_loaded = 1;
g_runtime_angle_written = 1;
debug_printf("\n"); debug_printf("\n");
} }
debug_printf("Set CMD_ANGLE : %u\r\n", pRcvBuf[1]); debug_printf("Set CMD_ANGLE : %u\r\n", pRcvBuf[1]);
@@ -446,6 +484,7 @@ void hid_receive_task_in_c(unsigned char * RcvData, unsigned * SendData)
angle = EX3D_VAngle[ChNum] << 16; angle = EX3D_VAngle[ChNum] << 16;
angle |= EX3D_HAngle[ChNum]; angle |= EX3D_HAngle[ChNum];
pSendBuf[idx] = angle; pSendBuf[idx] = angle;
debug_printf("Get CMD_ANGLE : %u, %d, %d\n", ChNum, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum]);
} else { } else {
ChNum = NUM_USB_CHAN_OUT; ChNum = NUM_USB_CHAN_OUT;
for (int i = 0; i < ChNum; i++) { for (int i = 0; i < ChNum; i++) {
@@ -963,6 +1002,27 @@ void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c
unsigned mon_sw = chan_in_word(cc_mic_level); unsigned mon_sw = chan_in_word(cc_mic_level);
SET_SHARED_GLOBAL(g_monitor_switch_t1, mon_sw); SET_SHARED_GLOBAL(g_monitor_switch_t1, mon_sw);
debug_printf("Monitor sync: sw=%d\n", mon_sw); debug_printf("Monitor sync: sw=%d\n", mon_sw);
} else if (tmp == 0xF9) {
uint32_t incoming_angles[8];
for (int i = 0; i < 8; ++i) {
incoming_angles[i] = chan_in_word(cc_mic_level);
}
if (g_runtime_angle_written) {
// 改动原因主机运行期已写入角度时0xF9可能携带启动早期flash旧值此处只消费通道数据但不覆盖当前角度。
debug_printf("Boot sync ex3d angles ignored (runtime angle already written)\n");
} else {
for (int i = 0; i < 8; ++i) {
g_boot_angle_values[i] = incoming_angles[i];
}
g_boot_angle_loaded = 1;
// 改动原因若EX3D已初始化完成0xF9角度同步需要立刻生效
// 否则仅缓存会导致HID GET仍读到初始化时的默认角度。
if (g_ex3d_init_done) {
ex3d_apply_boot_angles();
debug_printf("Boot sync ex3d angles applied immediately (post-init)\n");
}
debug_printf("Boot sync ex3d angles loaded\n");
}
} }
} }
continue; continue;
@@ -1126,6 +1186,11 @@ void ex3d_task(){
} }
// 0xFD boot sync在init前调用了EX3DAudio_SetExpandGaininit后重新应用 // 0xFD boot sync在init前调用了EX3DAudio_SetExpandGaininit后重新应用
EX3DAudio_SetExpandGain(Ex3dExpandGain); EX3DAudio_SetExpandGain(Ex3dExpandGain);
ex3d_apply_boot_angles();
debug_printf("===ex3d_apply_boot_angles after init\n");
g_ex3d_init_done = 1;
debug_printf("ex3d_task init: expand_gain=%d\n", Ex3dExpandGain); debug_printf("ex3d_task init: expand_gain=%d\n", Ex3dExpandGain);
#endif #endif

View File

@@ -465,6 +465,9 @@ static chanend_t g_ex3d_hid_chanend = 0;
static unsigned ex3d_b0b1_result[HID_MAX_DATA_BYTES / 4] = {0}; static unsigned ex3d_b0b1_result[HID_MAX_DATA_BYTES / 4] = {0};
extern unsigned g_hid_expand_gain_request; extern unsigned g_hid_expand_gain_request;
extern unsigned g_hid_lmt_threshold_request; extern unsigned g_hid_lmt_threshold_request;
extern unsigned g_hid_angle_save_request;
extern unsigned g_hid_angle_save_channel;
extern unsigned g_hid_angle_values[8];
void SetEx3dHidChan(chanend_t c) { g_ex3d_hid_chanend = c; } void SetEx3dHidChan(chanend_t c) { g_ex3d_hid_chanend = c; }
#endif #endif
@@ -837,6 +840,34 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
} }
} }
// 若是SET CMD_ANGLE (0x83)通知button_task保存角度到flash
if (data[1] == 0xB0 && ex3d_cmd == 0x83 && params_len >= 8) {
uint32_t ch_num = (uint32_t)data[6] | ((uint32_t)data[7] << 8) |
((uint32_t)data[8] << 16) | ((uint32_t)data[9] << 24);
if (ch_num < 8) {
uint32_t angle_val = (uint32_t)data[10] | ((uint32_t)data[11] << 8) |
((uint32_t)data[12] << 16) | ((uint32_t)data[13] << 24);
// 改动原因:
// - 主机通常会连续发送多个“单通道CMD_ANGLE”来更新多通道例如ch3~ch8依次设置
// - 旧逻辑仅保存一个待处理channelbutton_task轮询周期内后到请求会覆盖先到请求
// 导致flash仅持久化最后一个或少量通道重启后其余通道回默认。
// 修复策略:
// - 在tile0持续维护全量角度缓存 g_hid_angle_values[]
// - 任意一次CMD_ANGLE到达后都触发“全通道保存请求”(channel=0xFFFFFFFF)
// 由button_task一次性把8通道快照落盘避免单槽位请求丢失前序通道更新。
g_hid_angle_values[ch_num] = angle_val;
debug_printf("channel %d angle %d saved\n", ch_num, angle_val);
} else if (params_len >= (4 + 8 * 4)) {
for (int i = 0; i < 8; ++i) {
uint32_t angle_val = (uint32_t)data[10 + i * 4] |
((uint32_t)data[11 + i * 4] << 8) |
((uint32_t)data[12 + i * 4] << 16) |
((uint32_t)data[13 + i * 4] << 24);
g_hid_angle_values[i] = angle_val;
}
}
}
// 发送命令到tile1并同步等待结果 // 发送命令到tile1并同步等待结果
// 协议: cmd(1 byte) + ex3d_cmd_code(4 bytes) + params_len(1 byte) + params(N bytes) // 协议: cmd(1 byte) + ex3d_cmd_code(4 bytes) + params_len(1 byte) + params(N bytes)
chan_out_byte(g_ex3d_hid_chanend, data[1]); chan_out_byte(g_ex3d_hid_chanend, data[1]);

View File

@@ -90,6 +90,18 @@ void save_value(unsigned char *path, unsigned char value)
lfs_deinit(); lfs_deinit();
} }
void save_value32(unsigned char *path, unsigned value)
{
// 改动原因新增32位持久化接口一次性写入完整unsigned值减少原先按字节拆分导致的多次lfs_init/lfs_write开销。
if (lfs_init() == 0)
{
debug_printf("save value32 %08x to %s\n", value, path);
lfs_write_config(path, (unsigned char*) &value, sizeof(value));
}
lfs_deinit();
}
unsigned char load_value(unsigned char *path) unsigned char load_value(unsigned char *path)
{ {
unsigned char value = 255; unsigned char value = 255;
@@ -107,6 +119,24 @@ unsigned char load_value(unsigned char *path)
return value; return value;
} }
unsigned load_value32(unsigned char *path)
{
unsigned value = 0xFFFFFFFF;
// 改动原因新增32位读取接口配合save_value32直接读取完整角度值避免4次单字节读取带来的时延和代码复杂度。
if (lfs_init() == 0)
{
lfs_read_config(path, (unsigned char*) &value, sizeof(value));
debug_printf("load value32 from %s %08x\n", path, value);
}
else
{
debug_printf("lfs_init failed\n");
}
lfs_deinit();
return value;
}
#if (NUM_USB_CHAN_OUT != 0) || (NUM_USB_CHAN_IN != 0) #if (NUM_USB_CHAN_OUT != 0) || (NUM_USB_CHAN_IN != 0)
unsigned short XUA_Endpoint0_getProductId(); unsigned short XUA_Endpoint0_getProductId();

View File

@@ -47,6 +47,17 @@ void save_userconfig_info(unsigned char *buffer);
void load_configs(void); void load_configs(void);
void save_configs(unsigned char save); void save_configs(unsigned char save);
void get_pid_vid(); void get_pid_vid();
#ifdef __XC__
void save_value(unsigned char *unsafe path, unsigned char value);
unsigned char load_value(unsigned char *unsafe path);
void save_value32(unsigned char *unsafe path, unsigned value);
unsigned load_value32(unsigned char *unsafe path);
#else
void save_value(unsigned char *path, unsigned char value);
unsigned char load_value(unsigned char *path);
void save_value32(unsigned char *path, unsigned value);
unsigned load_value32(unsigned char *path);
#endif
#endif #endif