/*! * \file cfg_drv.c * \brief 驱动配置接口 * \details * \author * \date * \copyright Actions */ #include "list.h" #include #include #include #include "drivers/cfg_drv/driver_config.h" #include "drv_cfg_head.h" #ifndef bool_t #define bool_t int #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif /*! * \brief 获取最小值 */ #define _MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) /*! * \brief 获取最大值 */ #define _MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b)) /*! * \brief 获取CFG key中的ID, OFFSET, LEN */ #define CFG_KEY_ID(key) ((key >> 24) & 0xff) #define CFG_KEY_OFFSET(key) ((key >> 12) & 0xfff) #define CFG_KEY_LEN(key) ((key) & 0xfff) typedef struct { u8_t format[4]; u8_t magic [4]; u16_t user_version; u8_t minor_version; u8_t major_version; u16_t total_size; u16_t num_cfg_items; } drv_config_file_header_t; typedef struct { u32_t cfg_id:8; u32_t sub_pos:12; u32_t cfg_len:12; } drv_config_item_info_t; typedef struct { struct list_head node; void *file; int num_cfg_items; u8_t* cfg_data; drv_config_item_info_t* cfg_items; } drv_config_file_info_t; typedef struct { /** item key value, defined by drivers */ uint32_t item_key_value; /** cfg key value, generated by config tools */ uint32_t cfg_key_value; } cfg_key_map_t; /* 最大配置文件数 */ #define MAX_DRV_CFG_FILE 2 drv_config_file_info_t cfg_file_info[MAX_DRV_CFG_FILE]; struct list_head drv_config_file_list = LIST_HEAD_INIT(drv_config_file_list); cfg_key_map_t cfg_key_map_table[]={ /* UART */ { ITEM_UART_TX_PIN , CFG_Console_UART_RX_Pin }, { ITEM_UART_RX_PIN , CFG_Console_UART_TX_Pin }, { ITEM_UART_BAUDRATE , CFG_Console_UART_Baudrate }, { ITEM_UART_PRINT_TIME_STAMP , CFG_Console_UART_Print_Time_Stamp }, /* LED */ { ITEM_LED_LED, CFG_LED_Drives_LED }, /* ONOFF KEY */ { ITEM_ONOFF_USE_INNER_ONOFF_KEY, CFG_ONOFF_Key_Use_Inner_ONOFF_Key }, { ITEM_ONOFF_CONTINUE_KEY_FUNCTION_AFTER_WAKE_UP, CFG_ONOFF_Key_Continue_Key_Function_After_Wake_Up }, { ITEM_ONOFF_KEY_VALUE, CFG_ONOFF_Key_Key_Value }, { ITEM_ONOFF_TIME_PRESS_POWER_ON, CFG_ONOFF_Key_Time_Press_Power_On }, { ITEM_ONOFF_TIME_LONG_PRESS_RESET, CFG_ONOFF_Key_Time_Long_Press_Reset }, { ITEM_ONOFF_BOOT_HOLD_KEY_FUNC, CFG_ONOFF_Key_Boot_Hold_Key_Func}, { ITEM_ONOFF_BOOT_HOLD_KEY_TIME_MS, CFG_ONOFF_Key_Boot_Hold_Key_Time_Ms }, { ITEM_ONOFF_DEBOUNCE_TIME_MS, CFG_ONOFF_Key_Debounce_Time_Ms }, { ITEM_ONOFF_REBOOT_AFTER_BOOT_HOLD_KEY_CLEAR_PAIRED_LIST, CFG_ONOFF_Key_Reboot_After_Boot_Hold_Key_Clear_Paired_List }, /* LRADC KEY */ { ITEM_LRADC_KEY, CFG_LRADC_Keys_Key }, { ITEM_LRADC_CTRL, CFG_LRADC_Keys_LRADC_Ctrl }, { ITEM_LRADC_PULL_UP, CFG_LRADC_Keys_LRADC_Pull_Up }, { ITEM_LRADC_KEY_WAKE_UP, CFG_LRADC_Keys_Use_LRADC_Key_Wake_Up }, { ITEM_LRADC_VALUE_TEST, CFG_LRADC_Keys_LRADC_Value_Test }, { ITEM_LRADC_DEBOUNCE_TIME_MS, CFG_LRADC_Keys_Debounce_Time_Ms }, /* GPIO KEY */ { ITEM_GPIO_KEY, CFG_GPIO_Keys_Key }, /* TAP KEY */ { ITEM_TAP_KEY_CONTROL, CFG_Tap_Key_Tap_Key_Control }, /* AUDIO */ { ITEM_AUDIO_OUT_MODE, CFG_Audio_Settings_Audio_Out_Mode }, { ITEM_AUDIO_I2STX_SELECT_GPIO, CFG_Audio_Settings_I2STX_Select_GPIO }, { ITEM_AUDIO_CHANNEL_SELECT_MODE, CFG_Audio_Settings_Channel_Select_Mode }, { ITEM_AUDIO_CHANNEL_SELECT_GPIO, CFG_Audio_Settings_Channel_Select_GPIO }, { ITEM_AUDIO_CHANNEL_SELECT_LRADC, CFG_Audio_Settings_Channel_Select_LRADC }, { ITEM_AUDIO_TWS_ALONE_AUDIO_CHANNEL, CFG_Audio_Settings_TWS_Alone_Audio_Channel }, { ITEM_AUDIO_L_SPEAKER_OUT, CFG_Audio_Settings_L_Speaker_Out }, { ITEM_AUDIO_R_SPEAKER_OUT, CFG_Audio_Settings_R_Speaker_Out }, { ITEM_AUDIO_ADC_BIAS_SETTING, CFG_Audio_Settings_ADC_Bias_Setting }, { ITEM_AUDIO_DAC_BIAS_SETTING, CFG_Audio_Settings_DAC_Bias_Setting }, { ITEM_AUDIO_KEEP_DA_ENABLED_WHEN_PLAY_PAUSE, CFG_Audio_Settings_Keep_DA_Enabled_When_Play_Pause }, { ITEM_AUDIO_DISABLE_PA_WHEN_RECONNECT, CFG_Audio_Settings_Disable_PA_When_Reconnect }, { ITEM_AUDIO_EXTERN_PA_CONTROL, CFG_Audio_Settings_Extern_PA_Control }, { ITEM_AUDIO_ANTIPOP_PROCESS_DISABLE, CFG_Audio_Settings_AntiPOP_Process_Disable }, { ITEM_AUDIO_DMIC01_CHANNEL_ALIGNING, CFG_Audio_Settings_DMIC01_Channel_Aligning }, { ITEM_AUDIO_DMIC23_CHANNEL_ALIGNING, CFG_Audio_Settings_DMIC23_Channel_Aligning }, { ITEM_AUDIO_DMIC_SELECT_GPIO, CFG_Audio_Settings_DMIC_Select_GPIO }, { ITEM_AUDIO_ENABLE_ANC, CFG_Audio_Settings_Enable_ANC }, { ITEM_AUDIO_ANCDMIC_SELECT_GPIO, CFG_Audio_Settings_ANCDMIC_Select_GPIO }, { ITEM_AUDIO_RECORD_ADC_SELECT, CFG_Audio_Settings_Record_Adc_Select }, { ITEM_AUDIO_ENABLE_VMIC, CFG_Audio_Settings_Enable_VMIC }, { ITEM_AUDIO_HW_AEC_SELECT, CFG_Audio_Settings_Hw_Aec_Select }, { ITEM_AUDIO_TM_ADC_SELECT, CFG_Audio_Settings_Tm_Adc_Select }, { ITEM_AUDIO_MIC_CONFIG, CFG_Audio_Settings_Mic_Config }, { ITEM_AUDIO_ADC_INPUT_SELECT, CFG_Audio_Settings_ADC_Select_INPUT }, { ITEM_AUDIO_PA_GAIN, CFG_Audio_Settings_Pa_Gain }, { ITEM_AUDIO_DUAL_MIC_EXCHANGE_ENABLE, CFG_Audio_Settings_Dual_MIC_Exchange_Enable }, { ITEM_AUDIO_LARGE_CURRENT_PROTOTECT_ENABLE, CFG_Audio_Settings_Large_Current_Protect_Enable}, { ITEM_AUDIO_ANALOG_GAIN_SETTINGS, CFG_Audio_Settings_ANALOG_GAIN_Settings }, /* BATTERY */ { ITEM_CHARGE_SELECT_CHARGE_MODE, CFG_Battery_Charge_Select_Charge_Mode }, { ITEM_CHARGE_CURRENT, CFG_Battery_Charge_Charge_Current }, { ITEM_CHARGE_VOLTAGE, CFG_Battery_Charge_Charge_Voltage }, { ITEM_CHARGE_STOP_MODE, CFG_Battery_Charge_Charge_Stop_Mode }, { ITEM_CHARGE_STOP_VOLTAGE, CFG_Battery_Charge_Charge_Stop_Voltage }, { ITEM_CHARGE_STOP_CURRENT, CFG_Battery_Charge_Charge_Stop_Current }, { ITEM_CHARGE_PRECHARGE_STOP_VOLTAGE, CFG_Battery_Charge_Precharge_Stop_Voltage }, { ITEM_CHARGE_PRECHARGE_CURRENT, CFG_Battery_Charge_Precharge_Current }, { ITEM_CHARGE_PRECHARGE_CURRENT_MIN_LIMIT, CFG_Battery_Charge_Precharge_Current_Min_Limit }, { ITEM_CHARGE_FAST_CHARGE_ENABLE, CFG_Battery_Charge_Fast_Charge_Enable }, { ITEM_CHARGE_FAST_CHARGE_CURRENT, CFG_Battery_Charge_Fast_Charge_Current }, { ITEM_CHARGE_FAST_CHARGE_VOLTAGE_THRESHOLD, CFG_Battery_Charge_Fast_Charge_Voltage_Threshold }, { ITEM_CHARGE_ENABLE_BATTERY_RECHARGE, CFG_Battery_Charge_Enable_Battery_Recharge }, { ITEM_CHARGE_BATTERY_RECHARGE_THRESHOLD, CFG_Battery_Charge_Enable_Battery_Recharge }, { ITEM_CHARGE_BATTERY_CHARGE_TOTAL_TIME_LIMIT, CFG_Battery_Charge_Charge_Total_Time_Limit }, { ITEM_CHARGE_BATTERY_CHECK_PERIOD_SEC, CFG_Battery_Charge_Battery_Check_Period_Sec }, { ITEM_CHARGE_CHECK_PERIOD_SEC, CFG_Battery_Charge_Charge_Check_Period_Sec }, { ITEM_CHARGE_FULL_CONTINUE_SEC, CFG_Battery_Charge_Charge_Full_Continue_Sec }, { ITEM_CHARGE_FRONT_CHARGE_FULL_POWER_OFF_WAIT_SEC, CFG_Battery_Charge_Front_Charge_Full_Power_Off_Wait_Sec }, { ITEM_CHARGE_DC5V_DETECT_DEBOUNCE_TIME_MS, CFG_Battery_Charge_DC5V_Detect_Debounce_Time_Ms }, /* CHARGER BOX*/ { ITEM_CHARGEBOX_ENABLE_CHARGER_BOX, CFG_Charger_Box_Enable_Charger_Box }, { ITEM_CHARGEBOX_DC5V_PULL_DOWN_CURRENT, CFG_Charger_Box_DC5V_Pull_Down_Current }, { ITEM_CHARGEBOX_DC5V_PULL_DOWN_HOLD_MS, CFG_Charger_Box_DC5V_Pull_Down_Hold_Ms }, { ITEM_CHARGEBOX_STANDBY_DELAY_MS, CFG_Charger_Box_Charger_Standby_Delay_Ms }, { ITEM_CHARGEBOX_STANDBY_VOLTAGE, CFG_Charger_Box_Charger_Standby_Voltage }, { ITEM_CHARGEBOX_WAKE_DELAY_MS, CFG_Charger_Box_Charger_Wake_Delay_Ms }, { ITEM_CHARGEBOX_BOX_STANDBY_CURRENT, CFG_Charger_Box_Charger_Box_Standby_Current }, { ITEM_CHARGEBOX_DC5V_UART_COMM_SETTINGS, CFG_Charger_Box_DC5V_UART_Comm_Settings }, { ITEM_CHARGEBOX_DC5V_IO_COMM_SETTINGS, CFG_Charger_Box_DC5V_IO_Comm_Settings }, /* BATTERY */ { ITEM_BATTERY_LEVEL, CFG_Battery_Level_Level }, { ITEM_BATTERY_TOO_LOW_VOLTAGE, CFG_Battery_Low_Battery_Too_Low_Voltage }, { ITEM_BATTERY_LOW_VOLTAGE, CFG_Battery_Low_Battery_Low_Voltage }, { ITEM_BATTERY_LOW_VOLTAGE_EX, CFG_Battery_Low_Battery_Low_Voltage_Ex }, { ITEM_BATTERY_LOW_PROMPT_INTERVAL_SEC, CFG_Battery_Low_Battery_Low_Prompt_Interval_Sec }, /* NTC */ { ITEM_NTC_SETTING, CFG_NTC_Settings_NTC_Settings }, { ITEM_NTC_RANGES, CFG_NTC_Settings_NTC_Ranges }, /* OTHER - SYS MORE CONFIG */ { ITEM_SYS_SETTINGS_SUPPORT_FEATURES, CFG_System_Settings_Support_Features}, }; /*! * \brief 加载驱动配置数据文件 * \n 注: 使用时必须先加载 defcfg.bin, 再加载 usrcfg.bin * \n * \n file_name : 配置文件名 * \return * 成功: TRUE * \n 失败: FALSE */ static bool_t drv_config_load( const char* file_name) { struct sd_file *file; drv_config_file_info_t* file_info; drv_config_file_header_t hdr; int len = sizeof(drv_config_file_header_t); int i; if ((file = sd_fopen(file_name)) == NULL) { goto err; } if (sd_fread(file, &hdr, sizeof(drv_config_file_header_t)) != len) { goto err; } if (memcmp(hdr.format, "CFG", 4) != 0 || memcmp(hdr.magic, "VER", 4) != 0) { goto err; } //file_info = app_mem_malloc(sizeof(drv_config_file_info_t)); for(i=0; i= MAX_DRV_CFG_FILE) return FALSE; file_info = &cfg_file_info[i]; file_info->num_cfg_items = hdr.num_cfg_items; file_info->file = file; list_add_tail(&file_info->node, &drv_config_file_list); return TRUE; err: return FALSE; } /*! * \brief 读取驱动配置数据 * \n 配置数据在读取前会被初始化为默认值 0 * \n * \param cfg_id : 应用配置 ID * \param cfg_data : 保存配置数据 * \param cfg_offs : 读取配置位置偏移 * \param cfg_len : 读取配置数据长度 * \return * 配置数据为默认配置时返回 1 * \n 配置数据非默认配置时返回 2 * \n 失败返回 0 */ static int drv_config_read ( uint32_t cfg_id, void* cfg_data, uint32_t cfg_offs, uint32_t cfg_len) { int ret_val = 0; drv_config_file_info_t* file_info; drv_config_item_info_t cfg_item; int file_offs; int i; //OSSchedLock(); memset(cfg_data, 0, cfg_len); /* 顺序读取配置文件, * 后面读取的新数据覆盖前面读取的数据 */ list_for_each_entry(file_info, &drv_config_file_list, node) { int start_pos = sizeof(drv_config_file_header_t) + file_info->num_cfg_items * sizeof(drv_config_item_info_t); int result = 0; file_offs = start_pos; for (i = 0; i < file_info->num_cfg_items; i++, file_offs += cfg_item.cfg_len) { int offs; int len; offs = sizeof(drv_config_file_header_t) + i * sizeof(drv_config_item_info_t); sd_fseek(file_info->file, offs, FS_SEEK_SET); sd_fread(file_info->file, &cfg_item, sizeof(drv_config_item_info_t)); if (cfg_item.cfg_id != cfg_id) { continue; } /* 只读取覆盖需要的部分数据 */ offs = _MAX(cfg_item.sub_pos, cfg_offs); len = _MIN(cfg_item.sub_pos + cfg_item.cfg_len, cfg_offs + cfg_len) - offs; if (len <= 0) { continue; } int pos = file_offs + (offs - cfg_item.sub_pos); void* data = (u8_t*)cfg_data + (offs - cfg_offs); sd_fseek(file_info->file, pos, FS_SEEK_SET); sd_fread(file_info->file, data, len); result = 1; } ret_val += result; } //OSSchedUnlock(); return ret_val; } /* return: 0 - 匹配失败 other - 成功 */ static uint32_t cfg_key_map(uint32_t item_key) { uint32_t cfg_key = 0; int i; for(i=0; i