diff --git a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/eq.c b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/eq.c index c64344f..33f3209 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/eq.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/eq.c @@ -19,7 +19,12 @@ void device_reboot(void); extern void SetRoleSwitchFlag(unsigned mode); extern unsigned g_3d_fps; +#if DEBUG_MEMORY_LOG_ENABLED unsigned g_log_switch = 1; +#else +unsigned g_log_switch = 0; +#endif + // 常量定义 #define EQ_DISABLED_MODE 10 // 禁用EQ的模式编号 diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/eq.c.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/eq.c.bak deleted file mode 100644 index f6cb676..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/eq.c.bak +++ /dev/null @@ -1,1330 +0,0 @@ -#if DEBUG_MEMORY_LOG_ENABLED -#define DEBUG_PRINT_ENABLE 1 -#else -#define DEBUG_PRINT_ENABLE 0 -#endif -#include "debug_print.h" -#include "xc_ptr.h" -#include // 添加数学函数支持 - -extern void device_reboot(void); - -#if HID_DFU_EN -#include "dfu_upgrade.h" -#endif - -// 常量定义 -#define EQ_DISABLED_MODE 10 // 禁用EQ的模式编号 -unsigned g_log_switch = 0; - -#include "xmath/filter.h" -#include "eq.h" -#include -#include -#include -#include "eq_params_44100.h" - -#define RSP_HDR(r, cmd) do { (r)[0] = 0x77; (r)[1] = (uint8_t)(cmd); } while(0) - -#include "eq_coefficient_calculator.h" -#include "biquad_standalone.h" -#include "eq_flash_storage.h" -#include "user_func.h" -#if (USE_EX3D == 1) && (HID_CONTROLS == 1) -#include -#endif - -static struct { - uint8_t pending_cmd; // 0xB0/0xB1 or 0 - uint8_t ex3d_params_len; - uint32_t ex3d_command_code; - uint8_t ex3d_params[56]; -} ex3d_request = {0}; - -#if EQ_EN - -unsigned int g_current_eq_mode = 0; -unsigned int g_request_eq_mode = 0; -unsigned int g_new_eq_mode = 9; -unsigned int g_eq_sample_rate = 0; -unsigned int g_force_eq_mode_change = 0; -unsigned int g_force_request_eq_mode_change = 0; -unsigned int g_eq_enable = 0; -unsigned int g_saved_eq_mode = 9; - -// 全局模式信息存储 - 只存储NUM_EQ_MODES条信息 -eq_mode_info_t g_mode_info = {0}; - -static struct { - uint8_t pending_cmd; // HID command code (0 = none pending) - uint8_t mode; - uint8_t eq_index; - uint8_t read_mode_request_mode; -} read_request = {0}; - -// Optimized: 51 entries for integer dB values 0 to -50 (was 183 entries at 0.5dB steps) -// 改动原因:log打印开关全局变量,0=关闭 1=开启;由0x70 SET_LOG_SWITCH 设置,debug_printf 宏在输出前检查该变量 -static const int32_t attenuation_table[51] = { - 0x01000000, // 0dB - 0x00E42905, // -1dB - 0x00CB5918, // -2dB - 0x00B53BEF, // -3dB - 0x00A1866B, // -4dB - 0x008FF599, // -5dB - 0x00804DCE, // -6dB - 0x007259DB, // -7dB - 0x0065EA59, // -8dB - 0x005AD50C, // -9dB - 0x0050F44D, // -10dB - 0x0048268D, // -11dB - 0x00404DE6, // -12dB - 0x00394FAE, // -13dB - 0x00331426, // -14dB - 0x002D8621, // -15dB - 0x002892C1, // -16dB - 0x00242934, // -17dB - 0x00203A7E, // -18dB - 0x001CB942, // -19dB - 0x00199999, // -20dB - 0x0016D0E6, // -21dB - 0x001455B5, // -22dB - 0x00121F97, // -23dB - 0x0010270A, // -24dB - 0x000E655C, // -25dB - 0x000CD494, // -26dB - 0x000B6F62, // -27dB - 0x000A3108, // -28dB - 0x0009154E, // -29dB - 0x0008186E, // -30dB - 0x0007370E, // -31dB - 0x00066E30, // -32dB - 0x0005BB2B, // -33dB - 0x00051B9D, // -34dB - 0x00048D69, // -35dB - 0x00040EAC, // -36dB - 0x00039DB8, // -37dB - 0x0003390C, // -38dB - 0x0002DF53, // -39dB - 0x00028F5C, // -40dB - 0x00024817, // -41dB - 0x00020892, // -42dB - 0x0001CFF5, // -43dB - 0x00019D81, // -44dB - 0x00017089, // -45dB - 0x00014875, // -46dB - 0x000124BD, // -47dB - 0x000104E7, // -48dB - 0x0000E887, // -49dB - 0x0000CF3E, // -50dB -}; - -static inline int get_gain_q24(int input, unsigned multipler){ - int result; - long long intermediate; - intermediate = (long long) input * (long long) multipler; - intermediate = intermediate >> 24; - - if (intermediate > INT32_MAX) { - intermediate = INT32_MAX; - } - else if (intermediate < INT32_MIN) { - intermediate = INT32_MIN; - } - - result = (int)(intermediate); - return result; -} - -static inline int32_t clamp_post_gain(int32_t gain) { - // 限制gain范围:0 >= gain >= -50 - if (gain > 0) { - return 0; - } else if (gain < -50) { - return -50; - } - return gain; -} - -// apply_gain: apply attenuation (Q24 format) -// gain_db is always in range [-50, 0] -static inline int32_t apply_gain(int32_t sample, int32_t gain_db) { - int32_t idx = -gain_db; - if (idx > 50) idx = 50; - return get_gain_q24(sample, attenuation_table[idx]); -} - -// Helper: check if name is empty (all NUL or all spaces) -static bool is_name_empty(const char *name, int len) { - if (name[0] == '\0') return true; - for (int i = 0; i < len && name[i] != '\0'; i++) { - if (name[i] != ' ') return false; - } - return true; -} - -// copy_params_from_44100: set sample rate flag for specified mode -static int copy_params_from_44100(uint32_t sample_rate, uint8_t mode) { - if (mode >= NUM_EQ_MODES) { - return -1; - } - - for (int ch = 0; ch < NUM_EQ_CHANS; ch++) { - sEQ_data_44100HZ[mode][ch].sample_rate = sample_rate; - sEQ_data_44100HZ[mode][ch].total_bshift = 0; - } - - return 0; -} - -// calculate_current_mode_coefficients: dynamically compute coefficients for all bands of a mode -int calculate_current_mode_coefficients(uint32_t sample_rate, uint8_t mode) { - copy_params_from_44100(sample_rate, mode); - - if (mode >= NUM_EQ_MODES) { - return -1; - } - - eq_mode_data_t *eq_data = &sEQ_data_44100HZ[mode][0]; - eq_mode_data_t *eq_data_2 = &sEQ_data_44100HZ[mode][1]; - - // 重置total_bshift - int total_bshift = 0; - - // 遍历所有band,计算系数 - for (int band_index = 0; band_index < MAX_EQ_BANDS; band_index++) { - filter_params_t *band = &eq_data->bands[band_index]; - - // 检查参数有效性 - if (isnan(band->fc) || isnan(band->q) || isnan(band->bw) || isnan(band->gain)) { - band->type = FILTER_TYPE_BYPASS; - band->fc = 1000.0f; - band->q = 0.707f; - band->bw = 1.0f; - band->gain = 0.0f; - } - - q2_30 coeffs[5]; - int calculated_bshift = 0; - - // 根据滤波器类型计算系数 - if (band->type == FILTER_TYPE_BYPASS) { - // bypass类型:直接设置bypass系数,不累加bshift - coeffs[0] = 1 << 30; // b0 = 1.0 in Q30 - coeffs[1] = 0; // b1 = 0 - coeffs[2] = 0; // b2 = 0 - coeffs[3] = 0; // a1 = 0 - coeffs[4] = 0; // a2 = 0 - calculated_bshift = 0; - } else { - // 非bypass类型:调用系数计算函数 - if (eq_calculate_coefficients_from_params(band, sample_rate, coeffs, &calculated_bshift) != 0) { - // 计算失败,使用bypass - coeffs[0] = 1 << 30; - coeffs[1] = 0; - coeffs[2] = 0; - coeffs[3] = 0; - coeffs[4] = 0; - calculated_bshift = 0; - } - // 累加非bypass滤波器的bshift - total_bshift += calculated_bshift; - } - - // 存储计算出的系数到两个通道 - for (int i = 0; i < 5; i++) { - eq_data->filter.coef[i][band_index] = coeffs[i]; - eq_data_2->filter.coef[i][band_index] = coeffs[i]; - } - // 同步band参数到第二个通道 - memcpy(&eq_data_2->bands[band_index], band, sizeof(filter_params_t)); - } - - // 更新total_bshift - eq_data->total_bshift = total_bshift; - eq_data_2->total_bshift = total_bshift; - - return 0; -} - -// Initialize EQ data for the specified sample rate -uint32_t init_eq_data(unsigned sample_freq) { - g_eq_sample_rate = sample_freq; - - // Clear EQ status for all sample rates, modes, and channels - for (int ch = 0; ch < NUM_EQ_CHANS; ch++) { - // Clear status for various sample rates - clear_eq_status(sample_freq, ch); - } - - // 为所有模式计算系数 (calculate_current_mode_coefficients already calls copy_params_from_44100) - for (int mode = 0; mode < NUM_EQ_MODES; mode++) { - calculate_current_mode_coefficients(sample_freq, mode); - } - - return 1; -} - -void update_eq_post_gain(void) { - for (int mode = EQ_USER_MODE_MIN; mode <= EQ_USER_MODE_MAX; mode++) { - int32_t gain = clamp_post_gain(g_mode_info.mode_gains[mode]); - if (gain != g_mode_info.mode_gains[mode]) { - g_mode_info.mode_gains[mode] = gain; - } - - if (sEQ_data_44100HZ[mode][0].post_gain_db != gain) { - sEQ_data_44100HZ[mode][0].post_gain_db = gain; - sEQ_data_44100HZ[mode][1].post_gain_db = gain; - } - } -} - -unsigned int is_mode_changed(void) -{ - if ((g_current_eq_mode != g_new_eq_mode) || (g_force_eq_mode_change == 1)) - { - g_force_eq_mode_change = 0; - return 1; - } - - return 0; -} - -void change_eq_mode(unsigned sample_freq) -{ - calculate_current_mode_coefficients(sample_freq, g_new_eq_mode); - g_current_eq_mode = g_new_eq_mode; -} - -unsigned int is_eq_disabled(void) -{ - return (g_eq_enable == 0); -} - -void clear_eq_status(unsigned sample_freq, unsigned ch_no) { - if(is_eq_disabled()) - { - return; - } - - // Clear status for the specified sample rate, mode, and channel - memset(sEQ_data_44100HZ[g_current_eq_mode][ch_no].filter.state, 0, - sizeof(sEQ_data_44100HZ[g_current_eq_mode][ch_no].filter.state)); -} - -// reset_eq_params: restore default EQ parameters for given mode -uint8_t reset_eq_params(uint8_t mode) { - // 检查模式号有效性 - if (mode != 0xFF && mode >= NUM_EQ_MODES) { - return 0x01; // 失败 - } - - // 删除Flash中的EQ参数文件 - delete_flash_eq_params(mode); - - // 删除Flash中的增益和模式名称文件(只删除相应模式的数据) - delete_flash_gain_and_names(mode); - - // 恢复头文件预设参数 - restore_default_eq_params(mode); - - // 恢复默认模式信息 - init_mode_info(); - - return 0x00; // 成功 -} - -int32_t handler_eq_filter(unsigned sample_freq, uint32_t ch, int32_t new_sample) { - int32_t temp_sample = new_sample; - - - if(is_eq_disabled()) - { - return temp_sample; - } - - - if (ch < NUM_EQ_CHANS) { - eq_mode_data_t *eq = &sEQ_data_44100HZ[g_current_eq_mode][ch]; - - // 应用增益或衰减 (Q24格式) - int32_t post_gain = eq->post_gain_db; - if (post_gain <= 0 && post_gain >= -50) { - temp_sample = apply_gain(temp_sample, post_gain); - } - - temp_sample = temp_sample >> 1; //Q30 - - // 应用均衡器滤波 - temp_sample = filter_biquads_s32(&eq->filter, 1, temp_sample); - - // 应用bshift补偿 - unsigned int bshift = eq->total_bshift; - - // Q2.30 -> Q31,溢出保护 - if (temp_sample > (INT32_MAX >> (bshift + 1))) { - temp_sample = INT32_MAX; - } else if (temp_sample < (INT32_MIN >> (bshift + 1))) { - temp_sample = INT32_MIN; - } else { - temp_sample = temp_sample << (bshift + 1); - } - } - - return temp_sample; -} - - - - -#endif - - -unsigned key_program = 0; - -extern unsigned short XUA_Endpoint0_getProductId(); -extern unsigned short XUA_Endpoint0_getVendorId(); -extern char* XUA_Endpoint0_getProductStr(); -extern char* XUA_Endpoint0_getVendorStr(); -extern char* XUA_Endpoint0_getSerialStr(); -extern unsigned g_request_volume_set; - -void get_device_info(unsigned char *response) { - unsigned short pid = XUA_Endpoint0_getProductId(); - unsigned short vid = XUA_Endpoint0_getVendorId(); - - // 产品ID (1字节,小端序,位置3-4) - response[2] = (uint8_t)(pid & 0xFF); - response[3] = (uint8_t)((pid >> 8) & 0xFF); - - // 厂商ID (1字节,小端序,位置5-6) - response[4] = (uint8_t)(vid & 0xFF); - response[5] = (uint8_t)((vid >> 8) & 0xFF); - - // 产品字符串 (15字节,UTF-8编码,位置7-22) - memcpy(&response[6], XUA_Endpoint0_getProductStr(), 16); - - // 厂商字符串 (15字节,UTF-8编码,位置23-38) - memcpy(&response[22], XUA_Endpoint0_getVendorStr(), 16); - - // 序列号字符串 (15字节,UTF-8编码,位置39-54) - memcpy(&response[38], XUA_Endpoint0_getSerialStr(), 16); -} - - - - -#if EQ_EN -// Shared EQ band param update logic — called from 0x8D HID handler and UART handler -static bool apply_eq_band_params(uint8_t mode, uint8_t band_index, uint8_t filter_type, - float fc, float q, float bw, float gain) -{ - if (isnan(fc) || isnan(q) || isnan(bw) || isnan(gain) || fc == 0) { - return false; - } - - filter_params_t new_params; - memset(&new_params, 0, sizeof(filter_params_t)); - new_params.index = band_index; - new_params.type = (filter_type_t)filter_type; - new_params.fc = fc; - new_params.q = q; - new_params.bw = bw; - new_params.gain = gain; - - filter_params_t *band_44100 = &sEQ_data_44100HZ[mode][0].bands[band_index]; - - if (eq_single_params_different(band_44100, &new_params)) { - *band_44100 = new_params; - memcpy(&sEQ_data_44100HZ[mode][1].bands[band_index], band_44100, sizeof(filter_params_t)); - - if (g_eq_enable == 1) { - SET_SHARED_GLOBAL(g_force_request_eq_mode_change, 1); - } - - uint32_t all_sample_rates[] = {48000, 88200, 96000, 176400, 192000}; - for (int i = 0; i < (int)(sizeof(all_sample_rates)/sizeof(all_sample_rates[0])); i++) { - calculate_current_mode_coefficients(all_sample_rates[i], mode); - } - calculate_current_mode_coefficients(44100, mode); - - eq_process_single_param_change(44100, mode, 0, band_index, band_44100); - eq_flash_mark_dirty(mode); - } - - return true; -} -#endif - -void program_key(unsigned char *, signed int); -#if (USE_EX3D == 1) && (HID_CONTROLS == 1) -extern void hid_receive_task_in_c(unsigned char * RcvData, unsigned * SendData); -#ifndef HID_MAX_DATA_BYTES -#define HID_MAX_DATA_BYTES (64) -#endif -static chanend_t g_ex3d_hid_chanend = 0; -static unsigned ex3d_b0b1_result[HID_MAX_DATA_BYTES / 4] = {0}; -extern unsigned g_hid_expand_gain_request; -extern unsigned g_hid_lmt_threshold_request; -void SetEx3dHidChan(chanend_t c) { g_ex3d_hid_chanend = c; } -#endif - -// 0x84 FACTORY_RESET: 删除Flash参数后触发重启(由button_task轮询执行) -extern unsigned g_request_factory_reset; -extern int lfs_remove_file(const char *path); -unsigned char process_send_params(uint8_t data[], uint16_t len) { - if (len < 60) { - return false; - } - - if (data[0] == 0x77 && data[1] == 0x5B && key_program == 0) - { - key_program = 1; - program_key(data, len); - } - -#if EQ_EN - // Check sync header - if (data[0] != 0x77) { - return false; - } - - // Process read request (0x8E) - GET_EQ_PARAMS - if (data[1] == 0x8E) { - // Get mode value - read_request.mode = data[2]; - // Get EQ index - read_request.eq_index = data[3]; - read_request.pending_cmd = 0x8E; - } - - if (data[1] == 0x8a) - { - if (data[2] > EQ_MODE_MAX ) { - return false; - } - SET_SHARED_GLOBAL(g_request_eq_mode, data[2]); - return true; - } - - // 处理读取EQ模式信息命令 (0x8B) - GET_EQ_MODE - if (data[1] == 0x8b) { - uint8_t mode = data[2]; - - // 验证mode参数:0xFF表示获取当前模式,0-9表示获取指定模式 - if (mode == 0xFF) { - read_request.pending_cmd = 0x8B; - read_request.read_mode_request_mode = 0xFF; - } else if (mode <= EQ_MODE_MAX) { - // 获取指定模式信息 - read_request.pending_cmd = 0x8B; - read_request.read_mode_request_mode = mode; - } else { - return false; - } - return true; - } - // 处理设置EQ整体增益和名称命令 (0x8C) - SET_MODE_GAIN_AND_NAME - if (data[1] == 0x8c) { - // 获取模式值 - uint8_t mode = data[2]; - - if (mode < EQ_USER_MODE_MIN || mode > EQ_USER_MODE_MAX ) { - return false; - } - // 获取增益值 (4字节,范围0到-50dB) - uint32_t gain = (uint32_t)data[3] | ((uint32_t)data[4] << 8) | ((uint32_t)data[5] << 16) | ((uint32_t)data[6] << 24); - - int32_t new_gain = clamp_post_gain((int32_t)gain); - - // 获取模式名称 (16字节,UTF-8编码) - char mode_name[17] = {0}; // 16字节 + 1个null终止符 - memcpy(mode_name, &data[7], 16); - mode_name[16] = '\0'; // 确保null终止 - - // 获取44100采样率下该模式的当前gain值,判断是否有变化 - int32_t current_gain_44100 = sEQ_data_44100HZ[mode][0].post_gain_db; - bool gain_changed = (current_gain_44100 != new_gain); - - // 获取当前模式名称,判断是否有变化 - char current_name[16] = {0}; - strncpy(current_name, g_mode_info.mode_names[mode], 15); - current_name[15] = '\0'; - - // 比较名称是否有变化 - bool name_changed = (strncmp(current_name, mode_name, 15) != 0); - - if (!is_name_empty(mode_name, 16) && name_changed) { - set_mode_name(mode, mode_name); - eq_mark_name_dirty(); - } - - if (gain_changed) { - if (mode < NUM_EQ_MODES) { - sEQ_data_44100HZ[mode][0].post_gain_db = new_gain; - sEQ_data_44100HZ[mode][1].post_gain_db = new_gain; - } - - set_mode_gain(mode, new_gain); - eq_mark_gain_dirty(); - } - - return true; - } - - // 处理获取设备信息命令 (0x8F) - GET_DEVICE_INFO - if (data[1] == 0x8f) { - read_request.pending_cmd = 0x8F; - return true; - } - - // 处理复位EQ参数命令 (0x90) - RESET_EQ_PARAMS - if (data[1] == 0x90) { - // 获取模式号 - uint8_t mode = data[2]; - - reset_eq_params(mode); - - // 设置读取请求标志,读取时只返回保存的状态 - read_request.pending_cmd = 0x90; - read_request.mode = mode; - - device_reboot(); - while(1); // 防止编译器警告 - - return true; - } - - if (data[1] == 0x91) - { - // 设置读取请求,返回EQ模式总数 - read_request.pending_cmd = 0x91; - return true; - } - - // 处理设置并保存EQ模式命令 (0x92) - SET_AND_SAVE_EQ_MODE - if (data[1] == 0x92) { - read_request.pending_cmd = 0x92; - - // 获取模式值 - uint8_t mode = data[2]; - - // 验证模式值范围 - if (mode > EQ_MODE_MAX ) { - read_request.mode = 0xFF; // 使用0xFF表示失败 - return true; - } - - // 设置当前模式 - SET_SHARED_GLOBAL(g_request_eq_mode, mode); - - // 更新保存的模式(用于0x9D启用时恢复) - g_saved_eq_mode = mode; - - // 保存到Flash(只保存模式,不影响使能状态) - eq_flash_save_current_mode(mode); - read_request.mode = mode; - - return true; - } - - // 处理设置麦克风增益命令 (0x82) - SET_MIC_VOLUME - // 范围: 0-37 (0=mute, 1-37=0dB~36dB, 1dB/步; register=38的+1.5dB仅firmware内部) - if (data[1] == 0x82) { - uint8_t mic_level = data[2]; - - // 参数验证: 0-37 - if (mic_level > 37) { - return false; - } - - extern unsigned g_mic_volume_level; - extern unsigned g_request_mic_volume_set; - g_mic_volume_level = mic_level; - g_request_mic_volume_set = 1; - read_request.pending_cmd = 0x83; // 设置后用0x83格式回报当前增益 - - return true; - } - - // 处理读取麦克风增益命令 (0x83) - GET_MIC_VOLUME - if (data[1] == 0x83) { - read_request.pending_cmd = 0x83; - return true; - } - - // 处理设置AI降噪强度命令 (0x85) - SET_AI_NOISE_STRENGTH - // 有效值: 0(关闭), 2,4,...,100(步进2); 强度映射: strength*2 → dB (100→-200dB) - if (data[1] == 0x85) { - uint8_t strength = data[2]; - if (strength > 100 || (strength != 0 && strength % 2 != 0)) { - return false; - } - extern unsigned g_dnr_strength; - extern unsigned g_request_dnr_strength_set; - g_dnr_strength = strength; - g_request_dnr_strength_set = 1; - read_request.pending_cmd = 0x86; // 设置后用0x86格式回报当前强度 - return true; - } - - // 处理读取AI降噪强度命令 (0x86) - GET_AI_NOISE_STRENGTH - if (data[1] == 0x86) { - read_request.pending_cmd = 0x86; - return true; - } - - // 处理设置耳返开关命令 (0x87) - SET_MONITOR_SWITCH - // 0=关闭耳返(ADC不路由到耳机输出),1=开启耳返 - if (data[1] == 0x87) { - uint8_t mon_sw = data[2]; - if (mon_sw > 1) { - return false; - } - extern unsigned g_monitor_switch; - extern unsigned g_request_monitor_switch_set; - g_monitor_switch = mon_sw; - g_request_monitor_switch_set = 1; - read_request.pending_cmd = 0x88; // 设置后用0x88格式回报当前状态 - return true; - } - - // 处理读取耳返开关命令 (0x88) - GET_MONITOR_SWITCH - if (data[1] == 0x88) { - read_request.pending_cmd = 0x88; - return true; - } - - // 处理设置音量命令 (0x93) - SET_VOLUME - // 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步) - if (data[1] == 0x93) { - // 获取音量级别 - uint8_t volume_level = data[2]; - - // 参数验证: 0-29 (0=mute, 1-29=-28dB~0dB, 1dB/步) - if (volume_level > 29) { - return false; - } - - // 设置全局变量(直接赋值,因为在C文件中) - extern unsigned g_volume_level; - g_volume_level = volume_level; - g_request_volume_set = 1; - - return true; - } - - // 处理读取音量命令 (0x94) - GET_VOLUME - if (data[1] == 0x94) { - read_request.pending_cmd = 0x94; - return true; - } - - // 处理设置EQ使能开关命令 (0x9D) - SET_EQ_ENABLE - if (data[1] == 0x9D) { - uint8_t enable = data[2]; // 0=OFF禁用, 1=ON启用 - - if (enable > 1) { - return false; - } - - g_eq_enable = enable; - - // 只保存EQ使能状态到Flash,不影响已保存的模式(0x92保存的模式) - eq_flash_save_eq_enable(enable); - - read_request.pending_cmd = 0x9D; - return true; - } - - // 处理获取EQ使能开关命令 (0x9E) - GET_EQ_ENABLE - if (data[1] == 0x9E) { - read_request.pending_cmd = 0x9E; - return true; - } - - // 处理获取采样率和格式命令 (0x9F) - GET_SAMPLE_FORMAT - if (data[1] == 0x9F) { - read_request.pending_cmd = 0x9F; - return true; - } - - // 处理设置音效模式命令 (0xA4) - SET_SOUND_EFFECT_MODE - // 0=无音效(EQ/EX3D全关), 1=音乐模式, 2=游戏模式, 3=AI7.1模式 - if (data[1] == 0xA4) { - uint8_t game_mode = data[2]; - - // 参数验证:0-3 - if (game_mode > 3) { - return false; - } - - extern unsigned g_request_game_mode; - SET_SHARED_GLOBAL(g_request_game_mode, game_mode); - - return true; - } - - // 处理获取音效模式命令 (0xA5) - GET_SOUND_EFFECT_MODE - if (data[1] == 0xA5) { - read_request.pending_cmd = 0xA5; - return true; - } - - // 处理获取固件版本命令 (0xA6) - GET_FIRMWARE_VERSION - if (data[1] == 0xA6) { - read_request.pending_cmd = 0xA6; - return true; - } - - // 处理设置log打印开关命令 (0x70) - SET_LOG_SWITCH - // 改动原因:添加0x70命令,用全局变量g_log_switch记录开关状态(0=关闭 1=开启),debug_printf 据此决定是否输出 - if (data[1] == 0x70) { - uint8_t on = data[2]; - if (on > 1) { - debug_printf("Error: Invalid log switch %d (must be 0 or 1)\n", on); - return false; - } - g_log_switch = on; - debug_printf("Log switch set to %d (0=off, 1=on)\n", on); - return true; - } - - - - // 处理恢复出厂默认命令 (0x84) - FACTORY_RESET - if (data[1] == 0x84) { - // 通知button_task在合适时机删除其他文件并重启 - SET_SHARED_GLOBAL(g_request_factory_reset, 1); - read_request.pending_cmd = 0x84; - return true; - } - - // 处理发送/读取EX3D命令 (0xB0/0xB1) - SET_EX3D_CMD / GET_EX3D_CMD - // 数据通过 g_ex3d_hid_chanend 直接传到tile1的hid_button_task执行,结果同步返回 - if (data[1] == 0xB0 || data[1] == 0xB1) { -#if (USE_EX3D == 1) && (HID_CONTROLS == 1) - if (!g_ex3d_hid_chanend) return false; - - // 提取EX3D命令码(4字节,小端序) - uint32_t ex3d_cmd = (uint32_t)data[2] | ((uint32_t)data[3] << 8) | - ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 24); - - uint8_t params_len = (uint8_t)((len > 62) ? 56 : (len > 6 ? len - 6 : 0)); - - // 存储到ex3d_request供process_read_params构建响应 - ex3d_request.ex3d_command_code = ex3d_cmd; - ex3d_request.ex3d_params_len = params_len; - if (params_len > 0) memcpy(ex3d_request.ex3d_params, &data[6], params_len); - ex3d_request.pending_cmd = data[1]; - - // 若是SET CMD_EXPAND_GAIN (0x93),同步更新footstep LED状态 - if (data[1] == 0xB0 && ex3d_cmd == 0x93 && params_len >= 4) { - uint32_t gain_val = (uint32_t)data[6] | ((uint32_t)data[7] << 8) | - ((uint32_t)data[8] << 16) | ((uint32_t)data[9] << 24); - SET_SHARED_GLOBAL(g_hid_expand_gain_request, gain_val); - } - - // 若是SET CMD_LMT_THRESHOLD (0x87),通知button_task保存阈值到flash - // 存储编码: -threshold (0~35),避免与哨兵值0xFFFFFFFF冲突 - if (data[1] == 0xB0 && ex3d_cmd == 0x87 && params_len >= 4) { - int32_t threshold_val = (int32_t)((uint32_t)data[6] | ((uint32_t)data[7] << 8) | - ((uint32_t)data[8] << 16) | ((uint32_t)data[9] << 24)); - if (threshold_val >= -35 && threshold_val <= 0) { - // Encode as (-threshold_val + 1) so range is 1~36. - // Avoids save_code=0 (flash "uninitialized" sentinel) when threshold_val=0. - uint32_t save_code = (uint32_t)(-threshold_val) + 1; - SET_SHARED_GLOBAL(g_hid_lmt_threshold_request, save_code); - } - } - - // 发送命令到tile1并同步等待结果 - // 协议: 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_word(g_ex3d_hid_chanend, ex3d_cmd); - chan_out_byte(g_ex3d_hid_chanend, params_len); - for (int i = 0; i < params_len; i++) { - chan_out_byte(g_ex3d_hid_chanend, data[6 + i]); - } - // 接收tile1返回的结果(16个word) - for (int i = 0; i < (HID_MAX_DATA_BYTES / 4); i++) { - ex3d_b0b1_result[i] = chan_in_word(g_ex3d_hid_chanend); - } - return true; -#else - return false; -#endif - } - - if (data[1] == 0x8d) - { - uint8_t mode = data[2]; - if (mode < EQ_USER_MODE_MIN || mode > EQ_USER_MODE_MAX) { - return false; - } - uint8_t band_index = data[3]; - if (band_index >= MAX_EQ_BANDS) { - return false; - } - // 解析浮点参数(小端序) - float fc, q, bw, gain; - uint32_t v; - v = data[5]|(data[6]<<8)|(data[7]<<16)|(data[8]<<24); memcpy(&fc, &v, 4); - v = data[9]|(data[10]<<8)|(data[11]<<16)|(data[12]<<24); memcpy(&q, &v, 4); - v = data[13]|(data[14]<<8)|(data[15]<<16)|(data[16]<<24);memcpy(&bw, &v, 4); - v = data[17]|(data[18]<<8)|(data[19]<<16)|(data[20]<<24);memcpy(&gain, &v, 4); - return apply_eq_band_params(mode, band_index, data[4], fc, q, bw, gain); - } - -#endif // #if EQ_EN (for process_send_params EQ commands section starting at line 1228) - -#if HID_DFU_EN - // 0xA7 START: 转发到button_task (tile[0])执行,因为flash访问需要在tile[0]进行 - if (data[1] == FIRMWARE_UPGRADE_START) { - dfu_chan_forward(data, len); - return true; - } - // 0xA8 DATA / 0xA9 END / 0xAA STATUS / 0xAB ABORT / 0xAC ERASE: 直接处理 - if (data[1] >= FIRMWARE_UPGRADE_DATA && data[1] <= FIRMWARE_UPGRADE_ERASE) { - unsigned char result; - if (data[1] == FIRMWARE_UPGRADE_DATA) - result = handle_firmware_upgrade_data(data, len); - else if (data[1] == FIRMWARE_UPGRADE_END) - result = handle_firmware_upgrade_end(data, len); - else if (data[1] == FIRMWARE_UPGRADE_STATUS) - result = handle_firmware_upgrade_status(data, len); - else if (data[1] == FIRMWARE_UPGRADE_ABORT) - result = handle_firmware_upgrade_abort(data, len); - else - result = handle_firmware_upgrade_erase(data, len); - (void)result; - return true; - } -#endif - - // 0xAE DEVICE_REBOOT (通用命令,不仅限于固件升级) - if (data[1] == 0xAE) { - debug_printf("Received device REBOOT command (0xAE)\n"); - device_reboot(); - while(1); - return true; - } - - return true; -} - -#if EQ_EN - -// 标记增益和模式名称为脏(延迟保存) -extern void eq_mark_gain_dirty(void); -extern void eq_mark_name_dirty(void); - -// set_mode_gain: set gain for specified mode -void set_mode_gain(uint8_t mode, int32_t gain) { - if (mode >= NUM_EQ_MODES) { - return; - } - - int32_t clamped_gain = clamp_post_gain(gain); - - // 设置模式增益 - g_mode_info.mode_gains[mode] = clamped_gain; - - // 注意:不在这里自动标记脏标志,由调用者根据实际情况决定是否标记 -} - -// set_mode_name: set name for specified mode -void set_mode_name(uint8_t mode, const char* name) { - if (mode >= NUM_EQ_MODES || name == NULL) { - return; - } - - // 设置模式名称 - strncpy(g_mode_info.mode_names[mode], name, 15); - g_mode_info.mode_names[mode][15] = '\0'; // 确保null终止 - - // 注意:不在这里自动标记脏标志,由调用者根据实际情况决定是否标记 -} - -// get_mode_gain: retrieve gain for specified mode -void get_mode_gain(uint8_t mode, int32_t* gain) { - if (mode >= NUM_EQ_MODES || gain == NULL) { - return; - } - - *gain = g_mode_info.mode_gains[mode]; -} - -// get_mode_name: retrieve name for specified mode -void get_mode_name(uint8_t mode, char* name) { - if (mode >= NUM_EQ_MODES || name == NULL) { - return; - } - - strncpy(name, g_mode_info.mode_names[mode], 15); - name[15] = '\0'; // 确保null终止 -} - -// init_mode_info: initialize mode info with default names and gains -void init_mode_info(void) { - // 初始化默认模式名称 - const char* default_names[NUM_EQ_MODES] = { - "JAZZ", "POP", "ROCK", "CLASIC", "R&B", - "3A Game", "FPS", "HI-FI", "VOCAL", "DANCE", - "user 1", "user 2" - }; - - // 初始化默认增益(0dB) - for (int i = 0; i < NUM_EQ_MODES; i++) { - g_mode_info.mode_gains[i] = 0; - strncpy(g_mode_info.mode_names[i], default_names[i], 15); - g_mode_info.mode_names[i][15] = '\0'; - } -} - -#endif - -void get_key_ret(uint8_t *buffer); - -// process_read_params: build HID response from pending request state -unsigned char process_read_params(uint8_t response[]) { - memset(response, 0, 63); - -#if EQ_EN - // 处理读取当前EQ模式的请求 (0x8B) - GET_EQ_MODE - if (read_request.pending_cmd == 0x8B) { - RSP_HDR(response, 0x8B); - - // 确定要返回的模式值 - uint8_t target_mode; - if (read_request.read_mode_request_mode == 0xFF) { - // 获取当前模式(eq_enable是全局开关,不影响模式返回) - unsigned int current_mode; - GET_SHARED_GLOBAL(current_mode, g_request_eq_mode); - target_mode = current_mode; - } else { - // 获取指定模式 - target_mode = read_request.read_mode_request_mode; - } - - // 模式值 - response[2] = target_mode; - - if (target_mode >= EQ_DISABLED_MODE || target_mode > EQ_MODE_MAX) { - // 返回全0 - memset(&response[3], 0, 20); // 整体增益(4字节) + 模式名称(16字节) = 20字节 - } else { - // 获取指定模式的整体增益 (从当前采样率获取) - int32_t target_post_gain = 0; - if (target_mode < NUM_EQ_MODES) { - target_post_gain = sEQ_data_44100HZ[target_mode][0].post_gain_db; - } - - // 整体增益 (4字节,位置3-6) - memcpy(&response[3], &target_post_gain, 4); - - // 模式名称 (16字节,UTF-8编码,位置7-22) - if (target_mode < NUM_EQ_MODES) { - memcpy(&response[7], g_mode_info.mode_names[target_mode], 16); - } else { - // 如果模式超出范围,填充0 - memset(&response[7], 0, 16); - } - } - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理获取设备信息的请求 (0x8F) - GET_DEVICE_INFO - if (read_request.pending_cmd == 0x8F) { - RSP_HDR(response, 0x8F); - - get_device_info(response); - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理复位EQ参数的请求 (0x90) - RESET_EQ_PARAMS - if (read_request.pending_cmd == 0x90) { - RSP_HDR(response, 0x90); - - if (read_request.mode != 0xFF && read_request.mode >= EQ_PRESET_MODE_MIN && read_request.mode <= EQ_USER_MODE_MAX) { - response[3] = 0x01; // 失败 - } else { - response[3] = 0x00; // 成功 - } - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理获取EQ模式总数的请求 (0x91) - GET_EQ_MODE_COUNT - if (read_request.pending_cmd == 0x91) { - RSP_HDR(response, 0x91); - - // 模式总数:预定义模式(0-9) + 用户模式(10-11) = 12,不包含禁用模式(12) - uint8_t mode_count = NUM_EQ_MODES; // 固定返回12 - response[2] = mode_count; - - // 预定义模式数量:0-9共10个预设模式 - uint8_t preset_mode_count = EQ_PRESET_MODE_MAX + 1; - response[3] = preset_mode_count; - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理设置并保存EQ模式的请求 (0x92) - SET_AND_SAVE_EQ_MODE - if (read_request.pending_cmd == 0x92) { - RSP_HDR(response, 0x92); - - // 状态码:0x00=成功, 0x01=失败 - uint8_t status = (read_request.mode == 0xFF) ? 0x01 : 0x00; - response[2] = status; - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - // 处理读取麦克风增益请求 (0x83) - GET_MIC_VOLUME - if (read_request.pending_cmd == 0x83) { - RSP_HDR(response, 0x83); - - extern unsigned g_mic_volume_level; - response[2] = (uint8_t)g_mic_volume_level; - - read_request.pending_cmd = 0; - return true; - } - - // 处理AI降噪强度请求/响应 (0x86) - GET_AI_NOISE_STRENGTH - if (read_request.pending_cmd == 0x86) { - RSP_HDR(response, 0x86); - - extern unsigned g_dnr_strength; - response[2] = (uint8_t)g_dnr_strength; - - read_request.pending_cmd = 0; - return true; - } - - // 处理耳返开关请求/响应 (0x88) - GET_MONITOR_SWITCH - if (read_request.pending_cmd == 0x88) { - RSP_HDR(response, 0x88); - - extern unsigned g_monitor_switch; - response[2] = (uint8_t)g_monitor_switch; - - read_request.pending_cmd = 0; - return true; - } - - // 处理读取音量请求 (0x94) - GET_VOLUME - if (read_request.pending_cmd == 0x94) { - RSP_HDR(response, 0x94); - - // 读取全局变量(直接读取,因为在C文件中) - extern unsigned g_volume_level; - unsigned volume_level = g_volume_level; - - // 当前音量级别 (1字节,位置2) - response[2] = (uint8_t)volume_level; - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理设置EQ使能开关请求 (0x9D) - SET_EQ_ENABLE - if (read_request.pending_cmd == 0x9D) { - RSP_HDR(response, 0x9D); - - // 状态码:0x00=成功, 0x01=失败 - response[2] = 0x00; // 成功 - - // 当前EQ使能状态(全局开关,所有模式共用) - response[3] = g_eq_enable; - - read_request.pending_cmd = 0; // Clear request flag - return true; - } - - // 处理获取EQ使能开关请求 (0x9E) - GET_EQ_ENABLE - if (read_request.pending_cmd == 0x9E) { - RSP_HDR(response, 0x9E); - - // EQ使能开关状态(全局开关,所有模式共用) - response[2] = g_eq_enable; - - read_request.pending_cmd = 0; // Clear request flag - return true; - } - - // 处理获取采样率和格式请求 (0x9F) - GET_SAMPLE_FORMAT - if (read_request.pending_cmd == 0x9F) { - RSP_HDR(response, 0x9F); - - // 读取全局变量(使用SHARED_GLOBAL宏) - extern unsigned g_samfreq, g_dsd_mode; - unsigned samfreq, dsd_mode; - GET_SHARED_GLOBAL(samfreq, g_samfreq); - GET_SHARED_GLOBAL(dsd_mode, g_dsd_mode); - - // 采样率(32位,小端序,位置2-5) - memcpy(&response[2], &samfreq, 4); - - // DSD模式(1字节,位置6) - response[6] = (uint8_t)dsd_mode; - - read_request.pending_cmd = 0; // Clear request flag - return true; - } - - // 处理获取游戏模式请求 (0xA5) - GET_GAME_MODE - if (read_request.pending_cmd == 0xA5) { - RSP_HDR(response, 0xA5); - - // 读取全局变量(使用SHARED_GLOBAL宏) - extern unsigned g_game_mode; - unsigned game_mode; - GET_SHARED_GLOBAL(game_mode, g_game_mode); - - // 当前游戏模式 (1字节,位置2) - response[2] = (uint8_t)game_mode; - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理获取固件版本请求 (0xA6) - GET_FIRMWARE_VERSION - if (read_request.pending_cmd == 0xA6) { - RSP_HDR(response, 0xA6); - - // 读取固件版本号(BCD格式) - response[2] = (uint8_t)BCD_DEVICE_J; // 主版本号 - response[3] = (uint8_t)BCD_DEVICE_M; // 次版本号 - response[4] = (uint8_t)BCD_DEVICE_N; // 修订版本号 - - read_request.pending_cmd = 0; // Clear read request flag - return true; - } - - // 处理恢复出厂默认响应 (0x84) - FACTORY_RESET - if (read_request.pending_cmd == 0x84) { - RSP_HDR(response, 0x84); - response[2] = 0x00; // 成功 - read_request.pending_cmd = 0; - return true; - } - - // 处理发送EX3D命令响应 (0xB0) - SET_EX3D_CMD - // 结果已在process_send_params中同步从tile1获取,存于ex3d_b0b1_result - if (ex3d_request.pending_cmd == 0xB0) { - RSP_HDR(response, 0xB0); - -#if (USE_EX3D == 1) && (HID_CONTROLS == 1) - unsigned *send_data = ex3d_b0b1_result; - - // 状态码:检查send_data[1]是否有错误返回值(0xFFFFFFFF表示参数错误) - uint8_t status = (send_data[1] == 0xFFFFFFFF) ? 0x01 : 0x00; - response[2] = status; - - // 回显命令码(4字节) - response[3] = (uint8_t)(ex3d_request.ex3d_command_code & 0xFF); - response[4] = (uint8_t)((ex3d_request.ex3d_command_code >> 8) & 0xFF); - response[5] = (uint8_t)((ex3d_request.ex3d_command_code >> 16) & 0xFF); - response[6] = (uint8_t)((ex3d_request.ex3d_command_code >> 24) & 0xFF); - - // 返回send_data[1]中的返回值 - response[7] = (uint8_t)(send_data[1] & 0xFF); - response[8] = (uint8_t)((send_data[1] >> 8) & 0xFF); - response[9] = (uint8_t)((send_data[1] >> 16) & 0xFF); - response[10] = (uint8_t)((send_data[1] >> 24) & 0xFF); -#else - response[2] = 0x01; // 失败:EX3D支持未启用 -#endif - - ex3d_request.pending_cmd = 0; // Clear request flag - return true; - } - - // 处理读取EX3D命令响应 (0xB1) - GET_EX3D_CMD - // 结果已在process_send_params中同步从tile1获取,存于ex3d_b0b1_result - if (ex3d_request.pending_cmd == 0xB1) { - RSP_HDR(response, 0xB1); - -#if (USE_EX3D == 1) && (HID_CONTROLS == 1) - unsigned *send_data = ex3d_b0b1_result; - - // 回显命令码(4字节) - response[2] = (uint8_t)(ex3d_request.ex3d_command_code & 0xFF); - response[3] = (uint8_t)((ex3d_request.ex3d_command_code >> 8) & 0xFF); - response[4] = (uint8_t)((ex3d_request.ex3d_command_code >> 16) & 0xFF); - response[5] = (uint8_t)((ex3d_request.ex3d_command_code >> 24) & 0xFF); - - // 复制返回值(从send_data[1]开始,最多14个uint32值) - int response_idx = 6; - for (int i = 1; i < 16 && response_idx < 63; i++) { - if (response_idx + 3 < 63) { - response[response_idx++] = (uint8_t)(send_data[i] & 0xFF); - response[response_idx++] = (uint8_t)((send_data[i] >> 8) & 0xFF); - response[response_idx++] = (uint8_t)((send_data[i] >> 16) & 0xFF); - response[response_idx++] = (uint8_t)((send_data[i] >> 24) & 0xFF); - } - } -#else - // EX3D支持未启用,返回错误 - response[2] = 0xFF; - response[3] = 0xFF; - response[4] = 0xFF; - response[5] = 0xFF; -#endif - - ex3d_request.pending_cmd = 0; // Clear request flag - return true; - } - - if (read_request.pending_cmd == 0x8E) { - - // 检查EQ索引范围 - if (read_request.eq_index >= MAX_EQ_BANDS) { - return false; - } - - // Build response data - RSP_HDR(response, 0x8E); - - response[2] = read_request.mode; // Mode - response[3] = read_request.eq_index & 0xFF; // EQ index - - if (read_request.mode >= EQ_DISABLED_MODE || read_request.mode > EQ_MODE_MAX) { - // 返回全0 - response[4] = 0; // Filter type - memset(&response[5], 0, 16); // 所有参数(fc, q, bw, gain)都设为0 - } else { - // 优先使用44100Hz数据,因为串口设置参数时主要存储到44100Hz - filter_params_t *band = &sEQ_data_44100HZ[read_request.mode][0].bands[read_request.eq_index]; - response[4] = band->type; - - // Copy parameters - 直接写入float值 (位置调整) - memcpy(&response[5], &band->fc, 4); - memcpy(&response[9], &band->q, 4); - memcpy(&response[13], &band->bw, 4); - memcpy(&response[17], &band->gain, 4); - } - - // Copy coefficients - read_request.pending_cmd = 0; // Clear read request flag - - return true; - } -#endif -#if 1 - if (key_program == 1) - { - key_program = 0; - get_key_ret(response); - return true; - } -#endif - return false; -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c.bak deleted file mode 100644 index 62c87ba..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/lfs_services.c.bak +++ /dev/null @@ -1,233 +0,0 @@ -#include -#include -#include -#include "lfs.h" -#include "rtos_qspi_flash.h" -#include "swlock.h" -#include "debug_print.h" -// variables used by the filesystem -lfs_t lfs; -lfs_file_t file; -swlock_t lfs_lock = SWLOCK_INITIAL_VALUE; - -static rtos_qspi_flash_t qspi_flash_ctx_s; -#define FLASH_CLKBLK XS1_CLKBLK_3 -#ifndef FS_BASE_ADDR -#define FS_BASE_ADDR 0x1da000 -#endif -#define SECTOR_SIZE 4096 -rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; - -__attribute__((fptrgroup(" local_block_device_read_fptr_grp"))) -int local_block_device_read(const struct lfs_config *c, lfs_block_t block, - lfs_off_t off, void *buffer, lfs_size_t size) -{ - unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE + off); - qspi_flash_ctx->read(qspi_flash_ctx, buffer, address, size); - return 0; -} - -__attribute__((fptrgroup(" local_block_device_prog_fptr_grp"))) -int local_block_device_prog(const struct lfs_config *c, lfs_block_t block, - lfs_off_t off, const void *buffer, lfs_size_t size) -{ - unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE + off); - qspi_flash_ctx->write(qspi_flash_ctx, buffer, address, size); - return 0; -} - -__attribute__((fptrgroup(" local_block_device_erase_fptr_grp"))) -int local_block_device_erase(const struct lfs_config *c, lfs_block_t block) -{ - unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE); - qspi_flash_ctx->erase(qspi_flash_ctx, address, SECTOR_SIZE); - return 0; -} - -__attribute__((fptrgroup(" local_block_device_sync_fptr_grp"))) -int local_block_device_sync(const struct lfs_config *c) -{ - return 0; -} - -// configuration of the filesystem is provided by this struct -const struct lfs_config cfg = { - // block device operations - .read = local_block_device_read, - .prog = local_block_device_prog, - .erase = local_block_device_erase, - .sync = local_block_device_sync, - - // block device configuration - .read_size = 16, - .prog_size = 16, - .block_size = 4096, - .block_count = 128, - .cache_size = 16, - .lookahead_size = 16, - .block_cycles = 500, -}; - -int lfs_init(void) { - swlock_acquire(&lfs_lock); - rtos_qspi_flash_init( - qspi_flash_ctx, - FLASH_CLKBLK, - XS1_PORT_1B, - XS1_PORT_1C, - XS1_PORT_4B, - NULL); - - - // mount the filesystem - int err = lfs_mount(&lfs, &cfg); - - // reformat if we can't mount the filesystem - // this should only happen on the first boot - if (err) { - debug_printf("no lfs partiton is found, formating ...\n"); - lfs_format(&lfs, &cfg); - lfs_mount(&lfs, &cfg); - swlock_release(&lfs_lock); - return -1; - } - swlock_release(&lfs_lock); - return 0; - -} - -void lfs_deinit(void) { - swlock_acquire(&lfs_lock); - lfs_unmount(&lfs); - swlock_release(&lfs_lock); -} - -#pragma stackfunction 1300 -void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned size) -{ - swlock_acquire(&lfs_lock); - debug_printf("lfs_read_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); - debug_printf("lfs_read_config: %s, result: %d\n", config, result); - if (result != 0) { - debug_printf("lfs_read_config: %s, open file failed\n", config); - swlock_release(&lfs_lock); - return; - } - debug_printf("lfs_read_config: %s, file opened\n", config); - result = lfs_file_read(&lfs, &file, buffer, size); - debug_printf("lfs_read_config: %s, result: %d\n", config, result); - if (result < 0) { - debug_printf("lfs_read_config: %s, read file failed, error: %d\n", config, result); - // Update: Added lfs_file_close to ensure file is closed even on error. - // Missing this caused subsequent open calls to assert/crash. - lfs_file_close(&lfs, &file); - swlock_release(&lfs_lock); - return; - } - lfs_file_close(&lfs, &file); - swlock_release(&lfs_lock); -} - - -#pragma stackfunction 1300 -void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned size) -{ - swlock_acquire(&lfs_lock); - debug_printf("lfs_write_config: %s, size: %d\n", config, size); - int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT); - if (result != 0) { - debug_printf("lfs_write_config: open file failed\n"); - swlock_release(&lfs_lock); - return; - } - result = lfs_file_rewind(&lfs, &file); - if (result != 0) { - debug_printf("lfs_write_config: rewind file failed\n"); - // Update: Added lfs_file_close to prevent file remaining open if rewind fails. - lfs_file_close(&lfs, &file); - swlock_release(&lfs_lock); - return; - } - lfs_file_write(&lfs, &file, buffer, size); - lfs_file_close(&lfs, &file); - swlock_release(&lfs_lock); -} - - -// 检查文件是否存在 -int lfs_file_exists(const char * file_path) -{ - swlock_acquire(&lfs_lock); - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); - if (result == 0) { - lfs_file_close(&lfs, &file); - swlock_release(&lfs_lock); - return 1; // 文件存在 - } - swlock_release(&lfs_lock); - return 0; // 文件不存在 -} - -// EQ参数专用读写函数 -void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size) -{ - lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); - lfs_file_read(&lfs, &file, buffer, size); - lfs_file_close(&lfs, &file); -} - -void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size) -{ - lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT); - lfs_file_rewind(&lfs, &file); - lfs_file_write(&lfs, &file, buffer, size); - lfs_file_close(&lfs, &file); -} - - -// 删除文件 -int lfs_remove_file(const char * file_path) -{ - return lfs_remove(&lfs, file_path); -} - -// 创建目录(通过创建临时文件然后删除) -int lfs_create_directory(const char * dir_path) -{ - char temp_file[256]; - snprintf(temp_file, sizeof(temp_file), "%s/.dir", dir_path); - - lfs_file_t file; - int result = lfs_file_open(&lfs, &file, temp_file, LFS_O_RDWR | LFS_O_CREAT); - if (result == 0) { - lfs_file_close(&lfs, &file); - lfs_remove(&lfs, temp_file); - return 0; // 成功 - } - return -1; // 失败 -} - -#if 0 - // read current count - uint32_t boot_count = 0; - lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); - lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); - - // update boot count - boot_count += 1; - lfs_file_rewind(&lfs, &file); - for (int i = 0; i < 100; i++) - lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); - - // remember the storage is not updated until the file is closed successfully - lfs_file_close(&lfs, &file); - - // release any resources we were using - lfs_unmount(&lfs); - - // print the boot count - printf("boot_count: %d\n", boot_count); - -#endif