This commit is contained in:
huxi
2025-12-03 11:12:34 +08:00
parent c23ae4f24c
commit bc195654bf
8163 changed files with 3799544 additions and 92 deletions
+806
View File
@@ -0,0 +1,806 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".app_main.data.bss")
#pragma data_seg(".app_main.data")
#pragma const_seg(".app_main.text.const")
#pragma code_seg(".app_main.text")
#endif
#include "system/includes.h"
#include "app_config.h"
#include "gpadc.h"
#include "app_tone.h"
#include "gpio_config.h"
#include "app_main.h"
#include "asm/charge.h"
#include "update.h"
#include "app_power_manage.h"
#include "audio_config.h"
#include "app_charge.h"
#include "bt_profile_cfg.h"
#include "update_loader_download.h"
#include "idle.h"
#include "bt_tws.h"
#include "key_driver.h"
#include "user_cfg.h"
#include "app_default_msg_handler.h"
#include "app_music.h"
#include "fm.h"
#include "pc.h"
#include "linein.h"
#include "linein_dev.h"
#include "bt.h"
#include "rtc.h"
#include "record.h"
#include "usb/usb_task.h"
#include "usb/device/usb_stack.h"
#include "ui_manage.h"
#include "alarm.h"
#include "spdif.h"
#include "power_on.h"
#include "key/adkey.h"
#include "key/iokey.h"
#include "driver/trim.h"
#include "dev_manager.h"
#include "app_mode_update.h"
#include "app_version.h"
#include "sdfile.h"
#include "ui/lcd/lcd_drive.h"
#include "ui/ui_api.h"
#include "tp_api.h"
#include "data_storage.h"
#include "health_manager.h"
#include "clock_manager/clock_manager.h"
#include "product_test.h"
#include "chgbox_ctrl.h"
#define LOG_TAG "[APP]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
extern const u8 sfc0_dtr_mode_en;
extern u8 check_vbat_low_power(void);
#define TASK_PRIO_BASE 20
/*任务列表 */
const struct task_info task_info_table[] = {
#if TCFG_PAY_ALIOS_ENABLE
{"app_core", 0 + TASK_PRIO_BASE, 0, 2048, 1024 },
#else
{"app_core", 0 + TASK_PRIO_BASE, 0, 768, 768},
#endif
#if TCFG_PAY_TRANSITCODE_ENABLE
//乘车码应用使用完要kill 任务 对栈占用厉害
{"transitcode", 1, 0, 2048 + 2048 + 2048 + 1024, 512 },
#endif
{"btctrler", 4 + TASK_PRIO_BASE, 0, 512, 512 },
{"btencry", 1 + TASK_PRIO_BASE, 0, 512, 128 },
#if (BT_FOR_APP_EN)
{"btstack", 3 + TASK_PRIO_BASE, 0, 1024, 256 },
#else
{"btstack", 3 + TASK_PRIO_BASE, 0, 768, 256 },
#endif
{"jlstream", 3 + TASK_PRIO_BASE, 0, 768, 128 },
{"jlstream_0", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_1", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_2", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_3", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_4", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_5", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_6", 6 + TASK_PRIO_BASE, 0, 768, 0 },
{"jlstream_7", 6 + TASK_PRIO_BASE, 0, 768, 0 },
#if (TCFG_BT_SUPPORT_LHDC)
{"a2dp_dec", 7 + TASK_PRIO_BASE, 0, 512 + 256, 0 },
#else
{"a2dp_dec", 7 + TASK_PRIO_BASE, 0, 512, 0 },
#endif
{"file_dec", 5 + TASK_PRIO_BASE, 0, 640, 0 },
{"file_cache", 5 + TASK_PRIO_BASE, 0, 512, 0 },
{"write_file", 5 + TASK_PRIO_BASE, 0, 512, 0 },
/* 混响任务优先级要高 */
{"mic_effect1", 7 + TASK_PRIO_BASE, 0, 768, 0 },
{"mic_effect2", 7 + TASK_PRIO_BASE, 0, 768, 0 },
/*
*为了防止dac buf太大,通话一开始一直解码,
*导致编码输入数据需要很大的缓存,这里提高编码的优先级
*/
{"audio_enc", 7 + TASK_PRIO_BASE, 0, 768, 128 },
{"aec", 2 + TASK_PRIO_BASE, 1, 768, 128 },
{"aec_dbg", 3 + TASK_PRIO_BASE, 0, 512, 128 },
{"update", 1 + TASK_PRIO_BASE, 0, 512, 0 },
{"tws_ota", 2 + TASK_PRIO_BASE, 0, 256, 0 },
{"tws_ota_msg", 2 + TASK_PRIO_BASE, 0, 256, 128 },
{"dw_update", 2 + TASK_PRIO_BASE, 0, 256, 128 },
{"aud_capture", 4 + TASK_PRIO_BASE, 0, 512, 256 },
{"data_export", 5 + TASK_PRIO_BASE, 0, 512, 256 },
{"anc", 3 + TASK_PRIO_BASE, 0, 512, 128 },
{"pmu_task", 6 + TASK_PRIO_BASE, 0, 256, 128 },
{"dac", 2 + TASK_PRIO_BASE, 0, 256, 128 },
#if RCSP_MODE
{"rcsp", 4 + TASK_PRIO_BASE, 0, 768, 128 },
#if RCSP_FILE_OPT
{"rcsp_file_bs", 1 + TASK_PRIO_BASE, 0, 768, 128 },
#endif
#endif
#if TCFG_KWS_VOICE_RECOGNITION_ENABLE
{"kws", 2 + TASK_PRIO_BASE, 0, 256, 64 },
#endif
{"usb_stack", 1 + TASK_PRIO_BASE, 0, 512, 128 },
#if (BT_AI_SEL_PROTOCOL & (GFPS_EN | REALME_EN | TME_EN | DMA_EN | GMA_EN))
{"app_proto", 2 + TASK_PRIO_BASE, 0, 768, 64 },
#endif
#if (defined CONFIG_LVGL_UI_ENABLE && CONFIG_LVGL_UI_ENABLE)
{"ui", 3 + TASK_PRIO_BASE, 0, 1408, 512 },
{"gpu", 8 + TASK_PRIO_BASE, 0, 1408, 512 },
{"lcd_init", 4 + TASK_PRIO_BASE, 0, 256, 0 },
{"tp_init", 5 + TASK_PRIO_BASE, 0, 256, 0 },
#elif (defined CONFIG_JL_UI_ENABLE && CONFIG_JL_UI_ENABLE)
{"ui", 3 + TASK_PRIO_BASE, 0, 1408, 512 },
{"gpu", 8 + TASK_PRIO_BASE, 0, 1408, 512 },
{"lcd_init", 4 + TASK_PRIO_BASE, 0, 256, 0 },
{"tp_init", 5 + TASK_PRIO_BASE, 0, 256, 0 },
{"lcd", 8 + TASK_PRIO_BASE, 0, 256, 64 },
#endif
#if (TCFG_DEV_MANAGER_ENABLE)
{"dev_mg", 3 + TASK_PRIO_BASE, 0, 256, 32 },
#endif
{"audio_vad", 1 + TASK_PRIO_BASE, 1, 512, 128 },
#if TCFG_KEY_TONE_EN
{"key_tone", 5 + TASK_PRIO_BASE, 0, 256, 32 },
#endif
#if (BT_AI_SEL_PROTOCOL & TUYA_DEMO_EN)
{"user_deal", 7 + TASK_PRIO_BASE, 0, 512, 512 }, //定义线程 tuya任务调度
{"dw_update", 2 + TASK_PRIO_BASE, 0, 256, 128 },
#endif
#if(TCFG_UPDATE_UART_IO_EN)
{"uart_update", 1 + TASK_PRIO_BASE, 0, 512, 128 },
#endif
#if (USER_FILE_UPDATE_V2_EN)
{"ex_f_update", 1 + TASK_PRIO_BASE, 1, 512, 0 },
#endif
{"periph_demo", 3 + TASK_PRIO_BASE, 0, 512, 0 },
{"CVP_RefTask", 4 + TASK_PRIO_BASE, 0, 256, 128 },
{"touch_task", 9 + TASK_PRIO_BASE, 0, 512, 0 },
#if (TCFG_SPORT_HEALTH_ENABLE)
{"health_manager", 3 + TASK_PRIO_BASE, 0, 512, 128},
#endif
{"aud_adc_demo", 1 + TASK_PRIO_BASE, 0, 512, 128 },
#if PRODUCT_TEST_ENABLE
{"pt", 1 + TASK_PRIO_BASE, 0, 512, 128 },
#endif
#if TCFG_CHARGE_IC_MANAGER_MODE_ENABLE
{"sbox_uart_task", 5 + TASK_PRIO_BASE, 0, 256, 256 },
#endif
#if (TCFG_DEV_MANAGER_ENABLE)
{"ftran_back", 1 + TASK_PRIO_BASE, 0, 512, 0 },
#endif
#if TCFG_VIDEO_DIAL_ENABLE
{"avi_task", 4 + TASK_PRIO_BASE, 0, 1408, 256 },
#endif
{0, 0},
};
APP_VAR app_var;
__attribute__((weak))
int eSystemConfirmStopStatus(void)
{
/* 系统进入在未来时间里,无任务超时唤醒,可根据用户选择系统停止,
* 或者系统定时唤醒(100ms),或自己指定唤醒时间
* return:
* 1:Endless Sleep
* 0:100 ms wakeup
* other: x ms wakeup
*/
return 0;
}
__attribute__((used))
int *__errno()
{
static int err;
return &err;
}
void app_var_init(void)
{
app_var.play_poweron_tone = 1;
}
u8 get_power_on_status(void)
{
#if TCFG_ADKEY_ENABLE
return is_adkey_press_down();
#endif
#if TCFG_IOKEY_ENABLE
return is_iokey_press_down();
#endif
return 0;
}
void check_power_on_key(void)
{
#if PRODUCT_TEST_ENABLE
u8 pt_result;
int r = syscfg_read(PT_TEST_RESULT, (u8 *)&pt_result, sizeof(pt_result));
if (r <= 0) {
log_info("vm read pt_test_result faild\n");
return;
}
#endif
u32 delay_10ms_cnt = 0;
while (1) {
wdt_clear();
os_time_dly(1);
if (get_power_on_status()) {
putchar('+');
delay_10ms_cnt++;
if (delay_10ms_cnt > 70) {
app_var.poweron_reason = SYS_POWERON_BY_KEY;
return;
}
} else {
log_info("enter softpoweroff\n");
delay_10ms_cnt = 0;
app_var.poweroff_reason = SYS_POWEROFF_BY_KEY;
power_set_soft_poweroff();
}
}
}
__attribute__((weak))
u8 get_charge_online_flag(void)
{
return 0;
}
/*充电拔出,CPU软件复位, 不检测按键,直接开机*/
static void app_poweron_check(int update)
{
#if (CONFIG_BT_MODE == BT_NORMAL)
if (!update && cpu_reset_by_soft()) {
app_var.play_poweron_tone = 0;
return;
}
#if (TCFG_CHARGE_ENABLE && TCFG_CHARGE_OFF_POWERON_EN)
if (is_ldo5v_wakeup()) {
#if TCFG_CHARGE_OFF_POWERON_EN
app_var.play_poweron_tone = 0;
app_var.poweron_reason = SYS_POWERON_BY_OUT_BOX;
return;
#else
//拔出关机
power_set_soft_poweroff();
#endif
}
#endif
#if TCFG_AUTO_POWERON_ENABLE
return;
#endif
check_power_on_key();
#endif
}
__attribute__((weak))
void board_init()
{
}
__attribute__((weak))
void arch_trim()
{
}
static void app_version_check()
{
puts("=================Version===============\n");
for (char *version = __VERSION_BEGIN; version < __VERSION_END;) {
version += 4;
printf("%s\n", version);
version += strlen(version) + 1;
}
puts("=======================================\n");
}
static struct app_mode *app_task_init()
{
app_var_init();
app_version_check();
/* sdfile_init(); */
/* syscfg_tools_init(); */
do_early_initcall();
board_init();
tzflash_change_mode();//dtr(clk),continue,wps
do_platform_initcall();
#if (defined TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE) && TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
#if(TCFG_CHARGE_BOX_ENABLE)
/* clock_add_set(CHARGE_BOX_CLK); */
chgbox_init_app();
static u8 flag = 0;
extern int send_to_trig_vcb(void (*func)(void), char *taskname);
extern void soc_check_init();
if (flag == 0) {
flag = 1;
send_to_trig_vcb(soc_check_init, "app_core");
}
#endif
#endif
tzflash_dump();
cfg_file_parse(0);
key_driver_init();
do_initcall();
do_module_initcall();
do_late_initcall();
dev_manager_init();
#if TCFG_APP_RTC_EN
alarm_init();
#endif
int update = 0;
if (CONFIG_UPDATE_ENABLE) {
update = update_result_deal();
}
app_var.start_time = jiffies_msec();
int msg[4] = { MSG_FROM_APP, APP_MSG_GOTO_MODE, 0, 0 };
#if (!TCFG_CHARGE_OFF_POWERON_EN)
if (get_charge_online_flag()) {
#if(TCFG_SYS_LVD_EN == 1)
vbat_check_init();
#endif
msg[2] = APP_MODE_IDLE;
msg[3] = IDLE_MODE_CHARGE;
} else {
msg[2] = APP_MODE_POWERON;
check_power_on_voltage();
app_poweron_check(update);
app_send_message(APP_MSG_POWER_ON, 0);
}
#else//关机插入后先进power on 开bt
//vpwr在线,vpwr供电
if (get_charge_online_flag()) {
#if(TCFG_SYS_LVD_EN == 1)
vbat_check_init();
#endif
if (check_vbat_low_power()) { //vbat浮空
//进idle,不允许开蓝牙和退出充电UI
msg[2] = APP_MODE_IDLE;
msg[3] = IDLE_MODE_CHARGE;
} else {
//进power_on,允许开机
msg[2] = APP_MODE_POWERON;
/* app_poweron_check(update); */
app_send_message(APP_MSG_POWER_ON, 0);
}
} else { //vpwr未插入,检测电量
msg[2] = APP_MODE_POWERON;
check_power_on_voltage();
app_poweron_check(update);
app_send_message(APP_MSG_POWER_ON, 0);
}
#endif
#if TCFG_CHARGE_ENABLE
set_charge_event_flag(1);
#endif
#if TCFG_DYNAMIC_SWITCHING_IOVDDM_ENABLE
miovdd_adaptive_adjustment();
#endif
arch_trim();
#if (defined TCFG_UI_ENABLE && TCFG_UI_ENABLE)
#if GPU_PORT_DEMO_ENABLE
extern int gpu_port_demo_task(void);
gpu_port_demo_task();
#elif defined GPU_DEMO_ENABLE && GPU_DEMO_ENABLE
extern void gpu_demo_run(void);
gpu_demo_run();
#else
#if (defined CONFIG_JL_UI_ENABLE && CONFIG_JL_UI_ENABLE)
// JLUI 框架 依赖文件系统 在dev挂载后才能初始化
UI_INIT((void *)&ui_cfg_data);
/* wdt_disable(); */
#endif
#endif
#endif
#if (defined CONFIG_LVGL_UI_ENABLE && CONFIG_LVGL_UI_ENABLE)
extern const struct ui_devices_cfg ui_cfg_data;
extern int lvgl_ui_init(void *param);
lvgl_ui_init((void *)&ui_cfg_data);
#endif
#if TCFG_TOUCH_PANEL_ENABLE
// tp和lcd共电源情况下,tp初始化需要放lcd初始化之后
TP_INIT();
/* wdt_close(); */
#endif
#if TCFG_DATA_STORAGE_ENABLE
data_small_file_init();
#endif
#if TCFG_SPORT_HEALTH_ENABLE
sport_health_manager_init();
#endif
//程序正常运行看门狗时间
wdt_init(WDT_APP_RUN_TIME);
#if PRODUCT_TEST_ENABLE
extern void product_test_open();
app_var.play_poweron_tone = 0;
product_test_open();
#endif
struct app_mode *mode;
mode = app_mode_switch_handler(msg);
ASSERT(mode != NULL);
clock_refurbish();
return mode;
}
static int app_core_get_message(int *msg, int max_num)
{
while (1) {
int res = os_taskq_pend(NULL, msg, max_num);
if (res != OS_TASKQ) {
continue;
}
if (msg[0] & Q_MSG) {
return 1;
}
}
return 0;
}
static int g_mode_switch_arg;
static int g_mode_switch_msg[2];
static void retry_goto_mode_in_irq(void *_arg)
{
if (g_mode_switch_msg[0] == APP_MSG_GOTO_MODE) {
app_send_message2(g_mode_switch_msg[0], g_mode_switch_msg[1], g_mode_switch_arg);
} else {
app_send_message(g_mode_switch_msg[0], g_mode_switch_arg);
}
}
int app_task_switch_to(u8 app_task, int priv)
{
int ret = app_send_message2(APP_MSG_GOTO_MODE, app_task, priv);
if (!ret) {
if (app_get_current_mode_name()) {
app_push_mode(app_get_current_mode_name());
}
return TRUE;
}
return FALSE;
}
int app_task_switch_back()
{
int app_task = app_pop_mode();
if (app_task != 0xff) {
return app_task_switch_to(app_task, 0);
} else {
return app_task_switch_to(APP_MODE_BT, 0);
}
}
u8 idle_sub_mode_get();
struct app_mode *app_mode_switch_handler(int *msg)
{
int arg;
struct app_mode *next_mode;
if (msg[0] != MSG_FROM_APP) {
return NULL;
}
switch (msg[1]) {
case APP_MSG_GOTO_MODE:
arg = msg[3];
log_info("APP_MSG_GOTO_MODE, CURR_TASK = %d,NEXT_TASK= %d \n", app_get_current_mode_name(), msg[2]);
/*判断当前是否已经处于GOTO MODE希望切换的任务,如果是则不反复切换*/
if (app_get_current_mode() && app_get_current_mode()->name == msg[2]) {
if (app_get_current_mode_name() != APP_MODE_IDLE) {
return NULL;
}
if (idle_sub_mode_get() == arg) {
return NULL;
}
}
next_mode = app_get_mode_by_name(msg[2]);
break;
case APP_MSG_GOTO_NEXT_MODE:
arg = msg[2];
next_mode = app_get_next_mode();
break;
default:
return NULL;
}
g_mode_switch_arg = arg;
g_mode_switch_msg[0] = msg[1];
g_mode_switch_msg[1] = msg[2];
#if TCFG_APP_BT_EN && TCFG_BT_BACKGROUND_ENABLE
if (!bt_check_already_initializes()) { //如果是后台使能蓝牙还没初始化,需要先记录切换的模式,等到蓝牙初始化完成之后再切回去
if (next_mode->name != APP_MODE_BT && next_mode->name != APP_MODE_POWERON && next_mode->name != APP_MODE_IDLE) {
bt_background_set_switch_mode(next_mode->name);
if (app_get_current_mode()->name == APP_MODE_POWERON) {
next_mode = app_get_mode_by_name(APP_MODE_BT);
} else {
return NULL;
}
}
}
#endif
/*
* 循环检查下一个模式是否可以进入
*/
do {
if (app_try_enter_mode(next_mode, arg)) {
break;
}
next_mode = app_next_mode(next_mode);
} while (next_mode);
/*
* 等待当前模式退出
*/
if (!app_try_exit_curr_mode()) {
sys_hi_timeout_add(NULL, retry_goto_mode_in_irq, 100);
return NULL;
}
return next_mode;
}
int app_get_message(int *msg, int max_num, const struct key_remap_table *key_table)
{
const struct app_msg_handler *handler;
app_core_get_message(msg, max_num);
if (msg[0] == MSG_FROM_KEY && key_table) {
/*
* 按键消息映射成当前模式的消息
*/
struct app_mode *mode = app_get_current_mode();
if (mode) {
int key_msg = app_key_event_remap(key_table, msg + 1);
if (key_msg == APP_MSG_NULL) {
return 1;
}
if (mode->name == APP_MODE_BT) { //蓝牙模式 判断是否需要tws同步按键消息
#if TCFG_USER_TWS_ENABLE
bt_tws_key_msg_sync(key_msg);
#else
msg[0] = MSG_FROM_APP;
msg[1] = key_msg;
#endif
} else {
msg[0] = MSG_FROM_APP;
msg[1] = key_msg;
}
}
}
//消息截获,返回1表示中断消息分发
int abandon = 0;
for_each_app_msg_prob_handler(handler) {
if (handler->from == msg[0]) {
abandon = handler->handler(msg + 1);
if (abandon) {
break;
}
}
}
if (abandon) {
return 0;
}
return 1;
}
void mem_printf(void *priv)
{
mem_stats();
}
static void app_task_loop(void *p)
{
struct app_mode *mode;
printf("app_task_loop\n");
/* sys_timer_add(NULL, mem_printf, 1000); */
mode = app_task_init();
#if CONFIG_FINDMY_INFO_ENABLE || (BT_AI_SEL_PROTOCOL & REALME_EN)
#if (VFS_ENABLE == 1)
if (mount(NULL, "mnt/sdfile", "sdfile", 0, NULL)) {
log_debug("sdfile mount succ");
} else {
log_debug("sdfile mount failed!!!");
}
#if BT_AI_SEL_PROTOCOL & REALME_EN
int update = 0;
u32 realme_breakpoint = 0;
if (CONFIG_UPDATE_ENABLE) {
update = update_result_deal();
extern int realme_check_upgrade_area(int update);
realme_check_upgrade_area(update);
}
#endif
#endif /* #if (VFS_ENABLE == 1) */
#endif
while (1) {
app_set_current_mode(mode);
audio_digital_vol_default_init();
//需要根据具体开发需求选择是否开启切mode也需要缓存flash
//1.需要注意的缓存到flash需要较长一段时间(1~3s),特别是从蓝牙后台模式切换到蓝牙前台模式,会出现用户明显感知卡顿现象,因此需要具体需求选择性开启。
#if 0
//如果开启了VM配置项暂存RAM功能则在每次切模式的时候保存数据到vm_flash,避免丢失数据
if (get_vm_ram_storage_enable()) {
vm_flush2flash();
}
#endif //#if 0
//
switch (mode->name) {
case APP_MODE_IDLE:
mode = app_enter_idle_mode(g_mode_switch_arg);
break;
case APP_MODE_POWERON:
mode = app_enter_poweron_mode(g_mode_switch_arg);
break;
#if TCFG_APP_BT_EN
case APP_MODE_BT:
log_info("APP_MODE_BT \n");
mode = app_enter_bt_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_MUSIC_EN
case APP_MODE_MUSIC:
log_info("APP_MODE_MUSIC \n");
mode = app_enter_music_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_FM_EN
case APP_MODE_FM:
log_info("APP_MODE_FM \n");
mode = app_enter_fm_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_RECORD_EN
case APP_MODE_RECORD:
log_info("APP_MODE_RECORD \n");
mode = app_enter_record_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_LINEIN_EN
case APP_MODE_LINEIN:
log_info("APP_MODE_LINEIN \n");
mode = app_enter_linein_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_RTC_EN
case APP_MODE_RTC:
log_info("APP_MODE_RTC \n");
mode = app_enter_rtc_mode(g_mode_switch_arg);
break;
#endif
#if TCFG_APP_PC_EN
case APP_MODE_PC:
log_info("APP_MODE_PC \n");
mode = app_enter_pc_mode(g_mode_switch_arg);
break;
#endif
case APP_MODE_UPDATE:
log_info("APP_MODE_UPDATE \n");
mode = app_enter_update_mode(g_mode_switch_arg);
break;
#if (RCSP_MODE)
case APP_MODE_RCSP:
extern struct app_mode *app_enter_rcsp_mode(int arg);
log_info("APP_MODE_RCSP \n");
mode = app_enter_rcsp_mode(g_mode_switch_arg);
break;
#endif
default:
break;
}
}
}
void app_main()
{
#if (defined TCFG_UI_ENABLE && TCFG_UI_ENABLE)
printf("UI FRAME INIT: %s\n", (TCFG_UI_ENABLE ? (CONFIG_LVGL_UI_ENABLE ? "LVGL" : (CONFIG_JL_UI_ENABLE ? "JLUI" : "NULL")) : "NULL"));
#endif
#ifdef CONFIG_CXX_SUPPORT
void cpp_run_init(void);
cpp_run_init();
#endif
#if (defined TCFG_UI_ENABLE && TCFG_UI_ENABLE)
extern const struct ui_devices_cfg ui_cfg_data;
#if (defined CONFIG_LVGL_UI_ENABLE && CONFIG_LVGL_UI_ENABLE)
// GPU DEMO
/* extern int jlgpu_demo_task_start(char *name, void *arg); */
/* jlgpu_demo_task_start("ui", (void *)&ui_cfg_data); */
#endif
#endif
task_create(app_task_loop, NULL, "app_core");
os_start(); //no return
while (1) {
asm("idle");
}
}
@@ -0,0 +1,539 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".jlstream_event_handler.data.bss")
#pragma data_seg(".jlstream_event_handler.data")
#pragma const_seg(".jlstream_event_handler.text.const")
#pragma code_seg(".jlstream_event_handler.text")
#endif
#include "jlstream.h"
#include "overlay_code.h"
#include "media/audio_base.h"
#include "media/audio_general.h"
#include "clock_manager/clock_manager.h"
#include "a2dp_player.h"
#include "esco_player.h"
#include "app_tone.h"
#include "app_config.h"
#include "effects/effects_adj.h"
#include "audio_manager.h"
#include "file_player.h"
#include "linein_player.h"
#include "fm_player.h"
#include "spdif_player.h"
#include "pc_spk_player.h"
#include "app_main.h"
#include "classic/tws_api.h"
#include "call/call_common.h"
#define PIPELINE_UUID_TONE_NORMAL 0x7674
#define PIPELINE_UUID_A2DP 0xD96F
#define PIPELINE_UUID_ESCO 0xBA11
#define PIPELINE_UUID_LINEIN 0x1207
#define PIPELINE_UUID_SPDIF 0x96BE
#define PIPELINE_UUID_MUSIC 0x2A09
#define PIPELINE_UUID_FM 0x05FB
#define PIPELINE_UUID_MIC_EFFECT 0x9C2D
#define PIPELINE_UUID_MEDIA 0x1408
#define PIPELINE_UUID_A2DP_DUT 0xC9DB
#define PIPELINE_UUID_PC_AUDIO 0xDC8D
#define PIPELINE_UUID_RECODER 0x49EC
#define PIPELINE_UUID_AI_VOICE 0x5475
#define PIPELINE_UUID_AVI_VOICE 0x10BB
#if TCFG_A2DP_PREEMPTED_ENABLE
const int CONFIG_A2DP_ENERGY_CALC_ENABLE = 0;
#else
const int CONFIG_A2DP_ENERGY_CALC_ENABLE = 1;
#endif
static u8 g_a2dp_slience;
static u32 g_a2dp_slience_begin;
static void a2dp_energy_detect_handler(int *arg)
{
// cppcheck-suppress knownConditionTrueFalse
if (CONFIG_A2DP_ENERGY_CALC_ENABLE == 0) {
return;
}
int energy = arg[0];
if (energy == 0) {
if (g_a2dp_slience_begin == 0) {
g_a2dp_slience_begin = jiffies_msec();
} else {
int msec = jiffies_msec2offset(g_a2dp_slience_begin, jiffies_msec());
if (msec >= 2000 && g_a2dp_slience == 0) {
g_a2dp_slience = 1;
audio_event_to_user(AUDIO_EVENT_A2DP_NO_ENERGY);
}
}
} else {
g_a2dp_slience = 0;
g_a2dp_slience_begin = 0;
}
}
int get_system_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_TONE_NORMAL, par);
}
int get_media_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_MEDIA, par);
}
int get_esco_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_ESCO, par);
}
int get_mic_eff_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_MIC_EFFECT, par);
}
int get_usb_audio_stream_bit_width(void *par)
{
return jlstream_read_bit_width(PIPELINE_UUID_PC_AUDIO, par);
}
static int get_pipeline_uuid(const char *name)
{
#if defined(MEDIA_UNIFICATION_EN)&&MEDIA_UNIFICATION_EN
if (!strcmp(name, "tone")) {
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "ring")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "esco")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "mic_effect")) {
clock_alloc("mic_effect", 24 * 1000000UL);
return PIPELINE_UUID_MIC_EFFECT;
}
if (!strcmp(name, "pc_spk")) {
clock_alloc("pc_spk", 96 * 1000000UL);
return PIPELINE_UUID_PC_AUDIO;
}
if (!strcmp(name, "pc_mic")) {
clock_alloc("pc_mic", 96 * 1000000UL);
return PIPELINE_UUID_PC_AUDIO;
}
if (!strcmp(name, "mix_recorder")) {
return PIPELINE_UUID_RECODER;
}
if (!strcmp(name, "ai_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AI_VOICE;
}
if (!strcmp(name, "avi_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AVI_VOICE;
}
if (!strcmp(name, "a2dp")) {
clock_alloc("a2dp", 24 * 1000000UL);
#if TCFG_AUDIO_DUT_ENABLE
if (audio_dec_dut_en_get(0)) {
return PIPELINE_UUID_A2DP_DUT;
}
#endif
}
if (!strcmp(name, "music")) {
clock_alloc("music", 24 * 1000000UL);
}
if (!strcmp(name, "linein")) {
//此处设置时钟不低于120M是由于切时钟会停止cpu,多次切会导致DAC缓存少于1ms
clock_alloc("linein", 120 * 1000000UL);
}
if (!strcmp(name, "fm")) {
clock_alloc("fm", 48 * 1000000UL);
}
if (!strcmp(name, "iis")) {
clock_alloc("iis", 48 * 1000000UL);
}
return PIPELINE_UUID_MEDIA;
#else
if (!strcmp(name, "tone")) {
if (a2dp_player_runing()) {
return PIPELINE_UUID_A2DP;
}
if (esco_player_runing()) {
return PIPELINE_UUID_ESCO;
}
if (ring_player_runing()) {
return PIPELINE_UUID_ESCO;
}
if (music_player_runing()) {
return PIPELINE_UUID_MUSIC;
}
if (linein_player_runing()) {
return PIPELINE_UUID_LINEIN;
}
return PIPELINE_UUID_TONE_NORMAL;
}
if (!strcmp(name, "ring")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "esco")) {
clock_alloc("esco", 48 * 1000000UL);
return PIPELINE_UUID_ESCO;
}
if (!strcmp(name, "a2dp")) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP;
}
if (!strcmp(name, "music")) {
clock_alloc("music", 24 * 1000000UL);
return PIPELINE_UUID_MUSIC;
}
if (!strcmp(name, "linein")) {
struct app_mode *mode = app_get_current_mode();
if (mode && mode->name == APP_MODE_BT) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP;
} else {
clock_alloc("linein", 24 * 1000000UL);
return PIPELINE_UUID_LINEIN;
}
}
if (!strcmp(name, "mix_recorder")) {
return PIPELINE_UUID_RECODER;
}
if (!strcmp(name, "spdif")) {
//spdif 192k采样率输入,同步节点硬件SRC,时钟至少为160MHz
clock_alloc("spdif", 160 * 1000000UL);
return PIPELINE_UUID_SPDIF;
}
if (!strcmp(name, "fm")) {
clock_alloc("fm", 48 * 1000000UL);
return PIPELINE_UUID_FM;
}
if (!strcmp(name, "mic_effect")) {
clock_alloc("mic_effect", 24 * 1000000UL);
return PIPELINE_UUID_MIC_EFFECT;
}
if (!strcmp(name, "a2dp_dut")) {
clock_alloc("a2dp", 24 * 1000000UL);
return PIPELINE_UUID_A2DP_DUT;
}
if (!strcmp(name, "ai_voice")) {
/* clock_alloc("a2dp", 24 * 1000000UL); */
return PIPELINE_UUID_AI_VOICE;
}
#endif
return 0;
}
static void player_close_handler(const char *name)
{
if (!strcmp(name, "a2dp") || !strcmp(name, "a2dp_dut")) {
clock_free("a2dp");
} else if (!strcmp(name, "esco") || !strcmp(name, "ring")) {
clock_free("esco");
} else if (!strcmp(name, "linein")) {
clock_free("linein");
} else if (!strcmp(name, "music")) {
clock_free("music");
} else if (!strcmp(name, "mic_effect")) {
clock_free("mic_effect");
} else if (!strcmp(name, "fm")) {
clock_free("fm");
} else if (!strcmp(name, "pc_spk")) {
clock_free("pc_spk");
} else if (!strcmp(name, "pc_mic")) {
clock_free("pc_mic");
}
if (!strcmp(name, "iis")) {
clock_free("iis");
}
}
#if TCFG_CODE_RUN_RAM_AAC_CODE
static void *aac_code_run_addr = NULL;
extern u32 __aac_movable_slot_start[];
extern u32 __aac_movable_slot_end[];
extern u8 __aac_movable_region_start[];
extern u8 __aac_movable_region_end[];
#endif
#if TCFG_CODE_RUN_RAM_AEC_CODE
static void *aec_code_run_addr = NULL;
extern u32 __aec_movable_slot_start[];
extern u32 __aec_movable_slot_end[];
extern u8 __aec_movable_region_start[];
extern u8 __aec_movable_region_end[];
#endif
void aac_code_movable_load(void)
{
#if TCFG_CODE_RUN_RAM_AAC_CODE
int aac_code_size = __aac_movable_region_end - __aac_movable_region_start;
mem_stats();
if (aac_code_size && !aac_code_run_addr) {
aac_code_run_addr = phy_malloc(aac_code_size);
}
if (!aac_code_run_addr) {
return;
}
code_movable_load(__aac_movable_region_start, aac_code_size, aac_code_run_addr, __aac_movable_slot_start, __aac_movable_slot_end);
printf("aac code load addr : 0x%x, size : %d\n", (u32)aac_code_run_addr, aac_code_size);
mem_stats();
#endif
}
void aac_code_movable_unload(void)
{
#if TCFG_CODE_RUN_RAM_AAC_CODE
if (aac_code_run_addr) {
mem_stats();
code_movable_unload(__aac_movable_region_start, __aac_movable_slot_start, __aac_movable_slot_end);
phy_free(aac_code_run_addr);
aac_code_run_addr = NULL;
printf("aac code unload\n");
mem_stats();
}
#endif
}
void aec_code_movable_load(void)
{
#if TCFG_CODE_RUN_RAM_AEC_CODE
int aec_code_size = __aec_movable_region_end - __aec_movable_region_start;
mem_stats();
if (aec_code_size && !aec_code_run_addr) {
aec_code_run_addr = phy_malloc(aec_code_size);
}
if (!aec_code_run_addr) {
return;
}
code_movable_load(__aec_movable_region_start, aec_code_size, aec_code_run_addr, __aec_movable_slot_start, __aec_movable_slot_end);
printf("aec code load addr : 0x%x, size : %d\n", (u32)aec_code_run_addr, aec_code_size);
mem_stats();
#endif
}
void aec_code_movable_unload(void)
{
#if TCFG_CODE_RUN_RAM_AEC_CODE
if (aec_code_run_addr) {
mem_stats();
code_movable_unload(__aec_movable_region_start, __aec_movable_slot_start, __aec_movable_slot_end);
phy_free(aec_code_run_addr);
aec_code_run_addr = NULL;
printf("aec code unload\n");
mem_stats();
}
#endif
}
static int load_decoder_handler(struct stream_decoder_info *info)
{
if (info->coding_type == AUDIO_CODING_AAC) {
/*printf("overlay_lode_code: aac\n");*/
aac_code_movable_load();
}
if (info->scene == STREAM_SCENE_A2DP) {
g_a2dp_slience = 0;
g_a2dp_slience_begin = 0;
info->task_name = "a2dp_dec";
}
if (info->scene == STREAM_SCENE_ESCO) { //AEC PLC共用overlay
}
if (info->scene == STREAM_SCENE_MUSIC) {
info->task_name = "file_dec";
}
return 0;
}
static void unload_decoder_handler(u32 coding_type)
{
if (coding_type == AUDIO_CODING_AAC) {
aac_code_movable_unload();
}
}
static int load_encoder_handler(struct stream_encoder_info *info)
{
if (info->scene == STREAM_SCENE_ESCO) {
//AEC overlay归节点自己管理, 不依赖编码
/* printf("overlay_lode_code: aec\n"); */
/* overlay_load_code(OVERLAY_AEC); */
/* aec_code_movable_load(); */
}
return 0;
}
static void unload_encoder_handler(struct stream_encoder_info *info)
{
if (info->scene == STREAM_SCENE_ESCO) {
/* aec_code_movable_unload(); */
}
}
/*
*获取需要指定得默认配置
* */
static int get_node_parm(int arg)
{
int ret = 0;
ret = get_eff_default_param(arg);
return ret ;
}
/*
*获取ram内在线音效参数
*/
static int get_eff_online_parm(int arg)
{
int ret = 0;
#if TCFG_CFG_TOOL_ENABLE
ASSERT(arg);
struct eff_parm {
int uuid;
char name[16];
u8 data[0];
};
struct eff_parm *parm = (struct eff_parm *)arg;
/* printf("eff_online_uuid %x, %s\n", parm->uuid, parm->name); */
ret = get_eff_online_param(parm->uuid, parm->name, (void *)arg);
#endif
return ret;
}
static int tws_switch_get_status()
{
int state = tws_api_get_tws_state();
if (state & TWS_STA_SIBLING_DISCONNECTED) {
return 0;
}
return 1;
}
static int a2dp_switch_get_status()
{
#if TCFG_USER_EMITTER_ENABLE
extern u8 *get_cur_connect_emitter_mac_addr(void);
void *bt_addr = get_cur_connect_emitter_mac_addr();
if (bt_addr) {
return 1;
}
#endif
return 0;
}
static int dac_switch_get_status()
{
if (!a2dp_switch_get_status()) {
return 1;
}
return 0;
}
static int get_switch_node_callback(const char *arg)
{
if (!strcmp(arg, "TWS_Switch")) {
return (int)tws_switch_get_status;
}
if (!strcmp(arg, "Switch_a2dp")) {
return (int)a2dp_switch_get_status;
}
if (!strcmp(arg, "Switch_dac")) {
return (int)dac_switch_get_status;
}
return 0;
}
static int jlstream_get_cvp_mode(void)
{
#if TCFG_SIRI_MODE_AEC_BYPASS /*SIRI模式省ram方式*/
if (call_ctrl_get_status() != BT_SIRI_STATE) {
return 1;
}
#endif
return 0;
}
int jlstream_event_notify(enum stream_event event, int arg)
{
int ret = 0;
switch (event) {
case STREAM_EVENT_LOAD_DECODER:
ret = load_decoder_handler((struct stream_decoder_info *)arg);
break;
case STREAM_EVENT_UNLOAD_DECODER:
unload_decoder_handler((u32)arg);
break;
case STREAM_EVENT_LOAD_ENCODER:
ret = load_encoder_handler((struct stream_encoder_info *)arg);
break;
case STREAM_EVENT_UNLOAD_ENCODER:
unload_encoder_handler((struct stream_encoder_info *)arg);
break;
case STREAM_EVENT_GET_PIPELINE_UUID:
ret = get_pipeline_uuid((const char *)arg);
r_printf("pipeline_uuid: %x\n", ret);
clock_refurbish();
break;
case STREAM_EVENT_CLOSE_PLAYER:
player_close_handler((const char *)arg);
break;
case STREAM_EVENT_INC_SYS_CLOCK:
clock_refurbish();
break;
case STREAM_EVENT_GET_NODE_PARM:
ret = get_node_parm(arg);
break;
case STREAM_EVENT_GET_EFF_ONLINE_PARM:
ret = get_eff_online_parm(arg);
break;
case STREAM_EVENT_A2DP_ENERGY:
a2dp_energy_detect_handler((int *)arg);
break;
#if TCFG_SWITCH_NODE_ENABLE
case STREAM_EVENT_GET_SWITCH_CALLBACK:
ret = get_switch_node_callback((const char *)arg);
break;
#endif
#if TCFG_SIRI_MODE_AEC_BYPASS
case STREAM_EVENT_GET_CVP_MODE:
ret = jlstream_get_cvp_mode();
break;
#endif
default:
break;
}
return ret;
}
+233
View File
@@ -0,0 +1,233 @@
#include "typedef.h"
#include "app_main.h"
#include "app_config.h"
#include "vol_sync.h"
#include "audio_config.h"
#include "app_tone.h"
#include "volume_node.h"
#include "mix_record_api.h"
#include "system/includes.h"
#include "app_action.h"
#include "default_event_handler.h"
#include "bt.h"
#include "tone_player.h"
#include "dev_manager.h"
#include "file_recorder.h"
#if TCFG_MIX_RECORD_ENABLE
struct mix_recode_handle {
void *recorder;
FILE *old_file;
FILE *new_file;
char logo[20];
int status;
const char *suffix;
};
static struct mix_recode_handle g_rec_hdl = {
.status = 0,
};
int mix_record_device_msg_handler(int *msg)
{
const char *logo = NULL;
int err = 0;
switch (msg[0]) {
case DRIVER_EVENT_FROM_SD0:
case DRIVER_EVENT_FROM_SD1:
case DRIVER_EVENT_FROM_SD2:
logo = (char *)msg[2];
case DEVICE_EVENT_FROM_USB_HOST:
if (!strncmp((char *)msg[2], "udisk", 5)) {
logo = (char *)msg[2];
}
if (msg[1] == DEVICE_EVENT_IN) {
} else if (msg[1] == DEVICE_EVENT_OUT) {
if (g_rec_hdl.recorder) {
if (!strcmp(g_rec_hdl.logo, logo)) {
mix_recorder_stop();
}
}
}
break;
default:
break;
}
return false;
}
static FILE *mix_recorder_open_file()
{
char folder[] = {TCFG_REC_FOLDER_NAME}; //录音文件夹名称
char filename[] = {TCFG_REC_FILE_NAME}; //录音文件名,不需要加后缀
#if (TCFG_NOR_REC)
char logo[] = {"rec_nor"}; //外挂flash录音
#elif (FLASH_INSIDE_REC_ENABLE)
char logo[] = {"rec_sdfile"}; //内置flash录音
#else
/* char *logo = dev_manager_get_phy_logo(dev_manager_find_active(0));//普通设备录音,获取最后活动设备 */
char logo[] = {RECODER_DEVICE_LOGO}; //sd卡录音
#endif
snprintf(g_rec_hdl.logo, sizeof(g_rec_hdl.logo), "%s", logo);
char *root_path = dev_manager_get_root_path_by_logo(logo);
char path[64] = {};
snprintf(path, sizeof(path), "%s%s/%s.%s", root_path, folder, filename, g_rec_hdl.suffix);
FILE *file = fopen(path, "w+");
if (!file) {
printf("recorder_open_file_faild: %s\n", path);
} else {
fget_name(file, (u8 *)path, 64);
printf("recorder_open_file_suss: %s\n", path);
}
return file;
}
static void file_ops_in_app_task(void *p)
{
switch ((int)p) {
case SEAMLESS_OPEN_FILE:
g_rec_hdl.new_file = mix_recorder_open_file();
break;
case SEAMLESS_CHANGE_FILE:
if (g_rec_hdl.old_file) {
fclose(g_rec_hdl.old_file);
g_rec_hdl.old_file = NULL;
}
break;
case -ENOENT:
mix_recorder_stop();
break;
}
}
/*
* 此回调函数在音频流任务中调用,不能执行耗时长的操作,否则可能导致音频播放卡顿
*/
static int change_file_in_stream_task(void *priv, enum change_file_step step)
{
int msg[4] = { (int)file_ops_in_app_task, 1, step};
if (step == SEAMLESS_CHANGE_FILE) {
g_rec_hdl.old_file = file_recorder_change_file(g_rec_hdl.recorder, g_rec_hdl.new_file);
if (g_rec_hdl.new_file) {
g_rec_hdl.new_file = NULL;
} else {
msg[2] = -ENOENT;
}
}
return os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
}
void mix_recorder_start()
{
int err;
void *recorder;
u16 uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"mix_recorder");
recorder = file_recorder_open(uuid, NODE_UUID_ADC);
/* recorder = file_recorder_open(uuid, NODE_UUID_ZERO_ACTIVE); */
if (!recorder) {
puts("file_recorder_open_faild\n");
return;
}
struct stream_enc_fmt fmt;
err = file_recorder_get_fmt(recorder, &fmt);
if (err) {
file_recorder_close(recorder, 0);
return;
}
printf("recorder_fmt: ch %d, sample rate %d\n", fmt.channel, fmt.sample_rate);
switch (fmt.coding_type) {
case AUDIO_CODING_PCM:
g_rec_hdl.suffix = "pcm";
break;
case AUDIO_CODING_WAV:
g_rec_hdl.suffix = "wav";
break;
case AUDIO_CODING_MP3:
g_rec_hdl.suffix = "mp3";
break;
case AUDIO_CODING_AMR:
g_rec_hdl.suffix = "amr";
break;
default:
g_rec_hdl.suffix = "bin";
break;
}
FILE *file = mix_recorder_open_file();
if (!file) {
file_recorder_close(recorder, 0);
return;
}
file_recorder_set_file(recorder, file, NULL);
struct seamless_recording seamless = {
.advance_time = 10, //提前10s创建新文件
.time = 3600, //单个文件录音时长
.priv = recorder,
.change_file = change_file_in_stream_task,
};
file_recorder_seamless_set(recorder, &seamless);
err = file_recorder_start(recorder);
if (err) {
printf("file_recorder_err: %d\n", err);
file_recorder_close(recorder, 1);
return;
}
g_rec_hdl.status = 1;
g_rec_hdl.recorder = recorder;
mem_stats();
}
void mix_recorder_stop()
{
// 先停掉录音,会有淡出操作
file_recorder_stop(g_rec_hdl.recorder, 1);
// 再关闭音源
g_rec_hdl.status = 0;
os_time_dly(1);
if (g_rec_hdl.old_file) {
fclose(g_rec_hdl.old_file);
g_rec_hdl.old_file = NULL;
}
if (g_rec_hdl.new_file) {
fdelete(g_rec_hdl.new_file);
g_rec_hdl.new_file = NULL;
}
file_recorder_release(g_rec_hdl.recorder);
g_rec_hdl.recorder = NULL;
}
int get_mix_recorder_status(void)
{
return g_rec_hdl.status ? 1 : 0;
}
static u8 mix_record_idle_query(void)
{
return g_rec_hdl.status ? 0 : 1;
}
REGISTER_LP_TARGET(mix_record_lp_target) = {
.name = "mix_record",
.is_idle = mix_record_idle_query,
};
#endif // TCFG_MIX_RECORD_ENABLE
+341
View File
@@ -0,0 +1,341 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".scene_switch.data.bss")
#pragma data_seg(".scene_switch.data")
#pragma const_seg(".scene_switch.text.const")
#pragma code_seg(".scene_switch.text")
#endif
#include "jlstream.h"
#include "effects/effects_adj.h"
#include "node_param_update.h"
#include "scene_switch.h"
#include "app_main.h"
#include "effects/audio_vocal_remove.h"
static u8 music_scene = 0; //记录音乐场景序号
static u8 music_eq_preset_index = 0; //记录 Eq0Media EQ配置序号
static u8 mic_scene = 0; //记录混响场景序号
/* 命名规则:节点名+模式名,如 SurBt、CrossAux、Eq0File */
#if defined(MEDIA_UNIFICATION_EN)&&MEDIA_UNIFICATION_EN
static char *music_mode[] = {"Media", "Media", "Media", "Media", "Media"};
#else
static char *music_mode[] = {"Bt", "Aux", "File", "Fm", "Spd"};
#endif
static char *sur_name[] = {"Sur"};
static char *crossover_name[] = {"Cross"};
static char *band_merge_name[] = {"Band"};
static char *bass_treble_name[] = {"Bass"};
static char *smix_name[] = {"Smix0", "Smix1"};
static char *eq_name[] = {"Eq0", "Eq1", "Eq2", "Eq3"};
static char *drc_name[] = {"Drc0", "Drc1", "Drc2", "Drc3", "Drc4"};
static char *vbass_name[] = {"VBass"};
static char *gain_name[] = {"Gain"};
static char *harmonic_exciter_name[] = {"Hexciter"};
static char *dy_eq_name[] = {"DyEq"};
/* 混响模块命名 */
static char *mic_name = "Eff";
static char *mic_bass_treble_name[] = {"BassTre"};
static char *mic_noisegate_name[] = {"NoiseGate"};
static char *mic_crossover_name[] = {"Crossover"};
static char *mic_band_merge_name[] = {"BMerge1", "BMerge2"};
static char *mic_howling_fs_name[] = {"Fshift"};
static char *mic_howling_supress_name[] = {"Hspress"};
static char *mic_voice_changer_name[] = {"Vchanger"};
static char *mic_autotune_name[] = {"Atune"};
static char *mic_plate_reverb_advance_name[] = {"PReverb"};
static char *mic_echo_name[] = {"Echo"};
static char *mic_eq_name[] = {"Eq1", "Eq2", "Eq3", "Eq4", "Eq5", "Eq6"};
static char *mic_drc_name[] = {"Drc1", "Drc2", "Drc3", "Drc4", "Drc5", "Drc6", "Drc7"};
/* 获取音乐模式场景序号 */
u8 get_current_scene()
{
return music_scene;
}
/* 获取mic混响模式场景序号 */
u8 get_mic_current_scene()
{
return mic_scene;
}
void set_default_scene(u8 index)
{
music_scene = index;
}
/* 获EQ0 配置序号 */
u8 get_music_eq_preset_index(void)
{
return music_eq_preset_index;
}
void set_music_eq_preset_index(u8 index)
{
music_eq_preset_index = index;
syscfg_write(CFG_EQ0_INDEX, &music_eq_preset_index, 1);
}
/* 获取当前处于的模式 */
u8 get_current_mode_index()
{
struct app_mode *mode;
mode = app_get_current_mode();
switch (mode->name) {
case APP_MODE_BT:
return BT_MODE;
case APP_MODE_LINEIN:
return AUX_MODE;
case APP_MODE_MUSIC:
return FILE_MODE;
case APP_MODE_FM:
return FM_MODE;
case APP_MODE_SPDIF:
return SPDIF_MODE;
case APP_MODE_PC:
return PC_MODE;
default:
printf("mode not support scene switch %d\n", mode->name);
return NOT_SUPPORT_MODE;
}
}
/* 获取当前模式中场景个数 */
int get_mode_scene_num()
{
struct app_mode *mode;
mode = app_get_current_mode();
u16 uuid;
u8 scene_num;
switch (mode->name) {
case APP_MODE_BT:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"a2dp");
break;
case APP_MODE_LINEIN:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"linein");
break;
case APP_MODE_MUSIC:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"music");
break;
case APP_MODE_FM:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"fm");
break;
case APP_MODE_SPDIF:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"spdif");
break;
case APP_MODE_PC:
uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"pc_spk");
break;
default:
printf("mode not support scene switch %d\n", mode->name);
return -1;
}
jlstream_read_pipeline_param_group_num(uuid, &scene_num);
return scene_num;
}
/* 音乐模式:根据参数组序号进行场景切换 */
void effect_scene_set(u8 scene)
{
int scene_num = get_mode_scene_num();
if (scene >= scene_num) {
printf("err : without this scene %d\n", scene);
return;
}
music_scene = scene;
printf("current music scene : %d\n", scene);
syscfg_write(CFG_SCENE_INDEX, &music_scene, 1);
char tar_name[16];
u8 cur_mode = get_current_mode_index();
for (int i = 0; i < ARRAY_SIZE(sur_name); i++) {
sprintf(tar_name, "%s%s", sur_name[i], music_mode[cur_mode]);
surround_effect_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(crossover_name); i++) {
sprintf(tar_name, "%s%s", crossover_name[i], music_mode[cur_mode]);
crossover_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(band_merge_name); i++) {
sprintf(tar_name, "%s%s", band_merge_name[i], music_mode[cur_mode]);
band_merge_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(bass_treble_name); i++) {
sprintf(tar_name, "%s%s", bass_treble_name[i], music_mode[cur_mode]);
bass_treble_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(smix_name); i++) {
sprintf(tar_name, "%s%s", smix_name[i], music_mode[cur_mode]);
stereo_mix_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(eq_name); i++) {
sprintf(tar_name, "%s%s", eq_name[i], music_mode[cur_mode]);
if (i == 0) {
eq_update_parm(scene, tar_name, music_eq_preset_index);
} else {
eq_update_parm(scene, tar_name, 0);
}
}
for (int i = 0; i < ARRAY_SIZE(drc_name); i++) {
sprintf(tar_name, "%s%s", drc_name[i], music_mode[cur_mode]);
drc_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(vbass_name); i++) {
sprintf(tar_name, "%s%s", vbass_name[i], music_mode[cur_mode]);
virtual_bass_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(gain_name); i++) {
sprintf(tar_name, "%s%s", gain_name[i], music_mode[cur_mode]);
gain_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(harmonic_exciter_name); i++) {
sprintf(tar_name, "%s%s", harmonic_exciter_name[i], music_mode[cur_mode]);
harmonic_exciter_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(dy_eq_name); i++) {
sprintf(tar_name, "%s%s", dy_eq_name[i], music_mode[cur_mode]);
dynamic_eq_update_parm(scene, tar_name, 0);
}
}
/* 音乐模式:根据参数组个数顺序切换场景 */
void effect_scene_switch()
{
int scene_num = get_mode_scene_num();
if (!scene_num) {
puts("scene switch err\n");
return;
}
music_scene++;
if (music_scene >= scene_num) {
music_scene = 0;
}
effect_scene_set(music_scene);
}
/* mic混响:获取场景个数 */
static u8 get_mic_effect_scene_num()
{
u8 scene_num;
u16 uuid = jlstream_event_notify(STREAM_EVENT_GET_PIPELINE_UUID, (int)"mic_effect");
jlstream_read_pipeline_param_group_num(uuid, &scene_num);
return scene_num;
}
/* mic混响:根据参数组序号进行场景切换 */
void mic_effect_scene_set(u8 scene)
{
u8 scene_num = get_mic_effect_scene_num();
if (scene >= scene_num) {
printf("err : without this scene %d\n", scene);
return;
}
mic_scene = scene;
char tar_name[16];
for (int i = 0; i < ARRAY_SIZE(mic_noisegate_name); i++) {
sprintf(tar_name, "%s%s", mic_noisegate_name[i], mic_name);
noisegate_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_crossover_name); i++) {
sprintf(tar_name, "%s%s", mic_crossover_name[i], mic_name);
crossover_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_band_merge_name); i++) {
sprintf(tar_name, "%s%s", mic_band_merge_name[i], mic_name);
band_merge_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_howling_fs_name); i++) {
sprintf(tar_name, "%s%s", mic_howling_fs_name[i], mic_name);
howling_frequency_shift_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_howling_supress_name); i++) {
sprintf(tar_name, "%s%s", mic_howling_supress_name[i], mic_name);
howling_suppress_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_voice_changer_name); i++) {
sprintf(tar_name, "%s%s", mic_voice_changer_name[i], mic_name);
voice_changer_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_autotune_name); i++) {
sprintf(tar_name, "%s%s", mic_autotune_name[i], mic_name);
autotune_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_plate_reverb_advance_name); i++) {
sprintf(tar_name, "%s%s", mic_plate_reverb_advance_name[i], mic_name);
reverb_advance_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_echo_name); i++) {
sprintf(tar_name, "%s%s", mic_echo_name[i], mic_name);
echo_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_eq_name); i++) {
sprintf(tar_name, "%s%s", mic_eq_name[i], mic_name);
eq_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_drc_name); i++) {
sprintf(tar_name, "%s%s", mic_drc_name[i], mic_name);
drc_update_parm(scene, tar_name, 0);
}
for (int i = 0; i < ARRAY_SIZE(mic_bass_treble_name); i++) {
sprintf(tar_name, "%s%s", mic_bass_treble_name[i], mic_name);
bass_treble_update_parm(scene, tar_name, 0);
}
}
/* mic混响:根据参数组个数顺序切换场景 */
void mic_effect_scene_switch()
{
int scene_num = get_mic_effect_scene_num();
if (!scene_num) {
puts("scene switch err\n");
return;
}
mic_scene++;
if (mic_scene >= scene_num) {
mic_scene = 0;
}
mic_effect_scene_set(mic_scene);
}
static u8 vocla_remove_mark = 0xff;//
//实时更新media数据流中人声消除bypass参数,启停人声消除功能
void music_vocal_remover_switch(void)
{
#if TCFG_VOCAL_REMOVER_NODE_ENABLE
vocal_remover_param_tool_set cfg = {0};
char *vocal_node_name = "VocalRemovMedia";
int ret = jlstream_read_form_data(0, vocal_node_name, 0, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, vocal_node_name);
return;
}
if (vocla_remove_mark == 0xff) {
vocla_remove_mark = cfg.is_bypass;
}
vocla_remove_mark ^= 1;
cfg.is_bypass = vocla_remove_mark;
jlstream_set_node_param(NODE_UUID_VOCAL_REMOVER, vocal_node_name, &cfg, sizeof(cfg));
#endif
}
//media数据流启动后更新人声消除bypass参数
void music_vocal_remover_update_parm()
{
#if TCFG_VOCAL_REMOVER_NODE_ENABLE
vocal_remover_param_tool_set cfg = {0};
char *vocal_node_name = "VocalRemovMedia";
int ret = jlstream_read_form_data(0, vocal_node_name, 0, &cfg);
if (!ret) {
printf("read parm err, %s, %s\n", __func__, vocal_node_name);
return;
}
if (vocla_remove_mark == 0xff) {
vocla_remove_mark = cfg.is_bypass;
}
cfg.is_bypass = vocla_remove_mark;
jlstream_set_node_param(NODE_UUID_VOCAL_REMOVER, vocal_node_name, &cfg, sizeof(cfg));
#endif
}
u8 get_music_vocal_remover_statu(void)
{
return vocla_remove_mark ;
}
+121
View File
@@ -0,0 +1,121 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".tone_table.data.bss")
#pragma data_seg(".tone_table.data")
#pragma const_seg(".tone_table.text.const")
#pragma code_seg(".tone_table.text")
#endif
#include "app_config.h"
#include "app_tone.h"
#include "fs/resfile.h"
static const struct tone_files chinese_tone_files = {
.num = {
"tone_zh/0.*",
"tone_zh/1.*",
"tone_zh/2.*",
"tone_zh/3.*",
"tone_zh/4.*",
"tone_zh/5.*",
"tone_zh/6.*",
"tone_zh/7.*",
"tone_zh/8.*",
"tone_zh/9.*",
},
.power_on = "tone_zh/power_on.*",
.power_off = "tone_zh/power_off.*",
.bt_mode = "tone_zh/bt.*",
.bt_connect = "tone_zh/bt_conn.*",
.bt_disconnect = "tone_zh/bt_dconn.*",
.phone_in = "tone_zh/ring.*",
.phone_out = "tone_zh/ring.*",
.low_power = "tone_zh/low_power.*",
.max_vol = "tone_zh/vol_max.*",
.tws_connect = "tone_zh/tws_conn.*",
.tws_disconnect = "tone_zh/tws_dconn.*",
.normal = "tone_zh/normal.*",
.low_latency_in = "tone_zh/game_in.*",
.low_latency_out = "tone_zh/game_out.*",
.anc_on = "tone_zh/anc_on.*",
.anc_trans = "tone_zh/anc_trans.*",
.anc_off = "tone_zh/anc_off.*",
.key_tone = "tone_zh/key_tone.*",
.music_mode = "tone_zh/music.*",
.record_mode = "tone_zh/record.*",
.device_sd = "tone_zh/sd.*",
.device_udisk = "tone_zh/udisk.*",
.fm_mode = "tone_zh/fm.*",
.linein_mode = "tone_zh/linein.*",
.pc_mode = "tone_zh/pc.*",
.rtc_mode = "tone_zh/rtc.*",
.spdif_mode = "tone_zh/spdif.*",
};
static const struct tone_files english_tone_files = {
.num = {
"tone_en/0.*",
"tone_en/1.*",
"tone_en/2.*",
"tone_en/3.*",
"tone_en/4.*",
"tone_en/5.*",
"tone_en/6.*",
"tone_en/7.*",
"tone_en/8.*",
"tone_en/9.*",
},
.power_on = "tone_en/power_on.*",
.power_off = "tone_en/power_off.*",
.bt_mode = "tone_en/bt.*",
.bt_connect = "tone_en/bt_conn.*",
.bt_disconnect = "tone_en/bt_dconn.*",
.phone_in = "tone_en/ring.*",
.phone_out = "tone_en/ring.*",
.low_power = "tone_en/low_power.*",
.max_vol = "tone_en/vol_max.*",
.tws_connect = "tone_en/tws_conn.*",
.tws_disconnect = "tone_en/tws_dconn.*",
.normal = "tone_en/normal.*",
.low_latency_in = "tone_en/game_in.*",
.low_latency_out = "tone_en/game_out.*",
.anc_on = "tone_en/anc_on.*",
.anc_trans = "tone_en/anc_trans.*",
.anc_off = "tone_en/anc_off.*",
.key_tone = "tone_en/key_tone.*",
.music_mode = "tone_en/music.*",
.record_mode = "tone_en/record.*",
.device_sd = "tone_en/sd.*",
.device_udisk = "tone_en/udisk.*",
.fm_mode = "tone_en/fm.*",
.linein_mode = "tone_en/linein.*",
.pc_mode = "tone_en/pc.*",
.rtc_mode = "tone_en/rtc.*",
.spdif_mode = "tone_en/spdif.*",
};
#if TCFG_TONE_EN_ENABLE
static enum tone_language g_lang_used = TONE_ENGLISH;
#else
static enum tone_language g_lang_used = TONE_CHINESE;
#endif
enum tone_language tone_language_get()
{
return g_lang_used;
}
void tone_language_set(enum tone_language lang)
{
g_lang_used = lang;
}
const struct tone_files *get_tone_files()
{
#if TCFG_TONE_ZH_ENABLE
if (g_lang_used == TONE_CHINESE) {
return &chinese_tone_files;
}
#endif
return &english_tone_files;
}
+183
View File
@@ -0,0 +1,183 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".vol_sync.data.bss")
#pragma data_seg(".vol_sync.data")
#pragma const_seg(".vol_sync.text.const")
#pragma code_seg(".vol_sync.text")
#endif
#include "typedef.h"
#include "app_main.h"
#include "app_config.h"
#include "vol_sync.h"
#include "audio_config.h"
#include "app_tone.h"
#include "volume_node.h"
#include "jlui_app/ui_api.h"
u8 vol_sys_tab[17] = {0, 2, 3, 4, 6, 8, 10, 11, 12, 14, 16, 18, 19, 20, 22, 23, 25};
const u8 vol_sync_tab[17] = {0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127};
static s16 max_vol = 100;
void vol_sys_tab_init(void)
{
#if TCFG_BT_VOL_SYNC_ENABLE
#if 1
u8 i = 0;
max_vol = app_audio_volume_max_query(AppVol_BT_MUSIC);
for (i = 0; i < 17; i++) {
vol_sys_tab[i] = i * max_vol / 16;
}
#else
u8 i = 0;
max_vol = app_audio_volume_max_query(AppVol_BT_MUSIC);
vol_sys_tab[0] = 0;
//最大音量<16,补最大值
if (max_vol <= 16) {
for (i = 1; i <= max_vol; i++) {
vol_sys_tab[i] = i;
}
for (; i < 17; i++) {
vol_sys_tab[i] = max_vol;
}
} else {
u8 j = max_vol - 16;
u8 k = 1;
for (i = 1; i <= max_vol; i++) {
/* g_printf("i=%d j=%d k=%d",i,j,k); */
if (i % 2) {
} else {
//忽略多余的级数
if (j > 0) {
j--;
continue;
}
}
if (k < 17) {
vol_sys_tab[k] = i;
}
k++;
}
vol_sys_tab[16] = max_vol;
}
#endif
#if 0
for (i = 0; i < 17; i++) {
g_printf("[%d]:%d ", i, vol_sys_tab[i]);
}
#endif
#endif
}
//注册给库的回调函数,用户手机设置设备音量
void set_music_device_volume(int volume)
{
r_printf("set_music_device_volume=%d\n", volume);
#if TCFG_BT_VOL_SYNC_ENABLE
s16 music_volume;
//音量同步最大是127,请计数比例
if (volume > 127) {
/*log_info("vol %d invalid\n", volume);*/
#if TCFG_VOL_RESET_WHEN_NO_SUPPORT_VOL_SYNC
/*不支持音量同步的设备,默认设置到最大值,可以根据实际需要进行修改。
注意如果不是最大值,设备又没有按键可以调音量到最大,则输出也就达不到最大*/
music_volume = max_vol;
log_i("unsupport vol_sync,reset vol:%d\n", music_volume);
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, music_volume, 1);
#endif
return;
}
if (tone_player_runing() || ring_player_runing() || bt_get_esco_coder_busy_flag()) {
log_i("It's not smart to sync a2dp vol now\n");
//app_var.music_volume = vol_sys_tab[(volume + 1) / 8];
app_var.music_volume = ((volume + 1) * max_vol) / 127;
return;
}
#if 1
/*
*0~16,总共17级
*这里将手机的0~127的音量值换成实际的dac音量等级
*/
music_volume = ((volume + 1) * max_vol) / 127;
#else
music_volume = vol_sys_tab[(volume + 1) / 8];
#endif
y_printf("phone_vol:%d,dac_vol:%d", volume, music_volume);
app_var.opid_play_vol_sync = vol_sync_tab[(volume + 1) / 8];
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, music_volume, 1);
app_audio_set_volume_def_state(0);
#endif
#if (defined CONFIG_JL_UI_ENABLE)&&CONFIG_JL_UI_ENABLE
UI_MSG_POST("volume");
#endif
}
//注册给库的回调函数,用于手机获取当前设备音量
int phone_get_device_vol(void)
{
//音量同步最大是127,请计数比例
#if 0
return (app_var.sys_vol_l * max_vol / 127) ;
#else
return app_var.opid_play_vol_sync;
#endif
}
void opid_play_vol_sync_fun(s16 *vol, u8 mode)
{
#if TCFG_BT_VOL_SYNC_ENABLE
vol_sys_tab[16] = max_vol;
if (*vol == 0) {
if (mode) {
*vol = vol_sys_tab[1];
app_var.opid_play_vol_sync = vol_sync_tab[1];
} else {
*vol = vol_sys_tab[0];
app_var.opid_play_vol_sync = vol_sync_tab[0];
}
} else if (*vol >= max_vol) {
if (mode) {
*vol = vol_sys_tab[16];
app_var.opid_play_vol_sync = vol_sync_tab[16];
} else {
*vol = vol_sys_tab[15];
app_var.opid_play_vol_sync = vol_sync_tab[15];
}
} else {
for (u8 i = 0; i < sizeof(vol_sys_tab) / sizeof(vol_sys_tab[0]); i++) {
if (*vol == vol_sys_tab[i]) {
if (mode) {
app_var.opid_play_vol_sync = vol_sync_tab[i + 1];
*vol = vol_sys_tab[i + 1];
} else {
app_var.opid_play_vol_sync = vol_sync_tab[i - 1];
*vol = vol_sys_tab[i - 1];
}
break;
} else if (*vol < vol_sys_tab[i]) {
if (mode) {
*vol = vol_sys_tab[i + 1];
app_var.opid_play_vol_sync = vol_sync_tab[i];
} else {
*vol = vol_sys_tab[i - 1];
app_var.opid_play_vol_sync = vol_sync_tab[i - 1];
}
break;
}
}
}
#endif
}
+795
View File
@@ -0,0 +1,795 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".battery_level.data.bss")
#pragma data_seg(".battery_level.data")
#pragma const_seg(".battery_level.text.const")
#pragma code_seg(".battery_level.text")
#endif
#include "system/includes.h"
#include "battery_manager.h"
#include "app_power_manage.h"
#include "app_main.h"
#include "app_config.h"
#include "app_action.h"
#include "asm/charge.h"
#include "app_tone.h"
#include "gpadc.h"
#include "btstack/avctp_user.h"
#include "user_cfg.h"
#include "bt_tws.h"
#include "idle.h"
#include "ui/ui_api.h"
#include "rcsp.h"
#include "power/power_manage.h"
#include "rtc.h"
#include "timestamp/timestamp.h"
#if RCSP_ADV_EN
#include "ble_rcsp_adv.h"
#endif
#define LOG_TAG "[BATTERY]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
enum {
VBAT_NORMAL = 0,
VBAT_WARNING,
VBAT_LOWPOWER,
} VBAT_STATUS;
#define VBAT_DETECT_CNT 3 //每次更新电池电量采集的次数
#define VBAT_DETECT_TIME 10L //每次采集的时间间隔
#define VBAT_UPDATE_SLOW_TIME 60000L //慢周期更新电池电量
#define VBAT_UPDATE_FAST_TIME 10000L //快周期更新电池电量
#define VBAT_PERCENT_MODE_OPEN_CIRCUIT_VOLTAGE 0 //开路电压法
#define VBAT_PERCENT_MODE_CURRENT_INTEGRATING_METHOD 1 //安时积分法
#define VBAT_PERCENT_MODE_SEL VBAT_PERCENT_MODE_OPEN_CIRCUIT_VOLTAGE
/* #define VBAT_PERCENT_MODE_SEL VBAT_PERCENT_MODE_CURRENT_INTEGRATING_METHOD */
struct battery_curve {
u8 percent;
u16 voltage;
};
union battery_data {
u32 raw_data;
struct {
u8 reserved;
u16 voltage;
u8 percent;
} __attribute__((packed)) data;
};
#define REAL_CHANEG_VAL 15 //参考值20
#define REAL_CHANGE_PER 85 //真实电流占比
#define PRED_CHANGE_PER 15 //模拟电流占比
#define BATTERY_CHARGE_K (1.0f) //模拟充电电流系数
#define BATTERY_CAPACITY (200.0f) //电池总容量,单位mAh
#define BATTERY_RESISTOR (0.15f) //电池阻值
#define VBAT_UPDATE_SEC 8 //刷新间隔
#define BATTERY_CHANGE_SAVE 5 //电量变化超过5%时存储到vm
#define RECHECK_HOUR 24 //关机超过24小时,开机时校准
#define RECHECK_SOC 10 //误差超过10%电量,开机时校准
#define abs(x) ((x)>0?(x):-(x))
static float current_soc = 0;
static u16 last_present_k = 0;
static u32 is_sleep_cnt = 0;
static u16 vbat_slow_timer = 0;
static u16 vbat_fast_timer = 0;
static u16 lowpower_timer = 0;
static u8 old_battery_level = 9;
static u16 cur_battery_voltage = 0;
static u8 cur_battery_level = 0;
static u8 old_battery_percent = 0;
static u8 cur_battery_percent = 0;
static u8 tws_sibling_bat_level = 0xff;
static u8 tws_sibling_bat_percent_level = 0xff;
static u8 cur_bat_st = VBAT_NORMAL;
static u8 battery_curve_max;
static struct battery_curve *battery_curve_p;
void vbat_check(void *priv);
void clr_wdt(void);
u8 get_charge_full_flag(void);
#if TCFG_USER_TWS_ENABLE
u8 get_tws_sibling_bat_level(void)
{
return tws_sibling_bat_level & 0x7f;
}
u8 get_tws_sibling_bat_persent(void)
{
return tws_sibling_bat_percent_level;
}
void app_power_set_tws_sibling_bat_level(u8 vbat, u8 percent)
{
tws_sibling_bat_level = vbat;
tws_sibling_bat_percent_level = percent;
/*
** 发出电量同步事件进行进一步处理
**/
batmgr_send_msg(POWER_EVENT_SYNC_TWS_VBAT_LEVEL, 0);
log_info("set_sibling_bat_level: %d, %d\n", vbat, percent);
}
static void set_tws_sibling_bat_level(void *_data, u16 len, bool rx)
{
u8 *data = (u8 *)_data;
if (rx) {
app_power_set_tws_sibling_bat_level(data[0], data[1]);
}
}
REGISTER_TWS_FUNC_STUB(vbat_sync_stub) = {
.func_id = TWS_FUNC_ID_VBAT_SYNC,
.func = set_tws_sibling_bat_level,
};
void tws_sync_bat_level(void)
{
#if TCFG_BT_DISPLAY_BAT_ENABLE
u8 battery_level = cur_battery_level;
#if CONFIG_DISPLAY_DETAIL_BAT
u8 percent_level = get_vbat_percent();
#else
u8 percent_level = get_self_battery_level() * 10 + 10;
#endif
if (get_charge_online_flag()) {
percent_level |= BIT(7);
}
u8 data[2];
data[0] = battery_level;
data[1] = percent_level;
tws_api_send_data_to_sibling(data, 2, TWS_FUNC_ID_VBAT_SYNC);
log_info("tws_sync_bat_level: %d,%d\n", battery_level, percent_level);
#endif
}
#endif
static void power_warning_timer(void *p)
{
batmgr_send_msg(POWER_EVENT_POWER_WARNING, 0);
}
static int app_power_event_handler(int *msg)
{
int ret = false;
#if(TCFG_SYS_LVD_EN == 1)
switch (msg[0]) {
case POWER_EVENT_POWER_NORMAL:
break;
case POWER_EVENT_POWER_WARNING:
play_tone_file(get_tone_files()->low_power);
#ifdef CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE
UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_LOW_POWER_TIPS, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_CHARGE); // 低电提醒页面
#endif
if (lowpower_timer == 0) {
lowpower_timer = sys_timer_add(NULL, power_warning_timer, LOW_POWER_WARN_TIME);
}
break;
case POWER_EVENT_POWER_LOW:
r_printf(" POWER_EVENT_POWER_LOW");
vbat_timer_delete();
if (lowpower_timer) {
sys_timer_del(lowpower_timer);
lowpower_timer = 0 ;
}
#if TCFG_APP_BT_EN
#if RCSP_ADV_EN
adv_tws_both_in_charge_box(1);
#endif
if (!app_in_mode(APP_MODE_IDLE)) {
sys_enter_soft_poweroff(POWEROFF_NORMAL);
} else {
power_set_soft_poweroff();
}
#else
app_goto_mode(APP_MODE_IDLE, IDLE_MODE_PLAY_POWEROFF);
#endif
break;
#if TCFG_APP_BT_EN
case POWER_EVENT_SYNC_TWS_VBAT_LEVEL:
if (tws_api_get_role() == TWS_ROLE_MASTER) {
bt_cmd_prepare(USER_CTRL_HFP_CMD_UPDATE_BATTARY, 0, NULL);
}
break;
case POWER_EVENT_POWER_CHANGE:
log_info("POWER_EVENT_POWER_CHANGE\n");
if (!app_in_mode(APP_MODE_BT)) {
break;
}
#if TCFG_USER_TWS_ENABLE
if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
if (tws_api_get_tws_state()&TWS_STA_ESCO_OPEN) {
break;
}
tws_sync_bat_level();
}
#endif
bt_cmd_prepare(USER_CTRL_HFP_CMD_UPDATE_BATTARY, 0, NULL);
#endif
RCSP_UPDATE(COMMON_FUNCTION, BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_BATTERY));
break;
case POWER_EVENT_POWER_CHARGE:
if (lowpower_timer) {
sys_timer_del(lowpower_timer);
lowpower_timer = 0 ;
}
break;
#if TCFG_CHARGE_ENABLE
case CHARGE_EVENT_LDO5V_OFF:
//充电拔出时重新初始化检测定时器
vbat_check_init();
break;
#endif
default:
break;
}
#endif
return ret;
}
APP_MSG_HANDLER(bat_level_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BATTERY,
.handler = app_power_event_handler,
};
static u16 get_vbat_voltage(void)
{
return gpadc_battery_get_voltage();
}
static u16 battery_calc_voltage(u16 percent)
{
u8 i;
u16 max, min, div_voltage, tmp_voltage;
if (battery_curve_p == NULL) {
printf("%s battery_curve not init!!!\n", __func__);
return 0;
}
for (i = 0; i < (battery_curve_max - 1); i++) {
if (percent <= battery_curve_p[i].percent) {
printf("%s(1) %d", __func__, battery_curve_p[i].voltage);
return battery_curve_p[i].voltage;
}
if (percent >= battery_curve_p[i + 1].percent) {
continue;
}
div_voltage = battery_curve_p[i + 1].voltage - battery_curve_p[i].voltage;
min = battery_curve_p[i].percent;
max = battery_curve_p[i + 1].percent;
tmp_voltage = battery_curve_p[i].voltage;
tmp_voltage += ((percent - min) * div_voltage / (max - min));
printf("%s(2) %d percent:%d div:%d min:%d max:%d tvp:%d", __func__, tmp_voltage, percent, div_voltage, min, max, battery_curve_p[i].voltage);
return tmp_voltage;
}
printf("%s(3) %d", __func__, battery_curve_p[battery_curve_max - 1].voltage);
return battery_curve_p[battery_curve_max - 1].voltage;
}
static u16 battery_calc_percent(u16 bat_val)
{
u8 i, tmp_percent;
u16 max, min, div_percent;
if (battery_curve_p == NULL) {
log_error("battery_curve not init!!!\n");
return 0;
}
for (i = 0; i < (battery_curve_max - 1); i++) {
if (bat_val <= battery_curve_p[i].voltage) {
return battery_curve_p[i].percent;
}
if (bat_val >= battery_curve_p[i + 1].voltage) {
continue;
}
div_percent = battery_curve_p[i + 1].percent - battery_curve_p[i].percent;
min = battery_curve_p[i].voltage;
max = battery_curve_p[i + 1].voltage;
tmp_percent = battery_curve_p[i].percent;
tmp_percent += (bat_val - min) * div_percent / (max - min);
return tmp_percent;
}
return battery_curve_p[battery_curve_max - 1].percent;
}
u16 get_vbat_value(void)
{
return cur_battery_voltage;
}
u8 get_vbat_percent(void)
{
return cur_battery_percent;
}
bool get_vbat_need_shutdown(void)
{
if ((cur_battery_voltage <= app_var.poweroff_tone_v) || adc_check_vbat_lowpower()) {
return TRUE;
}
return FALSE;
}
//将当前电量转换为1~9级发送给手机同步电量
u8 battery_value_to_phone_level(void)
{
u8 battery_level = 0;
u8 vbat_percent = get_vbat_percent();
if (vbat_percent < 5) { //小于5%电量等级为0,显示10%
return 0;
}
battery_level = (vbat_percent - 5) / 10;
return battery_level;
}
//获取自身的电量
u8 get_self_battery_level(void)
{
return cur_battery_level;
}
#if TCFG_USER_TWS_ENABLE
u8 get_cur_battery_level(void)
{
u8 bat_lev = tws_sibling_bat_level & (~BIT(7));
if (bat_lev == 0x7f) {
return cur_battery_level;
}
#if (CONFIG_DISPLAY_TWS_BAT_TYPE == CONFIG_DISPLAY_TWS_BAT_LOWER)
return cur_battery_level < bat_lev ? cur_battery_level : bat_lev;
#elif (CONFIG_DISPLAY_TWS_BAT_TYPE == CONFIG_DISPLAY_TWS_BAT_HIGHER)
return cur_battery_level < bat_lev ? bat_lev : cur_battery_level;
#elif (CONFIG_DISPLAY_TWS_BAT_TYPE == CONFIG_DISPLAY_TWS_BAT_LEFT)
return tws_api_get_local_channel() == 'L' ? cur_battery_level : bat_lev;
#elif (CONFIG_DISPLAY_TWS_BAT_TYPE == CONFIG_DISPLAY_TWS_BAT_RIGHT)
return tws_api_get_local_channel() == 'R' ? cur_battery_level : bat_lev;
#else
return cur_battery_level;
#endif
}
#else
u8 get_cur_battery_level(void)
{
return cur_battery_level;
}
#endif
struct battery_info {
u32 time_stamp;
u16 percent;
};
int read_bat_info_vm(struct battery_info *info)
{
int ret = syscfg_read(VM_BATTERY_INFO, info, sizeof(struct battery_info));
if (ret != sizeof(struct battery_info)) {
return -1;
}
return 0;
}
int bat_info_need_recheck(u16 vpercent)
{
struct battery_info info;
int ret = read_bat_info_vm(&info);
if (ret) {
printf("%s vm not find", __func__);
return true;
}
last_present_k = vpercent;
struct sys_time time;
rtc_read_time(&time);
u32 timestamp = timestamp_mytime_2_utc_sec(&time);
if (timestamp - info.time_stamp > RECHECK_HOUR * 60 * 60) { //超过半小时
printf("%s time need reset", __func__);
return true;
}
if (abs(vpercent - info.percent) > RECHECK_SOC) { //误差超过10%
printf("%s vbat percent more than 10per", __func__);
return true;
}
cur_battery_percent = info.percent;
printf("%s used vm info:%d\n ", __func__, info.percent);
return false;
}
void update_bat_info_vm()
{
struct sys_time time;
rtc_read_time(&time);
u32 timestamp = timestamp_mytime_2_utc_sec(&time);
struct battery_info info = {
.time_stamp = timestamp,
.percent = cur_battery_percent,
};
syscfg_write(VM_BATTERY_INFO, &info, sizeof(struct battery_info));
}
void bat_info_storage_task_sync()
{
if (abs(cur_battery_percent - last_present_k) >= BATTERY_CHANGE_SAVE) {
last_present_k = cur_battery_percent;
int argv[3];
argv[0] = (int)update_bat_info_vm;
argv[1] = 0;
int ret = os_taskq_post_type("app_core", Q_CALLBACK, 2, argv);
if (ret) {
log_error("vbat change post ret:%d \n", ret);
}
}
}
void vbat_sys_sleep_check()
{
int is_low_power = !low_power_sys_not_idle_cnt();
if (is_low_power) {
++is_sleep_cnt;
} else {
is_sleep_cnt = 0;
}
}
float vbat_predicted_current(u16 voltage, u16 soc)
{
u16 ocv = battery_calc_voltage(soc);
printf("%s ocv:%d soc:%d vol:%d ", __func__, ocv, soc, voltage);
return (float)(voltage - ocv) / BATTERY_RESISTOR;//I mA
}
void vbat_calculate_loop()
{
// 模拟每 8 秒更新一次电池电压 curr_present_k
int curr_present_k;
//获取vbat电压
u16 current_vbat = get_vbat_voltage() ;//mv
u16 ocv2soc = battery_calc_percent(current_vbat);
float I = 0.0f;
//长时间休眠且非充电状态直接校准
if ((is_sleep_cnt > 20000) && !LVCMP_DET_GET()) {
is_sleep_cnt = 0;
if (current_vbat >= battery_calc_voltage(100)) {
current_soc = 100;
} else if (current_vbat <= battery_calc_voltage(0)) {
current_soc = 0;
} else {
current_soc = ocv2soc;
}
} else {// 根据电池状态进行放电或充电运算
if (!LVCMP_DET_GET()) { // 放电
//模拟充电电量ma
I = vbat_predicted_current(current_vbat, current_soc);
//转mAh积分->百分比
current_soc += (float)I * VBAT_UPDATE_SEC * 100 / 3600 / BATTERY_CAPACITY;
} else { // 充电状态
//模拟充电电量,使用电流镜时,建议按比例获取电流
float I1 = vbat_predicted_current(current_vbat, current_soc) * BATTERY_CHARGE_K;
float I2 = adc_get_voltage(AD_CH_PMU_PROGI) * REAL_CHANEG_VAL / 100;
I = (REAL_CHANGE_PER * I2 + PRED_CHANGE_PER * I1) / 100;
printf("change:I1 :%f I2:%f I:%f ", I1, I2, I);
//转mAh积分->百分比
current_soc += (float)I * VBAT_UPDATE_SEC * 100 / 3600 / BATTERY_CAPACITY;
if (!get_charge_full_flag()) { //未充满
current_soc = (current_soc > 99.99f) ? 99.99f : current_soc;
} else {
current_soc += 1;//快速逼近100%
}
}
}
//soc边界处理
if (current_soc < 0) {
current_soc = 0;
} else if (current_soc > 100) {
current_soc = 100;
}
//soc2percent
curr_present_k = current_soc;
// 防止电压回弹
if (get_charge_online_flag()) {
//充电过程中电量下降使用之前电量
if (curr_present_k < last_present_k) {
curr_present_k = last_present_k;
}
} else {
//未充电过程中电量上升使用之前电量
if (curr_present_k >= last_present_k) {
curr_present_k = last_present_k;
}
}
cur_battery_percent = curr_present_k;
printf("%s V:%d(mV) I:%f(mA) SOC:%d(per%f) OCV2SOC:%d(per) last:%d(per) charge_flag:%d is_sleep_cnt:%d",
__func__, current_vbat, I, cur_battery_percent, current_soc, ocv2soc, last_present_k, get_charge_online_flag(), is_sleep_cnt);
bat_info_storage_task_sync();
}
void vbat_check_slow(void *priv)
{
if (vbat_fast_timer == 0) {
vbat_fast_timer = sys_s_hi_timer_add(NULL, vbat_check, VBAT_DETECT_TIME);
}
if (get_charge_online_flag()) {
sys_s_hi_timer_modify(vbat_slow_timer, VBAT_UPDATE_SLOW_TIME);
} else {
sys_s_hi_timer_modify(vbat_slow_timer, VBAT_UPDATE_FAST_TIME);
}
}
void vbat_check_init(void)
{
u8 tmp[128] = {0};
int i;
u16 battery_0, battery_100;
union battery_data battery_data_t;
//初始化电池曲线
if (battery_curve_p == NULL) {
memset(tmp, 0x00, sizeof(tmp));
int ret = syscfg_read(CFG_BATTERY_CURVE_ID, tmp, sizeof(tmp));
if (ret > 0) {
battery_curve_max = ret / sizeof(battery_data_t);
} else {
battery_curve_max = 2;
}
battery_curve_p = malloc(battery_curve_max * sizeof(struct battery_curve));
ASSERT(battery_curve_p, "malloc battery_curve err!");
if (ret < 0) {
log_error("battery curve id, ret: %d\n", ret);
battery_0 = app_var.poweroff_tone_v;
#if TCFG_CHARGE_ENABLE
//防止部分电池充不了这么高电量,充满显示未满的情况
battery_100 = (get_charge_full_value() - 100);
#else
battery_100 = 4100;
#endif
battery_curve_p[0].percent = 0;
battery_curve_p[0].voltage = battery_0;
battery_curve_p[1].percent = 100;
battery_curve_p[1].voltage = battery_100;
log_info("percent: %d, voltage: %d mV", 0, battery_curve_p[0].voltage);
log_info("percent: %d, voltage: %d mV", 100, battery_curve_p[1].voltage);
} else {
for (i = 0; i < battery_curve_max; i++) {
memcpy(&battery_data_t.raw_data,
&tmp[i * sizeof(battery_data_t)], sizeof(battery_data_t));
battery_curve_p[i].percent = battery_data_t.data.percent;
battery_curve_p[i].voltage = battery_data_t.data.voltage;
printf("percent: %d, voltage: %d mV\n",
battery_curve_p[i].percent, battery_curve_p[i].voltage);
}
}
//初始化相关变量
cur_battery_voltage = get_vbat_voltage();
u16 tmp_percent = battery_calc_percent(cur_battery_voltage);
int check_ret = bat_info_need_recheck(tmp_percent);
if (check_ret == true) {
cur_battery_percent = tmp_percent;
current_soc = cur_battery_percent;
printf("%s %d", __func__, cur_battery_percent);
cur_battery_level = battery_value_to_phone_level();
}
}
#if (VBAT_PERCENT_MODE_SEL == VBAT_PERCENT_MODE_CURRENT_INTEGRATING_METHOD)
sys_s_hi_timer_add(NULL, vbat_calculate_loop, VBAT_UPDATE_SEC * 1000);
#endif
if (vbat_slow_timer == 0) {
vbat_slow_timer = sys_s_hi_timer_add(NULL, vbat_check_slow, VBAT_UPDATE_FAST_TIME);
} else {
sys_s_hi_timer_modify(vbat_slow_timer, VBAT_UPDATE_FAST_TIME);
}
if (vbat_fast_timer == 0) {
vbat_fast_timer = sys_s_hi_timer_add(NULL, vbat_check, VBAT_DETECT_TIME);
}
}
void vbat_timer_delete(void)
{
if (vbat_slow_timer) {
sys_s_hi_timer_del(vbat_slow_timer);
vbat_slow_timer = 0;
}
if (vbat_fast_timer) {
sys_s_hi_timer_del(vbat_fast_timer);
vbat_fast_timer = 0;
}
}
void vbat_check(void *priv)
{
static u8 unit_cnt = 0;
static u8 low_voice_cnt = 0;
static u8 low_power_cnt = 0;
static u8 power_normal_cnt = 0;
static u8 charge_online_flag = 0;
static u8 low_voice_first_flag = 1;//进入低电后先提醒一次
static u32 bat_voltage = 0;
u16 tmp_percent;
bat_voltage += get_vbat_voltage();
unit_cnt++;
if (unit_cnt < VBAT_DETECT_CNT) {
return;
}
unit_cnt = 0;
//更新电池电压,以及电池百分比,还有电池等级
cur_battery_voltage = bat_voltage / VBAT_DETECT_CNT;
bat_voltage = 0;
tmp_percent = battery_calc_percent(cur_battery_voltage);
#if (VBAT_PERCENT_MODE_SEL == VBAT_PERCENT_MODE_OPEN_CIRCUIT_VOLTAGE)
if (get_charge_online_flag()) {
if (tmp_percent > cur_battery_percent) {
cur_battery_percent++;
}
} else {
if (tmp_percent < cur_battery_percent) {
cur_battery_percent--;
}
}
bat_info_storage_task_sync();
#endif
cur_battery_level = battery_value_to_phone_level();
printf("cur_voltage: %d mV, tmp_percent: %d, cur_percent: %d, cur_level: %d\n",
cur_battery_voltage, tmp_percent, cur_battery_percent, cur_battery_level);
if (get_charge_online_flag() == 0) {
if (adc_check_vbat_lowpower() ||
(cur_battery_voltage <= app_var.poweroff_tone_v)) { //低电关机
low_power_cnt++;
low_voice_cnt = 0;
power_normal_cnt = 0;
cur_bat_st = VBAT_LOWPOWER;
if (low_power_cnt > 6) {
log_info("\n*******Low Power,enter softpoweroff********\n");
low_power_cnt = 0;
batmgr_send_msg(POWER_EVENT_POWER_LOW, 0);
sys_s_hi_timer_del(vbat_fast_timer);
vbat_fast_timer = 0;
}
} else if (cur_battery_voltage <= app_var.warning_tone_v) { //低电提醒
low_voice_cnt ++;
low_power_cnt = 0;
power_normal_cnt = 0;
cur_bat_st = VBAT_WARNING;
if ((low_voice_first_flag && low_voice_cnt > 1) || //第一次进低电10s后报一次
(!low_voice_first_flag && low_voice_cnt >= 5)) {
low_voice_first_flag = 0;
low_voice_cnt = 0;
#if(TCFG_SYS_LVD_EN == 1)
if (!lowpower_timer) {
log_info("\n**Low Power,Please Charge Soon!!!**\n");
batmgr_send_msg(POWER_EVENT_POWER_WARNING, 0);
}
#endif
}
} else {
power_normal_cnt++;
low_voice_cnt = 0;
low_power_cnt = 0;
if (power_normal_cnt > 2) {
if (cur_bat_st != VBAT_NORMAL) {
log_info("[Noraml power]\n");
cur_bat_st = VBAT_NORMAL;
batmgr_send_msg(POWER_EVENT_POWER_NORMAL, 0);
}
}
}
} else {
batmgr_send_msg(POWER_EVENT_POWER_CHARGE, 0);
}
if (cur_bat_st != VBAT_LOWPOWER) {
sys_s_hi_timer_del(vbat_fast_timer);
vbat_fast_timer = 0;
//电量等级变化,或者在仓状态变化,交换电量
if ((cur_battery_level != old_battery_level) ||
(charge_online_flag != get_charge_online_flag()) ||
(cur_battery_percent != old_battery_percent)) {
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
}
charge_online_flag = get_charge_online_flag();
old_battery_level = cur_battery_level;
old_battery_percent = cur_battery_percent;
}
UI_MSG_POST("batcharge:process=%4", cur_battery_percent);
}
bool vbat_is_low_power(void)
{
return (cur_bat_st != VBAT_NORMAL);
}
void check_power_on_voltage(void)
{
#if(TCFG_SYS_LVD_EN == 1)
u16 val = 0;
u8 normal_power_cnt = 0;
u8 low_power_cnt = 0;
while (1) {
clr_wdt();
val = get_vbat_voltage();
printf("vbat: %d\n", val);
if ((val < app_var.poweroff_tone_v) || adc_check_vbat_lowpower()) {
low_power_cnt++;
normal_power_cnt = 0;
if (low_power_cnt > 10) {
/* ui_update_status(STATUS_POWERON_LOWPOWER); */
os_time_dly(100);
log_info("power on low power , enter softpoweroff!\n");
power_set_soft_poweroff();
}
} else {
normal_power_cnt++;
low_power_cnt = 0;
if (normal_power_cnt > 10) {
vbat_check_init();
return;
}
}
}
#endif
}
u8 check_vbat_low_power(void)
{
int ret = 0;
#if(TCFG_SYS_LVD_EN == 1)
u16 val = 0;
u8 normal_power_cnt = 0;
u8 low_power_cnt = 0;
while (1) {
clr_wdt();
val = get_vbat_voltage();
printf("vbat: %d\n", val);
if ((val < app_var.poweroff_tone_v) || adc_check_vbat_lowpower()) {
low_power_cnt++;
normal_power_cnt = 0;
if (low_power_cnt > 10) {
/* ui_update_status(STATUS_POWERON_LOWPOWER); */
os_time_dly(100);
ret = 1;
/* printf("%s low_power",__func__); */
return ret;
}
} else {
normal_power_cnt++;
low_power_cnt = 0;
if (normal_power_cnt > 10) {
/* printf("%s power_on",__func__); */
ret = 0;
return ret;
}
}
}
#endif
return ret;
}
+116
View File
@@ -0,0 +1,116 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".battery_offset.data.bss")
#pragma data_seg(".battery_offset.data")
#pragma const_seg(".battery_offset.text.const")
#pragma code_seg(".battery_offset.text")
#endif
#include "system/includes.h"
#include "app_config.h"
#include "battery_manager.h"
#include "gpadc.h"
#define LOG_TAG "[BATTERY]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_BATTER_OFFSET_EN
#define VBAT_OFFSET_NUM 5
static const u16 vbat_offset_clk_Mhz[VBAT_OFFSET_NUM] = {
48, 96, 144, 230, 288,
};
static const u8 vbat_offset_value_max[VBAT_OFFSET_NUM] = {
0, 3, 5, 13, 16
};
static u8 vbat_offset_value[VBAT_OFFSET_NUM];
static u8 vbat_offset_idx;
static u16 vbat_adc_1V; //每1V对应的adc数值
static u8 vbat_usr_mA[VBAT_OFFSET_USR_MAX]; //用户层耗电补偿
static void vbat_offset_refresh(void)
{
int offset = vbat_offset_value[vbat_offset_idx];
int total_mA = 0;
for (int i = 0; i < ARRAY_SIZE(vbat_usr_mA); i++) {
total_mA += vbat_usr_mA[i];
}
offset += (total_mA * vbat_adc_1V * 1 / 10 / 1000); // 0.1欧内阻
log_info("offset:%d \n", offset);
gpadc_battery_set_offset(offset);
}
static void clock_critical_enter(void)
{
}
static void clock_critical_exit(void)
{
int hsb_clk = clk_get("sys") / MHz;
int i = VBAT_OFFSET_NUM - 1;
for (; i > 0; i--) {
if (hsb_clk >= vbat_offset_clk_Mhz[i]) {
break;
}
}
vbat_offset_idx = i;
/* log_info("vbat_offset_idx:%d \n", vbat_offset_idx); */
vbat_offset_refresh();
}
HSB_CRITICAL_HANDLE_REG(vbat_adc, clock_critical_enter, clock_critical_exit)
void gpadc_battery_offset_trim(u16 ref_vol, u16 adc_value)
{
vbat_adc_1V = ((u32)adc_value) * 1000 / ref_vol;
log_info("vbat_adc_1V:%d \n", vbat_adc_1V);
u32 sys_clk = clk_get("sys");
u32 vbat_adc[VBAT_OFFSET_NUM];
u32 vbat_offset_tmp[VBAT_OFFSET_NUM];
for (int i = 0; i < VBAT_OFFSET_NUM; i++) {
clk_set_api("sys", vbat_offset_clk_Mhz[i] * MHz);
vbat_adc[i] = adc_get_value_blocking_filter(AD_CH_PMU_VBAT, 30);
vbat_offset_tmp[i] = vbat_adc[0] - vbat_adc[i];
// 补一部分
if (vbat_offset_tmp[i] * 3 / 4 > vbat_offset_value_max[i]) {
vbat_offset_value[i] = vbat_offset_value_max[i];
} else {
vbat_offset_value[i] = vbat_offset_tmp[i] * 3 / 4;
}
}
clk_set_api("sys", sys_clk);
for (int i = 0; i < VBAT_OFFSET_NUM; i++) {
log_info("sys:%4dMhz, vbat adc:%4d, offset tmp:%4d, offset value:%4d \n",
vbat_offset_clk_Mhz[i], vbat_adc[i], vbat_offset_tmp[i], vbat_offset_value[i]);
}
vbat_offset_refresh();
/* os_time_dly(150); */
}
void battery_offset_usr_set(enum battery_offset_usr idx, u8 mA)
{
if (idx < VBAT_OFFSET_USR_MAX) {
vbat_usr_mA[idx] = mA;
vbat_offset_refresh();
}
}
#else /* #if TCFG_BATTER_OFFSET_EN */
void battery_offset_usr_set(enum battery_offset_usr idx, u8 mA)
{
}
#endif /* #if TCFG_BATTER_OFFSET_EN */
+462
View File
@@ -0,0 +1,462 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".charge.data.bss")
#pragma data_seg(".charge.data")
#pragma const_seg(".charge.text.const")
#pragma code_seg(".charge.text")
#endif
#include "app_config.h"
#include "asm/charge.h"
#include "asm/power_interface.h"
#include "system/event.h"
#include "system/includes.h"
#include "app_action.h"
#include "asm/wdt.h"
#include "app_power_manage.h"
#include "app_chargestore.h"
#include "btstack/avctp_user.h"
#include "app_main.h"
#include "bt_tws.h"
#include "usb/otg.h"
#include "bt_common.h"
#include "battery_manager.h"
#include "app_charge.h"
#include "dual_bank_updata_api.h"
#include "gpadc.h"
#include "ui/ui_api.h"
#include "jlui_app/ui_sys_param.h"
#define LOG_TAG_CONST APP_CHARGE
#define LOG_TAG "[APP_CHARGE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if TCFG_CHARGE_ENABLE
static u8 charge_full_flag = 0;
#if TCFG_RECHARGE_ENABLE
static int recharge_timer = 0;
static void recharge_check(void *priv)
{
if ((adc_get_voltage(AD_CH_PMU_VBAT) * AD_CH_PMU_VBAT_DIV) < TCFG_RECHARGE_VOLTAGE) {
sys_timer_del(recharge_timer);
recharge_timer = 0;
charge_start();
}
}
static void recharge_detect_start(void)
{
if (recharge_timer == 0) {
recharge_timer = sys_timer_add(NULL, recharge_check, 10000);
}
}
static void recharge_detect_close(void)
{
if (recharge_timer) {
sys_timer_del(recharge_timer);
recharge_timer = 0;
}
}
#endif
u8 get_charge_full_flag(void)
{
return charge_full_flag;
}
static void charge_start_deal(void)
{
log_info("%s\n", __FUNCTION__);
power_set_mode(PWR_LDO15);
batmgr_send_msg(BAT_MSG_CHARGE_START, 0);
}
static void charge_full_deal(void)
{
const struct app_charge_handler *handler;
log_info("%s\n", __func__);
charge_full_flag = 1;
charge_close();
#if TCFG_RECHARGE_ENABLE
recharge_detect_start();
#endif
for_each_app_charge_handler(handler) {
handler->handler(CHARGE_EVENT_CHARGE_FULL, 0);
}
if (get_charge_poweron_en() == 0) {
/* power_set_soft_poweroff(); */
#if (!TCFG_CHARGESTORE_ENABLE)
vbat_timer_delete();
#endif
} else {
batmgr_send_msg(BAT_MSG_CHARGE_FULL, 0);
}
}
static void charge_close_deal(void)
{
log_info("%s\n", __FUNCTION__);
/* power_set_mode(TCFG_LOWPOWER_POWER_SEL); */
batmgr_send_msg(BAT_MSG_CHARGE_CLOSE, 0);
}
void app_charge_power_off_keep_mode()
{
//兼容一些充电仓5v输出慢的时候会导致无法充电的问题
if (get_lvcmp_det()) {
log_info("...charge ing...\n");
cpu_reset();
}
log_info("get_charge_online_flag:%d %d\n", get_charge_online_flag(), get_ldo5v_online_hw());
if (get_ldo5v_online_hw() && get_charge_online_flag()) {
power_set_soft_poweroff();
} else {
charge_check_and_set_pinr(1);
#if TCFG_CHARGE_OFF_POWERON_EN
cpu_reset();
#else
power_set_soft_poweroff();
#endif
}
}
static void ldo5v_keep_softoff(void)
{
log_info("%s\n", __func__);
if (!app_in_mode(APP_MODE_IDLE)) {
sys_enter_soft_poweroff(POWEROFF_POWER_KEEP);
} else {
app_charge_power_off_keep_mode();
}
}
/*ldoin电压大于拔出电压(0.6V左右)且小于VBat电压时调用该函数进行一些错误提示或其他处理*/
void ldo5v_keep_deal(void)
{
int abandon = 0;
const struct app_charge_handler *handler;
log_info("%s\n", __func__);
#if TCFG_RECHARGE_ENABLE
recharge_detect_close();
#endif
//插入交换
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
charge_check_and_set_pinr(0);
for_each_app_charge_handler(handler) {
abandon += handler->handler(CHARGE_EVENT_LDO5V_KEEP, 0);
}
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
//升级过程中,不执行关机操作
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
return;
}
#endif
if (get_charge_poweron_en() == 0) {
if (abandon == 0) {
ldo5v_keep_softoff();
}
} else {
batmgr_send_msg(BAT_MSG_CHARGE_ERR, 0);
}
}
void charge_ldo5v_in_deal(void)
{
int abandon = 0;
const struct app_charge_handler *handler;
log_info("%s\n", __FUNCTION__);
#if TCFG_RECHARGE_ENABLE
recharge_detect_close();
#endif
//插入交换
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
charge_full_flag = 0;
charge_check_and_set_pinr(0);
for_each_app_charge_handler(handler) {
abandon += handler->handler(CHARGE_EVENT_LDO5V_IN, 0);
}
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
//升级过程中,不执行充电插入关机流程
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
return;
}
#endif
if (get_charge_poweron_en() == 0) {
if (!app_in_mode(APP_MODE_IDLE)) {
if (abandon == 0) {
sys_enter_soft_poweroff(POWEROFF_RESET);
}
} else {
charge_start();
wdt_init(WDT_32S);
log_info("set wdt to 32s!\n");
goto _check_reset;
}
} else {
charge_start();
goto _check_reset;
}
return;
_check_reset:
//防止耳机低电时,插拔充电有几率出现关机不充电问题
if (app_var.goto_poweroff_flag) {
cpu_reset();
}
}
void charge_ldo5v_off_deal(void)
{
int abandon = 0;
int off_type = LDO5V_OFF_TYPE_NORMAL_ON;
bool lowpower_flag = FALSE, is_bt_mode, is_idle_mode;
const struct app_charge_handler *handler;
log_info("%s\n", __FUNCTION__);
//拨出交换
batmgr_send_msg(POWER_EVENT_POWER_CHANGE, 0);
charge_full_flag = 0;
charge_close();
power_set_mode(TCFG_LOWPOWER_POWER_SEL);
#if TCFG_RECHARGE_ENABLE
recharge_detect_close();
#endif
batmgr_send_msg(BAT_MSG_CHARGE_LDO5V_OFF, 0);
charge_check_and_set_pinr(1);
#if TCFG_SYS_LVD_EN
lowpower_flag = get_vbat_need_shutdown();
#endif
is_bt_mode = app_in_mode(APP_MODE_BT);
is_idle_mode = app_in_mode(APP_MODE_IDLE);
if ((get_charge_poweron_en() == 0)) {
wdt_init(WDT_4S);
log_info("set wdt to 4s!\n");
#if TCFG_CHARGE_OFF_POWERON_EN
log_info("ldo5v off,task switch to BT\n");
if (app_var.goto_poweroff_flag == 0) {
if (!is_bt_mode) {
if (lowpower_flag == FALSE) {
off_type = LDO5V_OFF_TYPE_NORMAL_ON;//正常拔出开机
} else {
log_info("ldo5v off,lowpower,need enter softpoweroff\n");
off_type = LDO5V_OFF_TYPE_LOWPOWER_OFF;//拔出低电关机
}
}
}
#else //TCFG_CHARGE_OFF_POWERON_EN
log_info("ldo5v off,enter softpoweroff\n");
off_type = LDO5V_OFF_TYPE_NORMAL_OFF;//正常拔出关机
#endif
} else {
if (is_idle_mode && (app_var.goto_poweroff_flag == 0)) {
#if TCFG_CHARGE_OFF_POWERON_EN
log_info("ldo5v off,task switch to BT\n");
if (lowpower_flag == FALSE) {
off_type = LDO5V_OFF_TYPE_NORMAL_ON;//正常拔出开机
} else {
log_info("ldo5v off,lowpower,need enter softpoweroff\n");
off_type = LDO5V_OFF_TYPE_LOWPOWER_OFF;//拔出低电关机
}
#else
off_type = LDO5V_OFF_TYPE_NORMAL_OFF;//正常拔出关机
#endif
}
}
for_each_app_charge_handler(handler) {
abandon += handler->handler(CHARGE_EVENT_LDO5V_OFF, off_type);
}
if (abandon) {
return;
}
switch (off_type) {
case LDO5V_OFF_TYPE_NORMAL_OFF:
case LDO5V_OFF_TYPE_LOWPOWER_OFF:
power_set_soft_poweroff();
break;
case LDO5V_OFF_TYPE_CHARGESTORE_OFF:
if (is_bt_mode) {
sys_enter_soft_poweroff(POWEROFF_NORMAL);
} else {
power_set_soft_poweroff();
}
break;
case LDO5V_OFF_TYPE_NORMAL_ON:
#if 1//idle充电,需要拔出开机先power_on
if (app_in_mode(APP_MODE_IDLE)) {
app_var.play_poweron_tone = 1;
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_POWERON);
}
#else
app_var.play_poweron_tone = 0;
app_send_message(APP_MSG_GOTO_MODE, APP_MODE_BT);
#endif//直接开机
break;
}
}
static int app_charge_event_handler(int *msg)
{
int ret = false;
u8 otg_status = 0;
switch (msg[0]) {
case CHARGE_EVENT_CHARGE_START:
#if TCFG_UI_ENABLE
if (get_ui_sys_param(bed_light)) {//床头时钟
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH); */
/* UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_BEDSIDE_WATCH, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_CHARGE); */
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_BEDSIDE_WATCH);
} else {
#if 0
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE);
UI_WINDOW_PREEMPTION_POSH(ID_WINDOW_BATCHARGE, NULL, NULL, UI_WINDOW_PREEMPTION_TYPE_CHARGE);
#else
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
#endif
}
#endif
charge_start_deal();
break;
case CHARGE_EVENT_CHARGE_CLOSE:
charge_close_deal();
#if TCFG_UI_ENABLE
if (get_ui_sys_param(bed_light)) {
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH); */
} else {
/*充满后退出充电页面*/
#if 0
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE);
//退出页面后,如果没有记录页面,则回表盘
if (!ui_return_page_id()) {
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
}
#else
//拔出的时候再显示一次电量页面
UI_HIDE_CURR_WINDOW();
UI_SHOW_WINDOW(ID_WINDOW_BATCHARGE);
#endif
}
#endif
break;
case CHARGE_EVENT_CHARGE_FULL:
charge_full_deal();
break;
case CHARGE_EVENT_LDO5V_KEEP:
ldo5v_keep_deal();
break;
case CHARGE_EVENT_LDO5V_IN:
#if ((TCFG_OTG_MODE & OTG_SLAVE_MODE) && (TCFG_OTG_MODE & OTG_CHARGE_MODE))
while (1) {
otg_status = usb_otg_online(0);
if (otg_status != IDLE_MODE) {
break;
}
os_time_dly(2);
}
if (otg_status == SLAVE_MODE) {
set_charge_poweron_en(1);
}
#endif
if (get_charge_poweron_en() || (otg_status != SLAVE_MODE)) {
charge_ldo5v_in_deal();
}
break;
case CHARGE_EVENT_LDO5V_OFF:
#if TCFG_UI_ENABLE
if (get_ui_sys_param(bed_light)) {
/*拔出时退出床头时钟*/
#if 0
UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BEDSIDE_WATCH);
#else
if (ui_get_current_window_id() == ID_WINDOW_BEDSIDE_WATCH) {
int page_ret = UI_WINDOW_BACK_SHOW(0);
if (page_ret == 2) {
UI_SHOW_WINDOW(ID_WINDOW_DIAL);
}
}
#endif
} else {
/* UI_WINDOW_PREEMPTION_POP(ID_WINDOW_BATCHARGE); */
}
#endif
#if ((TCFG_OTG_MODE & OTG_SLAVE_MODE) && (TCFG_OTG_MODE & OTG_CHARGE_MODE))
while (1) {
otg_status = usb_otg_online(0);
if (otg_status != IDLE_MODE) {
break;
}
os_time_dly(2);
}
#endif
if (get_charge_poweron_en() || (otg_status != SLAVE_MODE)) {
charge_ldo5v_off_deal();
}
break;
default:
break;
}
return ret;
}
APP_MSG_HANDLER(bat_charge_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BATTERY,
.handler = app_charge_event_handler,
};
#else
u8 get_charge_full_flag(void)
{
return 0;
}
#endif
@@ -0,0 +1,104 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".charge_device_handle.data.bss")
#pragma data_seg(".charge_device_handle.data")
#pragma const_seg(".charge_device_handle.text.const")
#pragma code_seg(".charge_device_handle.text")
#endif
#include "app_config.h"
#include "asm/charge.h"
#include "asm/power_interface.h"
#include "system/event.h"
#include "system/includes.h"
#include "app_action.h"
#include "app_main.h"
#include "app_charge.h"
#include "bt_tws.h"
#include "bt_common.h"
#if TCFG_CHARGE_ENABLE
/*
* 充电插入拔出事件,外设处理接口
* IR_SENSOR G_SENSOR GX8002 ...
*
*/
#if TCFG_GSENSOR_ENABLE
extern void gSensor_wkupup_disable(void);
extern void gSensor_wkupup_enable(void);
#endif
#if TCFG_GX8002_NPU_ENABLE
extern void gx8002_module_suspend(u8 keep_vddio);
extern void gx8002_module_resumed();
#endif
static int app_device_msg_charge_full(void)
{
return 0;
}
static int app_device_msg_ldo5v_online(u8 is_5v)
{
#if TCFG_IRSENSOR_ENABLE
if (get_bt_tws_connect_status() && is_5v) {
tws_api_sync_call_by_uuid('T', SYNC_CMD_EARPHONE_CHAREG_START, 300);
}
#endif
#if TCFG_GSENSOR_ENABLE
//在舱关闭gSensor
gSensor_wkupup_disable();
#endif
#if TCFG_GX8002_NPU_ENABLE
gx8002_module_suspend(0);
#endif
return 0;
}
static int app_device_msg_ldo5v_offline(int type)
{
//只需要处理正常拔出开机,和正常拔出关机的case
switch (type) {
case LDO5V_OFF_TYPE_NORMAL_ON:
#if TCFG_GSENSOR_ENABLE
//出舱使能gSensor
gSensor_wkupup_enable();
#endif
#if TCFG_GX8002_NPU_ENABLE
gx8002_module_resumed();
#endif
break;
case LDO5V_OFF_TYPE_NORMAL_OFF:
break;
default:
break;
}
return 0;
}
static int app_device_charge_msg_handler(int msg, int type)
{
switch (msg) {
case CHARGE_EVENT_LDO5V_KEEP:
return app_device_msg_ldo5v_online(0);
case CHARGE_EVENT_LDO5V_IN:
return app_device_msg_ldo5v_online(1);
case CHARGE_EVENT_LDO5V_OFF:
return app_device_msg_ldo5v_offline(type);
case CHARGE_EVENT_CHARGE_FULL:
return app_device_msg_charge_full();
default:
break;
}
return 0;
}
APP_CHARGE_HANDLER(device_charge_msg_entry, 0) = {
.handler = app_device_charge_msg_handler,
};
#endif
+897
View File
@@ -0,0 +1,897 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".charge_store.data.bss")
#pragma data_seg(".charge_store.data")
#pragma const_seg(".charge_store.text.const")
#pragma code_seg(".charge_store.text")
#endif
#include "init.h"
#include "app_config.h"
#include "system/includes.h"
#include "asm/charge.h"
#include "asm/chargestore.h"
#include "user_cfg.h"
#include "app_chargestore.h"
#include "device/vm.h"
#include "btstack/avctp_user.h"
#include "app_power_manage.h"
#include "app_action.h"
#include "app_main.h"
#include "app_charge.h"
#include "classic/tws_api.h"
#include "update.h"
#include "bt_ble.h"
#include "bt_tws.h"
#include "bt_common.h"
#include "app_testbox.h"
#include "battery_manager.h"
#include "dual_bank_updata_api.h"
#define LOG_TAG_CONST APP_CHARGESTORE
#define LOG_TAG "[APP_CHARGESTORE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
//-----------------------------------------------------------------------------------
//-----------以下配对相关的接口,提供充电舱和蓝牙测试盒-------------------------------
//-----------------------------------------------------------------------------------
#if (TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE)
static void new_addr_generating_for_pair(u8 *addr)
{
u8 i;
for (i = 0; i < 6; i++) {
addr[i] = addr[i] + 1;
}
}
void chargestore_set_tws_channel_info(u8 channel)
{
if ((channel == 'L') || (channel == 'R')) {
syscfg_write(CFG_CHARGESTORE_TWS_CHANNEL, &channel, 1);
}
}
u8 chargestore_get_tws_channel_info(void)
{
u8 channel = 'U';
syscfg_read(CFG_CHARGESTORE_TWS_CHANNEL, &channel, 1);
return channel;
}
bool chargestore_set_tws_remote_info(u8 *data, u8 len)
{
bool ret = true;
int w_ret = 0;
u8 remote_addr[6];
u8 common_addr[6];
u8 local_addr[6];
CHARGE_STORE_INFO *charge_store_info = (CHARGE_STORE_INFO *)data;
if (len > sizeof(CHARGE_STORE_INFO)) {
log_error("len err\n");
return false;
}
//set remote addr
syscfg_read(CFG_TWS_REMOTE_ADDR, remote_addr, sizeof(remote_addr));
if (memcmp(remote_addr, charge_store_info->tws_local_addr, sizeof(remote_addr))) {
ret = false;
}
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_status()) {
//using new remote addr generating;
new_addr_generating_for_pair(charge_store_info->tws_local_addr);
}
#endif
if (sizeof(remote_addr) != syscfg_write(CFG_TWS_REMOTE_ADDR, charge_store_info->tws_local_addr, sizeof(remote_addr))) {
w_ret = -1;
}
bt_get_tws_local_addr(local_addr);
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_status()) {
new_addr_generating_for_pair(local_addr);
if (sizeof(local_addr) != syscfg_write(CFG_TWS_LOCAL_ADDR, local_addr, sizeof(local_addr))) {
w_ret = -2;
}
}
#endif
#if TCFG_USER_TWS_ENABLE
#if (CONFIG_TWS_COMMON_ADDR_SELECT != CONFIG_TWS_COMMON_ADDR_USED_LEFT)
//set common addr
syscfg_read(CFG_TWS_COMMON_ADDR, common_addr, sizeof(common_addr));
for (u8 i = 0; i < sizeof(common_addr); i++) {
if (common_addr[i] != (u8)(local_addr[i] + charge_store_info->tws_local_addr[i])) {
ret = false;
}
common_addr[i] = local_addr[i] + charge_store_info->tws_local_addr[i];
}
if (sizeof(common_addr) != syscfg_write(CFG_TWS_COMMON_ADDR, common_addr, sizeof(common_addr))) {
w_ret = -3;
}
#endif
#endif
if (0 == w_ret) {
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_status()) {
u8 cmd = CMD_BOX_TWS_REMOTE_ADDR;
chargestore_api_write(&cmd, 1);
testbox_set_testbox_tws_paired(1);
}
#endif
}
return ret;
}
void chargestore_clean_tws_conn_info(u8 type)
{
CHARGE_STORE_INFO charge_store_info;
log_info("chargestore_clean_tws_conn_info=%d\n", type);
if (type == TWS_DEL_TWS_ADDR) {
log_info("TWS_DEL_TWS_ADDR\n");
} else if (type == TWS_DEL_PHONE_ADDR) {
log_info("TWS_DEL_PHONE_ADDR\n");
} else if (type == TWS_DEL_ALL_ADDR) {
log_info("TWS_DEL_ALL_ADDR\n");
}
memset(&charge_store_info, 0xff, sizeof(CHARGE_STORE_INFO));
syscfg_write(CFG_TWS_REMOTE_ADDR, charge_store_info.tws_remote_addr, sizeof(charge_store_info.tws_remote_addr));
}
u16 chargestore_get_tws_remote_info(u8 *data)
{
u16 ret_len = 0;
#if TCFG_USER_TWS_ENABLE
CHARGE_STORE_INFO *charge_store_info = (CHARGE_STORE_INFO *)data;
bt_get_tws_local_addr(charge_store_info->tws_local_addr);
bt_get_vm_mac_addr(charge_store_info->tws_mac_addr);
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_keep_tws_conn_flag()) {
memcpy(charge_store_info->tws_mac_addr, bt_get_mac_addr(), 6);
}
#endif
#if (CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_AS_LEFT) \
||(CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_AS_RIGHT) \
||(CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_EXTERN_DOWN_AS_LEFT) \
||(CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_EXTERN_UP_AS_LEFT) \
||(CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_EXTERN_DOWN_AS_RIGHT) \
||(CONFIG_TWS_CHANNEL_SELECT == CONFIG_TWS_EXTERN_UP_AS_RIGHT)
charge_store_info->local_channel = tws_api_get_local_channel();
#else
charge_store_info->local_channel = 'U';
#endif
charge_store_info->device_ind = bt_get_tws_device_indicate(NULL);
charge_store_info->reserved_data = chargestore_api_crc8(data, sizeof(CHARGE_STORE_INFO) - 2);
#if TCFG_TEST_BOX_ENABLE
if (testbox_get_status()) {
charge_store_info->reserved_data = 0;
}
#endif
ret_len = sizeof(CHARGE_STORE_INFO);
#else
CHARGE_STORE_INFO *charge_store_info = (CHARGE_STORE_INFO *)data;
bt_get_vm_mac_addr(charge_store_info->tws_mac_addr);
ret_len = sizeof(CHARGE_STORE_INFO);
#endif
return ret_len;
}
#endif //TCFG_CHARGESTORE_ENABLE || TCFG_TEST_BOX_ENABLE
//-----------------------------------------------------------------------------------
//-----------分割线---------以下是充电舱流程实现-------------------------------------
//-----------------------------------------------------------------------------------
#if TCFG_CHARGESTORE_ENABLE
struct chargestore_info {
int timer;
int shutdown_timer;
u8 version;
u8 chip_type;
u8 max_packet_size;//充电舱端一包的最大值
u8 bt_init_ok;//蓝牙协议栈初始化成功
u8 power_level;//本机记录的充电舱电量百分比
u8 pre_power_lvl;
u8 sibling_chg_lev;//对耳同步的充电舱电量
u8 power_status;//充电舱供电状态 0:断电 5V不在线 1:升压 5V在线
u8 cover_status;//充电舱盖子状态 0:合盖 1:开盖
u8 connect_status;//通信成功
u8 ear_number;//盒盖时耳机在线数
u8 channel;//左右
u8 tws_power;//对耳的电量
u8 power_sync;//第一次获取到充电舱电量时,同步到对耳
u8 pair_flag;//配对标记
u8 close_ing;//等待合窗超时
u8 active_disconnect;//主动断开连接
u8 switch2bt;
};
static struct chargestore_info info = {
.power_status = 1,
.ear_number = 1,
.tws_power = 0xff,
.power_level = 0xff,
.sibling_chg_lev = 0xff,
.max_packet_size = 32,
.channel = 'U',
};
#define __this (&info)
static u8 local_packet[36];
static CHARGE_STORE_INFO read_info, write_info;
static u8 read_index, write_index;
u8 chargestore_get_power_level(void)
{
if ((__this->power_level == 0xff) ||
((!get_charge_online_flag()) &&
(__this->sibling_chg_lev != 0xff))) {
return __this->sibling_chg_lev;
}
return __this->power_level;
}
u8 chargestore_get_power_status(void)
{
return __this->power_status;
}
u8 chargestore_get_cover_status(void)
{
return __this->cover_status;
}
u8 chargestore_get_earphone_online(void)
{
return __this->ear_number;
}
void chargestore_set_earphone_online(u8 ear_number)
{
__this->ear_number = ear_number;
}
void chargestore_set_pair_flag(u8 pair_flag)
{
__this->pair_flag = pair_flag;
}
void chargestore_set_active_disconnect(u8 active_disconnect)
{
__this->active_disconnect = active_disconnect;
}
u8 chargestore_get_earphone_pos(void)
{
u8 channel = chargestore_get_tws_channel_info();
log_info("get_ear_channel = %c\n", channel);
return channel;
}
u8 chargestore_get_sibling_power_level(void)
{
return __this->tws_power;
}
static void set_tws_sibling_charge_level(void *_data, u16 len, bool rx)
{
if (rx) {
u8 *data = (u8 *)_data;
chargestore_set_sibling_chg_lev(data[0]);
}
}
REGISTER_TWS_FUNC_STUB(charge_level_stub) = {
.func_id = TWS_FUNC_ID_CHARGE_SYNC,
.func = set_tws_sibling_charge_level,
};
int chargestore_sync_chg_level(void)
{
#if TCFG_USER_TWS_ENABLE
int err = -1;
if (app_in_mode(APP_MODE_BT) && !app_var.goto_poweroff_flag) {
err = tws_api_send_data_to_sibling((u8 *)&__this->power_level, 1,
TWS_FUNC_ID_CHARGE_SYNC);
}
return err;
#else
return 0;
#endif
}
void chargestore_set_sibling_chg_lev(u8 chg_lev)
{
__this->sibling_chg_lev = chg_lev;
}
void chargestore_set_power_level(u8 power)
{
__this->power_level = power;
}
u8 chargestore_check_going_to_poweroff(void)
{
return __this->close_ing;
}
void chargestore_shutdown_reset(void)
{
if (__this->shutdown_timer) {
sys_timer_del(__this->shutdown_timer);
__this->shutdown_timer = 0;
}
}
void chargestore_set_bt_init_ok(u8 flag)
{
__this->bt_init_ok = flag;
}
void chargestore_shutdown_do(void *priv)
{
log_info("chargestore shutdown!\n");
power_set_soft_poweroff();
}
void chargestore_event_to_user(u8 *packet, u8 event, u8 size)
{
struct chargestore_event evt;
if (packet != NULL) {
if (size > sizeof(local_packet)) {
return;
}
memcpy(local_packet, packet, size);
}
evt.event = event;
evt.packet = local_packet;
evt.size = size;
os_taskq_post_type("app_core", MSG_FROM_CHARGE_STORE,
(sizeof(evt) + 3) / 4, (int *)&evt);
}
bool chargestore_check_data_succ(u8 *data, u8 len)
{
u16 crc;
u16 device_ind;
CHARGE_STORE_INFO *charge_store_info = (CHARGE_STORE_INFO *)data;
if (len > sizeof(CHARGE_STORE_INFO)) {
log_error("len err\n");
return false;
}
crc = chargestore_api_crc8(data, len - 2);
if (crc != charge_store_info->reserved_data) {
log_error("crc err\n");
return false;
}
device_ind = bt_get_tws_device_indicate(NULL);
if (device_ind != charge_store_info->device_ind) {
log_error("device_ind err\n");
return false;
}
return true;
}
u16 chargestore_f95_read_tws_remote_info(u8 *data, u8 flag)
{
u8 read_len;
u8 *pbuf = (u8 *)&read_info;
if (flag) {//first packet
read_index = 0;
chargestore_get_tws_remote_info((u8 *)&read_info);
}
read_len = sizeof(read_info) - read_index;
read_len = (read_len > (__this->max_packet_size - 1)) ? (__this->max_packet_size - 1) : read_len;
memcpy(data, pbuf + read_index, read_len);
read_index += read_len;
return read_len;
}
u16 chargestore_f95_write_tws_remote_info(u8 *data, u8 len, u8 flag)
{
u8 write_len;
u8 *pbuf = (u8 *)&write_info;
if (flag) {
write_index = 0;
memset(&write_info, 0, sizeof(write_info));
}
write_len = sizeof(write_info) - write_index;
write_len = (write_len >= len) ? len : write_len;
memcpy(pbuf + write_index, data, write_len);
write_index += write_len;
return write_len;
}
void chargestore_timeout_deal(void *priv)
{
__this->timer = 0;
__this->close_ing = 0;
if (!__this->cover_status || __this->active_disconnect) {
//当前为合盖或者主动断开连接
if (!app_in_mode(APP_MODE_IDLE)) {
sys_enter_soft_poweroff(POWEROFF_RESET);
}
} else {
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
/* if ((!bt_get_total_connect_dev()) && (tws_api_get_role() == TWS_ROLE_MASTER) && (get_bt_tws_connect_status())) { */
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("charge_icon_ctl...\n");
bt_ble_icon_reset();
#if CONFIG_NO_DISPLAY_BUTTON_ICON
if (bt_get_total_connect_dev()) {
//蓝牙未真正断开;重新广播
bt_ble_icon_open(ICON_TYPE_RECONNECT);
} else {
//蓝牙未连接,重新开可见性
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
#else
//不管蓝牙是否连接,默认打开
bt_ble_icon_open(ICON_TYPE_RECONNECT);
#endif
}
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("charge_icon_ctl...\n");
#if CONFIG_NO_DISPLAY_BUTTON_ICON
if (bt_get_total_connect_dev()) {
//蓝牙未真正断开;重新广播
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_CONNECTED, 1);
} else {
//蓝牙未连接,重新开可见性
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_UNCONNECTED, 1);
}
#else
//不管蓝牙是否连接,默认打开
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_CONNECTED, 1);
#endif
}
#endif
}
__this->ear_number = 1;
}
void chargestore_set_phone_disconnect(void)
{
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
#if (!CONFIG_NO_DISPLAY_BUTTON_ICON)
if (__this->pair_flag && get_tws_sibling_connect_state()) {
//check ble inquiry
//printf("get box log_key...con_dev=%d\n",get_tws_phone_connect_state());
if ((bt_ble_icon_get_adv_state() == ADV_ST_RECONN)
|| (bt_ble_icon_get_adv_state() == ADV_ST_DISMISS)
|| (bt_ble_icon_get_adv_state() == ADV_ST_END)) {
bt_ble_icon_reset();
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
}
#endif
__this->pair_flag = 0;
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
#if (!CONFIG_NO_DISPLAY_BUTTON_ICON)
if (__this->pair_flag && get_tws_sibling_connect_state()) {
//check ble inquiry
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_UNCONNECTED, 1);
}
#endif
__this->pair_flag = 0;
#endif
}
void chargestore_set_phone_connect(void)
{
__this->active_disconnect = 0;
}
static int app_chargestore_event_handler(int *msg)
{
int ret = false;
struct chargestore_event *chargestore_dev = (struct chargestore_event *)msg;
#if defined(TCFG_CHARGE_KEEP_UPDATA) && TCFG_CHARGE_KEEP_UPDATA
//在升级过程中,不响应智能充电舱app层消息
if (dual_bank_update_exist_flag_get() || classic_update_task_exist_flag_get()) {
return ret;
}
#endif
switch (chargestore_dev->event) {
case CMD_RESTORE_SYS:
#if TCFG_USER_TWS_ENABLE
bt_tws_remove_pairs();
#endif
bt_cmd_prepare(USER_CTRL_DEL_ALL_REMOTE_INFO, 0, NULL);
cpu_reset();
break;
case CMD_TWS_CHANNEL_SET:
chargestore_set_tws_channel_info(__this->channel);
break;
#if TCFG_USER_TWS_ENABLE
case CMD_TWS_REMOTE_ADDR:
log_info("event_CMD_TWS_REMOTE_ADDR\n");
if (chargestore_set_tws_remote_info(chargestore_dev->packet, chargestore_dev->size) == false) {
//交换地址后,断开与手机连接,并删除所有连过的手机地址
bt_cmd_prepare(USER_CTRL_DEL_ALL_REMOTE_INFO, 0, NULL);
__this->ear_number = 2;
sys_enter_soft_poweroff(POWEROFF_RESET);
} else {
__this->pair_flag = 1;
if (bt_get_total_connect_dev()) {
__this->active_disconnect = 1;
bt_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
} else {
chargestore_set_phone_disconnect();
}
}
break;
case CMD_TWS_ADDR_DELETE:
log_info("event_CMD_TWS_ADDR_DELETE\n");
chargestore_clean_tws_conn_info(chargestore_dev->packet[0]);
break;
#endif
case CMD_POWER_LEVEL_OPEN:
log_info("event_CMD_POWER_LEVEL_OPEN\n");
//电压过低,不进响应开盖命令
#if TCFG_SYS_LVD_EN
if (get_vbat_need_shutdown() == TRUE) {
log_info(" lowpower deal!\n");
break;
}
#endif
if (__this->cover_status) {//当前为开盖
if (__this->power_sync) {
// cppcheck-suppress knownConditionTrueFalse
if (chargestore_sync_chg_level() == 0) {
__this->power_sync = 0;
}
}
if (!app_in_mode(APP_MODE_BT) && app_var.goto_poweroff_flag == 0) {
app_var.play_poweron_tone = 0;
power_set_mode(TCFG_LOWPOWER_POWER_SEL);
__this->switch2bt = 1;
app_goto_mode(APP_MODE_BT, 0);
__this->switch2bt = 0;
}
}
break;
case CMD_POWER_LEVEL_CLOSE:
log_info("event_CMD_POWER_LEVEL_CLOSE\n");
if (!__this->cover_status) {//当前为合盖
if (!app_in_mode(APP_MODE_IDLE)) {
sys_enter_soft_poweroff(POWEROFF_RESET);
}
}
break;
case CMD_CLOSE_CID:
log_info("event_CMD_CLOSE_CID\n");
if (!__this->cover_status) {//当前为合盖
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
if ((__this->bt_init_ok) && (tws_api_get_role() == TWS_ROLE_MASTER)) {
bt_ble_icon_close(1);
}
#elif (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
if ((__this->bt_init_ok) && (tws_api_get_role() == TWS_ROLE_MASTER)) {
bt_ble_adv_ioctl(BT_ADV_SET_EDR_CON_FLAG, SECNE_DISMISS, 1);
}
#endif
if (!__this->timer) {
__this->timer = sys_timeout_add(NULL, chargestore_timeout_deal, 2000);
if (!__this->timer) {
log_error("timer alloc err!\n");
} else {
__this->close_ing = 1;
}
} else {
sys_timer_modify(__this->timer, 2000);
__this->close_ing = 1;
}
} else {
__this->ear_number = 1;
__this->close_ing = 0;
}
break;
case CMD_SHUT_DOWN:
log_info("event_CMD_SHUT_DOWN\n");
if (!__this->shutdown_timer) {
__this->shutdown_timer = sys_timer_add(NULL, chargestore_shutdown_do, 1000);
} else {
sys_timer_modify(__this->shutdown_timer, 1000);
}
break;
default:
break;
}
return ret;
}
APP_MSG_HANDLER(chargestore_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_CHARGE_STORE,
.handler = app_chargestore_event_handler,
};
static int chargestore_tws_msg_handler(int *msg)
{
struct tws_event *evt = (struct tws_event *)msg;
int role = evt->args[0];
int phone_link_connection = evt->args[1];
int reason = evt->args[2];
switch (evt->event) {
case TWS_EVENT_CONNECTED:
chargestore_sync_chg_level();//同步充电舱电量
break;
case TWS_EVENT_CONNECTION_DETACH:
case TWS_EVENT_REMOVE_PAIRS:
if (app_var.goto_poweroff_flag) {
break;
}
chargestore_set_sibling_chg_lev(0xff);
break;
}
return 0;
}
APP_MSG_HANDLER(chargestore_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = chargestore_tws_msg_handler,
};
u8 chargestore_get_vbat_percent(void)
{
u8 power;
#if CONFIG_DISPLAY_DETAIL_BAT
power = get_vbat_percent();//显示个位数的电量
#else
power = get_self_battery_level() * 10 + 10; //显示10%~100%
#endif
#if TCFG_CHARGE_ENABLE
if (get_charge_full_flag()) {
power = 100;
} else if (power == 100) {
power = 99;
}
if (get_charge_online_flag()) {
power |= BIT(7);
}
#endif
return power;
}
void chargestore_set_power_status(u8 *buf, u8 len)
{
__this->version = buf[0] & 0x0f;
__this->chip_type = (buf[0] >> 4) & 0x0f;
//f95可能传一个大于100的电量
if ((buf[1] & 0x7f) > 100) {
__this->power_level = (buf[1] & 0x80) | 100;
} else {
__this->power_level = buf[1];
}
if (len > 2) {
__this->max_packet_size = buf[2];
if (len > 3) {
__this->tws_power = buf[3];
}
}
}
static int app_chargestore_data_handler(u8 *buf, u8 len)
{
u8 send_buf[36];
/* log_info_hexdump(buf, len); */
chargestore_shutdown_reset();
send_buf[0] = buf[0];
#ifdef CONFIG_CHARGESTORE_REMAP_ENABLE
if (remap_app_chargestore_data_deal(buf, len)) {
return 1;
}
#endif
switch (buf[0]) {
case CMD_TWS_CHANNEL_SET:
__this->channel = (buf[1] == TWS_CHANNEL_LEFT) ? 'L' : 'R';
chargestore_event_to_user(NULL, buf[0], 0);
if (__this->bt_init_ok) {
len = chargestore_get_tws_remote_info(&send_buf[1]);
chargestore_api_write(send_buf, len + 1);
} else {
send_buf[0] = CMD_UNDEFINE;
chargestore_api_write(send_buf, 1);
}
break;
case CMD_TWS_SET_CHANNEL:
__this->channel = (buf[1] == TWS_CHANNEL_LEFT) ? 'L' : 'R';
log_info("f95 set channel = %c\n", __this->channel);
chargestore_event_to_user(NULL, CMD_TWS_CHANNEL_SET, 0);
if (__this->bt_init_ok) {
chargestore_api_write(send_buf, 1);
} else {
send_buf[0] = CMD_UNDEFINE;
chargestore_api_write(send_buf, 1);
}
break;
case CMD_TWS_REMOTE_ADDR:
__this->close_ing = 0;
if (chargestore_check_data_succ((u8 *)&buf[1], len - 1) == true) {
chargestore_event_to_user((u8 *)&buf[1], buf[0], len - 1);
} else {
send_buf[0] = CMD_FAIL;
}
chargestore_api_write(send_buf, 1);
break;
case CMD_EX_FIRST_READ_INFO:
log_info("read first!\n");
__this->close_ing = 0;
len = chargestore_f95_read_tws_remote_info(&send_buf[1], 1);
chargestore_api_write(send_buf, len + 1);
break;
case CMD_EX_CONTINUE_READ_INFO:
log_info("read continue!\n");
__this->close_ing = 0;
len = chargestore_f95_read_tws_remote_info(&send_buf[1], 0);
chargestore_api_write(send_buf, len + 1);
break;
case CMD_EX_FIRST_WRITE_INFO:
log_info("write first!\n");
__this->close_ing = 0;
chargestore_f95_write_tws_remote_info(&buf[1], len - 1, 1);
chargestore_api_write(send_buf, 1);
break;
case CMD_EX_CONTINUE_WRITE_INFO:
log_info("write continue!\n");
__this->close_ing = 0;
chargestore_f95_write_tws_remote_info(&buf[1], len - 1, 0);
chargestore_api_write(send_buf, 1);
break;
case CMD_EX_INFO_COMPLETE:
log_info("ex complete!\n");
if (chargestore_check_data_succ((u8 *)&write_info, sizeof(write_info)) == true) {
chargestore_event_to_user((u8 *)&write_info, CMD_TWS_REMOTE_ADDR, sizeof(write_info));
} else {
send_buf[0] = CMD_FAIL;
}
chargestore_api_write(send_buf, 1);
break;
case CMD_TWS_ADDR_DELETE:
__this->close_ing = 0;
chargestore_event_to_user(&buf[1], CMD_TWS_ADDR_DELETE, len - 1);
chargestore_api_write(send_buf, 1);
break;
case CMD_POWER_LEVEL_OPEN:
__this->power_status = 1;
__this->cover_status = 1;
__this->close_ing = 0;
if (__this->power_level == 0xff) {
__this->power_sync = 1;
}
chargestore_set_power_status(&buf[1], len - 1);
if (__this->power_level != __this->pre_power_lvl) {
__this->power_sync = 1;
}
__this->pre_power_lvl = __this->power_level;
send_buf[1] = chargestore_get_vbat_percent();
send_buf[2] = chargestore_get_det_level(__this->chip_type);
chargestore_api_write(send_buf, 3);
//切模式过程中不发送消息,防止堆满消息
if (__this->switch2bt == 0) {
chargestore_event_to_user(NULL, CMD_POWER_LEVEL_OPEN, 0);
}
break;
case CMD_POWER_LEVEL_CLOSE:
__this->power_status = 1;
__this->cover_status = 0;
__this->close_ing = 0;
chargestore_set_power_status(&buf[1], len - 1);
send_buf[1] = chargestore_get_vbat_percent();
send_buf[2] = chargestore_get_det_level(__this->chip_type);
chargestore_api_write(send_buf, 3);
chargestore_event_to_user(NULL, CMD_POWER_LEVEL_CLOSE, 0);
break;
case CMD_SHUT_DOWN:
log_info("shut down\n");
__this->power_status = 0;
__this->cover_status = 0;
__this->close_ing = 0;
chargestore_api_write(send_buf, 1);
chargestore_event_to_user(NULL, CMD_SHUT_DOWN, 0);
break;
case CMD_CLOSE_CID:
log_info("close cid\n");
__this->power_status = 1;
__this->cover_status = 0;
__this->ear_number = buf[1];
chargestore_api_write(send_buf, 1);
chargestore_event_to_user(NULL, CMD_CLOSE_CID, 0);
break;
case CMD_RESTORE_SYS:
r_printf("restore sys\n");
__this->power_status = 1;
__this->cover_status = 1;
__this->close_ing = 0;
chargestore_api_write(send_buf, 1);
chargestore_event_to_user(NULL, CMD_RESTORE_SYS, 0);
break;
//不是充电舱的指令,返回0
default:
return 0;
}
return 1;
}
CHARGESTORE_HANDLE_REG(chargestore, app_chargestore_data_handler);
#if TCFG_CHARGE_ENABLE
static int app_chargestore_charge_msg_handler(int msg, int type)
{
switch (msg) {
case CHARGE_EVENT_LDO5V_KEEP:
if (!get_charge_poweron_en()) {
batmgr_send_msg(BAT_MSG_CHARGE_LDO5V_OFF, 0);
return 1;//拦截关机,智能充电舱不在维持电压消息关机
}
break;
case CHARGE_EVENT_LDO5V_IN:
chargestore_shutdown_reset();
if (!get_charge_poweron_en()) {
//开启了弹窗才需要等待弹窗关闭才复位进充电
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV)
if (chargestore_check_going_to_poweroff()) {
log_info("chargestore do poweroff!\n");
return 1;//不要关闭蓝牙,让充电舱流程执行关蓝牙
}
#endif
}
break;
case CHARGE_EVENT_LDO5V_OFF:
#if TCFG_USER_TWS_ENABLE
if (TWS_ROLE_SLAVE == tws_api_get_role()) {
chargestore_set_power_level(0xFF);
}
#endif
chargestore_shutdown_reset();
break;
}
return 0;
}
APP_CHARGE_HANDLER(chargestore_charge_msg_entry, 0) = {
.handler = app_chargestore_charge_msg_handler,
};
#endif
#endif //TCFG_CHARGESTORE_ENABLE
+288
View File
@@ -0,0 +1,288 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".ble_adv.data.bss")
#pragma data_seg(".ble_adv.data")
#pragma const_seg(".ble_adv.text.const")
#pragma code_seg(".ble_adv.text")
#endif
#include "app_config.h"
#if TCFG_BT_BLE_ADV_ENABLE
#include "bt.h"
#include "app_main.h"
#include "bt_ble.h"
#include "bt_common.h"
#include "btstack/avctp_user.h"
#include "system/includes.h"
#include "bt_tws.h"
#define LOG_TAG "[BLE-ADV]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
typedef struct {
u8 miss_flag: 1;
u8 exchange_bat: 2;
u8 poweron_flag: 1;
u8 reserver: 4;
} icon_ctl_t;
static icon_ctl_t ble_icon_contrl;
int adv_earphone_state_set_page_scan_enable()
{
#if (TCFG_USER_TWS_ENABLE == 0)
bt_ble_icon_open(ICON_TYPE_INQUIRY);
#elif (CONFIG_NO_DISPLAY_BUTTON_ICON || !TCFG_CHARGESTORE_ENABLE)
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("switch_icon_ctl11...\n");
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
#endif
return 0;
}
int adv_earphone_state_cancel_page_scan()
{
#if (TCFG_USER_TWS_ENABLE == 1)
#if (CONFIG_NO_DISPLAY_BUTTON_ICON || !TCFG_CHARGESTORE_ENABLE)
if (tws_api_get_role() == TWS_ROLE_MASTER) {
if (ble_icon_contrl.miss_flag) {
ble_icon_contrl.miss_flag = 0;
puts("ble_icon_contrl.miss_flag...\n");
} else {
printf("switch_icon_ctl00...\n");
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
}
#endif
#endif
return 0;
}
int adv_earphone_state_tws_init(int paired)
{
memset(&ble_icon_contrl, 0, sizeof(icon_ctl_t));
ble_icon_contrl.poweron_flag = 1;
if (paired) {
if (tws_api_get_role() == TWS_ROLE_MASTER) {
bt_ble_set_control_en(1);
} else {
//slave close
bt_ble_set_control_en(0);
}
} else {
}
return 0;
}
int adv_earphone_state_enter_soft_poweroff()
{
#if (!TCFG_CHARGESTORE_ENABLE)
//非智能充电仓时,做停止广播操作
if (bt_ble_icon_get_adv_state() != ADV_ST_NULL &&
bt_ble_icon_get_adv_state() != ADV_ST_END) {
bt_ble_icon_close(1);
os_time_dly(50);//盒盖时间,根据效果调整时间
}
#endif
bt_ble_exit();
return 0;
}
static int adv_bt_status_event_handler(int *msg)
{
u8 connet_type;
struct bt_event *bt = (struct bt_event *)msg;
switch (bt->event) {
case BT_STATUS_SECOND_CONNECTED:
case BT_STATUS_FIRST_CONNECTED:
if (bt_get_auto_connect_state(bt->args)) {
connet_type = ICON_TYPE_RECONNECT;
} else {
connet_type = ICON_TYPE_CONNECTED;
}
if (tws_api_get_role() == TWS_ROLE_MASTER) {
bt_ble_icon_open(connet_type);
} else {
//maybe slave already open
bt_ble_icon_close(0);
}
break;
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
break;
case BT_STATUS_SCO_STATUS_CHANGE:
break;
case BT_STATUS_PHONE_INCOME:
case BT_STATUS_PHONE_OUT:
case BT_STATUS_PHONE_ACTIVE:
break;
case BT_STATUS_PHONE_HANGUP:
break;
}
return 0;
}
APP_MSG_HANDLER(adv_btstack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = adv_bt_status_event_handler,
};
int ble_adv_hci_event_handler(int *msg)
{
struct bt_event *bt = (struct bt_event *)msg;
switch (bt->event) {
case HCI_EVENT_CONNECTION_COMPLETE:
switch (bt->value) {
case ERROR_CODE_PIN_OR_KEY_MISSING:
#if (CONFIG_NO_DISPLAY_BUTTON_ICON && TCFG_CHARGESTORE_ENABLE)
//已取消配对了
if (bt_ble_icon_get_adv_state() == ADV_ST_RECONN) {
//切换广播
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
#endif
break;
}
break;
}
return 0;
}
APP_MSG_HANDLER(adv_bthci_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_HCI,
.handler = ble_adv_hci_event_handler,
};
int ble_adv_bt_tws_event_handler(int *msg)
{
struct tws_event *bt = (struct tws_event *)msg;
int role = bt->args[0];
int phone_link_connection = bt->args[1];
int reason = bt->args[2];
switch (bt->event) {
case TWS_EVENT_CONNECTED:
bt_ble_icon_slave_en(1);
if (tws_api_get_role() == TWS_ROLE_MASTER) {
//master enable
log_info("master do icon_open\n");
bt_ble_set_control_en(1);
if (phone_link_connection) {
bt_ble_icon_open(ICON_TYPE_RECONNECT);
} else {
#if (TCFG_CHARGESTORE_ENABLE && !CONFIG_NO_DISPLAY_BUTTON_ICON)
bt_ble_icon_open(ICON_TYPE_RECONNECT);
#else
if (ble_icon_contrl.poweron_flag) { //上电标记
if (g_bt_hdl.auto_connection_counter > 0) {
//有回连手机动作
/* g_printf("ICON_TYPE_RECONNECT"); */
/* bt_ble_icon_open(ICON_TYPE_RECONNECT); //没按键配对的话,等回连成功的时候才显示电量。如果在这里显示,手机取消配对后耳机开机,会显示出按键的界面*/
} else {
//没有回连,设可连接
/* g_printf("ICON_TYPE_INQUIRY"); */
bt_ble_icon_open(ICON_TYPE_INQUIRY);
}
}
#endif
}
} else {
//slave disable
bt_ble_set_control_en(0);
}
ble_icon_contrl.poweron_flag = 0;
break;
case TWS_EVENT_CONNECTION_TIMEOUT:
/*
* TWS连接超时
*/
bt_ble_icon_slave_en(0);
break;
case TWS_EVENT_PHONE_LINK_DETACH:
/*
* 跟手机的链路LMP层已完全断开, 只有tws在连接状态才会收到此事件
*/
if (reason == 0x0b) {
//CONNECTION ALREADY EXISTS
ble_icon_contrl.miss_flag = 1;
} else {
ble_icon_contrl.miss_flag = 0;
}
break;
case TWS_EVENT_ROLE_SWITCH:
bt_ble_icon_role_switch(role);
break;
}
return 0;
}
APP_MSG_HANDLER(adv_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = ble_adv_bt_tws_event_handler,
};
static int adv_app_msg_handler(int *msg)
{
u8 comm_addr[6];
switch (msg[0]) {
case APP_MSG_BT_OPEN_PAGE_SCAN:
adv_earphone_state_set_page_scan_enable();
break;
case APP_MSG_BT_CLOSE_PAGE_SCAN:
adv_earphone_state_cancel_page_scan();
break;
case APP_MSG_BT_ENTER_SNIFF:
bt_ble_icon_state_sniff(1);
break;
case APP_MSG_BT_EXIT_SNIFF:
bt_ble_icon_state_sniff(0);
break;
case APP_MSG_TWS_PAIRED:
adv_earphone_state_tws_init(1);
break;
case APP_MSG_TWS_UNPAIRED:
adv_earphone_state_tws_init(0);
break;
case APP_MSG_TWS_PAIR_SUSS:
syscfg_read(CFG_TWS_COMMON_ADDR, comm_addr, 6);
bt_ble_icon_set_comm_address(comm_addr);
break;
case APP_MSG_POWER_OFF:
adv_earphone_state_enter_soft_poweroff();
break;
}
return 0;
}
APP_MSG_HANDLER(adv_app_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_APP,
.handler = adv_app_msg_handler,
};
#endif
File diff suppressed because it is too large Load Diff
+252
View File
@@ -0,0 +1,252 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".adkey_config.data.bss")
#pragma data_seg(".adkey_config.data")
#pragma const_seg(".adkey_config.text.const")
#pragma code_seg(".adkey_config.text")
#endif
#include "app_config.h"
#include "utils/syscfg_id.h"
#include "gpio_config.h"
#include "key/adkey.h"
#include "key_driver.h"
struct _cfg_adkey {
u8 len;
u16 uuid_key_value;
u16 res;
} __attribute__((packed));
struct adkey_info {
u16 io_uuid;
u16 pull_up_type;
u16 pull_up_value;
u16 max_ad_value;
u8 long_press_enable;
u8 long_press_time;
struct _cfg_adkey cfg_key_list[CONFIG_ADKEY_MAX_NUM];
};
static struct adkey_platform_data platform_data;
static const u16 key_uuid_table[][2] = {
{ 0xD191, KEY_AD_NUM0 },
{ 0xD192, KEY_AD_NUM1 },
{ 0xD193, KEY_AD_NUM2 },
{ 0xD194, KEY_AD_NUM3 },
{ 0xD195, KEY_AD_NUM4 },
{ 0xD196, KEY_AD_NUM5 },
{ 0xD197, KEY_AD_NUM6 },
{ 0xD198, KEY_AD_NUM7 },
{ 0xD199, KEY_AD_NUM8 },
{ 0xD19A, KEY_AD_NUM9 },
{ 0x0402, KEY_AD_NUM10 },
{ 0x0403, KEY_AD_NUM11 },
{ 0x0404, KEY_AD_NUM12 },
{ 0x0405, KEY_AD_NUM13 },
{ 0x0406, KEY_AD_NUM14 },
{ 0x0407, KEY_AD_NUM15 },
{ 0x0408, KEY_AD_NUM16 },
{ 0x0409, KEY_AD_NUM17 },
{ 0x040a, KEY_AD_NUM18 },
{ 0x040b, KEY_AD_NUM19 },
};
static u8 uuid2keyValue(u16 uuid)
{
for (int i = 0; i < ARRAY_SIZE(key_uuid_table); i++) {
if (key_uuid_table[i][0] == uuid) {
return key_uuid_table[i][1];
}
}
return 0xff;
}
const struct adkey_platform_data *get_adkey_platform_data()
{
struct adkey_info info;
u16 key_numbers;
if (platform_data.enable) {
return &platform_data;
}
#if 0
key_numbers = 2;
info.cfg_key_list[0].res = 100; // adkey1电阻值
info.cfg_key_list[1].res = 330; // adkey2电阻值
info.max_ad_value = 4096; // adc最大值
info.pull_up_value = 1000; // 上拉电阻值
platform_data.adkey_pin = IO_PORTB_07;
platform_data.extern_up_en = 0;
platform_data.ad_channel = adc_io2ch(platform_data.adkey_pin);
platform_data.long_press_enable = 1;
platform_data.long_press_time = 8;
platform_data.key_value[0] = KEY_AD_NUM0;
platform_data.key_value[1] = KEY_AD_NUM1;
platform_data.enable = 1;
printf("adkey_pin: %d\n", platform_data.adkey_pin);
printf("extern_up_en: %d\n", platform_data.extern_up_en);
printf("ad_channel: %d\n", platform_data.ad_channel);
printf("long_press_enable:%d time:%ds\n", platform_data.long_press_enable, platform_data.long_press_time);
u16 i, j, tmp;
u16 ordering_res[CONFIG_ADKEY_MAX_NUM][2];
//记录电阻与序号
for (i = 0; i < key_numbers; i++) {
ordering_res[i][0] = info.cfg_key_list[i].res;
ordering_res[i][1] = i;
/* printf("ordering_res:%d,s_number:%d\n", ordering_res[i][0], ordering_res[i][1]); */
}
//按电阻从小到大排序,序号要跟随电阻值
for (i = 0; i < key_numbers - 1; i++) {
for (j = 0; j < key_numbers - 1 - i; j++) {
if (ordering_res[j][0] > ordering_res[j + 1][0]) {
tmp = ordering_res[j][0];
ordering_res[j][0] = ordering_res[j + 1][0];
ordering_res[j + 1][0] = tmp;
tmp = ordering_res[j][1];
ordering_res[j][1] = ordering_res[j + 1][1];
ordering_res[j + 1][1] = tmp;
}
}
}
/*for test查看排序后的数据*/
/* for (i = 0; i < key_numbers; i++) { */
/* printf("after ordering res:%d,s_number:%d\n", ordering_res[i][0], ordering_res[i][1]); */
/* } */
//配置 ad判断值与key值
u16 tmp_value1, tmp_value2;
for (i = 0; i < key_numbers; i++) {
tmp_value1 = info.max_ad_value * ordering_res[i][0] / (ordering_res[i][0] + info.pull_up_value);
if (i == key_numbers - 1) {
tmp_value2 = info.max_ad_value;
} else {
tmp_value2 = info.max_ad_value * ordering_res[i + 1][0] / (ordering_res[i + 1][0] + info.pull_up_value);
}
platform_data.ad_value[i] = (tmp_value1 + tmp_value2) / 2;
printf("ADkey:%d,judge_advalue:%d,key_value:%d\n", i, platform_data.ad_value[i], platform_data.key_value[i]);
}
#else
int len = syscfg_read(CFG_ADKEY_ID, &info, sizeof(struct adkey_info));
if (len <= 0) {
puts("ERR:Can not read the adkey config,total adkeys should <= CONFIG_ADKEY_MAX_NUM\n");
return NULL;
}
printf("adkey info len: %d\n", len);
key_numbers = CONFIG_ADKEY_MAX_NUM - ((sizeof(info) - len) / sizeof(struct _cfg_adkey));
platform_data.adkey_pin = uuid2gpio(info.io_uuid);
platform_data.extern_up_en = info.pull_up_type;
platform_data.ad_channel = adc_io2ch(platform_data.adkey_pin);
platform_data.long_press_enable = info.long_press_enable;
platform_data.long_press_time = info.long_press_time;
if (platform_data.ad_channel == 0xff) {
puts("ERR:Please check that the ad key is correct\n");
return NULL;
}
printf("key_numbers: %d\n", key_numbers);
printf("adkey_pin: %d\n", platform_data.adkey_pin);
printf("extern_up_en: %d\n", platform_data.extern_up_en);
printf("pull_up_value: %d\n", info.pull_up_value);
printf("ad_channel: %d\n", platform_data.ad_channel);
printf("long_press_enable:%d time:%ds\n", platform_data.long_press_enable, platform_data.long_press_time);
u16 i, j, tmp;
u16 ordering_res[CONFIG_ADKEY_MAX_NUM][2];
//记录电阻与序号
for (i = 0; i < key_numbers; i++) {
ordering_res[i][0] = info.cfg_key_list[i].res;
ordering_res[i][1] = i;
/* printf("ordering_res:%d,s_number:%d\n", ordering_res[i][0], ordering_res[i][1]); */
}
//按电阻从小到大排序,序号要跟随电阻值
for (i = 0; i < key_numbers - 1; i++) {
for (j = 0; j < key_numbers - 1 - i; j++) {
if (ordering_res[j][0] > ordering_res[j + 1][0]) {
tmp = ordering_res[j][0];
ordering_res[j][0] = ordering_res[j + 1][0];
ordering_res[j + 1][0] = tmp;
tmp = ordering_res[j][1];
ordering_res[j][1] = ordering_res[j + 1][1];
ordering_res[j + 1][1] = tmp;
}
}
}
/*for test查看排序后的数据*/
/* for (i = 0; i < key_numbers; i++) { */
/* printf("after ordering res:%d,s_number:%d\n", ordering_res[i][0], ordering_res[i][1]); */
/* } */
//配置 ad判断值与key值
u16 tmp_value1, tmp_value2;
for (i = 0; i < key_numbers; i++) {
tmp_value1 = info.max_ad_value * ordering_res[i][0] / (ordering_res[i][0] + info.pull_up_value);
if (i == key_numbers - 1) {
tmp_value2 = info.max_ad_value;
} else {
tmp_value2 = info.max_ad_value * ordering_res[i + 1][0] / (ordering_res[i + 1][0] + info.pull_up_value);
}
platform_data.ad_value[i] = (tmp_value1 + tmp_value2) / 2;
platform_data.key_value[i] = uuid2keyValue(info.cfg_key_list[ordering_res[i][1]].uuid_key_value);
printf("ADkey:%d,judge_advalue:%d,key_value:%d\n", i, platform_data.ad_value[i], platform_data.key_value[i]);
}
platform_data.enable = 1;
#endif
return &platform_data;
}
bool is_adkey_press_down()
{
#if TCFG_ADKEY_ENABLE
if (platform_data.enable == 0) {
return false;
}
#ifdef TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE
if (adc_get_value(platform_data.ad_channel) < 300) {
#else
if (adc_get_value(platform_data.ad_channel) < 10) {
#endif
return true;
}
#endif
return false;
}
int get_adkey_io()
{
#if TCFG_ADKEY_ENABLE
if (platform_data.enable) {
return platform_data.adkey_pin;
}
#endif
return -1;
}
+101
View File
@@ -0,0 +1,101 @@
#include "app_config.h"
SECTIONS
{
.text : ALIGN(4)
{
gsensor_dev_begin = .;
KEEP(*(.gsensor_dev))
gsensor_dev_end = .;
imusensor_dev_begin = .;
KEEP(*(.imusensor_dev))
imusensor_dev_end = .;
fm_dev_begin = .;
KEEP(*(.fm_dev))
fm_dev_end = .;
fm_emitter_dev_begin = .;
KEEP(*(.fm_emitter_dev))
fm_emitter_dev_end = .;
storage_device_begin = .;
KEEP(*(.storage_device))
storage_device_end = .;
. = ALIGN(4);
key_ops_begin = .;
KEEP(*(.key_operation))
key_ops_end = .;
. = ALIGN(4);
key_callback_begin = .;
KEEP(*(.key_cb))
key_callback_end = .;
. = ALIGN(4);
_watch_syscfg_begin = .;
PROVIDE(watch_syscfg_begin = .);
KEEP(*(.watch_syscfg))
_watch_syscfg_end = .;
PROVIDE(watch_syscfg_end = .);
. = ALIGN(4);
flashdb_partition_begin = .;
KEEP(*(.flashdb_partition))
flashdb_partition_end = .;
. = ALIGN(4);
sport_health_module_begin = .;
KEEP(*(.sport_health_module))
sport_health_module_end = .;
. = ALIGN(4);
sensor_dev_begin = .;
KEEP(*(.sensor_dev))
sensor_dev_end = .;
. = ALIGN(4);
sensor_hal_begin = .;
KEEP(*(.sensor_hal))
sensor_hal_end = .;
. = ALIGN(4);
ui_effect_module_begin = .;
KEEP(*(.ui_effect_module))
ui_effect_module_end = .;
. = ALIGN(4);
charge_ic_begin = .;
KEEP(*(.charge_ic))
charge_ic_end = .;
. = ALIGN(4);
pt_module_begin = .;
PROVIDE(pt_module_begin = .);
KEEP(*(.pt_module))
pt_module_end = .;
PROVIDE(pt_module_end = .);
. = ALIGN(4);
camera_device_module_begin = .;
KEEP(*(.camera_device))
camera_device_module_end = .;
. = ALIGN(32);
}
.data ALIGN(32):
{
} > ram0
.bss ALIGN(32):
{
} > ram0
.data_code ALIGN(32):
{
} > ram0
}
+183
View File
@@ -0,0 +1,183 @@
/*不使用动态加载时,使用overlay*/
#ifndef CONFIG_CODE_MOVABLE_ENABLE
OVERLAY : AT(0x200000) SUBALIGN(4)
{
.overlay_aec
{
aec_code_begin = . ;
#if AUDIO_CVP_TEXT_AT_RAM
. = ALIGN(4);
*(.text._*)
#endif
#if AUDIO_CVP_AEC_AT_RAM
*(.jlsp_aec_code)
*(.jlsp_aec_const)
#endif
#if AUDIO_CVP_NLP_AT_RAM
*(.nlp_code)
*(.nlp_const)
*(.qmf_code)
*(.qmf_const)
*(.jlsp_nlp_code)
*(.jlsp_nlp_const)
#endif
#if AUDIO_CVP_NS_AT_RAM
*(.ns_code)
*(.ns_const)
#endif
#if AUDIO_CVP_COMMON_AT_RAM
. = ALIGN(4);
*(.aec_mem)
*(.aec_mux)
*(.aec_code)
*(.aec_const)
*(.res_code)
*(.res_const)
*(.bark_const)
*(.fft_code)
*(.fft_const)
*(.der_code)
*(.der_const)
#endif
#if AUDIO_CVP_DNS_AT_RAM
. = ALIGN(4);
*(.dns_common_data)
*(.dns_param_data_single)
*(.dns_param_data_dual)
. = ALIGN(4);
#endif
#if AUDIO_CVP_AGC_AT_RAM
*(.agc_code)
*(.agc_const)
*(.jlsp_agc_code)
*(.jlsp_agc_const)
#endif
#if AUDIO_CVP_DMS_AT_RAM
*(.dms_code)
*(.dms_const)
*(.jlsp_enc_code)
*(.jlsp_enc_const)
*(.jlsp_dms_hybrid_code)
*(.jlsp_dms_hybrid_const)
*(.jlsp_dms_awn_code)
*(.jlsp_dms_awn_const)
#endif
#if AUDIO_CVP_SMS_AT_RAM
*(.sms_const)
*(.sms_code)
#endif
#if AUDIO_CVP_PREP_AT_RAM
*(.jlsp_prep_code)
*(.jlsp_prep_const)
#endif
#if AUDIO_CVP_WN_AT_RAM
*(.jlsp_wn_code)
*(.jlsp_wn_const)
#endif
#if AUDIO_CVP_THIRD_AT_RAM
*(.jlsp_tri_code)
*(.jlsp_tri_const)
#endif
aec_code_end = . ;
aec_code_size = aec_code_end - aec_code_begin ;
#if AUDIO_ENCODER_AT_RAM
*(.msbc_enc)
*(.cvsd_codec)
#endif
}
.overlay_aac
{
#if AUD_AAC_DEC_AT_RAM
aac_dec_code_begin = .;
*(.bt_aac_dec_code)
*(.bt_aac_dec_sparse_code)
aac_dec_code_end = .;
aac_dec_code_size = aac_dec_code_end - aac_dec_code_begin ;
. = ALIGN(4);
bt_aac_dec_const_begin = .;
*(.bt_aac_dec_const)
*(.bt_aac_dec_sparse_const)
bt_aac_dec_const_end = .;
bt_aac_dec_const_size = bt_aac_dec_const_end - bt_aac_dec_const_begin ;
. = ALIGN(4);
*(.aac_mem)
*(.aac_ctrl_mem)
#endif
}
/*
.overlay_lc3
{
lc3_dec_code_begin = .;
*(.lc3_dec_code)
lc3_dec_code_end = .;
lc3_dec_code_size = lc3_dec_code_end - lc3_dec_code_begin;
. = ALIGN(4);
lc3_dec_const_begin = .;
*(.lc3_dec_const)
lc3_dec_const_end = .;
lc3_dec_const_size = lc3_dec_const_end - lc3_dec_const_begin;
*(.lc3_dec_data)
*(.lc3_dec_bss)
}
*/
.overlay_mp3
{
*(.mp3_mem)
*(.mp3_ctrl_mem)
*(.mp3pick_mem)
*(.mp3pick_ctrl_mem)
*(.dec2tws_mem)
}
.overlay_wma
{
*(.wma_mem)
*(.wma_ctrl_mem)
*(.wmapick_mem)
*(.wmapick_ctrl_mem)
}
.overlay_wav
{
*(.wav_mem)
*(.wav_ctrl_mem)
}
.overlay_ape
{
*(.ape_mem)
*(.ape_ctrl_mem)
}
.overlay_flac
{
*(.flac_mem)
*(.flac_ctrl_mem)
}
.overlay_m4a
{
*(.m4a_mem)
*(.m4a_ctrl_mem)
}
.overlay_amr
{
*(.amr_mem)
*(.amr_ctrl_mem)
}
.overlay_dts
{
*(.dts_mem)
*(.dts_ctrl_mem)
}
.overlay_fm
{
*(.fm_mem)
}
.overlay_pc
{
}
} > ram0
#endif
@@ -0,0 +1,603 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".board_config.data.bss")
#pragma data_seg(".board_config.data")
#pragma const_seg(".board_config.text.const")
#pragma code_seg(".board_config.text")
#endif
#include "app_config.h"
#ifdef CONFIG_BOARD_JL7074_DEMO
#include "system/includes.h"
#include "app_main.h"
#include "rtc/rtc.h"
#include "spi.h"
#include "asm/sdmmc.h"
#include "asm/spi_hw.h"
#include "asm/lpctmu_hw.h"
#include "asm/psram_api.h"
#include "linein_dev.h"
#include "usb/device/usb_stack.h"
#include "usb/host/usb_storage.h"
#include "ui/ui_api.h"
#include "ui_manage.h"
#include "iic_api.h"
#include "ui/lcd/lcd_drive.h"
#include "include/norflash_sfc.h"
#include "fs/virfat_flash.h"
#include "alarm.h"
#include "data_storage.h"
#include "tp_api.h"
#include "gpadc.h"
#include "rdec_key.h"
#include "asm/espi.h"
#include "../sdk_config.c"
#if (CONFIG_BT_MODE != BT_NORMAL) || TCFG_NORMAL_SET_DUT_MODE
#if ((TCFG_RDEC0_ECODEA_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEA_PORT==IO_PORT_DM)) || \
((TCFG_RDEC0_ECODEB_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEB_PORT==IO_PORT_DM))
// 蓝牙测试会用到DPDM
#undef TCFG_RDEC_KEY_ENABLE
#define TCFG_RDEC_KEY_ENABLE DISABLE_THIS_MOUDLE
#endif
#endif
#if TCFG_APP_RTC_EN
static struct sys_time def_sys_time = { //初始化系统时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 0,
.sec = 0,
};
static struct sys_time def_alarm = { //初始化闹钟时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 5,
.sec = 0,
};
void rtc_event_isr(u32 event) //闹钟回调函数测试
{
if (event == MSYS_ALARM_WKUP_EVENT) {
alm_wakeup_isr();
} else if (event == MSYS_RTC_1HZ_EVENT) {
}
}
struct rtc_config_init rtc_dev_config = { //RTC初始化结构体
.default_sys_time = &def_sys_time, //配置默认系统时钟
.default_alarm = &def_alarm, //配置默认闹钟
.rtc_clk = CLK_SEL_LRC, // 配置时钟源
.alm_en = 1, //闹钟使能
.cbfun = rtc_event_isr,
//rtc闹钟回调函数
};
#endif
#if TCFG_PSRAM_DEV_ENABLE
PSRAM_PLATFORM_DATA_BEGIN(psram_config)
.power_port = TCFG_PSRAM_POWER_PORT,//power io
.port = TCFG_PSRAM_PORT_SEL ,//默认A口
.mode = TCFG_PSRAM_MODE,//4线读写
.init_clk = TCFG_PSRAM_INIT_CLK,//hz
PSRAM_PLATFORM_DATA_END()
#endif//TCFG_PSRAM_DEV_ENABLE
#if TCFG_SD0_ENABLE
extern void sdpg_config(int enable);
#define SDX_POWER_ALONE 1
#if (TCFG_SD0_POWER_SEL == SD_PWR_SDPG)
#define sd_power_config sdpg_config
#else
void sd_power_config(int enable)
{
//TODO: 使用普通io供电
if (enable) {
/* printf("\n\n sd power enable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_OUTPUT_LOW);
} else {
/* printf("\n\n sd power disable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_HIGHZ);
}
}
#endif
#if SDX_POWER_ALONE
static u8 sdx_power_enable = 0xff;
void sd_set_power(u8 enable)
{
/* enable = !!enable; */
// y_printf("sd_set_power:%d, %d \n", sdx_power_enable, enable);
if (sdx_power_enable == enable) {
return;
}
sd_power_config(enable);
sdx_power_enable = enable;
}
#endif /* #if SDX_POWER_ALONE */
#if TCFG_SD_ALWAY_ONLINE_ENABLE
int sdmmc_0_io_detect(const struct sdmmc_platform_data *data)
{
return 1;
}
#endif /* #if TCFG_SD_ALWAY_ONLINE_ENABLE */
SD0_PLATFORM_DATA_BEGIN(sd0_data) = {
.port = {
TCFG_SD0_PORT_CMD,
TCFG_SD0_PORT_CLK,
TCFG_SD0_PORT_DA0,
TCFG_SD0_PORT_DA1,
TCFG_SD0_PORT_DA2,
TCFG_SD0_PORT_DA3,
},
.data_width = TCFG_SD0_DAT_MODE,
.speed = TCFG_SD0_CLK,
.detect_mode = TCFG_SD0_DET_MODE,
.priority = 3,
#if (TCFG_SD0_DET_MODE == SD_IO_DECT)
.detect_io = TCFG_SD0_DET_IO,
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_io_detect,
.power = sd_set_power,
/* .power = NULL, */
#elif (TCFG_SD0_DET_MODE == SD_CLK_DECT)
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_clk_detect,
.power = sd_set_power,
/* .power = NULL, */
#else
.detect_func = sdmmc_cmd_detect,
.power = NULL,
#endif
SD0_PLATFORM_DATA_END()
};
#endif /* #if TCFG_SD0_ENABLE */
// *INDENT-OFF*
#if TCFG_LPCTMU_ENABLE
LPCTMU_PLATFORM_DATA_BEGIN(lpctmu_pdata)
#if LPCTMU_ANA_CFG_ADAPTIVE
.aim_vol_delta = 800,
.aim_charge_khz = 7,//2500,
#else
.hv_level = 3,
.lv_level = 0,
.cur_level = 7,
#endif
LPCTMU_PLATFORM_DATA_END();
LPCTMU_CFG_DATA_BEGIN(lpctmu_cfg)
.ch_en = ((TCFG_LPCTMU_CH0_EN << 0) | \
(TCFG_LPCTMU_CH1_EN << 1) | \
(TCFG_LPCTMU_CH2_EN << 2) | \
(TCFG_LPCTMU_CH3_EN << 3) | \
(TCFG_LPCTMU_CH4_EN << 4)),
.pdata = &lpctmu_pdata,
LPCTMU_CFG_DATA_END();
#endif
/************************** linein KEY ****************************/
#if TCFG_APP_LINEIN_EN
struct linein_dev_data linein_data = {
.enable = TCFG_APP_LINEIN_EN,
.port = NO_CONFIG_PORT,
.up = 1,
.down = 0,
.ad_channel = NO_CONFIG_PORT,
.ad_vol = 0,
};
#endif
#if TCFG_UI_ENABLE
#if TCFG_SPI_LCD_ENABLE
//推屏使用有专门硬件模块,不是普通spi模块,io固定,根据屏幕驱动类似输出时序
LCD_SPI_PLATFORM_DATA_BEGIN(lcd_spi_data) = {
.pin_reset = IO_PORTA_05,
.pin_en = IO_PORTA_03,
.pin_en_ex = IO_PORTC_02,
.pin_te = TCFG_LCD_TE_IO,
.pin_bl = TCFG_LCD_BL_IO,
LCD_SPI_PLATFORM_DATA_END()
};
const struct ui_devices_cfg ui_cfg_data = {
.type = TFT_LCD,
.private_data = (void *) &lcd_spi_data,
};
#endif /*TCFG_SPI_LCD_ENABLE*/
#endif /*TCFG_UI_ENABLE*/
const struct iic_master_config soft_iic_cfg_const[MAX_SOFT_IIC_NUM] = {
//soft iic0
#if 0
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C0_CLK_PORT,
.sda_io = TCFG_SW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C0_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
#if 0
//soft iic1
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C1_CLK_PORT,
.sda_io = TCFG_SW_I2C1_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C1_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
};
const struct iic_master_config hw_iic_cfg_const[MAX_HW_IIC_NUM] = {
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C0_CLK_PORT,
.sda_io = TCFG_HW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C0_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic0
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C_P11_CLK_PORT,
.sda_io = TCFG_HW_I2C_P11_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C_P11_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic_p11
};
#if (TCFG_HW_SPI1_ENABLE || TCFG_HW_SPI2_ENABLE)
const struct spi_platform_data spix_p_data[HW_SPI_MAX_NUM] = {
{
//spi0
},
#if 0
{
//spi1
.port = {
TCFG_HW_SPI1_PORT_CLK, //clk any io
TCFG_HW_SPI1_PORT_DO, //do any io
TCFG_HW_SPI1_PORT_DI, //di any io
0xff, //d2 any io
0xff, //d3 any io
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI1_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI1_BAUD,
.mode = TCFG_HW_SPI1_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
.cpha = 0,//sampling edge:0:first, 1:second
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
#if SUPPORT_SPI2
{
//spi2
.port = {
TCFG_HW_SPI2_PORT_CLK, //clk any io
TCFG_HW_SPI2_PORT_DO, //do any io
TCFG_HW_SPI2_PORT_DI, //di any io
0xff, //d2 any io
0xff, //d3 any io
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI2_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI2_BAUD,
.mode = TCFG_HW_SPI2_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
.cpha = 0,//sampling edge:0:first, 1:second
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
};
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
#include "nandflash.h"
NANDFLASH_DEV_PLATFORM_DATA_BEGIN(nandflash_dev_data) = {
.spi_hw_num = TCFG_FLASH_DEV_SPI_HW_NUM,
.spi_cs_port = TCFG_FLASH_DEV_SPI_CS_PORT,
.spi_read_width = TCFG_FLASH_DEV_FLASH_READ_WIDTH,//flash读数据的线宽
.start_addr = 0,
.size = 256 * 1024 * 1024,
#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1)
.spi_pdata = &spi1_p_data,
#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2)
.spi_pdata = &spi2_p_data,
#endif
};
#endif
const u32 g_res_nor_unencry_start_addr = 0; //temp, todo...
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_mode_data)
.path = (const u8 *)"mnt/sdfile/app/MODE",
.start_addr = TCFG_MODE_INSERT_FLASH_BASE,
.size = TCFG_MODE_INSERT_FLASH_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_data)
.path = (const u8 *)"mnt/sdfile/app/FATFSI",
.start_addr = TCFG_WATCH_INSERT_FLASH_BASE,
.size = TCFG_WATCH_INSERT_FLASH_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_DATA_STORAGE_FDB_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_watch_data_dev_data)
.start_addr = TCFG_DATA_INSERT_FLASH_BASE,
.size = TCFG_DATA_INSERT_FLASH_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
//这里是外挂flash分区的配置
#if TCFG_NORFLASH_SFC_DEV_ENABLE
SFC_SPI_PLATFORM_DATA_BEGIN(sfc_spi_data)
.sfc_data_width = SFC_DATA_WIDTH_4,
.sfc_read_mode = SFC_RD_IO,
SFC_SPI_PLATFORM_DATA_END()
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_data)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = 0,
.size = CONFIG_EXTERN_FLASH_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
REGISTER_DEVICES(device_table) = {
#if TCFG_SD0_ENABLE
{ "sd0", &sd_dev_ops, (void *) &sd0_data},
#endif
#if TCFG_APP_LINEIN_EN
{ "linein", &linein_dev_ops, (void *) &linein_data},
#endif
#if TCFG_UDISK_ENABLE
{ "udisk0", &mass_storage_ops, NULL},
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
{"nand_flash", &nandflash_dev_ops, (void *) &nandflash_dev_data},
{"nandflash_ftl", &ftl_dev_ops, NULL },
#endif
#if TCFG_VIRFAT_FLASH_ENABLE
//虚拟文件系统对接jl sdfile fat 文件系统设备入口,往下对接文件系统,往上对接物理设备
{ "virfat_flash", &virfat_flash_dev_ops, (void *)"res_nor"},
//res_nor 是物理设备入口
#endif
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
//使用内置flash 跑ui
{ "res_nor", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_data},
#endif//TCFG_VIRFAT_INSERT_FLASH_ENABLE
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
//内置只读文件系统
{ "res_nor_mode", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_mode_data},
#endif
#if TCFG_NORFLASH_SFC_DEV_ENABLE
#if TCFG_VIRFAT_EXT_FLASH_ENABLE
//使用外挂flash 跑ui
{ "res_nor", &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_data},
#endif
#endif /*TCFG_NORFLASH_SFC_DEV_ENABLE*/
#if TCFG_DATA_STORAGE_FDB_ENABLE
{ TCFG_DATA_DEV_NAME, &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_watch_data_dev_data},
#endif//TCFG_DATA_STORAGE_FDB_ENABLE
};
#if TCFG_SD_ALWAY_ONLINE_ENABLE
extern int sdx_dev_entry_lowpower(const char *sdx_name);
static int sdx_entry_lowpower(int param)
{
/* putchar('s'); */
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif /* #if TCFG_SD1_ENABLE */
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif /* #if TCFG_SD1_ENABLE */
return 0;
}
static void sdx_sleep_callback(void)
{
int argv[3];
argv[0] = (int)sdx_entry_lowpower;
argv[1] = 1;
/* argv[2] = ; */
int ret = os_taskq_post_type("app_core", Q_CALLBACK, 3, argv);
if (ret) {
printf("post ret:%d \n", ret);
}
}
#else /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
extern void sdx_dev_detect_modify(u32 modify_time);
void sniff_hook(u32 slot, u8 num, u8 first_conn, int t_sniff)
{
if (num) {
if (first_conn) {
/* printf("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 12);
}
} else {
/* printf("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 3);
}
}
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
void board_init()
{
board_power_init();
#if TCFG_APP_RTC_EN
rtc_dev_init(&rtc_dev_config);
#endif
adc_init();
#if TCFG_APP_FM_EN
y_printf(">> Func:%s, Line:%d, call: fm_dev_init Func!\n", __func__, __LINE__);
fm_dev_init((void *)(&fm_dev_data));
#endif
#if TCFG_RDEC_KEY_ENABLE
rdec_key_init();
#endif
#if TCFG_LPCTMU_ENABLE
lpctmu_init(&lpctmu_cfg);
#endif
#if TCFG_PAY_ALIOS_ENABLE
extern void alipay_upay_init(void);
alipay_upay_init();
#endif /* #if TCFG_PAY_ALIOS_ENABLE */
#if TCFG_SD0_ENABLE
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(1);
#endif
#endif
#if TCFG_PSRAM_DEV_ENABLE
psram_init(&psram_config);
#endif
}
/*-----------------------------------------------------------------------
*进入、退出低功耗函数回调状态,函数单核操作、关中断,请勿做耗时操作
*
*/
#include "iokey.h"
#include "irkey.h"
#include "adkey.h"
#include "gpio_config.h"
void board_sleep_enter_callback()
{
/* 此函数禁止添加打印 */
putchar('<');
}
void board_sleep_exit_callback()
{
putchar('>');
#if TCFG_SD_ALWAY_ONLINE_ENABLE
#if SDX_POWER_ALONE // sd使用单独的电源才能用
if (sdx_power_enable && (sdx_power_enable != 0xff)) {
sdx_sleep_callback();
}
#endif /* #if SDX_POWER_ALONE */
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
}
////关机回调执行顺序
//power_soff_callback()->do_platform_uninitcall()->board_poweroff_uninit->gpio_config_soft_poweroff()
//关机的注册的段
void board_poweroff_uninit()
{
//用户进行自己模块的关闭操作
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(0);
#endif
}
platform_uninitcall(board_poweroff_uninit);
//设置关机保持状态的io
void board_gpio_config_soft_poweroff(u32 *gpio_config)
{
//设置后关机io会保持原来状态
// PORT_PROTECT(IO_PORTB_01);
// PORT_PROTECT(IO_PORTB_01);
}
#endif
@@ -0,0 +1,501 @@
#ifndef CONFIG_BOARD_AC7074_DEMO_CFG_H
#define CONFIG_BOARD_AC7074_DEMO_CFG_H
#include "board_ac7074_demo_global_build_cfg.h"
#ifdef CONFIG_BOARD_JL7074_DEMO
#define CONFIG_SDFILE_ENABLE
//*********************************************************************************//
// 配置开始 //
//*********************************************************************************//
#define ENABLE_THIS_MOUDLE 1
#define DISABLE_THIS_MOUDLE 0
#define ENABLE 1
#define DISABLE 0
#define NO_CONFIG_PORT (-1)
// NTC配置 //
//*********************************************************************************//
#define NTC_DET_EN 0
#define NTC_POWER_IO IO_PORTC_03
#define NTC_DETECT_IO IO_PORTC_04
#define NTC_DET_AD_CH (0x4) //根据adc_api.h修改通道号
#define NTC_DET_UPPER 235 //正常范围AD值上限,0度时
#define NTC_DET_LOWER 34 //正常范围AD值下限,45度时
//*********************************************************************************//
// FPGA 配置 //
//*********************************************************************************//
#define FPGA_DEVELOP_IOKEY 0
//*********************************************************************************//
// FLASH 配置 //
//*********************************************************************************//
//FLASH公共配置
#if TCFG_USER_BLE_ENABLE
#define TCFG_FLASH_ERASE_WAIT_BLE ENABLE //flash擦除前等待ble状态
#else
#define TCFG_FLASH_ERASE_WAIT_BLE DISABLE //flash擦除前等待ble状态
#endif
//外挂flash配置
#define TCFG_NORFLASH_SFC_DEV_ENABLE DISABLE //外挂flash驱动
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE // 外挂FLASH虚拟文件系统
#define TCFG_EX_FLASH_POWER_IO IO_PORTC_10 // 外置flash电源脚
#define CONFIG_EX_FLASH_POWER_IO PC10 // NULL // 外置flash电源脚。不接IO时填NULL或者屏蔽掉该宏定义
#define CONFIG_EX_FLASH_POWER_IO_CTRL 1 // 0:power_io低电平时供电;1:高电平时供电 (针对io口低电平控制mos管导通来供电的情况)
//分区配置
#if CONFIG_JL_UI_ENABLE || CONFIG_LVGL_UI_ENABLE
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE ENABLE // 内置FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE ENABLE // 内置只读文件系统
#else
#define TCFG_VIRFAT_FLASH_ENABLE DISABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE // 内置FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE // 内置只读文件系统
#endif
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE
#define TCFG_DATA_STORAGE_ENABLE (TCFG_DATA_STORAGE_FDB_ENABLE || TCFG_DATA_STORAGE_VM_ENABLE)
//内置flash配置
#if (CONFIG_FLASH_SIZE == 0x800000) //8M
#define TCFG_MODE_INSERT_FLASH_BASE 0x17e000 // 1.5M - 8k开始 内置FLASH虚拟文件系统空间基础地址
#define TCFG_MODE_INSERT_FLASH_SIZE 0x580000 // 5.5M
#define TCFG_WATCH_INSERT_FLASH_BASE 0x6FE000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_WATCH_INSERT_FLASH_SIZE 0xD8000 // 864K
#if TCFG_DATA_STORAGE_FDB_ENABLE
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_INSERT_FLASH_BASE 0x7D6000//(TCFG_WATCH_INSERT_FLASH_BASE + TCFG_WATCH_INSERT_FLASH_SIZE)
#define TCFG_DATA_INSERT_FLASH_SIZE 0x28000 // 160K
#endif
#elif TCFG_DATA_STORAGE_FDB_ENABLE
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_INSERT_FLASH_BASE 0x1D6000//
#define TCFG_DATA_INSERT_FLASH_SIZE 0x28000 // 160K
#elif (TCFG_UI_ENABLE && CONFIG_JL_UI_ENABLE)
#error "flash size config error !!!"
#endif
#if TCFG_VIRFAT_EXT_FLASH_ENABLE && TCFG_VIRFAT_INSERT_FLASH_ENABLE
#error "vir fat flash only support one dev !!!"
#endif
#if TCFG_VIRFAT_EXT_FLASH_ENABLE && (!CONFIG_EXTERN_FLASH_SIZE)
#error "CONFIG_EXTERN_FLASH_SIZE is 0 !!!"
#endif
//*********************************************************************************//
// PSRAM 配置 //
//*********************************************************************************//
//#define TCFG_PSRAM_POWER_PORT IO_FS_PG2
#define TCFG_PSRAM_POWER_PORT IO_PORTB_05//7074使用pb5供电
#define TCFG_PSRAM_PORT_SEL PSRAM_PORT_SEL_PORTA
#define TCFG_PSRAM_MODE PSRAM_MODE_4_WIRE_CMD4_ADR4_DAT4
#define TCFG_PSRAM_INIT_CLK (144* 1000000) //144Mhz //内封跑144M
// #define TCFG_PSRAM_INIT_CLK (96*1000000) //96Mhz //顶板外挂考虑降频
#if TCFG_NORFLASH_SFC_DEV_ENABLE && TCFG_PSRAM_DEV_ENABLE
#error "ext norflash and psram only support one dev !!!"
#endif
//*********************************************************************************//
// tp 配置 //
//*********************************************************************************//
#define TCFG_TOUCH_PANEL_ENABLE 1
#define TCFG_TP_CST816D_ENABLE 1
#define TCFG_TP_SLEEP_EN 1
#define TCFG_TP_INT_IO IO_PORTB_08 //TP中断脚
#define TCFG_TP_RESET_IO IO_PORTA_02 //TP复位脚
//*********************************************************************************//
// LCD 配置 //
//*********************************************************************************//
#define TCFG_SPI_LCD_ENABLE 1//spi lcd开关
#define TCFG_LCD_SPI_GC9B71_ENABLE 0
#define TCFG_LCD_SPI_ST77916_ENABLE 1
#define TCFG_LCD_SPI_SH8501A_ENABLE 0
#define TCFG_LCD_SPI_SH8601A_ENABLE 0
#define TCFG_LCD_QSPI_ST77903_V2_ENABLE 0
#define TCFG_LCD_SPI_RM69330_ENABLE 0
#define TCFG_LCD_MCU_JD5858_ENABLE 0
#define TCFG_LCD_RGB_ST7789V_ENABLE 0
#define TCFG_LCD_RGB_ENABLE 0
#define TCFG_LCD_MATCH_MODE 0
#define LCD_MATCH_BY_LOGO 0 //通过屏驱logo来匹配
#define LCD_LOGO "null"
#define TCFG_LCD_TE_USED_PEND 1
#define TCFG_LCD_TE_IO IO_PORTA_06 //TCFG_LCD_PIN_TE
#define TCFG_LCD_TE_QUICK_SYNC 1//te优化策略
#define TCFG_LCD_BL_IO IO_LCD_PG
#define TCFG_BACKLIGHT_PWM_MODE 2 // 0-on/off, 1-pwmled(no support), 2-mcpwm
#define TCFG_UI_SHUT_DOWN_TIME ENABLE // 自动息屏
#define TCFG_LCD_TP_USE_SAME_PWR ENABLE // lcd和tp 使用相同的电源
#if TCFG_LCD_TP_USE_SAME_PWR
#undef TCFG_TP_SLEEP_EN
#define TCFG_TP_SLEEP_EN DISABLE
#define LCD_POWER_DOWN_EN ENABLE
#define TP_POWER_DOWN_EN ENABLE
#endif
#define TCFG_GPU_DOUBLE_TASK_ENABLE ENABLE
//*********************************************************************************//
// MOTO 配置 //
//*********************************************************************************//
#define TCFG_MOTO_PWM_IO IO_MT_PG
//*********************************************************************************//
// rdec_key 配置 //
//*********************************************************************************//
#define TCFG_RDEC_KEY_ENABLE ENABLE_THIS_MOUDLE //是否使能RDEC按键
//RDEC0配置
#define TCFG_RDEC0_ECODEA_PORT IO_PORT_DP
#define TCFG_RDEC0_ECODEB_PORT IO_PORT_DM
#define TCFG_RDEC0_KEY0_VALUE 0
#define TCFG_RDEC0_KEY1_VALUE 1
//*********************************************************************************//
// p11 iic 配置 //
//*********************************************************************************//
#define TCFG_HW_I2C_P11_CLK_PORT TCFG_HW_I2C1_CLK_PORT
#define TCFG_HW_I2C_P11_DAT_PORT TCFG_HW_I2C1_DAT_PORT
#define TCFG_HW_I2C_P11_CLK TCFG_HW_I2C1_CLK
//*********************************************************************************//
// 充电 配置 (补充sdk_config_h) //
//*********************************************************************************//
#ifndef TCFG_CHARGE_NVDC_EN
#define TCFG_CHARGE_NVDC_EN TCFG_CHARGE_ENABLE
#endif
#define TCFG_CHANEG_DONT_ENTER_LOW_POWER ENABLE //充电不进低功耗
//*********************************************************************************//
// 看门狗配置 //
//*********************************************************************************//
#define WDT_APP_INIT_TIME WDT_16S //开机初始化的看门狗时间,适当给长一些
#define WDT_APP_RUN_TIME WDT_LRC_4S //程序正常运行的看门狗时间,用LRC看门狗准一点
/**************
*ANC配置
*************/
#define TCFG_AUDIO_ANC_ENABLE CONFIG_ANC_ENABLE //ANC总使能,根据global_bulid_cfg板级定义
// #define TCFG_ANC_TOOL_DEBUG_ONLINE DISABLE_THIS_MOUDLE //ANC工具蓝牙spp调试
#define TCFG_ANC_EXPORT_RAM_EN DISABLE_THIS_MOUDLE //ANCdebug数据释放RAM使能
#if TCFG_ANC_EXPORT_RAM_EN
#define TCFG_AUDIO_CVP_CODE_AT_RAM DISABLE_THIS_MOUDLE
#define TCFG_AUDIO_AAC_CODE_AT_RAM DISABLE_THIS_MOUDLE
#endif/*TCFG_ANC_EXPORT_RAM_EN*/
/*
*系统音量类型选择
*软件数字音量是指纯软件对声音进行运算后得到的
*硬件数字音量是指dac内部数字模块对声音进行运算后输出
*/
#define VOL_TYPE_DIGITAL 0 //软件数字音量(调节解码输出数据的音量)
#define VOL_TYPE_ANALOG 1 //(暂未支持)硬件模拟音量
#define VOL_TYPE_AD 2 //(暂未支持)联合音量(模拟数字混合调节)
#define VOL_TYPE_DIGITAL_HW 3 //硬件数字音量(调节DAC模块的硬件音量)
/*注意:ANC使能情况下使用软件数字音量*/
#if TCFG_AUDIO_ANC_ENABLE
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL
#else
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL_HW
#endif/*TCFG_AUDIO_ANC_ENABLE*/
/*
*通话的时候使用数字音量
*0:通话使用和SYS_VOL_TYPE一样的音量调节类型
*1:通话使用数字音量调节,更加平滑
*/
#define TCFG_CALL_USE_DIGITAL_VOLUME 0
//第三方清晰语音开发使能
// #define TCFG_CVP_DEVELOP_ENABLE DISABLE_THIS_MOUDLE
/*通话降噪模式配置*/
// #define CVP_ANS_MODE 0 [>传统降噪<]
// #define CVP_DNS_MODE 1 [>神经网络降噪<]
// #define TCFG_AUDIO_CVP_NS_MODE CVP_ANS_MODE
/*
* ENC(双mic降噪)配置
* 双mic降噪包括DMS_NORMAL和DMS_FLEXIBLE,在使能TCFG_AUDIO_DUAL_MIC_ENABLE
* 的前提下,根据具体需求,选择对应的DMS模式
*/
/*ENC(双mic降噪)使能*/
// #define TCFG_AUDIO_DUAL_MIC_ENABLE DISABLE_THIS_MOUDLE
/*DMS模式选择*/
// #define DMS_NORMAL 1 //普通双mic降噪(mic距离固定)
// #define DMS_FLEXIBLE 2 //适配mic距离不固定且距离比较远的情况,比如头戴式话务耳机
// #define TCFG_AUDIO_DMS_SEL DMS_NORMAL
/*ENC双mic配置主mic副mic对应的mic port*/
// #define DMS_MASTER_MIC0 0 //mic0是主mic
// #define DMS_MASTER_MIC1 1 //mic1是主mic
// #define TCFG_AUDIO_DMS_MIC_MANAGE DMS_MASTER_MIC0
/*双mic降噪/单麦mic降噪 DUT测试模式,配合设备测试mic频响和(双mic)降噪量*/
//MIC通道配置
// #if TCFG_AUDIO_DUAL_MIC_ENABLE
//#define TCFG_AUDIO_ADC_MIC_CHA (AUDIO_ADC_MIC_0 | AUDIO_ADC_MIC_1)
// #else
//#define TCFG_AUDIO_ADC_MIC_CHA AUDIO_ADC_MIC_0
// #endif[>TCFG_AUDIO_DUAL_MIC_ENABLE<]
/*MIC模式配置:单端隔直电容模式/差分隔直电容模式/单端省电容模式*/
// #if TCFG_AUDIO_ANC_ENABLE
/*注意:ANC使能情况下,使用差分mic*/
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_DIFF_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_DIFF_MODE
// #else
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_MODE
// #endif[>TCFG_AUDIO_ANC_ENABLE<]
/*
*>>MIC电源管理:根据具体方案,选择对应的mic供电方式
*(1)如果是多种方式混合,则将对应的供电方式或起来即可,比如(MIC_PWR_FROM_GPIO | MIC_PWR_FROM_MIC_BIAS)
*(2)如果使用固定电源供电(比如dacvdd),则配置成DISABLE_THIS_MOUDLE
*/
#define MIC_PWR_FROM_GPIO (1UL << 0) //使用普通IO输出供电
#define MIC_PWR_FROM_MIC_BIAS (1UL << 1) //使用内部mic_ldo供电(有上拉电阻可配)
#define MIC_PWR_FROM_MIC_LDO (1UL << 2) //使用内部mic_ldo供电
//配置MIC电源
// #define TCFG_AUDIO_MIC_PWR_CTL MIC_PWR_FROM_MIC_BIAS
/*提示音叠加配置*/
#define TCFG_WAV_TONE_MIX_ENABLE DISABLE
#define TCFG_MP3_TONE_MIX_ENABLE DISABLE
#define TCFG_WTG_TONE_MIX_ENABLE DISABLE
#define TCFG_WTS_TONE_MIX_ENABLE ENABLE
//*********************************************************************************//
// Spatial Audio Effect 空间音效配置 //
//*********************************************************************************//
// #define TCFG_AUDIO_SPATIAL_EFFECT_ENABLE DISABLE_THIS_MOUDLE
// #define TCFG_TWS_SPATIAL_AUDIO_AS_CHANNEL 'L'
/*独立任务里面跑空间音效*/
#define TCFG_AUDIO_EFFECT_TASK_EBABLE ENABLE_THIS_MOUDLE
/*空间音效在线调试*/
// #define TCFG_SPATIAL_EFFECT_ONLINE_ENABLE DISABLE_THIS_MOUDLE
/*空间音频传感器是否在解码任务读传感器数据*/
#define TCFG_SENSOR_DATA_READ_IN_DEC_TASK DISABLE_THIS_MOUDLE
/*传感器数据读取的频率间隔,单位ms*/
#define TCFG_SENSOR_DATA_READ_INTERVAL 20
/*空间音频独立EQ使能*/
#define TCFG_SPATIAL_EFFECT_EQ_ENABLE DISABLE_THIS_MOUDLE
/*陀螺仪数据导出配置:支持BT_SPP\UART载体导出*/
#define SENSOR_DATA_EXPORT_USE_UART 1
#define SENSOR_DATA_EXPORT_USE_SPP 2
#define TCFG_SENSOR_DATA_EXPORT_ENABLE DISABLE_THIS_MOUDLE
//*********************************************************************************//
// IIS 配置 //
//*********************************************************************************//
#define TCFG_IIS_ENABLE DISABLE_THIS_MOUDLE
#define TCFG_IIS_MODE (0) // 0:master 1:slave
#define TCFG_AUDIO_INPUT_IIS (ENABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_INPUT_DATAPORT_SEL ALINK_CH1
#define TCFG_AUDIO_OUTPUT_IIS (DISABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_OUTPUT_DATAPORT_SEL ALINK_CH0
#define TCFG_IIS_SAMPLE_RATE (16000L)
//*********************************************************************************//
// g-sensor配置 //
//*********************************************************************************//
#define TCFG_GSENSOR_ENABLE 0 //gSensor使能
#define TCFG_DA230_EN 0
#define TCFG_SC7A20_EN 0
#define TCFG_STK8321_EN 0
#define TCFG_IRSENSOR_ENABLE 0
#define TCFG_JSA1221_ENABLE 0
#define TCFG_GSENOR_USER_IIC_TYPE 0 //0:软件IIC 1:硬件IIC
//*********************************************************************************//
// imu-sensor配置 //
//*********************************************************************************//
#define TCFG_IMUSENSOR_ENABLE 1 //imu Sensor使能
//mpu6887 cfg
#define TCFG_MPU6887P_ENABLE 0
#define TCFG_MPU6887P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_MPU6887P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU6887P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU6887P_DETECT_IO (-1) //传感器中断io
#define TCFG_MPU6887P_AD0_SELETE_IO IO_PORTC_03 //iic地址选择io
//icm42607p cfg
#define TCFG_ICM42670P_ENABLE 0
#define TCFG_ICM42670P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_ICM42670P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_ICM42670P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_ICM42670P_DETECT_IO (-1) //传感器中断io
#define TCFG_ICM42670P_AD0_SELETE_IO (-1) //iic地址选择io
//mpu9250 cfg
#define TCFG_TP_MPU9250_ENABLE 0
#define TCFG_MPU9250_INTERFACE_TYPE 0 //不支持.0:iic, 1:spi
#define TCFG_MPU9250_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU9250_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU9250_DETECT_IO IO_PORTB_03 //传感器中断io
//sh3001 cfg
#define TCFG_SH3001_ENABLE 0
#define TCFG_SH3001_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_SH3001_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_SH3001_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_SH3001_DETECT_IO IO_PORTB_03 //传感器中断io
//qmi8658 cfg
#define TCFG_QMI8658_ENABLE 0
#define TCFG_QMI8658_INTERFACE_TYPE 0 //0:iic, 1:spi, 2:i3c
#define TCFG_QMI8658_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_QMI8658_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_QMI8658_DETECT_IO (-1) //传感器中断io
#define TCFG_QMI8658_AD0_SELETE_IO (-1) //iic地址选择io
//lsm6dsl cfg
#define TCFG_LSM6DSL_ENABLE 1
#define TCFG_LSM6DSL_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_LSM6DSL_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_LSM6DSL_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_LSM6DSL_DETECT_IO (-1) //传感器中断io
#define TCFG_LSM6DSL_AD0_SELETE_IO (-1) //iic地址选择io
//mpu6050 cfg
#define TCFG_MPU6050_EN 0
//qmc5883 cfg
/*
*imu-sensor power manager
*不用独立IO供电,则配置 NO_CONFIG_PORT
*/
#define TCFG_IMU_SENSOR_PWR_PORT IO_PORTD_05
//*********************************************************************************//
// 传感器与运动健康 配置 //
//*********************************************************************************//
//运动健康总开关
#define TCFG_SPORT_HEALTH_ENABLE ENABLE
#define TCFG_SENSOR_HUB_TASK_ENABLE DISABLE
//各模块开关
#define TCFG_SPORT_HEALTH_ALGO_GSENSOR ENABLE //gsensor算法
#define TCFG_SPORT_HEALTH_SPORT ENABLE //运动
#define TCFG_SPORT_HEALTH_DAILY_ACTIVE ENABLE //日常活动
#define TCFG_SPORT_HEALTH_SLEEP DISABLE //睡眠
#define TCFG_SPORT_HEALTH_HEART_RATE DISABLE //心率
#define TCFG_SPORT_HEALTH_BLOOD_OXYGEN DISABLE //血氧
#define TCFG_SPORT_HEALTH_DET_MENSE ENABLE //女性健康监测
//SENSOR HUB总开关
#define TCFG_SENSOR_HUB DISABLE
//P11 sensorhub开关
#define TCFG_SENSOR_HUB_P11 DISABLE
//common
#define TCFG_ALGO_STEP_COUNETER DISABLE
//p11
#define TCFG_ACCELER_P11_ENABLE DISABLE
#define TCFG_GYRO_P11_ENABLE DISABLE
#define TCFG_MAGNETIC_P11_ENABLE DISABLE
#define TCFG_VCHR11_P11_ENABLE DISABLE
#define TCFG_HRS3602_P11_ENABLE DISABLE
//master
#define TCFG_ACCELER_MASTER_ENABLE DISABLE
#define TCFG_GYRO_MASTER_ENABLE DISABLE
#define TCFG_MAGNETIC_MASTER_ENABLE DISABLE
#define TCFG_VCHR11_MASTER_ENABLE DISABLE
#define TCFG_HRS3602_MASTER_ENABLE DISABLE
//gsensor配置
#define TCFG_SENSOR_SC7A20_ENABLE DISABLE
//msensor配置
#define TCFG_SENSOR_MMC5603_ENABLE DISABLE
//*********************************************************************************//
// pay 配置 //
//*********************************************************************************//
#if CONFIG_JL_UI_ENABLE && TCFG_USER_BLE_ENABLE
#define TCFG_PAY_ALIOS_ENABLE 1
#else
#define TCFG_PAY_ALIOS_ENABLE 0
#endif
#define TCFG_PAY_ALIOS_WAY_T_HEAD 1 // 平头哥
#define TCFG_PAY_ALIOS_WAY_SEL TCFG_PAY_ALIOS_WAY_T_HEAD
#if (TCFG_PAY_ALIOS_WAY_SEL==TCFG_PAY_ALIOS_WAY_T_HEAD)
#define TCFG_PAY_ALIOS_PRODUCT_MODEL ""
#define TCFG_PAY_ALIOS_COMPANY_NAME "" //需要客户申请
#define ALIPAY_SE_FW_V2_0 1 //SE版本固件为2.0设置为1,否则设置为0
#define ALIPAY_SE_USE_RESET_PIN 0 //置1加密芯片采用reset管脚复位进低功耗,置0 上下电进低功耗
#define SE_POWER_GPIO 0 //使用GPIO口给SE芯片电源脚供电
#endif
//*********************************************************************************//
// 触摸配置 //
//*********************************************************************************//
#define TCFG_LPCTMU_ENABLE 0 //总开关
#define TCFG_LPCTMU_CH0_EN 0 //IO_PORTB_00
#define TCFG_LPCTMU_CH1_EN 1 //IO_PORTB_01
#define TCFG_LPCTMU_CH2_EN 0 //IO_PORTB_02
#define TCFG_LPCTMU_CH3_EN 0 //IO_PORTB_03
#define TCFG_LPCTMU_CH4_EN 0 //IO_PORTB_04
//*********************************************************************************//
// demo配置 //
//*********************************************************************************//
#define GPU_PORT_DEMO_ENABLE 0 //使能gpu_port_demo
#define GPU_DEMO_ENABLE 0 //运行gpu demo的总开关
//*********************************************************************************//
// 配置结束 //
//*********************************************************************************//
#endif //CONFIG_BOARD_JL7074_DEMO
#endif //CONFIG_BOARD_JL7074_DEMO_CFG_H
@@ -0,0 +1,105 @@
#ifndef CONFIG_BOARD_AC7074_DEMO_POST_BUILD_CFG_H
#define CONFIG_BOARD_AC7074_DEMO_POST_BUILD_CFG_H
/* 改文件只添加和isd_config.ini相关的配置,用以生成isd_config.ini */
/* 其他不相关的配置请勿添加在改文件 */
#ifdef CONFIG_BOARD_JL7074_DEMO
/* Following Macros Affect Periods Of Both Code Compiling And Post-build */
#define CONFIG_DOUBLE_BANK_ENABLE 0 //单双备份选择(若打开了改宏,FLASH结构变为双备份结构,适用于接入第三方协议的OTA, PS: JL-OTA同样支持双备份升级, 需要根据实际FLASH大小同时配置CONFIG_FLASH_SIZE)
#define CONFIG_UPDATE_JUMP_TO_MASK 0 //配置升级到loader的方式0为直接reset,1为跳转(适用于芯片电源由IO口KEEP住的方案,需要注意检查跳转前是否将使用DMA的硬件模块全部关闭)
#define CONFIG_ANC_ENABLE 0 //配置是否支持ANC
/* Above Macros Affect Periods Of Both Code Compiling And Post-build */
/* Following Macros Only For Post Bulid Configuaration */
#define CONFIG_DB_UPDATE_DATA_GENERATE_EN 0 //是否生成db_data.bin(用于第三方协议接入使用)
#define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 1 //ufw只生成1份4K对齐的代码
//config for supported chip version
#define CONFIG_SUPPORTED_CHIP_VERSION A,B,C
//DON'T MODIFY THIS CONFIG EXCEPT SDK PUBLISHER
#define CONFIG_CHIP_NAME AC707N //除了SDK发布者,请不要修改
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_PID AC707N //烧写或强制升级之前可以修改,之后升级要保持一致
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_VID 0.01 //烧写或强制升级之前可以修改,之后升级要保持一致
//Project with bluetooth,it must use OSC as PLL_SOURCE;
#define CONFIG_PLL_SOURCE_USING_LRC 0 //PLL时钟源选择 1:LRC 0:OSC
//config alignment size unit
#ifdef CONFIG_256K_FLASH
#define ALIGN_UNIT_256B 1 //FLASH对齐方式选择,如果是256K的FLASH,选择256BYTE对齐方式
#else
#define ALIGN_UNIT_256B 0
#endif
//partial platform check this config to select the uart IO for wired update
#define CONFIG_UART_UPDATE_PIN PB05
//isd_download loader/uboot/update_loader debug io config
//#define CONFIG_UBOOT_DEBUG_PIN PA05
//#define CONFIG_UBOOT_DEBUG_BAUD_RATE 1000000
//config long-press reset io pin,time,trigger level
#define CONFIG_RESET_PIN PB07 //io pin
#define CONFIG_RESET_TIME 08 //unit:second
#define CONFIG_RESET_LEVEL 0 //tigger level(0/1)
//reserved three custom cfg item for the future definition
//#define CONFIG_CUSTOM_CFG1_TYPE POWER_PIN
//#define CONFIG_CUSTOM_CFG1_VALUE PC01_1
//#define CONFIG_CUSTOM_CFG2_TYPE
//#define CONFIG_CUSTOM_CFG2_VALUE
//#define CONFIG_CUSTOM_CFG3_TYPE
//#define CONFIG_CUSTOM_CFG3_VALUE
//#define CONFIG_VDDIO_LVD_LEVEL 4 ////VDDIO_LVD挡位,0: 1.9V 1: 2.0V 2: 2.1V 3: 2.2V 4: 2.3V 5: 2.4V 6: 2.5V 7: 2.6V
//with single-bank mode,actual vm size should larger this VM_LEAST_SIZE,and dual bank mode,actual vm size equals this;
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_VM_OPT 1
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_BTIF_OPT 1
//reserved two custom cfg area for the future definition
//#define CONFIG_RESERVED_AREA1 EXIF1
#ifdef CONFIG_RESERVED_AREA1
#define CONFIG_RESERVED_AREA1_ADDR AUTO
#define CONFIG_RESERVED_AREA1_LEN 0x1000
#define CONFIG_RESERVED_AREA1_OPT 1
//#define CONFIG_RESERVED_AREA1_FILE anc_gains.bin
#endif
//#define CONFIG_RESERVED_AREA2 EXIF2
#ifdef CONFIG_RESERVED_AREA2
#define CONFIG_RESERVED_AREA2_ADDR AUTO
#define CONFIG_RESERVED_AREA2_LEN 0x1000
#define CONFIG_RESERVED_AREA2_OPT 1
//#define CONFIG_RESERVED_AREA2_FILE anc_gains.bin
#endif
#if (defined TCFG_CONFIG_DEBUG_RECORD_ENABLE && TCFG_CONFIG_DEBUG_RECORD_ENABLE)
#define CONFIG_DEBUG_ADDR AUTO
#define CONFIG_DEBUG_LEN 0x1000
#define CONFIG_DEBUG_OPT 0 //0: 擦除, 1:不操作
#endif
/* Above Macros Only For Post Bulid Configuaration */
#endif /* #ifdef CONFIG_BOARD_AC707N_DEMO */
#endif /* #ifndef CONFIG_BOARD_AC7074_DEMO_POST_BUILD_CFG_H */
@@ -0,0 +1,705 @@
/**
* @brief 彩屏仓(color_screen_charging_case)配置
*/
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".board_config.data.bss")
#pragma data_seg(".board_config.data")
#pragma const_seg(".board_config.text.const")
#pragma code_seg(".board_config.text")
#endif
#include "app_config.h"
#ifdef CONFIG_BOARD_JL707N_CSC_DEMO
#include "system/includes.h"
#include "app_main.h"
#include "rtc/rtc.h"
#include "spi.h"
#include "asm/sdmmc.h"
#include "asm/spi_hw.h"
#include "asm/lpctmu_hw.h"
#include "asm/psram_api.h"
#include "linein_dev.h"
#include "usb/device/usb_stack.h"
#include "usb/host/usb_storage.h"
#include "ui/ui_api.h"
#include "ui_manage.h"
#include "iic_api.h"
#include "ui/lcd/lcd_drive.h"
#include "include/norflash_sfc.h"
#include "fs/virfat_flash.h"
#include "alarm.h"
#include "data_storage.h"
#include "tp_api.h"
#include "gpadc.h"
#include "rdec_key.h"
#include "asm/espi.h"
#include "../sdk_config.c"
#define LOG_TAG_CONST BOARD
#define LOG_TAG "[707N]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if (CONFIG_BT_MODE != BT_NORMAL) || TCFG_NORMAL_SET_DUT_MODE
#if ((TCFG_RDEC0_ECODEA_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEA_PORT==IO_PORT_DM)) || \
((TCFG_RDEC0_ECODEB_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEB_PORT==IO_PORT_DM))
// 蓝牙测试会用到DPDM
#undef TCFG_RDEC_KEY_ENABLE
#define TCFG_RDEC_KEY_ENABLE DISABLE_THIS_MOUDLE
#endif
#endif
#if TCFG_APP_RTC_EN
static struct sys_time def_sys_time = { //初始化系统时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 0,
.sec = 0,
};
static struct sys_time def_alarm = { //初始化闹钟时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 5,
.sec = 0,
};
void rtc_event_isr(u32 event) //闹钟回调函数测试
{
if (event == MSYS_ALARM_WKUP_EVENT) {
alm_wakeup_isr();
} else if (event == MSYS_RTC_1HZ_EVENT) {
}
}
struct rtc_config_init rtc_dev_config = { //RTC初始化结构体
.default_sys_time = &def_sys_time, //配置默认系统时钟
.default_alarm = &def_alarm, //配置默认闹钟
.rtc_clk = CLK_SEL_LRC, // 配置时钟源
.alm_en = 1, //闹钟使能
.cbfun = rtc_event_isr,
//rtc闹钟回调函数
};
#endif
#if TCFG_PSRAM_DEV_ENABLE
PSRAM_PLATFORM_DATA_BEGIN(psram_config)
.power_port = TCFG_PSRAM_POWER_PORT,//power io
.port = TCFG_PSRAM_PORT_SEL ,//默认A口
.mode = TCFG_PSRAM_MODE,//4线读写
.init_clk = TCFG_PSRAM_INIT_CLK,//hz
PSRAM_PLATFORM_DATA_END()
#endif//TCFG_PSRAM_DEV_ENABLE
#if TCFG_SD0_ENABLE
extern void sdpg_config(int enable);
#define SDX_POWER_ALONE 1
#if (TCFG_SD0_POWER_SEL == SD_PWR_SDPG)
#define sd_power_config sdpg_config
#else
void sd_power_config(int enable)
{
//TODO: 使用普通io供电
if (enable) {
/* log_info("\n\n sd power enable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_OUTPUT_LOW);
} else {
/* log_info("\n\n sd power disable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_HIGHZ);
}
}
#endif
#if SDX_POWER_ALONE
static u8 sdx_power_enable = 0xff;
void sd_set_power(u8 enable)
{
/* enable = !!enable; */
// log_info("sd_set_power:%d, %d \n", sdx_power_enable, enable);
if (sdx_power_enable == enable) {
return;
}
sd_power_config(enable);
sdx_power_enable = enable;
}
#endif /* #if SDX_POWER_ALONE */
#if TCFG_SD_ALWAY_ONLINE_ENABLE
int sdmmc_0_io_detect(const struct sdmmc_platform_data *data)
{
return 1;
}
#endif /* #if TCFG_SD_ALWAY_ONLINE_ENABLE */
SD0_PLATFORM_DATA_BEGIN(sd0_data) = {
.port = {
TCFG_SD0_PORT_CMD,
TCFG_SD0_PORT_CLK,
TCFG_SD0_PORT_DA0,
TCFG_SD0_PORT_DA1,
TCFG_SD0_PORT_DA2,
TCFG_SD0_PORT_DA3,
},
.data_width = TCFG_SD0_DAT_MODE,
.speed = TCFG_SD0_CLK,
.detect_mode = TCFG_SD0_DET_MODE,
.priority = 3,
#if (TCFG_SD0_DET_MODE == SD_IO_DECT)
.detect_io = TCFG_SD0_DET_IO,
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_io_detect,
.power = sd_set_power,
/* .power = NULL, */
#elif (TCFG_SD0_DET_MODE == SD_CLK_DECT)
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_clk_detect,
.power = sd_set_power,
/* .power = NULL, */
#else
.detect_func = sdmmc_cmd_detect,
.power = NULL,
#endif
SD0_PLATFORM_DATA_END()
};
#endif /* #if TCFG_SD0_ENABLE */
// *INDENT-OFF*
#if TCFG_LPCTMU_ENABLE
LPCTMU_PLATFORM_DATA_BEGIN(lpctmu_pdata)
#if LPCTMU_ANA_CFG_ADAPTIVE
.aim_vol_delta = 800,
.aim_charge_khz = 2500,
#else
.hv_level = 3,
.lv_level = 0,
.cur_level = 7,
#endif
LPCTMU_PLATFORM_DATA_END();
LPCTMU_CFG_DATA_BEGIN(lpctmu_cfg)
.ch_en = ((TCFG_LPCTMU_CH0_EN << 0) | \
(TCFG_LPCTMU_CH1_EN << 1) | \
(TCFG_LPCTMU_CH2_EN << 2) | \
(TCFG_LPCTMU_CH3_EN << 3) | \
(TCFG_LPCTMU_CH4_EN << 4)),
.pdata = &lpctmu_pdata,
LPCTMU_CFG_DATA_END();
#endif
/************************** linein KEY ****************************/
#if TCFG_APP_LINEIN_EN
struct linein_dev_data linein_data = {
.enable = TCFG_APP_LINEIN_EN,
.port = NO_CONFIG_PORT,
.up = 1,
.down = 0,
.ad_channel = NO_CONFIG_PORT,
.ad_vol = 0,
};
#endif
#if TCFG_UI_ENABLE
#if TCFG_SPI_LCD_ENABLE
//推屏使用有专门硬件模块,不是普通spi模块,io固定,根据屏幕驱动类似输出时序
LCD_SPI_PLATFORM_DATA_BEGIN(lcd_spi_data) = {
#if (TCFG_NANDFLASH_DEV_ENABLE||TCFG_7074_EX_NORFLASH_CONFIG)//7074顶板差异
.pin_reset = IO_PORTA_03,
.pin_en = IO_PORTA_01 ,
.pin_en_ex = NO_CONFIG_PORT,
.pin_te = IO_PORTA_00,
.pin_bl = TCFG_LCD_PIN_BL,
#else
.pin_reset = TCFG_LCD_PIN_RESET,
.pin_en = IO_PORTC_01,
.pin_en_ex = IO_PORTC_02,
.pin_te = TCFG_LCD_PIN_TE,
.pin_bl = TCFG_LCD_PIN_BL,
#endif
LCD_SPI_PLATFORM_DATA_END()
};
const struct ui_devices_cfg ui_cfg_data = {
.type = TFT_LCD,
.private_data = (void *) &lcd_spi_data,
};
#endif /*TCFG_SPI_LCD_ENABLE*/
#endif /*TCFG_UI_ENABLE*/
const struct iic_master_config soft_iic_cfg_const[MAX_SOFT_IIC_NUM] = {
//soft iic0
#if 0
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C0_CLK_PORT,
.sda_io = TCFG_SW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C0_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
#if 0
//soft iic1
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C1_CLK_PORT,
.sda_io = TCFG_SW_I2C1_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C1_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
};
const struct iic_master_config hw_iic_cfg_const[MAX_HW_IIC_NUM] = {
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C0_CLK_PORT,
.sda_io = TCFG_HW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C0_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic0
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C_P11_CLK_PORT,
.sda_io = TCFG_HW_I2C_P11_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C_P11_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic_p11
};
#if (TCFG_HW_SPI1_ENABLE || TCFG_HW_SPI2_ENABLE)
const struct spi_platform_data spix_p_data[HW_SPI_MAX_NUM] = {
{
//spi0
},
#if SUPPORT_SPI1
{
//spi1
.port = {
TCFG_HW_SPI1_PORT_CLK, //clk any io
TCFG_HW_SPI1_PORT_DO, //do any io
TCFG_HW_SPI1_PORT_DI, //di any io
0xff, //d2 any io
0xff, //d3 any io
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI1_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI1_BAUD,
.mode = TCFG_HW_SPI1_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
#if (TCFG_HW_SPI1_BAUD == 32000000)
.cpha = 2,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#else
.cpha = 0,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#endif
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
#if SUPPORT_SPI2
{
//spi2
.port = {
TCFG_HW_SPI2_PORT_CLK, //clk any io
TCFG_HW_SPI2_PORT_DO, //D0
TCFG_HW_SPI2_PORT_DI, //DI/D1
TCFG_HW_SPI2_PORT_D2, //d2
TCFG_HW_SPI2_PORT_D3, //d3
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI2_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI2_BAUD,
.mode = TCFG_HW_SPI2_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
#if (TCFG_HW_SPI2_BAUD == 32000000)
.cpha = 2,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#else
.cpha = 0,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#endif
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
};
#endif
//--------------------------------------------------------------------------------------
//内置flash
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_mode_data)
.path = (const u8 *)"mnt/sdfile/app/MODE",
.start_addr = TCFG_SDFILE_FLASH_DEV_PATY_BASE,
.size = TCFG_SDFILE_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_data)
.path = (const u8 *)"mnt/sdfile/app/FATFSI",
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_DATA_STORAGE_FDB_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_watch_data_dev_data)
.start_addr =TCFG_DATA_FLASH_DEV_PATY_BASE,
.size =TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
//--------------------------------------------------------------------------------------
//这里是外挂norflash分区的配置
#if TCFG_NORFLASH_SFC_DEV_ENABLE
SFC_SPI_PLATFORM_DATA_BEGIN(sfc_spi_data)
.sfc_data_width = SFC_DATA_WIDTH_4,
.sfc_read_mode = SFC_RD_IO,
SFC_SPI_PLATFORM_DATA_END()
//fat分区(watch)
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_data)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
//exsdfile分区(mode)
#if TCFG_SDFILE_EXTERN_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_data_sdfile)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_SDFILE_FLASH_DEV_PATY_BASE,
.size = TCFG_SDFILE_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
//exsdfile分区(mode)
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_watch_data)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_DATA_FLASH_DEV_PATY_BASE,
.size = TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#endif
//--------------------------------------------------------------------------------------
//这里是外挂nandflash分区的配置
#if TCFG_NANDFLASH_DEV_ENABLE
/* nandflash驱动配置 */
NANDFLASH_DEV_PLATFORM_DATA_BEGIN(nandflash_dev_data) = {
.spi_hw_num = TCFG_FLASH_DEV_SPI_HW_NUM,
.spi_cs_port = TCFG_FLASH_DEV_SPI_CS_PORT,
.spi_read_width = TCFG_FLASH_DEV_FLASH_READ_WIDTH,//flash读数据的线宽
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1)
.spi_pdata = &spix_p_data[1],
#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2)
.spi_pdata = &spix_p_data[2],
#endif
};
#if TCFG_NANDFLASH_UI_FAT_ENABLE
//ui_fat使用
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(ui_fat_dev_data)
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE ,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_NANDFLASH_FAT_ENABLE
/* nandflash fat16 文件系统配置,多分区时使用 */
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(fat_nand_dev_data)
.start_addr = TCFG_NANDFLASH_FAT_BASE,
.size = TCFG_NANDFLASH_FAT_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(nandflash_sfc_dev_watch_data)
.start_addr = TCFG_DATA_FLASH_DEV_PATY_BASE,
.size = TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
extern const struct device_operations nandflash_ftl_ops;
extern const struct device_operations nandflash_sfc_ftl_ops;
extern const struct device_operations nandflash_fs_ftl_ops;
#endif // TCFG_NANDFLASH_DEV_ENABLE
const u32 g_res_nor_unencry_start_addr = 0; //temp, todo...
REGISTER_DEVICES(device_table) = {
#if TCFG_SD0_ENABLE
{ "sd0", &sd_dev_ops, (void *) &sd0_data},
#endif
#if TCFG_APP_LINEIN_EN
{ "linein", &linein_dev_ops, (void *) &linein_data},
#endif
#if TCFG_UDISK_ENABLE
{ "udisk0", &mass_storage_ops, NULL},
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
{"nand_flash", &nandflash_dev_ops, (void *) &nandflash_dev_data},
{"nandflash_ftl", &nandflash_ftl_ops, "nand_flash"},
#endif
#if TCFG_NANDFLASH_FAT_ENABLE
// nandflash fat16区
{TCFG_NANDFLASH_FAT_ROOT, &nandflash_sfc_ftl_ops, (void *)&fat_nand_dev_data},
#endif
#if TCFG_NANDFLASH_UI_FAT_ENABLE
//ui fat
{TCFG_NANDFLASH_UI_FAT_LOGO, &nandflash_sfc_ftl_ops, (void *)&ui_fat_dev_data},
#endif
#if TCFG_VIRFAT_FLASH_ENABLE
#if TCFG_NANDFLASH_DEV_ENABLE
//虚拟文件系统对接jl sdfile fat 文件系统设备入口,往下对接文件系统,往上对接物理设备
{ "virfat_flash", &virfat_flash_dev_ops, (void *)"nandflash_ftl"},
#else
//虚拟文件系统对接jl sdfile fat 文件系统设备入口,往下对接文件系统,往上对接物理设备
{ "virfat_flash", &virfat_flash_dev_ops, (void *)"res_nor"},
#endif
#endif
//res_nor 是物理设备入口
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
//使用内置flash 跑ui表盘
{ "res_nor", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_data},
#elif (TCFG_VIRFAT_EXT_FLASH_ENABLE && (!TCFG_NANDFLASH_DEV_ENABLE))
//使用外挂flash 跑ui表盘
{ "res_nor", &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_data},
#endif//TCFG_VIRFAT_INSERT_FLASH_ENABLE
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
//内置只读文件系统
{ "res_nor_mode", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_mode_data},
#elif TCFG_SDFILE_EXTERN_FLASH_ENABLE
//外挂只读文件系统
{ "res_nor_mode", &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_data_sdfile},
#endif
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
//用户数据放外挂
#if TCFG_NANDFLASH_DEV_ENABLE
{ TCFG_DATA_DEV_NAME, & nandflash_fs_ftl_ops, (void *) &nandflash_sfc_dev_watch_data},
#else
{ TCFG_DATA_DEV_NAME, &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_watch_data},
#endif
#elif TCFG_DATA_STORAGE_FDB_ENABLE
//用户数据放内置
{ TCFG_DATA_DEV_NAME, &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_watch_data_dev_data},
#endif
};
#if TCFG_SD_ALWAY_ONLINE_ENABLE
extern int sdx_dev_entry_lowpower(const char *sdx_name);
static int sdx_entry_lowpower(int param)
{
/* putchar('s'); */
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif /* #if TCFG_SD1_ENABLE */
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif /* #if TCFG_SD1_ENABLE */
return 0;
}
static void sdx_sleep_callback(void)
{
int argv[3];
argv[0] = (int)sdx_entry_lowpower;
argv[1] = 1;
/* argv[2] = ; */
int ret = os_taskq_post_type("app_core", Q_CALLBACK, 3, argv);
if (ret) {
log_info("post ret:%d \n", ret);
}
}
#else /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
extern void sdx_dev_detect_modify(u32 modify_time);
void sniff_hook(u32 slot, u8 num, u8 first_conn, int t_sniff)
{
if (num) {
if (first_conn) {
/* log_info("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 12);
}
} else {
/* log_info("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 3);
}
}
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
void board_init()
{
board_power_init();
#if TCFG_APP_RTC_EN
rtc_dev_init(&rtc_dev_config);
#endif
adc_init();
#if TCFG_APP_FM_EN
log_info(">> Func:%s, Line:%d, call: fm_dev_init Func!\n", __func__, __LINE__);
fm_dev_init((void *)(&fm_dev_data));
#endif
#if TCFG_RDEC_KEY_ENABLE
rdec_key_init();
#endif
#if TCFG_LPCTMU_ENABLE
lpctmu_init(&lpctmu_cfg);
#endif
#if TCFG_PAY_ALIOS_ENABLE
extern void alipay_upay_init(void);
alipay_upay_init();
#endif /* #if TCFG_PAY_ALIOS_ENABLE */
#if TCFG_SD0_ENABLE
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(4);
#endif
#endif
#if TCFG_PSRAM_DEV_ENABLE
psram_init(&psram_config);
#endif
}
/*-----------------------------------------------------------------------
*进入、退出低功耗函数回调状态,函数单核操作、关中断,请勿做耗时操作
*
*/
#include "iokey.h"
#include "irkey.h"
#include "adkey.h"
#include "gpio_config.h"
void board_sleep_enter_callback()
{
/* 此函数禁止添加打印 */
putchar('<');
}
void board_sleep_exit_callback()
{
putchar('>');
#if TCFG_SD_ALWAY_ONLINE_ENABLE
#if SDX_POWER_ALONE // sd使用单独的电源才能用
if (sdx_power_enable && (sdx_power_enable != 0xff)) {
sdx_sleep_callback();
}
#endif /* #if SDX_POWER_ALONE */
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
}
////关机回调执行顺序
//power_soff_callback()->do_platform_uninitcall()->board_poweroff_uninit->gpio_config_soft_poweroff()
//关机的注册的段
void board_poweroff_uninit()
{
//用户进行自己模块的关闭操作
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(0);
#endif
#if TCFG_NORFLASH_DEV_ENABLE
extern void ex_norflash_poweroff(void);
ex_norflash_poweroff();
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
extern void nandflash_poweroff(int priv);
struct device*dev = (struct device*)dev_open("nandflash_ftl",NULL);
ASSERT(dev);
while((int)atomic_read(&dev->ref)){
dev_close((void*)dev);
}
nandflash_poweroff(0);
#endif
/*关机后,霍尔检测io不需要响应中断。避免干扰*/
p33_io_wakeup_port_uninit(TCFG_HALL_PORT);
}
/* platform_uninitcall(board_poweroff_uninit); */
//设置关机保持状态的io
void board_gpio_config_soft_poweroff(u32 *gpio_config)
{
#if TCFG_UI_ENABLE
lcd_bl_ctrl(0);
#endif
PORT_PROTECT(IO_LCD_PG);
//设置后关机io会保持原来状态
// PORT_PROTECT(IO_PORTB_01);
// PORT_PROTECT(IO_PORTB_01);
}
#endif
@@ -0,0 +1,844 @@
/**
* @brief 彩屏仓(color_screen_charging_case)配置
*/
#ifndef CONFIG_BOARD_AC707N_CSC_DEMO_CFG_H
#define CONFIG_BOARD_AC707N_CSC_DEMO_CFG_H
#include "board_ac707n_csc_demo_global_build_cfg.h"
#ifdef CONFIG_BOARD_JL707N_CSC_DEMO
#define CONFIG_SDFILE_ENABLE
//*********************************************************************************//
// 配置开始 //
//*********************************************************************************//
#define ENABLE_THIS_MOUDLE 1
#define DISABLE_THIS_MOUDLE 0
#define ENABLE 1
#define DISABLE 0
#define NO_CONFIG_PORT (-1)
// NTC配置 //
//*********************************************************************************//
#define NTC_DET_EN 0
#define NTC_POWER_IO IO_PORTC_03
#define NTC_DETECT_IO IO_PORTC_04
#define NTC_DET_AD_CH (0x4) //根据adc_api.h修改通道号
#define NTC_DET_UPPER 235 //正常范围AD值上限,0度时
#define NTC_DET_LOWER 34 //正常范围AD值下限,45度时
//*********************************************************************************//
// FPGA 配置 //
//*********************************************************************************//
#define FPGA_DEVELOP_IOKEY 0
//*********************************************************************************//
// FLASH 配置 //
//*********************************************************************************//
//FLASH公共配置
#if TCFG_USER_BLE_ENABLE
#define TCFG_FLASH_ERASE_WAIT_BLE ENABLE //flash擦除前等待ble状态
#else
#define TCFG_FLASH_ERASE_WAIT_BLE DISABLE //flash擦除前等待ble状态
#endif
//外挂flash配置
#define TCFG_NORFLASH_SFC_DEV_ENABLE TCFG_NORFLASH_DEV_ENABLE //外挂flash驱动
#if TCFG_NORFLASH_SFC_DEV_ENABLE
#define TCFG_EX_FLASH_POWER_IO IO_PORTC_10 // 外置flash电源脚
#define CONFIG_EX_FLASH_POWER_IO PC10 // NULL // 外置flash电源脚。不接IO时填NULL或者屏蔽掉该宏定义
#define CONFIG_EX_FLASH_POWER_IO_CTRL 1 // 0:power_io低电平时供电;1:高电平时供电 (针对io口低电平控制mos管导通来供电的情况)
#endif//TCFG_NORFLASH_SFC_DEV_ENABLE
//NANDFLASH配置
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
//电源配置
#define TCFG_EX_FLASH_POWER_IO IO_PORTC_11 // 外置flash电源脚
#define CONFIG_EX_FLASH_POWER_IO PC11 // NULL // 外置flash电源脚。不接IO时填NULL或者屏蔽掉该宏定义
#define CONFIG_EX_FLASH_POWER_IO_CTRL 1 // 0:power_io低电平时供电;1:高电平时供电 (针对io口低电平控制mos管导通来供电的情况)
#define TCFG_FLASH_DEV_FLASH_READ_WIDTH SPI_MODE_UNIDIR_4BIT//SPI_MODE_BIDIR_1BIT//
#define TCFG_FLASH_DEV_SPI_HW_NUM 2// 1: SPI1 2: SPI2
#define TCFG_FLASH_DEV_SPI_CS_PORT IO_PORTC_01
// NANDFLASH驱动配置
#define TCFG_NANDFLASH_HEX_ID 0xc891 // flash ID, 十六进制值的字符串形式
#define TCFG_NANDFLASH_ECC_MASK 0x30
#define TCFG_NANDFLASH_ECC_ERR 0x20
#define TCFG_NANDFLASH_PLANE_SEL 0
#define TCFG_NANDFLASH_WRITE_ENABLE_POS 0
#define TCFG_NANDFLASH_QUAD_MODE_DUM_NUM 1
#define TCFG_NANDFLASH_QUAD_MODE_QE 1
#define TCFG_NANDFLASH_BLOCK_NUMBER 1024
#define TCFG_NANDFLASH_CAPACITY (128 * 1024 * 1024) // flash 总实际容量
#define TCFG_NANDFLASH_PAGE_NUM 64
#define TCFG_NANDFLASH_PAGE_SIZE 2048
#define TCFG_NANDFLASH_OOB_SIZE 64
#define TCFG_NANDFLASH_OOB_USER_OFFSET_0 0
#define TCFG_NANDFLASH_OOB_USER_OFFSET_1 0
#define TCFG_NANDFLASH_OOB_USER_SIZE_0 64
#define TCFG_NANDFLASH_OOB_USER_SIZE_1 0
#define TCFG_NANDFLASH_MAX_ERASE_CNT 100000 // 最大擦写次数,一般默认10万次
#endif//TCFG_NANDFLASH_DEV_ENABLE
//*********************************************************************************//
// FLASH dev分区 //
//*********************************************************************************//
//分区配置
#if (!TCFG_UI_ENABLE)//不开UI时,不使用文件系统
#define TCFG_VIRFAT_FLASH_ENABLE DISABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE DISABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE 0x1D6000 //
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 // 160K
#else//(!TCFG_UI_ENABLE)
//------------------------------------------------------------------------------------------
//ONLY_INSIDE_FLASH//只有内置flash,按8M规划
#if ((!TCFG_NORFLASH_DEV_ENABLE)&&(!TCFG_NANDFLASH_DEV_ENABLE)&&(CONFIG_FLASH_SIZE == 8*1024*1024))
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE ENABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE ENABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE DISABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x580000 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE 0x17e000 // 1.5M - 8k开始 内置FLASH虚拟文件系统空间基础地址
//virfat
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x6FE000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE 0xD8000 //864K
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE 0x7D6000//(TCFG_WATCH_INSERT_FLASH_BASE + TCFG_WATCH_INSERT_FLASH_SIZE)
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
//------------------------------------------------------------------------------------------
//EXT_NOR_FLASH//外挂NOR fals
#elif (TCFG_NORFLASH_DEV_ENABLE)
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE ENABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE ENABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE ENABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
#define TCFG_DATA_FLASH_DEV_PATY_BASE (CONFIG_EXTERN_FLASH_SIZE -TCFG_DATA_FLASH_DEV_PATY_SIZE)
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x580000 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE (CONFIG_EXTERN_FLASH_SIZE -TCFG_SDFILE_FLASH_DEV_PATY_SIZE-TCFG_DATA_FLASH_DEV_PATY_SIZE)
//virfat
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x000000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE (CONFIG_EXTERN_FLASH_SIZE -TCFG_SDFILE_FLASH_DEV_PATY_SIZE-TCFG_DATA_FLASH_DEV_PATY_SIZE)
//------------------------------------------------------------------------------------------
//EXT_NAND_FLASH//外挂NAND falsh
#elif (TCFG_NANDFLASH_DEV_ENABLE)
#define TCFG_VIRFAT_FLASH_ENABLE DISABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE ENABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
#define TCFG_NANDFLASH_UI_FAT_ENABLE ENABLE //nandflash ui_fat分区使能(与virfat互斥,可以超过32M)
#define TCFG_NANDFLASH_FAT_ENABLE ENABLE //nandflash fat分区使能
#define TCFG_NANDFLASH_UNUSED_FILE_SYSTEM DISABLE //不挂文件系统
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE 0
//uifat/virfat
#define TCFG_NANDFLASH_UI_FAT_LOGO "UI_FAT"
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x000000
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE 0x02000000 //32M (使用virfat时不能超过32M,使用ui_fat没有限制)
// nandflash 分区 fat16 区域地址和大小,与ini工具文件对应,即ini文件中,fat16文件的XX_ADR参数与BASE保持参数一致
#define TCFG_NANDFLASH_FAT_ROOT "fat_nand" // fat16 分区的设备名(存音乐)
#define TCFG_NANDFLASH_FAT_BASE TCFG_VIRFAT_FLASH_DEV_PATY_SIZE // fat16 分区起始地址
#define TCFG_NANDFLASH_FAT_SIZE (90 * 1024 * 1024) // fat16 分区容量大小
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE (TCFG_NANDFLASH_FAT_SIZE+TCFG_NANDFLASH_FAT_BASE)
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
#if( TCFG_VIRFAT_FLASH_ENABLE && TCFG_NANDFLASH_UI_FAT_ENABLE)
#error"config error,only enable one"
#endif
//------------------------------------------------------------------------------------------
#else
#error "FLASH_DEV_PART_CONFIG_ERROR !!!"
#endif
#endif
#define TCFG_DATA_STORAGE_ENABLE (TCFG_DATA_STORAGE_FDB_ENABLE || TCFG_DATA_STORAGE_VM_ENABLE ||TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE)
//*********************************************************************************//
// PSRAM 配置 //
//*********************************************************************************//
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
#define TCFG_PSRAM_POWER_PORT IO_PORTB_05//7074使用pb5供电
#else
#define TCFG_PSRAM_POWER_PORT IO_FS_PG2
#endif
#define TCFG_PSRAM_PORT_SEL PSRAM_PORT_SEL_PORTA
#define TCFG_PSRAM_MODE PSRAM_MODE_4_WIRE_CMD4_ADR4_DAT4
#define TCFG_PSRAM_INIT_CLK (144* 1000000) //144Mhz //内封跑144M
// #define TCFG_PSRAM_INIT_CLK (96*1000000) //96Mhz //顶板外挂考虑降频
#if TCFG_NORFLASH_SFC_DEV_ENABLE && TCFG_PSRAM_DEV_ENABLE
#error "ext norflash and psram only support one dev !!!"
#endif
//*********************************************************************************//
// tp 配置 //
//*********************************************************************************//
#define TCFG_TOUCH_PANEL_ENABLE TCFG_UI_ENABLE
#define TCFG_TP_CST816D_ENABLE 1
#define TCFG_TP_AXS5106_ENABLE 0
#define TCFG_TP_SLEEP_EN 1
#define TCFG_TP_INT_IO IO_PORTB_01 //TP中断脚
#define TCFG_TP_RESET_IO IO_PORTB_00 //TP复位脚
//*********************************************************************************//
// LCD 配置 //
//*********************************************************************************//
#define TCFG_SPI_LCD_ENABLE TCFG_UI_ENABLE//spi lcd开关
#define TCFG_LCD_NB3030_172X320 0
#define TCFG_LCD_SPI_GC9B71_ENABLE 0
#define TCFG_LCD_SPI_ST77916_ENABLE 0
#define TCFG_LCD_SPI_SH8501A_ENABLE 0
#define TCFG_LCD_SPI_ICNA3306_ENABLE 0
#define TCFG_LCD_SPI_SH8601A_ENABLE 0
#define TCFG_LCD_QSPI_ST77903_V2_ENABLE 0
#define TCFG_LCD_SPI_RM69330_ENABLE 0
#define TCFG_LCD_MCU_JD5858_ENABLE 0
#define TCFG_LCD_RGB_ST7789V_ENABLE 0
#define TCFG_LCD_RGB_ENABLE 0
#define TCFG_LCD_MATCH_MODE 0
#define TCFG_LCD_SPI_JD9853_320x172_ENABLE 0
#define TCFG_LCD_GC9307_172X320 1
#define LCD_MATCH_BY_LOGO 0 //通过屏驱logo来匹配
#define LCD_LOGO "null"
#define TCFG_LCD_TE_USED_PEND 1
#define TCFG_7074_EX_NORFLASH_CONFIG DISABLE//开发板使用,7074顶板外挂nand/nor开这个宏,改跳线
#if ((defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)||TCFG_7074_EX_NORFLASH_CONFIG)
#define TCFG_LCD_TE_IO IO_PORTA_00//TCFG_LCD_PIN_TE
#else
#define TCFG_LCD_TE_IO TCFG_LCD_PIN_TE
#endif
#define TCFG_LCD_TE_QUICK_SYNC 0//1//te优化策略 //彩屏仓公版使用GC9307无te
#define TCFG_LCD_BL_IO IO_LCD_PG
#define TCFG_BACKLIGHT_PWM_MODE 2 // 0-on/off, 1-pwmled(no support), 2-mcpwm
#define TCFG_UI_SHUT_DOWN_TIME ENABLE // 自动息屏
#define TCFG_LCD_TP_USE_SAME_PWR ENABLE // lcd和tp 使用相同的电源
#if TCFG_LCD_TP_USE_SAME_PWR
#undef TCFG_TP_SLEEP_EN
#define TCFG_TP_SLEEP_EN ENABLE
#define LCD_POWER_DOWN_EN DISABLE//ENABLE//ENABLE
#define TP_POWER_DOWN_EN DISABLE//ENABLE//ENABLE
#endif
#define TCFG_GPU_DOUBLE_TASK_ENABLE ENABLE
#define TCFG_LCD_BUF_IN_STATIC_RAM_ENABLE ENABLE //屏幕显存buf使用静态ram,可以优化帧率
#define TCFG_LCD_BUF_DYNAMIC_LINE_ENABLE DISABLE //屏幕显存高度动态计算,复杂场景下可以减少屏幕需要的ram
#define TP_DOUBLE_CLICK_WAKEUP ENABLE // 双击亮屏
//*********************************************************************************//
// MOTO 配置 //
//*********************************************************************************//
#define TCFG_MOTO_PWM_IO NO_CONFIG_PORT
//*********************************************************************************//
// rdec_key 配置 //
//*********************************************************************************//
#define TCFG_RDEC_KEY_ENABLE DISABLE_THIS_MOUDLE //是否使能RDEC按键
//RDEC0配置
#define TCFG_RDEC0_ECODEA_PORT IO_PORT_DP
#define TCFG_RDEC0_ECODEB_PORT IO_PORT_DM
#define TCFG_RDEC0_KEY0_VALUE 0
#define TCFG_RDEC0_KEY1_VALUE 1
//*********************************************************************************//
// p11 iic 配置 //
//*********************************************************************************//
#define TCFG_HW_I2C_P11_CLK_PORT TCFG_HW_I2C1_CLK_PORT
#define TCFG_HW_I2C_P11_DAT_PORT TCFG_HW_I2C1_DAT_PORT
#define TCFG_HW_I2C_P11_CLK TCFG_HW_I2C1_CLK
//*********************************************************************************//
// 充电 配置 (补充sdk_config_h) //
//*********************************************************************************//
#ifndef TCFG_CHARGE_NVDC_EN
#define TCFG_CHARGE_NVDC_EN TCFG_CHARGE_ENABLE
#endif
#define TCFG_CHANEG_DONT_ENTER_LOW_POWER ENABLE //充电不进低功耗
//*********************************************************************************//
// 看门狗配置 //
//*********************************************************************************//
#define WDT_APP_INIT_TIME WDT_16S //开机初始化的看门狗时间,适当给长一些
#define WDT_APP_RUN_TIME WDT_LRC_4S //程序正常运行的看门狗时间,用LRC看门狗准一点
/**************
*ANC配置
*************/
#define TCFG_AUDIO_ANC_ENABLE CONFIG_ANC_ENABLE //ANC总使能,根据global_bulid_cfg板级定义
// #define TCFG_ANC_TOOL_DEBUG_ONLINE DISABLE_THIS_MOUDLE //ANC工具蓝牙spp调试
#define TCFG_ANC_EXPORT_RAM_EN DISABLE_THIS_MOUDLE //ANCdebug数据释放RAM使能
#if TCFG_ANC_EXPORT_RAM_EN
#define TCFG_AUDIO_CVP_CODE_AT_RAM DISABLE_THIS_MOUDLE
#define TCFG_AUDIO_AAC_CODE_AT_RAM DISABLE_THIS_MOUDLE
#endif/*TCFG_ANC_EXPORT_RAM_EN*/
/*
*系统音量类型选择
*软件数字音量是指纯软件对声音进行运算后得到的
*硬件数字音量是指dac内部数字模块对声音进行运算后输出
*/
#define VOL_TYPE_DIGITAL 0 //软件数字音量(调节解码输出数据的音量)
#define VOL_TYPE_ANALOG 1 //(暂未支持)硬件模拟音量
#define VOL_TYPE_AD 2 //(暂未支持)联合音量(模拟数字混合调节)
#define VOL_TYPE_DIGITAL_HW 3 //硬件数字音量(调节DAC模块的硬件音量)
/*注意:ANC使能情况下使用软件数字音量*/
#if TCFG_AUDIO_ANC_ENABLE
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL
#else
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL_HW
#endif/*TCFG_AUDIO_ANC_ENABLE*/
/*
*通话的时候使用数字音量
*0:通话使用和SYS_VOL_TYPE一样的音量调节类型
*1:通话使用数字音量调节,更加平滑
*/
#define TCFG_CALL_USE_DIGITAL_VOLUME 0
//第三方清晰语音开发使能
// #define TCFG_CVP_DEVELOP_ENABLE DISABLE_THIS_MOUDLE
/*通话降噪模式配置*/
// #define CVP_ANS_MODE 0 [>传统降噪<]
// #define CVP_DNS_MODE 1 [>神经网络降噪<]
// #define TCFG_AUDIO_CVP_NS_MODE CVP_ANS_MODE
/*
* ENC(双mic降噪)配置
* 双mic降噪包括DMS_NORMAL和DMS_FLEXIBLE,在使能TCFG_AUDIO_DUAL_MIC_ENABLE
* 的前提下,根据具体需求,选择对应的DMS模式
*/
/*ENC(双mic降噪)使能*/
// #define TCFG_AUDIO_DUAL_MIC_ENABLE DISABLE_THIS_MOUDLE
/*DMS模式选择*/
// #define DMS_NORMAL 1 //普通双mic降噪(mic距离固定)
// #define DMS_FLEXIBLE 2 //适配mic距离不固定且距离比较远的情况,比如头戴式话务耳机
// #define TCFG_AUDIO_DMS_SEL DMS_NORMAL
/*ENC双mic配置主mic副mic对应的mic port*/
// #define DMS_MASTER_MIC0 0 //mic0是主mic
// #define DMS_MASTER_MIC1 1 //mic1是主mic
// #define TCFG_AUDIO_DMS_MIC_MANAGE DMS_MASTER_MIC0
/*双mic降噪/单麦mic降噪 DUT测试模式,配合设备测试mic频响和(双mic)降噪量*/
//MIC通道配置
// #if TCFG_AUDIO_DUAL_MIC_ENABLE
//#define TCFG_AUDIO_ADC_MIC_CHA (AUDIO_ADC_MIC_0 | AUDIO_ADC_MIC_1)
// #else
//#define TCFG_AUDIO_ADC_MIC_CHA AUDIO_ADC_MIC_0
// #endif[>TCFG_AUDIO_DUAL_MIC_ENABLE<]
/*MIC模式配置:单端隔直电容模式/差分隔直电容模式/单端省电容模式*/
// #if TCFG_AUDIO_ANC_ENABLE
/*注意:ANC使能情况下,使用差分mic*/
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_DIFF_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_DIFF_MODE
// #else
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_MODE
// #endif[>TCFG_AUDIO_ANC_ENABLE<]
/*
*>>MIC电源管理:根据具体方案,选择对应的mic供电方式
*(1)如果是多种方式混合,则将对应的供电方式或起来即可,比如(MIC_PWR_FROM_GPIO | MIC_PWR_FROM_MIC_BIAS)
*(2)如果使用固定电源供电(比如dacvdd),则配置成DISABLE_THIS_MOUDLE
*/
#define MIC_PWR_FROM_GPIO (1UL << 0) //使用普通IO输出供电
#define MIC_PWR_FROM_MIC_BIAS (1UL << 1) //使用内部mic_ldo供电(有上拉电阻可配)
#define MIC_PWR_FROM_MIC_LDO (1UL << 2) //使用内部mic_ldo供电
//配置MIC电源
// #define TCFG_AUDIO_MIC_PWR_CTL MIC_PWR_FROM_MIC_BIAS
/*提示音叠加配置*/
#define TCFG_WAV_TONE_MIX_ENABLE DISABLE
#define TCFG_MP3_TONE_MIX_ENABLE DISABLE
#define TCFG_WTG_TONE_MIX_ENABLE DISABLE
#define TCFG_WTS_TONE_MIX_ENABLE ENABLE
//*********************************************************************************//
// Spatial Audio Effect 空间音效配置 //
//*********************************************************************************//
// #define TCFG_AUDIO_SPATIAL_EFFECT_ENABLE DISABLE_THIS_MOUDLE
// #define TCFG_TWS_SPATIAL_AUDIO_AS_CHANNEL 'L'
/*独立任务里面跑空间音效*/
#define TCFG_AUDIO_EFFECT_TASK_EBABLE ENABLE_THIS_MOUDLE
/*空间音效在线调试*/
// #define TCFG_SPATIAL_EFFECT_ONLINE_ENABLE DISABLE_THIS_MOUDLE
/*空间音频传感器是否在解码任务读传感器数据*/
#define TCFG_SENSOR_DATA_READ_IN_DEC_TASK DISABLE_THIS_MOUDLE
/*传感器数据读取的频率间隔,单位ms*/
#define TCFG_SENSOR_DATA_READ_INTERVAL 20
/*空间音频独立EQ使能*/
#define TCFG_SPATIAL_EFFECT_EQ_ENABLE DISABLE_THIS_MOUDLE
/*陀螺仪数据导出配置:支持BT_SPP\UART载体导出*/
#define SENSOR_DATA_EXPORT_USE_UART 1
#define SENSOR_DATA_EXPORT_USE_SPP 2
#define TCFG_SENSOR_DATA_EXPORT_ENABLE DISABLE_THIS_MOUDLE
//*********************************************************************************//
// IIS 配置 //
//*********************************************************************************//
#define TCFG_IIS_ENABLE DISABLE_THIS_MOUDLE
#define TCFG_IIS_MODE (0) // 0:master 1:slave
#define TCFG_AUDIO_INPUT_IIS (ENABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_INPUT_DATAPORT_SEL ALINK_CH1
#define TCFG_AUDIO_OUTPUT_IIS (DISABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_OUTPUT_DATAPORT_SEL ALINK_CH0
#define TCFG_IIS_SAMPLE_RATE (16000L)
//*********************************************************************************//
// g-sensor配置 //
//*********************************************************************************//
#define TCFG_GSENSOR_ENABLE 0 //gSensor使能
#define TCFG_DA230_EN 0
#define TCFG_SC7A20_EN 0
#define TCFG_STK8321_EN 0
#define TCFG_IRSENSOR_ENABLE 0
#define TCFG_JSA1221_ENABLE 0
#define TCFG_GSENOR_USER_IIC_TYPE 0 //0:软件IIC 1:硬件IIC
//*********************************************************************************//
// imu-sensor配置 //
//*********************************************************************************//
#define TCFG_IMUSENSOR_ENABLE 0 //imu Sensor使能
//mpu6887 cfg
#define TCFG_MPU6887P_ENABLE 0
#define TCFG_MPU6887P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_MPU6887P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU6887P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU6887P_DETECT_IO (-1) //传感器中断io
#define TCFG_MPU6887P_AD0_SELETE_IO IO_PORTC_03 //iic地址选择io
//icm42607p cfg
#define TCFG_ICM42670P_ENABLE 0
#define TCFG_ICM42670P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_ICM42670P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_ICM42670P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_ICM42670P_DETECT_IO (-1) //传感器中断io
#define TCFG_ICM42670P_AD0_SELETE_IO (-1) //iic地址选择io
//mpu9250 cfg
#define TCFG_TP_MPU9250_ENABLE 0
#define TCFG_MPU9250_INTERFACE_TYPE 0 //不支持.0:iic, 1:spi
#define TCFG_MPU9250_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU9250_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU9250_DETECT_IO IO_PORTB_03 //传感器中断io
//sh3001 cfg
#define TCFG_SH3001_ENABLE 0
#define TCFG_SH3001_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_SH3001_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_SH3001_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_SH3001_DETECT_IO IO_PORTB_03 //传感器中断io
//qmi8658 cfg
#define TCFG_QMI8658_ENABLE 0
#define TCFG_QMI8658_INTERFACE_TYPE 0 //0:iic, 1:spi, 2:i3c
#define TCFG_QMI8658_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_QMI8658_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_QMI8658_DETECT_IO (-1) //传感器中断io
#define TCFG_QMI8658_AD0_SELETE_IO (-1) //iic地址选择io
//lsm6dsl cfg
#define TCFG_LSM6DSL_ENABLE 1
#define TCFG_LSM6DSL_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_LSM6DSL_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_LSM6DSL_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_LSM6DSL_DETECT_IO (-1) //传感器中断io
#define TCFG_LSM6DSL_AD0_SELETE_IO (-1) //iic地址选择io
//mpu6050 cfg
#define TCFG_MPU6050_EN 0
//qmc5883 cfg
/*
*imu-sensor power manager
*不用独立IO供电,则配置 NO_CONFIG_PORT
*/
#define TCFG_IMU_SENSOR_PWR_PORT IO_PORTD_05
//*********************************************************************************//
// 传感器与运动健康 配置 //
//*********************************************************************************//
//运动健康总开关
#define TCFG_SPORT_HEALTH_ENABLE DISABLE
#define TCFG_SENSOR_HUB_TASK_ENABLE DISABLE
//各模块开关
#define TCFG_SPORT_HEALTH_ALGO_GSENSOR DISABLE//DISABLE //gsensor算法
#define TCFG_SPORT_HEALTH_SPORT DISABLE//DISABLE //运动
#define TCFG_SPORT_HEALTH_DAILY_ACTIVE DISABLE//DISABLE //日常活动
#define TCFG_SPORT_HEALTH_SLEEP DISABLE//DISABLE //睡眠
#define TCFG_SPORT_HEALTH_HEART_RATE DISABLE//DISABLE //心率
#define TCFG_SPORT_HEALTH_BLOOD_OXYGEN DISABLE//DISABLE //血氧
#define TCFG_SPORT_HEALTH_DET_MENSE DISABLE//DISABLE //女性健康监测
//SENSOR HUB总开关
#define TCFG_SENSOR_HUB DISABLE
//P11 sensorhub开关
#define TCFG_SENSOR_HUB_P11 DISABLE
//common
#define TCFG_ALGO_STEP_COUNETER DISABLE
#define TCFG_ACCELER_SLEEP_ENABLE DISABLE
//p11
#define TCFG_ACCELER_P11_ENABLE DISABLE
#define TCFG_GYRO_P11_ENABLE DISABLE
#define TCFG_MAGNETIC_P11_ENABLE DISABLE
#define TCFG_VCHR11_P11_ENABLE DISABLE
#define TCFG_HRS3602_P11_ENABLE DISABLE
//master
#define TCFG_ACCELER_MASTER_ENABLE DISABLE
#define TCFG_GYRO_MASTER_ENABLE DISABLE
#define TCFG_MAGNETIC_MASTER_ENABLE DISABLE
#define TCFG_VCHR11_MASTER_ENABLE DISABLE
#define TCFG_HRS3602_MASTER_ENABLE DISABLE
//gsensor配置
#define TCFG_SENSOR_SC7A20_ENABLE DISABLE
//msensor配置
#define TCFG_SENSOR_MMC5603_ENABLE DISABLE
//*********************************************************************************//
// pay 配置 //
//*********************************************************************************//
#if CONFIG_JL_UI_ENABLE && TCFG_USER_BLE_ENABLE && (CONFIG_BT_MODE == BT_NORMAL)
#define TCFG_PAY_ALIOS_ENABLE 0
#else
#define TCFG_PAY_ALIOS_ENABLE 0
#endif
#define TCFG_PAY_ALIOS_WAY_T_HEAD 1 // 平头哥
#define TCFG_PAY_ALIOS_WAY_SEL TCFG_PAY_ALIOS_WAY_T_HEAD
#if (TCFG_PAY_ALIOS_WAY_SEL==TCFG_PAY_ALIOS_WAY_T_HEAD)
#define TCFG_PAY_ALIOS_PRODUCT_MODEL ""
#define TCFG_PAY_ALIOS_COMPANY_NAME "" //需要客户申请
#define ALIPAY_SE_FW_V2_0 1 //SE版本固件为2.0设置为1,否则设置为0
#define ALIPAY_SE_USE_RESET_PIN 0 //置1加密芯片采用reset管脚复位进低功耗,置0 上下电进低功耗
#define SE_POWER_GPIO 0 //使用GPIO口给SE芯片电源脚供电
#endif
//*********************************************************************************//
// 触摸配置 //
//*********************************************************************************//
#define TCFG_LPCTMU_ENABLE 0 //总开关
#define TCFG_LPCTMU_CH0_EN 0 //IO_PORTB_00
#define TCFG_LPCTMU_CH1_EN 1 //IO_PORTB_01
#define TCFG_LPCTMU_CH2_EN 0 //IO_PORTB_02
#define TCFG_LPCTMU_CH3_EN 0 //IO_PORTB_03
#define TCFG_LPCTMU_CH4_EN 0 //IO_PORTB_04
//*********************************************************************************//
// demo配置 //
//*********************************************************************************//
#define GPU_PORT_DEMO_ENABLE 0 //使能gpu_port_demo
#define GPU_DEMO_ENABLE 0 //运行gpu demo的总开关
//*********************************************************************************//
// Find my 配置 //
//*********************************************************************************//
#define TCFG_FINDMY_ENABLE 0
//*********************************************************************************//
// emitter配置 //
//*********************************************************************************//
#if TCFG_USER_EMITTER_ENABLE
#ifdef TCFG_BT_SUPPORT_HFP_AG
#undef TCFG_BT_SUPPORT_HFP_AG
#endif
#define TCFG_BT_SUPPORT_HFP_AG 1 // HFP AG
#endif
//*********************************************************************************//
// 产测配置 //
//*********************************************************************************//
#define PRODUCT_TEST_ENABLE DISABLE
#define PT_IO_TX_PIN IO_PORT_DM
#define PT_IO_RX_PIN IO_PORT_DP
#define PT_CHECK_OT 10000
#define PT_GPIO_ENABLE DISABLE
#define PT_GSENSOR_ENABLE DISABLE
#define PT_MOTOR_ENABLE DISABLE
#define PT_SD_ENABLE DISABLE
#define PT_HR_ENABLE DISABLE
#define PT_SPEAKER_MIC_ENABLE DISABLE
#define PT_GPIO_CHECK_LCD_TP DISABLE // 使用GPIO检查LCD_TP
#if PRODUCT_TEST_ENABLE
//公版rdec复用了dpdm
#undef TCFG_RDEC_KEY_ENABLE
#define TCFG_RDEC_KEY_ENABLE DISABLE
#endif
//*********************************************************************************//
// 彩屏仓相关 配置 //
//*********************************************************************************//
#define TCFG_COLOR_SCREEN_CHARGING_CASE_ENABLE ENABLE
//*********************************************************************************//
// 彩屏仓 蓝牙应用 相关配置 //
//*********************************************************************************//
#define TCFG_EARPHONE_PROTOCOL ENABLE //耳机功能
#if TCFG_EARPHONE_PROTOCOL
#define TCFG_BLE_POWER_ON_PAGE ENABLE //开机主动搜索BLE设备一段时间,关闭是一直搜索
#define TCFG_BLE_POWERON_PAGE_TIME (30*1000L) //开机搜索ble 从机时间
#define TCFG_BLE_RECONN_TIME (30*1000L) //异常断链后的回连时间
#define RCSP_MULTI_BLE_EN ENABLE
#endif
#define TCFG_CSC_BT_APP ENABLE //app应用
//*********************************************************************************//
// 彩屏仓 屏幕 相关配置 //
//*********************************************************************************//
#define TCFG_AUTO_POWER_OFF_TIME 360 //灭屏状态下自动关机时间 min
#define DRAW_X_DIV_EN ENABLE //UI横屏设计,使能X方向分块,让分块buf与scanline扫描方向一致
#if DRAW_X_DIV_EN
#define DRAW_BUF_ROTATE DISABLE //ENABLE//如果横屏竖推,需要使能BUF旋转,横屏横推则不需要,带TE屏可以使用横屏横推,不带TE屏必须要横屏竖推
#endif
//*********************************************************************************//
// 彩屏仓 电源 相关配置 //
//*********************************************************************************//
#define TCFG_SCREEN_AUTO_POWERON_ENABLE ENABLE //上电自动开机,检测到电池插入自动开机
#define TCFG_HOLD_TO_POWER_ON ENABLE //按键开机使能,使用此功能需要关闭上电开机
#define TCFG_HOLD_TO_POWER_ON_TIME (4) //按键开机时间/秒,不超过8秒,因为8秒强制复位,在jlstudio配置
//*********************************************************************************//
// 彩屏仓 独有功能 IO 相关配置 //
//*********************************************************************************//
// ** 充电相关配置 **
#define TCFG_SCREEN_USB_PIN IO_LDOIN_DET //插入检测
#define TCFG_SCREEN_CHARGE_FULL_PIN IO_PORTB_08 //满电检测
#define TCFG_SCREEN_CHRAGE_BAT_DET_PIN NO_CONFIG_PORT //电量检测
#define TCFG_SCREEN_CHARGE_STOP_PIN NO_CONFIG_PORT //停止充电
#define TCFG_SCREEN_CHARGE_BOOST_PIN IO_PORTB_08 //升压控制io
#define TCFG_SCREEN_CHARGE_PWR_PIN IO_MT_PG //升压输出耳机控制
#define TCFG_SCREEN_CHARGE_LDO_DET_PIN IO_PORTC_03 //升压输出检测
#define TCFG_SCREEN_L_EAR_PIN IO_PORTA_02 //左耳通讯
#define TCFG_SCREEN_R_EAR_PIN IO_PORTA_04 //右耳通讯
#define TCFG_SCREEN_CHARGE_IC_TX_PIN IO_PORTA_02 //充电ic通讯
#define TCFG_SCREEN_CHARGE_IC_RX_PIN IO_PORTA_04 //充电ic通讯
// ** 更多IO配置 **
#define TCFG_SCREEN_HALL_PIN IO_PORTB_02 //霍尔
//*********************************************************************************//
// 彩屏仓 霍尔传感器 相关配置 //
//*********************************************************************************//
#define TCFG_HALL_PORT TCFG_SCREEN_HALL_PIN //hall传感器的IO
//*********************************************************************************//
// 彩屏仓 充电 串口 相关配置 //
//*********************************************************************************//
//COMMON
#define TCFG_CHARGE_BOX_ENABLE ENABLE //充电舱模块开启宏
#define TCFG_CHARGE_MOUDLE_OUTSIDE ENABLE //使用外置充电模块
#define TCFG_USB_KEY_UPDATE_ENABLE DISABLE //USB插入升级使能
#define TCFG_WIRELESS_ENABLE DISABLE //是否支持无线充
#define TCFG_LDO_DET_ENABLE ENABLE //是否支持升压检测
#define TCFG_CHARGE_BOX_SOFT_POWER_OFF_IO_CTRL_ENABLE ENABLE //一些外设(如某些升压芯片)休眠时需要设置上下拉来维持关闭态
#define TCFG_HANDSHAKE_ENABLE DISABLE //充电握手协议
#define TCFG_TEMPERATURE_ENABLE DISABLE //过温充电保护使能(给充电盒充电)
#define TCFG_CURRENT_LIMIT_ENABLE DISABLE //充电过流保护使能(给耳机充电)
#define TCFG_SHORT_PROTECT_ENABLE DISABLE //充电过程中短路保护使能(给耳机充电)
#define TCFG_CHARGE_BOX_UI_ENABLE DISABLE //充电舱LED_UI开启宏
#define TCFG_CHARGGBOX_AUTO_SHUT_DOWN_TIME 8 //充电仓自动休眠时间 单位秒
#define TCFG_CHARGE_FULL_ENTER_SOFTOFF DISABLE //充电舱整机充满电后是否要进入soft power off
#define TCFG_CHARGE_BOX_AUTO_WAKEUP DISABLE //充电仓休眠后可配置时间自动唤醒
#define AUTO_WAKEUP_TIME_SEC 2592000 //默认定时一个月唤醒
#define CUSTOM_BATTERY_CURVE_MANAGEMENT ENABLE //自定义电池曲线
//功能配置
#define TCFG_USB_ONLE_DET_IO TCFG_SCREEN_USB_PIN //检测USB插入拔出配置,如果为NO_CONFIG_PORT则选ldoin为检测脚
#define TCFG_CHARGE_FULL_DET_IO TCFG_SCREEN_CHARGE_FULL_PIN //满电检测IO配置如果为NO_CONFIG_PORT则根据电压检测
#define TCFG_CHARGE_FULL_VOLTAGE (420)
#define TCFG_STOP_CHARGE_IO TCFG_SCREEN_CHARGE_STOP_PIN //停止充电控制脚-高阻时正常充电 输出1时充电截止
#define TCFG_BOOST_CTRL_IO TCFG_SCREEN_CHARGE_BOOST_PIN //升压控制IO
#define TCFG_BAT_DET_IO TCFG_SCREEN_CHRAGE_BAT_DET_PIN //电池电量检测IO(使用外部分压检测时需要配置)
#define TCFG_BAT_DET_AD_CH AD_CH_PMU_VBAT //电池电量检测AD通道
#if TCFG_LDO_DET_ENABLE
#define TCFG_CHG_LDO_DET_IO TCFG_SCREEN_CHARGE_LDO_DET_PIN //5V升压是否在成功检测IO
#define TCFG_CHG_LDO_DET_AD_CH AD_CH_IO_PC3 //5V升压是否在成功检测AD通道
#endif
//耳机相关
#define TCFG_CHARGEBOX_L_PORT TCFG_SCREEN_L_EAR_PIN //充电盒和左耳通信的IO口需要为高压IO
#define TCFG_CHARGEBOX_R_PORT TCFG_SCREEN_R_EAR_PIN //充电盒和右耳通信的IO口需要为高压IO
//PWR控制方式根据电路设计去选择
#define TCFG_PWR_CTRL_IO TCFG_SCREEN_CHARGE_PWR_PIN //耳机电源开关控制引脚
#define PWR_CTRL_TYPE_PU_PD 0 //定义:上下拉方式控制
#define PWR_CTRL_TYPE_OUTPUT_0 1 //定义:输出0使能(选择高压IO的时候配成该选项)
#define PWR_CTRL_TYPE_OUTPUT_1 2 //定义:输出1使能
#define TCFG_PWR_CTRL_TYPE PWR_CTRL_TYPE_OUTPUT_0 //选择输出模式
//ledui
#if TCFG_CHARGE_BOX_UI_ENABLE
#define TCFG_CHGBOX_UI_TIMERLED DISABLE //timer模拟的PWM呼吸灯,不支持亮灯进入低功耗
#define TCFG_CHGBOX_UI_PWMLED ENABLE //pwmled模块支持低功耗亮灯
#define CHG_LED_MODE DISABLE //timerLED模式有效 ENABLE--高亮 DISABLE--低亮, PWMLED模式请修改 PWM_LED_TWO_IO_CONNECT 这个宏定义
#define CHG_RED_LED_IO NO_CONFIG_PORT
#define CHG_GREEN_LED_IO NO_CONFIG_PORT
#define CHG_BLUE_LED_IO NO_CONFIG_PORT
#if (defined(CONFIG_DEBUG_ENABLE) && (TCFG_UART0_TX_PORT == IO_PORT_DM))
#undef CHG_GREEN_LED_IO
#define CHG_GREEN_LED_IO NO_CONFIG_PORT
#endif
#endif// TCFG_CHARGE_BOX_UI_ENABLE
//限流检测
#if TCFG_CURRENT_LIMIT_ENABLE
#define TCFG_CURRENT_DET_IO NO_CONFIG_PORT //检测电流的IO,定义了TCFG_CURRENT_LIMIT_ENABLE才有效
#define TCFG_CURRENT_DET_AD_CH AD_CH_PB6 //耳机充电电流检测AD通道
#endif
//短路保护
#if TCFG_SHORT_PROTECT_ENABLE
#define TCFG_SHORT_PROTECT_IO NO_CONFIG_PORT //短路保护检测IO
#if TCFG_LDO_DET_ENABLE && (TCFG_CHG_LDO_DET_IO == TCFG_SHORT_PROTECT_IO)
#error "短路保护和升压检测IO冲突"
#endif
#endif// TCFG_SHORT_PROTECT_ENABLE
//温度保护
#if TCFG_TEMPERATURE_ENABLE
#define TCFG_CHARGE_TEMP_IO NO_CONFIG_PORT
#define TCFG_CHARGE_TEMP_AD_CH AD_CH_PA3
#define TCFG_CHARGE_EXTERN_UP_ENABLE DISABLE //是否使用外部上拉
#if TCFG_CHARGE_EXTERN_UP_ENABLE
#define TCFG_RES_UP 100 //外部上拉值在这里修改
#else
#define TCFG_RES_UP 100 //内部上拉默认10K
#endif
#endif// TCFG_TEMPERATURE_ENABLE
//握手
#if TCFG_HANDSHAKE_ENABLE
#define TCFG_HANDSHAKE_IO NO_CONFIG_PORT //握手IO
#endif
//无线充
#if TCFG_WIRELESS_ENABLE
#define TCFG_WPC_COMM_IO NO_CONFIG_PORT //无线充电通信IO
#define TCFG_WL_AD_DET_IO NO_CONFIG_PORT //无线充电AD检测IO
#define TCFG_WL_AD_DET_CH NO_CONFIG_PORT //无线充电AD检测通道
#define TCFG_DCDC_CTRL_EN DISABLE //无线充电是否使能dcdc控制
#define TCFG_DCDC_EN_IO NO_CONFIG_PORT //无线充电dcdc使能IO
#endif
//usb key
#if (TCFG_CLOCK_SYS_SRC == SYS_CLOCK_INPUT_PLL_RCL)//免晶振时,USB key不能用
#undef TCFG_USB_KEY_UPDATE_ENABLE
#define TCFG_USB_KEY_UPDATE_ENABLE DISABLE
#endif
//pc模式
#if TCFG_CHARGE_BOX_ENABLE && TCFG_PC_ENABLE
#undef USB_DEVICE_CLASS_CONFIG
#define USB_DEVICE_CLASS_CONFIG (MASSSTORAGE_CLASS)
#endif
//充电ic
#define TCFG_CHARGE_IC_AC982 DISABLE //充电ic ac982
#define TCFG_CHARGE_IC_SY7609 ENABLE //充电ic sy7609
//充电ic通讯
#define TCFG_SCREEN_CHARGE_IC_BAUD_RATE 115200
#if TCFG_CHARGE_IC_AC982
#define TCFG_CHARGE_IC_MANAGER_MODE_ENABLE ENABLE //充电ic管理仓和耳机充电
#else
#define TCFG_CHARGE_IC_MANAGER_MODE_ENABLE DISABLE //主控管理仓和耳机充电
#endif
//开机充电
// #ifdef TCFG_CHARGE_OFF_POWERON_EN
// #undef TCFG_CHARGE_OFF_POWERON_EN
// #endif
#define TCFG_CHARGE_OFF_POWERON_EN ENABLE
#define TCFG_BOARD_707N_AC982_TEST_ENABLE TCFG_CHARGE_IC_AC982 //982开发板配置
#if TCFG_BOARD_707N_AC982_TEST_ENABLE
#undef TCFG_TP_INT_IO
#define TCFG_TP_INT_IO IO_PORTA_10 //TP中断脚
#undef TCFG_TP_RESET_IO
#define TCFG_TP_RESET_IO IO_PORTA_11 //TP复位脚
#undef TCFG_DEBUG_UART_TX_PIN
#define TCFG_DEBUG_UART_TX_PIN IO_PORTC_00
#endif//TCFG_BOARD_707N_AC982_TEST_ENABLE
//*********************************************************************************//
// 配置结束 //
//*********************************************************************************//
#endif //CONFIG_BOARD_JL707N_CSC_DEMO
#endif //CONFIG_BOARD_JL707N_CSC_DEMO_CFG_H
@@ -0,0 +1,105 @@
#ifndef CONFIG_BOARD_AC707N_CSC_DEMO_POST_BUILD_CFG_H
#define CONFIG_BOARD_AC707N_CSC_DEMO_POST_BUILD_CFG_H
/* 改文件只添加和isd_config.ini相关的配置,用以生成isd_config.ini */
/* 其他不相关的配置请勿添加在改文件 */
#ifdef CONFIG_BOARD_JL707N_CSC_DEMO
/* Following Macros Affect Periods Of Both Code Compiling And Post-build */
#define CONFIG_DOUBLE_BANK_ENABLE 0 //单双备份选择(若打开了改宏,FLASH结构变为双备份结构,适用于接入第三方协议的OTA, PS: JL-OTA同样支持双备份升级, 需要根据实际FLASH大小同时配置CONFIG_FLASH_SIZE)
#define CONFIG_UPDATE_JUMP_TO_MASK 0 //配置升级到loader的方式0为直接reset,1为跳转(适用于芯片电源由IO口KEEP住的方案,需要注意检查跳转前是否将使用DMA的硬件模块全部关闭)
#define CONFIG_ANC_ENABLE 0 //配置是否支持ANC
/* Above Macros Affect Periods Of Both Code Compiling And Post-build */
/* Following Macros Only For Post Bulid Configuaration */
#define CONFIG_DB_UPDATE_DATA_GENERATE_EN 0 //是否生成db_data.bin(用于第三方协议接入使用)
#define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 1 //ufw只生成1份4K对齐的代码
//config for supported chip version
#define CONFIG_SUPPORTED_CHIP_VERSION A,B,C
//DON'T MODIFY THIS CONFIG EXCEPT SDK PUBLISHER
#define CONFIG_CHIP_NAME AC707N //除了SDK发布者,请不要修改
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_PID AC707N //烧写或强制升级之前可以修改,之后升级要保持一致
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_VID 0.01 //烧写或强制升级之前可以修改,之后升级要保持一致
//Project with bluetooth,it must use OSC as PLL_SOURCE;
#define CONFIG_PLL_SOURCE_USING_LRC 0 //PLL时钟源选择 1:LRC 0:OSC
//config alignment size unit
#ifdef CONFIG_256K_FLASH
#define ALIGN_UNIT_256B 1 //FLASH对齐方式选择,如果是256K的FLASH,选择256BYTE对齐方式
#else
#define ALIGN_UNIT_256B 0
#endif
//partial platform check this config to select the uart IO for wired update
#define CONFIG_UART_UPDATE_PIN PB05
//isd_download loader/uboot/update_loader debug io config
//#define CONFIG_UBOOT_DEBUG_PIN PA05
//#define CONFIG_UBOOT_DEBUG_BAUD_RATE 1000000
//config long-press reset io pin,time,trigger level
#define CONFIG_RESET_PIN PB01 //io pin
#define CONFIG_RESET_TIME 08 //unit:second
#define CONFIG_RESET_LEVEL 0 //tigger level(0/1)
//reserved three custom cfg item for the future definition
//#define CONFIG_CUSTOM_CFG1_TYPE POWER_PIN
//#define CONFIG_CUSTOM_CFG1_VALUE PC01_1
//#define CONFIG_CUSTOM_CFG2_TYPE
//#define CONFIG_CUSTOM_CFG2_VALUE
//#define CONFIG_CUSTOM_CFG3_TYPE
//#define CONFIG_CUSTOM_CFG3_VALUE
//#define CONFIG_VDDIO_LVD_LEVEL 4 ////VDDIO_LVD挡位,0: 1.9V 1: 2.0V 2: 2.1V 3: 2.2V 4: 2.3V 5: 2.4V 6: 2.5V 7: 2.6V
//with single-bank mode,actual vm size should larger this VM_LEAST_SIZE,and dual bank mode,actual vm size equals this;
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_VM_OPT 1
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_BTIF_OPT 1
//reserved two custom cfg area for the future definition
//#define CONFIG_RESERVED_AREA1 EXIF1
#ifdef CONFIG_RESERVED_AREA1
#define CONFIG_RESERVED_AREA1_ADDR AUTO
#define CONFIG_RESERVED_AREA1_LEN 0x1000
#define CONFIG_RESERVED_AREA1_OPT 1
//#define CONFIG_RESERVED_AREA1_FILE anc_gains.bin
#endif
//#define CONFIG_RESERVED_AREA2 EXIF2
#ifdef CONFIG_RESERVED_AREA2
#define CONFIG_RESERVED_AREA2_ADDR AUTO
#define CONFIG_RESERVED_AREA2_LEN 0x1000
#define CONFIG_RESERVED_AREA2_OPT 1
//#define CONFIG_RESERVED_AREA2_FILE anc_gains.bin
#endif
#if (defined TCFG_CONFIG_DEBUG_RECORD_ENABLE && TCFG_CONFIG_DEBUG_RECORD_ENABLE)
#define CONFIG_DEBUG_ADDR AUTO
#define CONFIG_DEBUG_LEN 0x1000
#define CONFIG_DEBUG_OPT 0 //0: 擦除, 1:不操作
#endif
/* Above Macros Only For Post Bulid Configuaration */
#endif /* #ifdef CONFIG_BOARD_AC707N_CSC_DEMO */
#endif /* #ifndef CONFIG_BOARD_AC707N_CSC_DEMO_POST_BUILD_CFG_H */
@@ -0,0 +1,719 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".board_config.data.bss")
#pragma data_seg(".board_config.data")
#pragma const_seg(".board_config.text.const")
#pragma code_seg(".board_config.text")
#endif
#include "app_config.h"
#ifdef CONFIG_BOARD_JL707N_DEMO
#include "system/includes.h"
#include "app_main.h"
#include "rtc/rtc.h"
#include "spi.h"
#include "asm/sdmmc.h"
#include "asm/spi_hw.h"
#include "asm/lpctmu_hw.h"
#include "asm/psram_api.h"
#include "linein_dev.h"
#include "usb/device/usb_stack.h"
#include "usb/host/usb_storage.h"
#include "ui/ui_api.h"
#include "ui_manage.h"
#include "iic_api.h"
#include "ui/lcd/lcd_drive.h"
#include "include/norflash_sfc.h"
#include "fs/virfat_flash.h"
#include "alarm.h"
#include "data_storage.h"
#include "tp_api.h"
#include "gpadc.h"
#include "rdec_key.h"
#include "asm/espi.h"
#include "../sdk_config.c"
#include "nandflash.h"
#include "uvc_device.h"
#include "device/device.h"
#if (CONFIG_BT_MODE != BT_NORMAL) || TCFG_NORMAL_SET_DUT_MODE
#if ((TCFG_RDEC0_ECODEA_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEA_PORT==IO_PORT_DM)) || \
((TCFG_RDEC0_ECODEB_PORT==IO_PORT_DP) || (TCFG_RDEC0_ECODEB_PORT==IO_PORT_DM))
// 蓝牙测试会用到DPDM
#undef TCFG_RDEC_KEY_ENABLE
#define TCFG_RDEC_KEY_ENABLE DISABLE_THIS_MOUDLE
#endif
#endif
#if TCFG_APP_RTC_EN
static struct sys_time def_sys_time = { //初始化系统时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 0,
.sec = 0,
};
static struct sys_time def_alarm = { //初始化闹钟时间
.year = 2020,
.month = 1,
.day = 1,
.hour = 0,
.min = 5,
.sec = 0,
};
void rtc_event_isr(u32 event) //闹钟回调函数测试
{
if (event == MSYS_ALARM_WKUP_EVENT) {
alm_wakeup_isr();
} else if (event == MSYS_RTC_1HZ_EVENT) {
}
}
struct rtc_config_init rtc_dev_config = { //RTC初始化结构体
.default_sys_time = &def_sys_time, //配置默认系统时钟
.default_alarm = &def_alarm, //配置默认闹钟
.rtc_clk = CLK_SEL_LRC, // 配置时钟源
.alm_en = 1, //闹钟使能
.cbfun = rtc_event_isr,
//rtc闹钟回调函数
};
#endif
#if TCFG_PSRAM_DEV_ENABLE
PSRAM_PLATFORM_DATA_BEGIN(psram_config)
.power_port = TCFG_PSRAM_POWER_PORT,//power io
.port = TCFG_PSRAM_PORT_SEL ,//默认A口
.mode = TCFG_PSRAM_MODE,//4线读写
.init_clk = TCFG_PSRAM_INIT_CLK,//hz
PSRAM_PLATFORM_DATA_END()
#endif//TCFG_PSRAM_DEV_ENABLE
#if TCFG_SD0_ENABLE
extern void sdpg_config(int enable);
#define SDX_POWER_ALONE 1
#if (TCFG_SD0_POWER_SEL == SD_PWR_SDPG)
#define sd_power_config sdpg_config
#else
void sd_power_config(int enable)
{
//TODO: 使用普通io供电
if (enable) {
/* printf("\n\n sd power enable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_OUTPUT_LOW);
} else {
/* printf("\n\n sd power disable \n\n"); */
gpio_set_mode(IO_PORT_SPILT(TCFG_SD0_POWER_PORT), PORT_HIGHZ);
}
}
#endif
#if SDX_POWER_ALONE
static u8 sdx_power_enable = 0xff;
void sd_set_power(u8 enable)
{
/* enable = !!enable; */
// y_printf("sd_set_power:%d, %d \n", sdx_power_enable, enable);
if (sdx_power_enable == enable) {
return;
}
sd_power_config(enable);
sdx_power_enable = enable;
}
#endif /* #if SDX_POWER_ALONE */
#if TCFG_SD_ALWAY_ONLINE_ENABLE
int sdmmc_0_io_detect(const struct sdmmc_platform_data *data)
{
return 1;
}
#endif /* #if TCFG_SD_ALWAY_ONLINE_ENABLE */
SD0_PLATFORM_DATA_BEGIN(sd0_data) = {
.port = {
TCFG_SD0_PORT_CMD,
TCFG_SD0_PORT_CLK,
TCFG_SD0_PORT_DA0,
TCFG_SD0_PORT_DA1,
TCFG_SD0_PORT_DA2,
TCFG_SD0_PORT_DA3,
},
.data_width = TCFG_SD0_DAT_MODE,
.speed = TCFG_SD0_CLK,
.detect_mode = TCFG_SD0_DET_MODE,
.priority = 3,
#if (TCFG_SD0_DET_MODE == SD_IO_DECT)
.detect_io = TCFG_SD0_DET_IO,
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_io_detect,
.power = sd_set_power,
/* .power = NULL, */
#elif (TCFG_SD0_DET_MODE == SD_CLK_DECT)
.detect_io_level = TCFG_SD0_DET_IO_LEVEL,
.detect_func = sdmmc_0_clk_detect,
.power = sd_set_power,
/* .power = NULL, */
#else
.detect_func = sdmmc_cmd_detect,
.power = NULL,
#endif
SD0_PLATFORM_DATA_END()
};
#endif /* #if TCFG_SD0_ENABLE */
// *INDENT-OFF*
#if TCFG_LPCTMU_ENABLE
LPCTMU_PLATFORM_DATA_BEGIN(lpctmu_pdata)
#if LPCTMU_ANA_CFG_ADAPTIVE
.aim_vol_delta = 800,
.aim_charge_khz = 2500,
#else
.hv_level = 3,
.lv_level = 0,
.cur_level = 7,
#endif
LPCTMU_PLATFORM_DATA_END();
LPCTMU_CFG_DATA_BEGIN(lpctmu_cfg)
.ch_en = ((TCFG_LPCTMU_CH0_EN << 0) | \
(TCFG_LPCTMU_CH1_EN << 1) | \
(TCFG_LPCTMU_CH2_EN << 2) | \
(TCFG_LPCTMU_CH3_EN << 3) | \
(TCFG_LPCTMU_CH4_EN << 4)),
.pdata = &lpctmu_pdata,
LPCTMU_CFG_DATA_END();
#endif
/************************** linein KEY ****************************/
#if TCFG_APP_LINEIN_EN
struct linein_dev_data linein_data = {
.enable = TCFG_APP_LINEIN_EN,
.port = NO_CONFIG_PORT,
.up = 1,
.down = 0,
.ad_channel = NO_CONFIG_PORT,
.ad_vol = 0,
};
#endif
#if TCFG_UI_ENABLE
#if TCFG_SPI_LCD_ENABLE
//推屏使用有专门硬件模块,不是普通spi模块,io固定,根据屏幕驱动类似输出时序
LCD_SPI_PLATFORM_DATA_BEGIN(lcd_spi_data) = {
#if (TCFG_NANDFLASH_DEV_ENABLE||TCFG_7074_EX_NORFLASH_CONFIG)//7074顶板差异
.pin_reset = IO_PORTA_03,
.pin_en = IO_PORTA_01 ,
.pin_en_ex = NO_CONFIG_PORT,
.pin_te = IO_PORTA_00,
.pin_bl = TCFG_LCD_PIN_BL,
#else
.pin_reset = TCFG_LCD_PIN_RESET,
.pin_en = IO_PORTC_01,
.pin_en_ex = IO_PORTC_02,
.pin_te = TCFG_LCD_PIN_TE,
.pin_bl = TCFG_LCD_PIN_BL,
#endif
LCD_SPI_PLATFORM_DATA_END()
};
const struct ui_devices_cfg ui_cfg_data = {
.type = TFT_LCD,
.private_data = (void *) &lcd_spi_data,
};
#endif /*TCFG_SPI_LCD_ENABLE*/
#endif /*TCFG_UI_ENABLE*/
const struct iic_master_config soft_iic_cfg_const[MAX_SOFT_IIC_NUM] = {
//soft iic0
#if 0
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C0_CLK_PORT,
.sda_io = TCFG_SW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C0_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
#if 0
//soft iic1
{
.role = IIC_MASTER,
.scl_io = TCFG_SW_I2C1_CLK_PORT,
.sda_io = TCFG_SW_I2C1_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_SW_I2C1_DELAY_CNT, //IIC通讯波特率 未使用
.io_filter = 0, //软件iic无滤波器
},
#endif
};
const struct iic_master_config hw_iic_cfg_const[MAX_HW_IIC_NUM] = {
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C0_CLK_PORT,
.sda_io = TCFG_HW_I2C0_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C0_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic0
{
.role = IIC_MASTER,
.scl_io = TCFG_HW_I2C_P11_CLK_PORT,
.sda_io = TCFG_HW_I2C_P11_DAT_PORT,
.io_mode = PORT_INPUT_PULLUP_10K, //上拉或浮空,如果外部电路没有焊接上拉电阻需要置上拉
.hdrive = PORT_DRIVE_STRENGT_2p4mA, //IO口强驱
.master_frequency = TCFG_HW_I2C_P11_CLK, //IIC通讯波特率
.io_filter = 1, //是否打开滤波器(去纹波)
},//iic_p11
};
#if (TCFG_HW_SPI1_ENABLE || TCFG_HW_SPI2_ENABLE)
const struct spi_platform_data spix_p_data[HW_SPI_MAX_NUM] = {
{
//spi0
},
#if SUPPORT_SPI1
{
//spi1
.port = {
TCFG_HW_SPI1_PORT_CLK, //clk any io
TCFG_HW_SPI1_PORT_DO, //do any io
TCFG_HW_SPI1_PORT_DI, //di any io
0xff, //d2 any io
0xff, //d3 any io
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI1_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI1_BAUD,
.mode = TCFG_HW_SPI1_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
#if (TCFG_HW_SPI1_BAUD == 32000000)
.cpha = 2,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#else
.cpha = 0,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#endif
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
#if SUPPORT_SPI2
{
//spi2
.port = {
TCFG_HW_SPI2_PORT_CLK, //clk any io
TCFG_HW_SPI2_PORT_DO, //D0
TCFG_HW_SPI2_PORT_DI, //DI/D1
TCFG_HW_SPI2_PORT_D2, //d2
TCFG_HW_SPI2_PORT_D3, //d3
0xff, //cs any io(主机不操作cs)
},
.role = TCFG_HW_SPI2_ROLE,//SPI_ROLE_MASTER,
.clk = TCFG_HW_SPI2_BAUD,
.mode = TCFG_HW_SPI2_MODE,//SPI_MODE_BIDIR_1BIT,//SPI_MODE_UNIDIR_2BIT,
.bit_mode = SPI_FIRST_BIT_MSB,
.cpol = 0,//clk level in idle state:0:low, 1:high
#if (TCFG_HW_SPI2_BAUD == 32000000)
.cpha = 2,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#else
.cpha = 0,//0:s_rise,u_fall 1:s_fall,u_rise 2:s_fall,u_fall 3:s_rise,u_rise
#endif
.ie_en = 0, //ie enbale:0:disable, 1:enable
.irq_priority = 3,
.spi_isr_callback = NULL, //spi isr callback
},
#endif
};
#endif
//--------------------------------------------------------------------------------------
//内置flash
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_mode_data)
.path = (const u8 *)"mnt/sdfile/app/MODE",
.start_addr = TCFG_SDFILE_FLASH_DEV_PATY_BASE,
.size = TCFG_SDFILE_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_dev_data)
.path = (const u8 *)"mnt/sdfile/app/FATFSI",
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_DATA_STORAGE_FDB_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_norfs_inside_watch_data_dev_data)
.start_addr =TCFG_DATA_FLASH_DEV_PATY_BASE,
.size =TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
//--------------------------------------------------------------------------------------
//这里是外挂norflash分区的配置
#if TCFG_NORFLASH_SFC_DEV_ENABLE
SFC_SPI_PLATFORM_DATA_BEGIN(sfc_spi_data)
.sfc_data_width = SFC_DATA_WIDTH_4,
.sfc_read_mode = SFC_RD_IO,
SFC_SPI_PLATFORM_DATA_END()
//fat分区(watch)
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_data)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_VIRFAT_FLASH_DEV_PATY_BASE,
.size = TCFG_VIRFAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
//exsdfile分区(mode)
#if TCFG_SDFILE_EXTERN_FLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_data_sdfile)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_SDFILE_FLASH_DEV_PATY_BASE,
.size = TCFG_SDFILE_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
//exsdfile分区(mode)
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(norflash_sfc_dev_watch_data)
.sfc_spi_pdata = &sfc_spi_data,
.start_addr = TCFG_DATA_FLASH_DEV_PATY_BASE,
.size = TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#endif
//--------------------------------------------------------------------------------------
//这里是外挂nandflash分区的配置
#if TCFG_NANDFLASH_DEV_ENABLE
/* nandflash驱动配置 */
NANDFLASH_DEV_PLATFORM_DATA_BEGIN(nandflash_dev_data) = {
.spi_hw_num = TCFG_FLASH_DEV_SPI_HW_NUM,
.spi_cs_port = TCFG_FLASH_DEV_SPI_CS_PORT,
.spi_read_width = TCFG_FLASH_DEV_FLASH_READ_WIDTH,//flash读数据的线宽
.start_addr = 0,
.size = TCFG_NANDFLASH_CAPACITY,
#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1)
.spi_pdata = &spix_p_data[1],
#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2)
.spi_pdata = &spix_p_data[2],
#endif
};
#if TCFG_NANDFLASH_UI_FAT_ENABLE
//ui_fat使用
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(ui_fat_dev_data)
.start_addr = TCFG_UI_FAT_FLASH_DEV_PATY_BASE,
.size = TCFG_UI_FAT_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_NANDFLASH_FAT_ENABLE
/* nandflash fat16 文件系统配置,多分区时使用 */
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(fat_nand_dev_data)
.start_addr = TCFG_NANDFLASH_FAT_BASE,
.size = TCFG_NANDFLASH_FAT_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
NORFLASH_SFC_DEV_PLATFORM_DATA_BEGIN(nandflash_sfc_dev_watch_data)
.start_addr = TCFG_DATA_FLASH_DEV_PATY_BASE,
.size = TCFG_DATA_FLASH_DEV_PATY_SIZE,
NORFLASH_SFC_DEV_PLATFORM_DATA_END()
#endif
extern const struct device_operations nandflash_ftl_ops;
extern const struct device_operations nandflash_sfc_ftl_ops;
extern const struct device_operations nandflash_fs_ftl_ops;
#endif // TCFG_NANDFLASH_DEV_ENABLE
const u32 g_res_nor_unencry_start_addr = 0; //temp, todo...
#if TCFG_HOST_UVC_ENABLE
UVC_PLATFORM_DATA_BEGIN(uvc_data)
.width = 640,
.height = 480,
.fps = 25,
.mem_size = 100 * 1024,
.timeout = 500,//ms
UVC_PLATFORM_DATA_END()
static const struct video_subdevice_data video0_subdev_data[] = {
{ VIDEO_TAG_UVC, (void *)&uvc_data },
};
static const struct video_platform_data video0_data = {
.data = video0_subdev_data,
.num = ARRAY_SIZE(video0_subdev_data),
};
#endif
REGISTER_DEVICES(device_table) = {
#if TCFG_SD0_ENABLE
{ "sd0", &sd_dev_ops, (void *) &sd0_data},
#endif
#if TCFG_APP_LINEIN_EN
{ "linein", &linein_dev_ops, (void *) &linein_data},
#endif
#if TCFG_UDISK_ENABLE
{ "udisk0", &mass_storage_ops, NULL},
#endif
#if TCFG_HOST_UVC_ENABLE
{"uvc", &uvc_dev_ops, NULL},
{ "video0.*", &video_dev_ops, (void *)&video0_data },
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
{"nand_flash", &nandflash_dev_ops, (void *) &nandflash_dev_data},
{"nandflash_ftl", &nandflash_ftl_ops, "nand_flash"},
#endif
#if TCFG_NANDFLASH_FAT_ENABLE
// nandflash fat16区
{TCFG_NANDFLASH_FAT_ROOT, &nandflash_sfc_ftl_ops, (void *)&fat_nand_dev_data},
#endif
#if TCFG_NANDFLASH_UI_FAT_ENABLE
//ui fat
{TCFG_NANDFLASH_UI_FAT_LOGO, &nandflash_sfc_ftl_ops, (void *)&ui_fat_dev_data},
#endif
#if TCFG_VIRFAT_FLASH_ENABLE
#if TCFG_NANDFLASH_DEV_ENABLE &&(!TCFG_VIRFAT_INSERT_FLASH_ENABLE)
//虚拟文件系统对接jl sdfile fat 文件系统设备入口,往下对接文件系统,往上对接物理设备
{ "virfat_flash", &virfat_flash_dev_ops, (void *)"nandflash_ftl"},
#else
//虚拟文件系统对接jl sdfile fat 文件系统设备入口,往下对接文件系统,往上对接物理设备
{ "virfat_flash", &virfat_flash_dev_ops, (void *)"res_nor"},
#endif
#endif
//res_nor 是物理设备入口
#if TCFG_VIRFAT_INSERT_FLASH_ENABLE
//使用内置flash 跑ui表盘
{ "res_nor", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_data},
#elif (TCFG_VIRFAT_EXT_FLASH_ENABLE && (!TCFG_NANDFLASH_DEV_ENABLE))
//使用外挂flash 跑ui表盘
{ "res_nor", &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_data},
#endif//TCFG_VIRFAT_INSERT_FLASH_ENABLE
#if TCFG_SDFILE_INSERT_FLASH_ENABLE
//内置只读文件系统
{ "res_nor_mode", &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_dev_mode_data},
#elif TCFG_SDFILE_EXTERN_FLASH_ENABLE
//外挂只读文件系统
{ "res_nor_mode", &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_data_sdfile},
#endif
#if TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE
//用户数据放外挂
#if TCFG_NANDFLASH_DEV_ENABLE
{ TCFG_DATA_DEV_NAME, & nandflash_fs_ftl_ops, (void *) &nandflash_sfc_dev_watch_data},
#else
{ TCFG_DATA_DEV_NAME, &norflash_sfc_fs_dev_ops, (void *) &norflash_sfc_dev_watch_data},
#endif
#elif TCFG_DATA_STORAGE_FDB_ENABLE
//用户数据放内置
{ TCFG_DATA_DEV_NAME, &inside_norflash_fs_dev_ops, (void *) &norflash_norfs_inside_watch_data_dev_data},
#endif
};
#if TCFG_SD_ALWAY_ONLINE_ENABLE
extern int sdx_dev_entry_lowpower(const char *sdx_name);
static int sdx_entry_lowpower(int param)
{
/* putchar('s'); */
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif /* #if TCFG_SD1_ENABLE */
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif /* #if TCFG_SD1_ENABLE */
return 0;
}
static void sdx_sleep_callback(void)
{
int argv[3];
argv[0] = (int)sdx_entry_lowpower;
argv[1] = 1;
/* argv[2] = ; */
int ret = os_taskq_post_type("app_core", Q_CALLBACK, 3, argv);
if (ret) {
printf("post ret:%d \n", ret);
}
}
#else /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
extern void sdx_dev_detect_modify(u32 modify_time);
void sniff_hook(u32 slot, u8 num, u8 first_conn, int t_sniff)
{
if (num) {
if (first_conn) {
/* printf("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 12);
}
} else {
/* printf("..%d..\n", t_sniff); */
sdx_dev_detect_modify(t_sniff - 3);
}
}
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
void board_init()
{
board_power_init();
#if TCFG_APP_RTC_EN
rtc_dev_init(&rtc_dev_config);
#endif
adc_init();
#if TCFG_APP_FM_EN
y_printf(">> Func:%s, Line:%d, call: fm_dev_init Func!\n", __func__, __LINE__);
fm_dev_init((void *)(&fm_dev_data));
#endif
#if TCFG_RDEC_KEY_ENABLE
rdec_key_init();
#endif
#if TCFG_LPCTMU_ENABLE
lpctmu_init(&lpctmu_cfg);
#endif
#if TCFG_PAY_ALIOS_ENABLE
extern void alipay_upay_init(void);
alipay_upay_init();
#endif /* #if TCFG_PAY_ALIOS_ENABLE */
#if TCFG_AI_INTERACTION_ENABLE
extern void ai_interaction_init(void);
ai_interaction_init();
#endif
#if TCFG_SD0_ENABLE
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(1);
#endif
#endif
#if TCFG_PSRAM_DEV_ENABLE
psram_init(&psram_config);
#endif
}
/*-----------------------------------------------------------------------
*进入、退出低功耗函数回调状态,函数单核操作、关中断,请勿做耗时操作
*
*/
#include "iokey.h"
#include "irkey.h"
#include "adkey.h"
#include "gpio_config.h"
void board_sleep_enter_callback()
{
/* 此函数禁止添加打印 */
putchar('<');
}
void board_sleep_exit_callback()
{
putchar('>');
#if TCFG_SD_ALWAY_ONLINE_ENABLE
#if SDX_POWER_ALONE // sd使用单独的电源才能用
if (sdx_power_enable && (sdx_power_enable != 0xff)) {
sdx_sleep_callback();
}
#endif /* #if SDX_POWER_ALONE */
#endif /*#if TCFG_SD_ALWAY_ONLINE_ENABLE*/
}
////关机回调执行顺序
//power_soff_callback()->do_platform_uninitcall()->board_poweroff_uninit->gpio_config_soft_poweroff()
//关机的注册的段
void board_poweroff_uninit()
{
//用户进行自己模块的关闭操作
#if TCFG_SD0_ENABLE
sdx_dev_entry_lowpower("sd0");
#endif
#if TCFG_SD1_ENABLE
sdx_dev_entry_lowpower("sd1");
#endif
#if TCFG_SD_ALWAY_ONLINE_ENABLE
sd_power_config(0);
#endif
#if TCFG_NORFLASH_DEV_ENABLE
extern void ex_norflash_poweroff(void);
ex_norflash_poweroff();
#endif
#if TCFG_NANDFLASH_DEV_ENABLE
extern void nandflash_poweroff(int priv);
struct device*dev = (struct device*)dev_open("nandflash_ftl",NULL);
while((int)atomic_read(&dev->ref)){
dev_close((void*)dev);
}
nandflash_poweroff(0);
#endif
#if TCFG_PSRAM_DEV_ENABLE
extern void psram_power_off();
psram_power_off();
#endif
}
/* platform_uninitcall(board_poweroff_uninit); */
//设置关机保持状态的io
void board_gpio_config_soft_poweroff(u32 *gpio_config)
{
//设置后关机io会保持原来状态
// PORT_PROTECT(IO_PORTB_01);
// PORT_PROTECT(IO_PORTB_01);
}
#endif
@@ -0,0 +1,731 @@
#ifndef CONFIG_BOARD_AC707N_DEMO_CFG_H
#define CONFIG_BOARD_AC707N_DEMO_CFG_H
#include "board_ac707n_demo_global_build_cfg.h"
#ifdef CONFIG_BOARD_JL707N_DEMO
#define CONFIG_SDFILE_ENABLE
//*********************************************************************************//
// 配置开始 //
//*********************************************************************************//
#define ENABLE_THIS_MOUDLE 1
#define DISABLE_THIS_MOUDLE 0
#define ENABLE 1
#define DISABLE 0
#define NO_CONFIG_PORT (-1)
// NTC配置 //
//*********************************************************************************//
#define NTC_DET_EN 0
#define NTC_POWER_IO IO_PORTC_03
#define NTC_DETECT_IO IO_PORTC_04
#define NTC_DET_AD_CH (0x4) //根据adc_api.h修改通道号
#define NTC_DET_UPPER 235 //正常范围AD值上限,0度时
#define NTC_DET_LOWER 34 //正常范围AD值下限,45度时
//*********************************************************************************//
// FPGA 配置 //
//*********************************************************************************//
#define FPGA_DEVELOP_IOKEY 0
//*********************************************************************************//
// FLASH 配置 //
//*********************************************************************************//
//FLASH公共配置
#if TCFG_USER_BLE_ENABLE
#define TCFG_FLASH_ERASE_WAIT_BLE ENABLE //flash擦除前等待ble状态
#else
#define TCFG_FLASH_ERASE_WAIT_BLE DISABLE //flash擦除前等待ble状态
#endif
//外挂flash配置
#define TCFG_NORFLASH_SFC_DEV_ENABLE TCFG_NORFLASH_DEV_ENABLE //外挂flash驱动
#if TCFG_NORFLASH_SFC_DEV_ENABLE
#define TCFG_EX_FLASH_POWER_IO IO_PORTC_10 // 外置flash电源脚
#define CONFIG_EX_FLASH_POWER_IO PC10 // NULL // 外置flash电源脚。不接IO时填NULL或者屏蔽掉该宏定义
#define CONFIG_EX_FLASH_POWER_IO_CTRL 1 // 0:power_io低电平时供电;1:高电平时供电 (针对io口低电平控制mos管导通来供电的情况)
#endif//TCFG_NORFLASH_SFC_DEV_ENABLE
//NANDFLASH配置
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
//电源配置
#define TCFG_EX_FLASH_POWER_IO IO_PORTC_11 // 外置flash电源脚
#define CONFIG_EX_FLASH_POWER_IO PC11 // NULL // 外置flash电源脚。不接IO时填NULL或者屏蔽掉该宏定义
#define CONFIG_EX_FLASH_POWER_IO_CTRL 1 // 0:power_io低电平时供电;1:高电平时供电 (针对io口低电平控制mos管导通来供电的情况)
#define TCFG_FLASH_DEV_FLASH_READ_WIDTH SPI_MODE_UNIDIR_4BIT//SPI_MODE_BIDIR_1BIT//
#define TCFG_FLASH_DEV_SPI_HW_NUM 2// 1: SPI1 2: SPI2
#define TCFG_FLASH_DEV_SPI_CS_PORT IO_PORTC_01
// NANDFLASH驱动配置
#define TCFG_NANDFLASH_HEX_ID 0xc891 // flash ID, 十六进制值的字符串形式
#define TCFG_NANDFLASH_PLANE_NUMBER 1
#define TCFG_NANDFLASH_ECC_MASK 0x30
#define TCFG_NANDFLASH_ECC_ERR 0x20
#define TCFG_NANDFLASH_PLANE_SEL 0
#define TCFG_NANDFLASH_WRITE_ENABLE_POS 0
#define TCFG_NANDFLASH_QUAD_MODE_DUM_NUM 1
#define TCFG_NANDFLASH_QUAD_MODE_QE 1
#define TCFG_NANDFLASH_BLOCK_NUMBER 1024
#define TCFG_NANDFLASH_CAPACITY (128 * 1024 * 1024) // flash 总实际容量
#define TCFG_NANDFLASH_PAGE_NUM 64
#define TCFG_NANDFLASH_PAGE_SIZE 2048
#define TCFG_NANDFLASH_OOB_SIZE 64
#define TCFG_NANDFLASH_OOB_USER_OFFSET_0 0
#define TCFG_NANDFLASH_OOB_USER_OFFSET_1 0
#define TCFG_NANDFLASH_OOB_USER_SIZE_0 64
#define TCFG_NANDFLASH_OOB_USER_SIZE_1 0
#define TCFG_NANDFLASH_MAX_ERASE_CNT 100000 // 最大擦写次数,一般默认10万次
#if(!TCFG_PSRAM_DEV_ENABLE)
#error "need enable psram!!!"
#endif
#endif//TCFG_NANDFLASH_DEV_ENABLE
//*********************************************************************************//
// FLASH dev分区 //
//*********************************************************************************//
//分区配置
#if (!TCFG_UI_ENABLE)//不开UI时,不使用文件系统
#define TCFG_VIRFAT_FLASH_ENABLE DISABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE DISABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE 0x1D6000 //
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 // 160K
#else//(!TCFG_UI_ENABLE)
//------------------------------------------------------------------------------------------
//ONLY_INSIDE_FLASH//只有内置flash,按8M规划
#if ((!TCFG_NORFLASH_DEV_ENABLE)&&(!TCFG_NANDFLASH_DEV_ENABLE)&&(CONFIG_FLASH_SIZE == 8*1024*1024))
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE ENABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE ENABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE DISABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x500000 // 5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE 0x1fe000 // 2M - 8k开始 内置FLASH虚拟文件系统空间基础地址
//virfat
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x6FE000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE 0xD8000 //864K
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE 0x7D6000//(TCFG_WATCH_INSERT_FLASH_BASE + TCFG_WATCH_INSERT_FLASH_SIZE)
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
//------------------------------------------------------------------------------------------
//ONLY_INSIDE_FLASH//只有内置flash,按16M规划
#elif ((!TCFG_NORFLASH_DEV_ENABLE)&&(!TCFG_NANDFLASH_DEV_ENABLE)&&(CONFIG_FLASH_SIZE == 16*1024*1024))
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE ENABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE ENABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE DISABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x580000 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE 0x214000 // 1.5M - 8k开始 内置FLASH虚拟文件系统空间基础地址
//virfat
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x794000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE 0xD8000 //864K
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE 0x86c000//(TCFG_WATCH_INSERT_FLASH_BASE + TCFG_WATCH_INSERT_FLASH_SIZE)
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
//------------------------------------------------------------------------------------------
//EXT_NOR_FLASH//外挂NOR fals
#elif (TCFG_NORFLASH_DEV_ENABLE)
#define TCFG_VIRFAT_FLASH_ENABLE ENABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE ENABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE ENABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE ENABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
#define TCFG_DATA_FLASH_DEV_PATY_BASE (CONFIG_EXTERN_FLASH_SIZE -TCFG_DATA_FLASH_DEV_PATY_SIZE)
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x580000 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE (CONFIG_EXTERN_FLASH_SIZE -TCFG_SDFILE_FLASH_DEV_PATY_SIZE-TCFG_DATA_FLASH_DEV_PATY_SIZE)
//virfat
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x000000//(TCFG_MODE_INSERT_FLASH_BASE + TCFG_MODE_INSERT_FLASH_SIZE)
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE (CONFIG_EXTERN_FLASH_SIZE -TCFG_SDFILE_FLASH_DEV_PATY_SIZE-TCFG_DATA_FLASH_DEV_PATY_SIZE)
//------------------------------------------------------------------------------------------
//EXT_NAND_FLASH//外挂NAND falsh
#elif (TCFG_NANDFLASH_DEV_ENABLE)
#define TCFG_VIRFAT_FLASH_ENABLE DISABLE //虚拟文件系统
#define TCFG_VIRFAT_INSERT_FLASH_ENABLE DISABLE //内置FLASH虚拟文件系统
#define TCFG_VIRFAT_EXT_FLASH_ENABLE DISABLE //外挂FLASH虚拟文件系统
#define TCFG_SDFILE_INSERT_FLASH_ENABLE DISABLE //内置只读文件系统
#define TCFG_SDFILE_EXTERN_FLASH_ENABLE DISABLE //外挂只读文件系统
#define TCFG_DATA_STORAGE_FDB_ENABLE ENABLE //用户数据存FDB
#define TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE ENABLE //用户数据存FDB&外挂flash
#define TCFG_DATA_STORAGE_VM_ENABLE DISABLE //用户数据存VM
#define TCFG_NANDFLASH_UI_FAT_ENABLE ENABLE //nandflash ui_fat分区使能(与virfat互斥,可以超过32M)
#define TCFG_NANDFLASH_FAT_ENABLE ENABLE //nandflash fat分区使能
#define TCFG_NANDFLASH_UNUSED_FILE_SYSTEM DISABLE //不挂文件系统
//sdfile文件系统
#define TCFG_SDFILE_FLASH_DEV_PATY_SIZE 0x580000 // 5.5M
#define TCFG_SDFILE_FLASH_DEV_PATY_BASE 0x17e000
//uifat/virfat
#define TCFG_NANDFLASH_UI_FAT_LOGO "UI_FAT"
#define TCFG_UI_FAT_FLASH_DEV_PATY_BASE 0x00000000
#define TCFG_UI_FAT_FLASH_DEV_PATY_SIZE 0x02000000 //32M (使用virfat时不能超过32M,使用ui_fat没有限制)
//当TCFG_VIRFAT_INSERT_FLASH_ENABLE 或 TCFG_VIRFAT_EXT_FLASH_ENABLE使能时有效
#define TCFG_VIRFAT_FLASH_DEV_PATY_BASE 0x6FE000
#define TCFG_VIRFAT_FLASH_DEV_PATY_SIZE 0xD8000 //32M (使用virfat时不能超过32M,使用ui_fat没有限制)
// nandflash 分区 fat16 区域地址和大小,与ini工具文件对应,即ini文件中,fat16文件的XX_ADR参数与BASE保持参数一致
#define TCFG_NANDFLASH_FAT_ROOT "fat_nand" // fat16 分区的设备名(存音乐)
#define TCFG_NANDFLASH_FAT_BASE TCFG_UI_FAT_FLASH_DEV_PATY_SIZE // fat16 分区起始地址
#define TCFG_NANDFLASH_FAT_SIZE (90 * 1024 * 1024) // fat16 分区容量大小
//watch_data
#define TCFG_DATA_DEV_NAME "watch_data"
#define TCFG_DATA_FLASH_DEV_PATY_BASE (TCFG_NANDFLASH_FAT_SIZE+TCFG_NANDFLASH_FAT_BASE)
#define TCFG_DATA_FLASH_DEV_PATY_SIZE 0x28000 //160K
// #if( TCFG_VIRFAT_FLASH_ENABLE && TCFG_NANDFLASH_UI_FAT_ENABLE)
// #error"config error,only enable one"
// #endif
#if(TCFG_VIRFAT_INSERT_FLASH_ENABLE && TCFG_VIRFAT_EXT_FLASH_ENABLE)
#error"config error,only enable one"
#endif
//------------------------------------------------------------------------------------------
#else
#error "FLASH_DEV_PART_CONFIG_ERROR !!!"
#endif
#endif
#define TCFG_DATA_STORAGE_ENABLE (TCFG_DATA_STORAGE_FDB_ENABLE || TCFG_DATA_STORAGE_VM_ENABLE ||TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE)
//*********************************************************************************//
// PSRAM 配置 //
//*********************************************************************************//
#if (defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)
#define TCFG_PSRAM_POWER_PORT IO_PORTB_05//7074使用pb5供电
#else
#define TCFG_PSRAM_POWER_PORT IO_FS_PG2
#endif
#define TCFG_PSRAM_PORT_SEL PSRAM_PORT_SEL_PORTA
#define TCFG_PSRAM_MODE PSRAM_MODE_4_WIRE_CMD4_ADR4_DAT4
#define TCFG_PSRAM_INIT_CLK (144* 1000000) //144Mhz //内封跑144M
// #define TCFG_PSRAM_INIT_CLK (96*1000000) //96Mhz //顶板外挂考虑降频
#if TCFG_NORFLASH_SFC_DEV_ENABLE && TCFG_PSRAM_DEV_ENABLE
#error "ext norflash and psram only support one dev !!!"
#endif
//*********************************************************************************//
// tp 配置 //
//*********************************************************************************//
#define TCFG_TOUCH_PANEL_ENABLE 1
#define TCFG_TP_CST816D_ENABLE 1
#define TCFG_TP_FT3X68_ENABLE 0
#define TCFG_TP_SLEEP_EN 1
#define TCFG_TP_INT_IO IO_PORTB_08 //TP中断脚
#define TCFG_TP_RESET_IO IO_PORTA_02 //TP复位脚
//*********************************************************************************//
// LCD 配置 //
//*********************************************************************************//
#define TCFG_SPI_LCD_ENABLE 1//spi lcd开关
#define TCFG_LCD_SPI_ICNA3310B_ENABLE 0
#define TCFG_LCD_SPI_GC9B71_ENABLE 0
#define TCFG_LCD_SPI_ST77916_ENABLE 1
#define TCFG_LCD_SPI_SH8501A_ENABLE 0
#define TCFG_LCD_SPI_SH8601A_ENABLE 0
#define TCFG_LCD_QSPI_ST77903_V2_ENABLE 0
#define TCFG_LCD_QSPI_SD3302_ENABLE 0
#define TCFG_LCD_SPI_RM69330_ENABLE 0
#define TCFG_LCD_MCU_JD5858_ENABLE 0
#define TCFG_LCD_RGB_ST7789V_ENABLE 0
#define TCFG_LCD_RGB_ENABLE 0
#define TCFG_LCD_MATCH_MODE 0
#define LCD_MATCH_BY_LOGO 0 //通过屏驱logo来匹配
#define LCD_LOGO "null"
#define TCFG_LCD_TE_USED_PEND 1
#define TCFG_7074_EX_NORFLASH_CONFIG DISABLE//开发板使用,7074顶板外挂nand/nor开这个宏,改跳线
#if ((defined TCFG_NANDFLASH_DEV_ENABLE && TCFG_NANDFLASH_DEV_ENABLE)||TCFG_7074_EX_NORFLASH_CONFIG)
#define TCFG_LCD_TE_IO IO_PORTA_00//TCFG_LCD_PIN_TE
#else
#define TCFG_LCD_TE_IO TCFG_LCD_PIN_TE
#endif
#define TCFG_LCD_TE_QUICK_SYNC 1//te优化策略
#define TCFG_LCD_BL_IO TCFG_LCD_PIN_BL
#define TCFG_BACKLIGHT_PWM_MODE 2// 0-on/off, 1-pwmled(no support), 2-mcpwm
#define TCFG_UI_SHUT_DOWN_TIME ENABLE // 自动息屏
#define TCFG_LCD_TP_USE_SAME_PWR ENABLE // lcd和tp 使用相同的电源
#if TCFG_LCD_TP_USE_SAME_PWR
#undef TCFG_TP_SLEEP_EN
#define TCFG_TP_SLEEP_EN DISABLE
#define LCD_POWER_DOWN_EN ENABLE
#define TP_POWER_DOWN_EN ENABLE
#endif
#define TCFG_GPU_DOUBLE_TASK_ENABLE ENABLE
#define TCFG_LCD_BUF_IN_STATIC_RAM_ENABLE ENABLE //屏幕显存buf使用静态ram,可以优化帧率
#define TCFG_LCD_BUF_DYNAMIC_LINE_ENABLE DISABLE //屏幕显存高度动态计算,复杂场景下可以减少屏幕需要的ram
#if (CONFIG_JL_UI_ENABLE&&TCFG_APP_MUSIC_EN)
#define TCFG_LRC_LYRICS_ENABLE ENABLE //jlui本地播放打开歌词显示
#endif
#define TCFG_PC_MODE_LOCK_UI_ENABLE ENABLE //PC模式锁定UI
//*********************************************************************************//
// MOTO 配置 //
//*********************************************************************************//
#define TCFG_MOTO_PWM_IO IO_MT_PG
//*********************************************************************************//
// rdec_key 配置 //
//*********************************************************************************//
#define TCFG_RDEC_KEY_ENABLE ENABLE_THIS_MOUDLE //是否使能RDEC按键
//RDEC0配置
#define TCFG_RDEC0_ECODEA_PORT IO_PORT_DP
#define TCFG_RDEC0_ECODEB_PORT IO_PORT_DM
#define TCFG_RDEC0_KEY0_VALUE 0
#define TCFG_RDEC0_KEY1_VALUE 1
//*********************************************************************************//
// p11 iic 配置 //
//*********************************************************************************//
#define TCFG_HW_I2C_P11_CLK_PORT TCFG_HW_I2C1_CLK_PORT
#define TCFG_HW_I2C_P11_DAT_PORT TCFG_HW_I2C1_DAT_PORT
#define TCFG_HW_I2C_P11_CLK TCFG_HW_I2C1_CLK
//*********************************************************************************//
// 充电 配置 (补充sdk_config_h) //
//*********************************************************************************//
#ifndef TCFG_CHARGE_NVDC_EN
#define TCFG_CHARGE_NVDC_EN TCFG_CHARGE_ENABLE
#endif
#define TCFG_CHANEG_DONT_ENTER_LOW_POWER ENABLE //充电不进低功耗
//*********************************************************************************//
// 看门狗配置 //
//*********************************************************************************//
#define WDT_APP_INIT_TIME WDT_16S //开机初始化的看门狗时间,适当给长一些
#define WDT_APP_RUN_TIME WDT_LRC_4S //程序正常运行的看门狗时间,用LRC看门狗准一点
/**************
*ANC配置
*************/
#define TCFG_AUDIO_ANC_ENABLE CONFIG_ANC_ENABLE //ANC总使能,根据global_bulid_cfg板级定义
// #define TCFG_ANC_TOOL_DEBUG_ONLINE DISABLE_THIS_MOUDLE //ANC工具蓝牙spp调试
#define TCFG_ANC_EXPORT_RAM_EN DISABLE_THIS_MOUDLE //ANCdebug数据释放RAM使能
#if TCFG_ANC_EXPORT_RAM_EN
#define TCFG_AUDIO_CVP_CODE_AT_RAM DISABLE_THIS_MOUDLE
#define TCFG_AUDIO_AAC_CODE_AT_RAM DISABLE_THIS_MOUDLE
#endif/*TCFG_ANC_EXPORT_RAM_EN*/
/*
*系统音量类型选择
*软件数字音量是指纯软件对声音进行运算后得到的
*硬件数字音量是指dac内部数字模块对声音进行运算后输出
*/
#define VOL_TYPE_DIGITAL 0 //软件数字音量(调节解码输出数据的音量)
#define VOL_TYPE_ANALOG 1 //(暂未支持)硬件模拟音量
#define VOL_TYPE_AD 2 //(暂未支持)联合音量(模拟数字混合调节)
#define VOL_TYPE_DIGITAL_HW 3 //硬件数字音量(调节DAC模块的硬件音量)
/*注意:ANC使能情况下使用软件数字音量*/
#if TCFG_AUDIO_ANC_ENABLE
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL
#else
//#define SYS_VOL_TYPE VOL_TYPE_DIGITAL_HW
#endif/*TCFG_AUDIO_ANC_ENABLE*/
/*
*通话的时候使用数字音量
*0:通话使用和SYS_VOL_TYPE一样的音量调节类型
*1:通话使用数字音量调节,更加平滑
*/
#define TCFG_CALL_USE_DIGITAL_VOLUME 0
//第三方清晰语音开发使能
// #define TCFG_CVP_DEVELOP_ENABLE DISABLE_THIS_MOUDLE
/*通话降噪模式配置*/
// #define CVP_ANS_MODE 0 [>传统降噪<]
// #define CVP_DNS_MODE 1 [>神经网络降噪<]
// #define TCFG_AUDIO_CVP_NS_MODE CVP_ANS_MODE
/*
* ENC(双mic降噪)配置
* 双mic降噪包括DMS_NORMAL和DMS_FLEXIBLE,在使能TCFG_AUDIO_DUAL_MIC_ENABLE
* 的前提下,根据具体需求,选择对应的DMS模式
*/
/*ENC(双mic降噪)使能*/
// #define TCFG_AUDIO_DUAL_MIC_ENABLE DISABLE_THIS_MOUDLE
/*DMS模式选择*/
// #define DMS_NORMAL 1 //普通双mic降噪(mic距离固定)
// #define DMS_FLEXIBLE 2 //适配mic距离不固定且距离比较远的情况,比如头戴式话务耳机
// #define TCFG_AUDIO_DMS_SEL DMS_NORMAL
/*ENC双mic配置主mic副mic对应的mic port*/
// #define DMS_MASTER_MIC0 0 //mic0是主mic
// #define DMS_MASTER_MIC1 1 //mic1是主mic
// #define TCFG_AUDIO_DMS_MIC_MANAGE DMS_MASTER_MIC0
/*双mic降噪/单麦mic降噪 DUT测试模式,配合设备测试mic频响和(双mic)降噪量*/
//MIC通道配置
// #if TCFG_AUDIO_DUAL_MIC_ENABLE
//#define TCFG_AUDIO_ADC_MIC_CHA (AUDIO_ADC_MIC_0 | AUDIO_ADC_MIC_1)
// #else
//#define TCFG_AUDIO_ADC_MIC_CHA AUDIO_ADC_MIC_0
// #endif[>TCFG_AUDIO_DUAL_MIC_ENABLE<]
/*MIC模式配置:单端隔直电容模式/差分隔直电容模式/单端省电容模式*/
// #if TCFG_AUDIO_ANC_ENABLE
/*注意:ANC使能情况下,使用差分mic*/
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_DIFF_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_DIFF_MODE
// #else
// #define TCFG_AUDIO_MIC_MODE AUDIO_MIC_CAP_MODE
// #define TCFG_AUDIO_MIC1_MODE AUDIO_MIC_CAP_MODE
// #endif[>TCFG_AUDIO_ANC_ENABLE<]
/*
*>>MIC电源管理:根据具体方案,选择对应的mic供电方式
*(1)如果是多种方式混合,则将对应的供电方式或起来即可,比如(MIC_PWR_FROM_GPIO | MIC_PWR_FROM_MIC_BIAS)
*(2)如果使用固定电源供电(比如dacvdd),则配置成DISABLE_THIS_MOUDLE
*/
#define MIC_PWR_FROM_GPIO (1UL << 0) //使用普通IO输出供电
#define MIC_PWR_FROM_MIC_BIAS (1UL << 1) //使用内部mic_ldo供电(有上拉电阻可配)
#define MIC_PWR_FROM_MIC_LDO (1UL << 2) //使用内部mic_ldo供电
//配置MIC电源
// #define TCFG_AUDIO_MIC_PWR_CTL MIC_PWR_FROM_MIC_BIAS
/*提示音叠加配置*/
#define TCFG_WAV_TONE_MIX_ENABLE DISABLE
#define TCFG_MP3_TONE_MIX_ENABLE DISABLE
#define TCFG_WTG_TONE_MIX_ENABLE DISABLE
#define TCFG_WTS_TONE_MIX_ENABLE ENABLE
//*********************************************************************************//
// Spatial Audio Effect 空间音效配置 //
//*********************************************************************************//
// #define TCFG_AUDIO_SPATIAL_EFFECT_ENABLE DISABLE_THIS_MOUDLE
// #define TCFG_TWS_SPATIAL_AUDIO_AS_CHANNEL 'L'
/*独立任务里面跑空间音效*/
#define TCFG_AUDIO_EFFECT_TASK_EBABLE ENABLE_THIS_MOUDLE
/*空间音效在线调试*/
// #define TCFG_SPATIAL_EFFECT_ONLINE_ENABLE DISABLE_THIS_MOUDLE
/*空间音频传感器是否在解码任务读传感器数据*/
#define TCFG_SENSOR_DATA_READ_IN_DEC_TASK DISABLE_THIS_MOUDLE
/*传感器数据读取的频率间隔,单位ms*/
#define TCFG_SENSOR_DATA_READ_INTERVAL 20
/*空间音频独立EQ使能*/
#define TCFG_SPATIAL_EFFECT_EQ_ENABLE DISABLE_THIS_MOUDLE
/*陀螺仪数据导出配置:支持BT_SPP\UART载体导出*/
#define SENSOR_DATA_EXPORT_USE_UART 1
#define SENSOR_DATA_EXPORT_USE_SPP 2
#define TCFG_SENSOR_DATA_EXPORT_ENABLE DISABLE_THIS_MOUDLE
//*********************************************************************************//
// IIS 配置 //
//*********************************************************************************//
#define TCFG_IIS_ENABLE DISABLE_THIS_MOUDLE
#define TCFG_IIS_MODE (0) // 0:master 1:slave
#define TCFG_AUDIO_INPUT_IIS (ENABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_INPUT_DATAPORT_SEL ALINK_CH1
#define TCFG_AUDIO_OUTPUT_IIS (DISABLE && TCFG_IIS_ENABLE)
#define TCFG_IIS_OUTPUT_DATAPORT_SEL ALINK_CH0
#define TCFG_IIS_SAMPLE_RATE (16000L)
//*********************************************************************************//
// g-sensor配置 //
//*********************************************************************************//
#define TCFG_GSENSOR_ENABLE 0 //gSensor使能
#define TCFG_DA230_EN 0
#define TCFG_SC7A20_EN 0
#define TCFG_STK8321_EN 0
#define TCFG_IRSENSOR_ENABLE 0
#define TCFG_JSA1221_ENABLE 0
#define TCFG_GSENOR_USER_IIC_TYPE 0 //0:软件IIC 1:硬件IIC
//*********************************************************************************//
// imu-sensor配置 //
//*********************************************************************************//
#define TCFG_IMUSENSOR_ENABLE 1 //imu Sensor使能
//mpu6887 cfg
#define TCFG_MPU6887P_ENABLE 0
#define TCFG_MPU6887P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_MPU6887P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU6887P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU6887P_DETECT_IO (-1) //传感器中断io
#define TCFG_MPU6887P_AD0_SELETE_IO IO_PORTC_03 //iic地址选择io
//icm42607p cfg
#define TCFG_ICM42670P_ENABLE 0
#define TCFG_ICM42670P_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_ICM42670P_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_ICM42670P_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_ICM42670P_DETECT_IO (-1) //传感器中断io
#define TCFG_ICM42670P_AD0_SELETE_IO (-1) //iic地址选择io
//mpu9250 cfg
#define TCFG_TP_MPU9250_ENABLE 0
#define TCFG_MPU9250_INTERFACE_TYPE 0 //不支持.0:iic, 1:spi
#define TCFG_MPU9250_USER_IIC_TYPE 0 //iic有效:1:硬件iic, 0:软件iic
#define TCFG_MPU9250_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_MPU9250_DETECT_IO IO_PORTB_03 //传感器中断io
//sh3001 cfg
#define TCFG_SH3001_ENABLE 0
#define TCFG_SH3001_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_SH3001_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_SH3001_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_SH3001_DETECT_IO IO_PORTB_03 //传感器中断io
//qmi8658 cfg
#define TCFG_QMI8658_ENABLE 0
#define TCFG_QMI8658_INTERFACE_TYPE 0 //0:iic, 1:spi, 2:i3c
#define TCFG_QMI8658_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_QMI8658_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_QMI8658_DETECT_IO (-1) //传感器中断io
#define TCFG_QMI8658_AD0_SELETE_IO (-1) //iic地址选择io
//lsm6dsl cfg
#define TCFG_LSM6DSL_ENABLE 1
#define TCFG_LSM6DSL_INTERFACE_TYPE 0 //0:iic, 1:spi
#define TCFG_LSM6DSL_USER_IIC_TYPE 0 //1:硬件iic, 0:软件iic
#define TCFG_LSM6DSL_USER_IIC_INDEX 0 //IIC 序号
#define TCFG_LSM6DSL_DETECT_IO (-1) //传感器中断io
#define TCFG_LSM6DSL_AD0_SELETE_IO (-1) //iic地址选择io
//mpu6050 cfg
#define TCFG_MPU6050_EN 0
//qmc5883 cfg
/*
*imu-sensor power manager
*不用独立IO供电,则配置 NO_CONFIG_PORT
*/
#define TCFG_IMU_SENSOR_PWR_PORT IO_PORTD_05
//*********************************************************************************//
// 传感器与运动健康 配置 //
//*********************************************************************************//
//运动健康总开关
#define TCFG_SPORT_HEALTH_ENABLE ENABLE
#define TCFG_SENSOR_HUB_TASK_ENABLE DISABLE
//各模块开关
#define TCFG_SPORT_HEALTH_ALGO_GSENSOR ENABLE //gsensor算法
#define TCFG_SPORT_HEALTH_SPORT ENABLE //运动
#define TCFG_SPORT_HEALTH_DAILY_ACTIVE ENABLE //日常活动
#define TCFG_SPORT_HEALTH_SLEEP DISABLE //睡眠
#define TCFG_SPORT_HEALTH_HEART_RATE DISABLE //心率
#define TCFG_SPORT_HEALTH_BLOOD_OXYGEN DISABLE //血氧
#define TCFG_SPORT_HEALTH_DET_MENSE ENABLE //女性健康监测
//SENSOR HUB总开关
#define TCFG_SENSOR_HUB DISABLE
//P11 sensorhub开关
#define TCFG_SENSOR_HUB_P11 DISABLE
//common
#define TCFG_ALGO_STEP_COUNETER DISABLE
#define TCFG_ACCELER_SLEEP_ENABLE DISABLE
//p11
#define TCFG_ACCELER_P11_ENABLE DISABLE
#define TCFG_GYRO_P11_ENABLE DISABLE
#define TCFG_MAGNETIC_P11_ENABLE DISABLE
#define TCFG_VCHR11_P11_ENABLE DISABLE
#define TCFG_HRS3602_P11_ENABLE DISABLE
//master
#define TCFG_ACCELER_MASTER_ENABLE DISABLE
#define TCFG_GYRO_MASTER_ENABLE DISABLE
#define TCFG_MAGNETIC_MASTER_ENABLE DISABLE
#define TCFG_VCHR11_MASTER_ENABLE DISABLE
#define TCFG_HRS3602_MASTER_ENABLE DISABLE
//gsensor配置
#define TCFG_SENSOR_SC7A20_ENABLE DISABLE
//msensor配置
#define TCFG_SENSOR_MMC5603_ENABLE DISABLE
//*********************************************************************************//
// pay 配置 //
//*********************************************************************************//
#if CONFIG_JL_UI_ENABLE && TCFG_USER_BLE_ENABLE && (CONFIG_BT_MODE == BT_NORMAL)
#define TCFG_PAY_ALIOS_ENABLE 1
#else
#define TCFG_PAY_ALIOS_ENABLE 0
#endif
#define TCFG_PAY_TRANSITCODE_ENABLE 0 // 乘车码
#define TCFG_TRANSIT_USE_PSRAM 0 // 乘车码使用psram,需使能psram
#define TCFG_PAY_ALIOS_WAY_T_HEAD 1 // 平头哥
#define TCFG_PAY_ALIOS_WAY_SEL TCFG_PAY_ALIOS_WAY_T_HEAD
#if (TCFG_PAY_ALIOS_WAY_SEL==TCFG_PAY_ALIOS_WAY_T_HEAD)
#define TCFG_PAY_ALIOS_PRODUCT_MODEL ""
#define TCFG_PAY_ALIOS_COMPANY_NAME "" //需要客户申请
#define ALIPAY_SE_FW_V2_0 1 //SE版本固件为2.0设置为1,否则设置为0
#define ALIPAY_SE_USE_RESET_PIN 0 //置1加密芯片采用reset管脚复位进低功耗,置0 上下电进低功耗
#define SE_POWER_GPIO 0 //使用GPIO口给SE芯片电源脚供电
#endif
#if TCFG_PAY_TRANSITCODE_ENABLE
#ifdef LWIP_USE_BT
#undef USER_SUPPORT_PROFILE_PAN
#define USER_SUPPORT_PROFILE_PAN 1 //开启pan服务
#endif
#endif
//*********************************************************************************//
// 触摸配置 //
//*********************************************************************************//
#define TCFG_LPCTMU_ENABLE 0 //总开关
#define TCFG_LPCTMU_CH0_EN 0 //IO_PORTB_00
#define TCFG_LPCTMU_CH1_EN 1 //IO_PORTB_01
#define TCFG_LPCTMU_CH2_EN 0 //IO_PORTB_02
#define TCFG_LPCTMU_CH3_EN 0 //IO_PORTB_03
#define TCFG_LPCTMU_CH4_EN 0 //IO_PORTB_04
//*********************************************************************************//
// demo配置 //
//*********************************************************************************//
#define GPU_PORT_DEMO_ENABLE 0 //使能gpu_port_demo
#define GPU_DEMO_ENABLE 0 //运行gpu demo的总开关
//*********************************************************************************//
// Find my 配置 //
//*********************************************************************************//
#define TCFG_FINDMY_ENABLE 0
//*********************************************************************************//
// emitter配置 //
//*********************************************************************************//
#if TCFG_USER_EMITTER_ENABLE
#ifdef TCFG_BT_SUPPORT_HFP_AG
#undef TCFG_BT_SUPPORT_HFP_AG
#endif
#define TCFG_BT_SUPPORT_HFP_AG 1 // HFP AG
#endif
//*********************************************************************************//
// 视频配置 //
//*********************************************************************************//
//
#define TCFG_VIDEO_DIAL_ENABLE 0//视频表盘
//uvc
#define UVC_JPG_DATA_WRITE2SD 0//UVC jpg 数据写入SD卡,需要开启SD卡
//camera
#define TCFG_CAMERA_MANAGER_ENABLE 0//相机、相册、摄像头功能
#define TCFG_CAMERA_DEV_BF30A2 0//摄像头驱动bf30a2
//*********************************************************************************//
// 产测配置 //
//*********************************************************************************//
#define PRODUCT_TEST_ENABLE DISABLE
#define PT_IO_TX_PIN IO_PORT_DM
#define PT_IO_RX_PIN IO_PORT_DP
#define PT_CHECK_OT 10000
#define PT_GPIO_ENABLE DISABLE
#define PT_GSENSOR_ENABLE DISABLE
#define PT_MOTOR_ENABLE DISABLE
#define PT_SD_ENABLE DISABLE
#define PT_HR_ENABLE DISABLE
#define PT_SPEAKER_MIC_ENABLE DISABLE
#define PT_GPIO_CHECK_LCD_TP DISABLE // 使用GPIO检查LCD_TP
#if PRODUCT_TEST_ENABLE
//公版rdec复用了dpdm
#undef TCFG_RDEC_KEY_ENABLE
#define TCFG_RDEC_KEY_ENABLE DISABLE
#endif
//*********************************************************************************//
// 网络配置 //
//*********************************************************************************//
#define TCFG_AI_INTERACTION_ENABLE DISABLE // APP版科大讯飞
#define TCFG_IFLYTEK_ENABLE DISABLE // 科大讯飞网络版
#define TCFG_IFLYTEK_USE_PSRAM DISABLE // 科大讯飞网络版使用psram
#if TCFG_IFLYTEK_ENABLE
#define TCFG_IFLYTEK_APP_SECRET ""
#define TCFG_IFLYTEK_APP_KEY ""
#define TCFG_IFLYTEK_APP_ID ""
#endif
#if TCFG_IFLYTEK_ENABLE
#ifdef LWIP_USE_BT
#undef USER_SUPPORT_PROFILE_PAN
#define USER_SUPPORT_PROFILE_PAN 1 //开启pan服务
#endif
#endif
//*********************************************************************************//
// 配置结束 //
//*********************************************************************************//
#endif //CONFIG_BOARD_JL707N_DEMO
#endif //CONFIG_BOARD_JL707N_DEMO_CFG_H
@@ -0,0 +1,105 @@
#ifndef CONFIG_BOARD_AC707N_DEMO_POST_BUILD_CFG_H
#define CONFIG_BOARD_AC707N_DEMO_POST_BUILD_CFG_H
/* 改文件只添加和isd_config.ini相关的配置,用以生成isd_config.ini */
/* 其他不相关的配置请勿添加在改文件 */
#ifdef CONFIG_BOARD_JL707N_DEMO
/* Following Macros Affect Periods Of Both Code Compiling And Post-build */
#define CONFIG_DOUBLE_BANK_ENABLE 0 //单双备份选择(若打开了改宏,FLASH结构变为双备份结构,适用于接入第三方协议的OTA, PS: JL-OTA同样支持双备份升级, 需要根据实际FLASH大小同时配置CONFIG_FLASH_SIZE)
#define CONFIG_UPDATE_JUMP_TO_MASK 0 //配置升级到loader的方式0为直接reset,1为跳转(适用于芯片电源由IO口KEEP住的方案,需要注意检查跳转前是否将使用DMA的硬件模块全部关闭)
#define CONFIG_ANC_ENABLE 0 //配置是否支持ANC
/* Above Macros Affect Periods Of Both Code Compiling And Post-build */
/* Following Macros Only For Post Bulid Configuaration */
#define CONFIG_DB_UPDATE_DATA_GENERATE_EN 0 //是否生成db_data.bin(用于第三方协议接入使用)
#define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 1 //ufw只生成1份4K对齐的代码
//config for supported chip version
#define CONFIG_SUPPORTED_CHIP_VERSION A,B,C
//DON'T MODIFY THIS CONFIG EXCEPT SDK PUBLISHER
#define CONFIG_CHIP_NAME AC707N //除了SDK发布者,请不要修改
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_PID AC707N //烧写或强制升级之前可以修改,之后升级要保持一致
//it can be modified before first programming,but keep the same as the original version
#define CONFIG_VID 0.01 //烧写或强制升级之前可以修改,之后升级要保持一致
//Project with bluetooth,it must use OSC as PLL_SOURCE;
#define CONFIG_PLL_SOURCE_USING_LRC 0 //PLL时钟源选择 1:LRC 0:OSC
//config alignment size unit
#ifdef CONFIG_256K_FLASH
#define ALIGN_UNIT_256B 1 //FLASH对齐方式选择,如果是256K的FLASH,选择256BYTE对齐方式
#else
#define ALIGN_UNIT_256B 0
#endif
//partial platform check this config to select the uart IO for wired update
#define CONFIG_UART_UPDATE_PIN PB05
//isd_download loader/uboot/update_loader debug io config
//#define CONFIG_UBOOT_DEBUG_PIN PA05
//#define CONFIG_UBOOT_DEBUG_BAUD_RATE 1000000
//config long-press reset io pin,time,trigger level
#define CONFIG_RESET_PIN PB07 //io pin
#define CONFIG_RESET_TIME 08 //unit:second
#define CONFIG_RESET_LEVEL 0 //tigger level(0/1)
//reserved three custom cfg item for the future definition
//#define CONFIG_CUSTOM_CFG1_TYPE POWER_PIN
//#define CONFIG_CUSTOM_CFG1_VALUE PC01_1
//#define CONFIG_CUSTOM_CFG2_TYPE
//#define CONFIG_CUSTOM_CFG2_VALUE
//#define CONFIG_CUSTOM_CFG3_TYPE
//#define CONFIG_CUSTOM_CFG3_VALUE
//#define CONFIG_VDDIO_LVD_LEVEL 4 ////VDDIO_LVD挡位,0: 1.9V 1: 2.0V 2: 2.1V 3: 2.2V 4: 2.3V 5: 2.4V 6: 2.5V 7: 2.6V
//with single-bank mode,actual vm size should larger this VM_LEAST_SIZE,and dual bank mode,actual vm size equals this;
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_VM_OPT 1
//config whether erased this area when do a update,1-No Operation,0-Erase
#define CONFIG_BTIF_OPT 1
//reserved two custom cfg area for the future definition
//#define CONFIG_RESERVED_AREA1 EXIF1
#ifdef CONFIG_RESERVED_AREA1
#define CONFIG_RESERVED_AREA1_ADDR AUTO
#define CONFIG_RESERVED_AREA1_LEN 0x1000
#define CONFIG_RESERVED_AREA1_OPT 1
//#define CONFIG_RESERVED_AREA1_FILE anc_gains.bin
#endif
//#define CONFIG_RESERVED_AREA2 EXIF2
#ifdef CONFIG_RESERVED_AREA2
#define CONFIG_RESERVED_AREA2_ADDR AUTO
#define CONFIG_RESERVED_AREA2_LEN 0x1000
#define CONFIG_RESERVED_AREA2_OPT 1
//#define CONFIG_RESERVED_AREA2_FILE anc_gains.bin
#endif
#if (defined TCFG_CONFIG_DEBUG_RECORD_ENABLE && TCFG_CONFIG_DEBUG_RECORD_ENABLE)
#define CONFIG_DEBUG_ADDR AUTO
#define CONFIG_DEBUG_LEN 0x1000
#define CONFIG_DEBUG_OPT 0 //0: 擦除, 1:不操作
#endif
/* Above Macros Only For Post Bulid Configuaration */
#endif /* #ifdef CONFIG_BOARD_AC707N_DEMO */
#endif /* #ifndef CONFIG_BOARD_AC707N_DEMO_POST_BUILD_CFG_H */
+28
View File
@@ -0,0 +1,28 @@
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H
// 配置信息基本规则:
// 1、sdk_config.h 是由杰理可视化工具在线配置生成,原则上不建议客户直接修改sdk_config.h的文件,如果客户希望可视化工具不覆盖sdk_config.h,可以配置可视化工具脱机模式
// 2、board_config.h 是唯一包含有sdk_config.h和板卡配置的文件的,用户可以在自己的板卡对配置信息进行完善
// 3、app_config.h 包含有board_config.h
//
#include "sdk_config.h"
#include "audio_type.h"
/*
* 板级配置选择
*/
#define CONFIG_BOARD_JL707N_DEMO
// #define CONFIG_BOARD_JL7074_DEMO
// #define CONFIG_BOARD_JL707N_CSC_DEMO //彩屏仓配置
#include "media/audio_def.h"
#include "board_ac707n_demo/board_ac707n_demo_cfg.h"
#include "board_ac7074_demo/board_ac7074_demo_cfg.h"
#include "board_ac707n_csc_demo/board_ac707n_csc_demo_cfg.h"
#define DUT_AUDIO_DAC_LDO_VOLT DACVDD_LDO_1_35V
#endif
@@ -0,0 +1,256 @@
/**
* 注意点:
* 0.此文件变化,在工具端会自动同步修改到工具配置中
* 1.功能块通过【---------xxx------】和 【#endif // xxx 】,是工具识别的关键位置,请勿随意改动
* 2.目前工具暂不支持非文件已有的C语言语法,此文件应使用文件内已有的语法增加业务所需的代码,避免产生不必要的bug
* 3.修改该文件出现工具同步异常或者导出异常时,请先检查文件内语法是否正常
**/
#ifndef JLSTREAM_NODE_CFG_H
#define JLSTREAM_NODE_CFG_H
// ------------提示音宏定义------------
#define TCFG_TONE_EN_ENABLE 1
#define TCFG_TONE_ZH_ENABLE 1
#define TCFG_TONE_AAC_ENABLE 0 // AAC
#define TCFG_TONE_F2A_ENABLE 0 // F2A
#define TCFG_TONE_MP3_ENABLE 0 // MP3
#define TCFG_TONE_MSBC_ENABLE 0 // MSBC
#define TCFG_TONE_MTY_ENABLE 0 // MTY
#define TCFG_TONE_SBC_ENABLE 0 // SBC
#define TCFG_TONE_SIN_ENABLE 1 // SIN
#define TCFG_TONE_WAV_ENABLE 0 // WAV
#define TCFG_TONE_WTG_ENABLE 1 // WTG
#define TCFG_TONE_WTS_ENABLE 0 // WTS
// ------------提示音宏定义------------
// ------------流程图宏定义------------
#define TCFG_AUDIO_BIT_WIDTH 0 // 位宽
#define TCFG_2BAND_MERGE_ENABLE 0 // 2Band Merge
#define TCFG_3BAND_MERGE_ENABLE 0 // 3Band Merge
#define TCFG_A2DP_TX_NODE_ENABLE 1 // A2DP_TX
#define TCFG_ADC_NODE_ENABLE 1 // ADC
#define TCFG_AI_RX_NODE_ENABLE 1 // AI_RX
#define TCFG_AI_TX_NODE_ENABLE 1 // AI_TX
#define TCFG_AUDIO_CVP_DEVELOP_ENABLE 0 // 通话第三方算法
#define TCFG_AUDIO_CVP_DMS_ANS_MODE 0 // 双MIC通话
#define TCFG_AUDIO_CVP_DMS_DNS_MODE 0 // 双MIC+DNS
#define TCFG_AUDIO_CVP_DMS_FLEXIBLE_ANS_MODE 0 // 话务双MIC通话
#define TCFG_AUDIO_CVP_DMS_FLEXIBLE_DNS_MODE 0 // 话务双MIC+DNS
#define TCFG_AUDIO_CVP_SMS_ANS_MODE 1 // 单MIC通话
#define TCFG_AUDIO_CVP_SMS_DNS_MODE 0 // 单MIC+DNS
#define TCFG_AUTO_WAH_NODE_ENABLE 0 // Auto Wah
#define TCFG_AUTODUCK_NODE_ENABLE 0 // AutoDuck、AutoDuck Trigger
#define TCFG_AUTOTUNE_NODE_ENABLE 0 // Autotune
#define TCFG_BASS_TREBLE_NODE_ENABLE 0 // Bass Treble
#define TCFG_CHANNEL_EXPANDER_NODE_ENABLE 0 // Channel Expander
#define TCFG_CHANNEL_MERGE_NODE_ENABLE 1 // Channel Merge
#define TCFG_CHORUS_NODE_ENABLE 0 // Chorus
#define TCFG_CLASSD_DRIVER_NODE_ENABLE 1 // Class-D Driver
#define TCFG_CONVERT_NODE_ENABLE 0 // Convert、BitWidth Convert
#define TCFG_CROSSOVER_NODE_ENABLE 0 // 分频器 三段、分频器 两段
#define TCFG_DAC_NODE_ENABLE 0 // DAC
#define TCFG_DATA_EXPORT_NODE_ENABLE 0 // data export
#define TCFG_DATA_SATURATION_NODE_ENABLE 0 // Data Saturation
#define TCFG_DYNAMIC_EQ_EXT_DETECTOR_NODE_ENABLE 0 // Dynamic EQ Ext Detector
#define TCFG_DYNAMIC_EQ_NODE_ENABLE 0 // Dynamic EQ
#define TCFG_DYNAMIC_EQ_PRO_EXT_DETECTOR_NODE_ENABLE 0 // Dynamic EQ Pro Ext Detector
#define TCFG_DYNAMIC_EQ_PRO_NODE_ENABLE 0 // Dynamic EQ Pro
#define TCFG_ECHO_NODE_ENABLE 0 // Echo
#define TCFG_EFFECT_DEV0_NODE_ENABLE 0 // EffectDev0
#define TCFG_EFFECT_DEV1_NODE_ENABLE 0 // EffectDev1
#define TCFG_EFFECT_DEV2_NODE_ENABLE 0 // EffectDev2
#define TCFG_EFFECT_DEV3_NODE_ENABLE 0 // EffectDev3
#define TCFG_EFFECT_DEV4_NODE_ENABLE 0 // EffectDev4
#define TCFG_ENERGY_DETECT_NODE_ENABLE 0 // Energy Detect
#define TCFG_ESCO_RX_NODE_ENABLE 1 // ESCO_RX
#define TCFG_ESCO_TX_NODE_ENABLE 1 // ESCO_TX
#define TCFG_FADE_NODE_ENABLE 0 // Fade
#define TCFG_FILE_PACKAGE_NODE_ENABLE 1 // 封装
#define TCFG_FREQUENCY_SHIFT_HOWLING_NODE_ENABLE 0 // Frequency Shift
#define TCFG_GAIN_NODE_ENABLE 0 // Gain
#define TCFG_HARMONIC_EXCITER_NODE_ENABLE 0 // Harmonic Exciter
#define TCFG_INDICATOR_NODE_ENABLE 0 // Indicator
#define TCFG_KEY_TONE_NODE_ENABLE 1 // 按键音
#define TCFG_LIMITER_NODE_ENABLE 0 // Limiter
#define TCFG_LLNS_NODE_ENABLE 0 // LLNS
#define TCFG_MIXER_NODE_ENABLE 0 // MIXER
#define TCFG_MULTI_BAND_DRC_NODE_ENABLE 0 // MDRC
#define TCFG_MUTE_NODE_ENABLE 0 // mute
#define TCFG_NOISEGATE_NODE_ENABLE 0 // NoiseGate
#define TCFG_NOTCH_HOWLING_NODE_ENABLE 0 // Howling Suppress
#define TCFG_NS_NODE_ENABLE 0 // Noise Suppressor
#define TCFG_PCM_DELAY_NODE_ENABLE 0 // PCM Delay
#define TCFG_PDM_NODE_ENABLE 0 // PDM MIC
#define TCFG_PING_PONG_PCM_DELAY_NODE_ENABLE 0 // Pingpong Pcm Delay
#define TCFG_PITCH_SPEED_NODE_ENABLE 0 // Pitch Speed
#define TCFG_PLATE_REVERB_ADVANCE_NODE_ENABLE 0 // Plate Reverb Advance
#define TCFG_PLATE_REVERB_NODE_ENABLE 0 // Plate Reverb
#define TCFG_PLC_NODE_ENABLE 1 // 丢包修复PLC
#define TCFG_RING_TONE_NODE_ENABLE 1 // 铃声
#define TCFG_SOFWARE_EQ_NODE_ENABLE 1 // SW EQ
#define TCFG_SOUND_SPLITTER_NODE_ENABLE 1 // 音频分流器
#define TCFG_SPDIF_MASTER_NODE_ENABLE 0 // SPDIF_OUT
#define TCFG_SPEAKER_EQ_NODE_ENABLE 0 // SpeakerEQ
#define TCFG_SPECTRUM_ADVANCE_NODE_ENABLE 0 // Spectrum Advance
#define TCFG_SPECTRUM_NODE_ENABLE 0 // Spectrum
#define TCFG_STEREO_MTAPS_ECHO_NODE_ENABLE 0 // Stereo Mtaps Echo
#define TCFG_STEREO_WIDENER_NODE_ENABLE 0 // Stereo Widener
#define TCFG_STEROMIX_NODE_ENABLE 0 // SteroMix
#define TCFG_SURROUND_NODE_ENABLE 0 // Surround Effect
#define TCFG_SWITCH_NODE_ENABLE 1 // Switch
#define TCFG_THREE_D_EFFECT_NODE_ENABLE 0 // ThreeD
#define TCFG_TONE_NODE_ENABLE 1 // 提示音
#define TCFG_UART_NODE_ENABLE 0 // 串口打印
#define TCFG_VBASS_NODE_ENABLE 0 // Virtual Bass
#define TCFG_VOCAL_REMOVER_NODE_ENABLE 0 // Vocal Remover
#define TCFG_VOCAL_TRACK_SEPARATION_NODE_ENBALE 0 // 声道拆分
#define TCFG_VOCAL_TRACK_SYNTHESIS_NODE_ENABLE 0 // 声道组合
#define TCFG_VOICE_CHANGER_ADV_NODE_ENABLE 0 // Voice Changer Adv
#define TCFG_VOICE_CHANGER_NODE_ENABLE 0 // Voice Changer
#define TCFG_WDRC_ADVANCE_NODE_ENABLE 0 // DRC Advance
#define TCFG_WDRC_DETECTOR_NODE_ENABLE 0 // DRC Detector
#define TCFG_WDRC_NODE_ENABLE 1 // DRC
#define TCFG_WRITE_FILE_NODE_ENABLE 1 // 写文件
#define TCFG_ZERO_ACTIVE_NODE_ENABLE 0 // Zero Active
#define EQ_SECTION_MAX 0x5 // EQ_SECTION_MAX
#define TCFG_STREAM_BIN_ENC_ENABLE 0 // stream.bin加密使能
#define TCFG_VIDEO_DEC_NODE_ENABLE 1 // VIDEO_DEC
// ------------流程图宏定义------------
// ------------流程图节点位宽定义------------
#define TCFG_AUDIO_EFX_665C_RUN_MODE EFx_BW_UNUSED // 2Band Merge
#define TCFG_AUDIO_EFX_1B9D_RUN_MODE EFx_BW_UNUSED // 3Band Merge
#define TCFG_AUDIO_EFX_F975_RUN_MODE EFx_BW_16t16 // A2DP_RX
#define TCFG_AUDIO_EFX_D1B7_RUN_MODE EFx_BW_UNUSED // ANC
#define TCFG_AUDIO_EFX_D0D0_RUN_MODE EFx_BW_UNUSED // AGC
#define TCFG_AUDIO_EFX_D06D_RUN_MODE EFx_BW_16t16 // ADC
#define TCFG_AUDIO_EFX_DFDA_RUN_MODE EFx_BW_16t16 // AI_TX
#define TCFG_AUDIO_EFX_C07A_RUN_MODE EFx_BW_UNUSED // Autotune
#define TCFG_AUDIO_EFX_7099_RUN_MODE EFx_BW_UNUSED // AutoDuck Trigger
#define TCFG_AUDIO_EFX_6CE5_RUN_MODE EFx_BW_UNUSED // AutoDuck
#define TCFG_AUDIO_EFX_2F5E_RUN_MODE EFx_BW_UNUSED // Auto Wah
#define TCFG_AUDIO_EFX_F9B7_RUN_MODE EFx_BW_16t16 // A2DP_TX
#define TCFG_AUDIO_EFX_DF98_RUN_MODE EFx_BW_16t16 // AI_RX
#define TCFG_AUDIO_EFX_CC8C_RUN_MODE EFx_BW_UNUSED // Bass Treble
#define TCFG_AUDIO_EFX_7DE5_RUN_MODE EFx_BW_UNUSED // BitWidth Convert
#define TCFG_AUDIO_EFX_1AA6_RUN_MODE EFx_BW_UNUSED // Convert
#define TCFG_AUDIO_EFX_6DD9_RUN_MODE EFx_BW_UNUSED // Chorus
#define TCFG_AUDIO_EFX_DA15_RUN_MODE EFx_BW_UNUSED // Channel Expander
#define TCFG_AUDIO_EFX_BF8E_RUN_MODE EFx_BW_16t16 // Channel Merge
#define TCFG_AUDIO_EFX_5D98_RUN_MODE EFx_BW_16t16 // Class-D Driver
#define TCFG_AUDIO_EFX_DEFE_RUN_MODE EFx_BW_16t16 | EFx_BW_32t16 // DRC
#define TCFG_AUDIO_EFX_DCCD_RUN_MODE EFx_BW_UNUSED // DAC
#define TCFG_AUDIO_EFX_62B2_RUN_MODE EFx_BW_UNUSED // DMS全局压制
#define TCFG_AUDIO_EFX_1EB2_RUN_MODE EFx_BW_UNUSED // DMS回声消除AEC
#define TCFG_AUDIO_EFX_F4CA_RUN_MODE EFx_BW_UNUSED // DMS回声压制NLP
#define TCFG_AUDIO_EFX_5721_RUN_MODE EFx_BW_UNUSED // DMS降噪NS
#define TCFG_AUDIO_EFX_4C53_RUN_MODE EFx_BW_UNUSED // DMS神经网络降噪DNS
#define TCFG_AUDIO_EFX_87A0_RUN_MODE EFx_BW_UNUSED // Dynamic EQ
#define TCFG_AUDIO_EFX_A60B_RUN_MODE EFx_BW_UNUSED // Dynamic EQ Ext Detector
#define TCFG_AUDIO_EFX_9A58_RUN_MODE EFx_BW_UNUSED // DRC Detector
#define TCFG_AUDIO_EFX_4250_RUN_MODE EFx_BW_UNUSED // DRC Advance
#define TCFG_AUDIO_EFX_6B29_RUN_MODE EFx_BW_UNUSED // Data Saturation
#define TCFG_AUDIO_EFX_4731_RUN_MODE EFx_BW_UNUSED // Dynamic EQ Pro
#define TCFG_AUDIO_EFX_793C_RUN_MODE EFx_BW_UNUSED // Dynamic EQ Pro Ext Detector
#define TCFG_AUDIO_EFX_DE61_RUN_MODE EFx_BW_UNUSED // data export
#define TCFG_AUDIO_EFX_8458_RUN_MODE EFx_BW_16t16 // ESCO_RX
#define TCFG_AUDIO_EFX_849A_RUN_MODE EFx_BW_16t16 // ESCO_TX
#define TCFG_AUDIO_EFX_E2BB_RUN_MODE EFx_BW_UNUSED // ENC
#define TCFG_AUDIO_EFX_98A4_RUN_MODE EFx_BW_UNUSED // Echo
#define TCFG_AUDIO_EFX_A248_RUN_MODE EFx_BW_UNUSED // Energy Detect
#define TCFG_AUDIO_EFX_A4E1_RUN_MODE EFx_BW_UNUSED // EffectDev0
#define TCFG_AUDIO_EFX_A4E2_RUN_MODE EFx_BW_UNUSED // EffectDev1
#define TCFG_AUDIO_EFX_A4E3_RUN_MODE EFx_BW_UNUSED // EffectDev2
#define TCFG_AUDIO_EFX_A4E4_RUN_MODE EFx_BW_UNUSED // EffectDev3
#define TCFG_AUDIO_EFX_A4E5_RUN_MODE EFx_BW_UNUSED // EffectDev4
#define TCFG_AUDIO_EFX_6195_RUN_MODE EFx_BW_UNUSED // Frequency Shift
#define TCFG_AUDIO_EFX_7398_RUN_MODE EFx_BW_UNUSED // FM
#define TCFG_AUDIO_EFX_1BF5_RUN_MODE EFx_BW_UNUSED // Fade
#define TCFG_AUDIO_EFX_A904_RUN_MODE EFx_BW_UNUSED // Gain
#define TCFG_AUDIO_EFX_C482_RUN_MODE EFx_BW_UNUSED // Howling Suppress
#define TCFG_AUDIO_EFX_1B2A_RUN_MODE EFx_BW_UNUSED // Harmonic Exciter
#define TCFG_AUDIO_EFX_48E2_RUN_MODE EFx_BW_UNUSED // Indicator
#define TCFG_AUDIO_EFX_0624_RUN_MODE EFx_BW_UNUSED // LINEIN
#define TCFG_AUDIO_EFX_09FE_RUN_MODE EFx_BW_UNUSED // LLNS
#define TCFG_AUDIO_EFX_D45F_RUN_MODE EFx_BW_UNUSED // LocalTWS Source
#define TCFG_AUDIO_EFX_7303_RUN_MODE EFx_BW_UNUSED // LocalTWS Sink
#define TCFG_AUDIO_EFX_4E5B_RUN_MODE EFx_BW_UNUSED // Limiter
#define TCFG_AUDIO_EFX_E62A_RUN_MODE EFx_BW_UNUSED // MIXER
#define TCFG_AUDIO_EFX_D5E0_RUN_MODE EFx_BW_UNUSED // mute
#define TCFG_AUDIO_EFX_74CB_RUN_MODE EFx_BW_UNUSED // MDRC
#define TCFG_AUDIO_EFX_B7C4_RUN_MODE EFx_BW_UNUSED // NoiseGate
#define TCFG_AUDIO_EFX_3BC9_RUN_MODE EFx_BW_UNUSED // Noise Suppressor
#define TCFG_AUDIO_EFX_B711_RUN_MODE EFx_BW_16t16 // PCMIC
#define TCFG_AUDIO_EFX_5101_RUN_MODE EFx_BW_UNUSED // Plate Reverb
#define TCFG_AUDIO_EFX_540E_RUN_MODE EFx_BW_UNUSED // Pitch Speed
#define TCFG_AUDIO_EFX_0753_RUN_MODE EFx_BW_UNUSED // Plate Reverb Advance
#define TCFG_AUDIO_EFX_A8F4_RUN_MODE EFx_BW_UNUSED // PCM Delay
#define TCFG_AUDIO_EFX_A09F_RUN_MODE EFx_BW_UNUSED // PDM MIC
#define TCFG_AUDIO_EFX_F936_RUN_MODE EFx_BW_UNUSED // Pingpong Pcm Delay
#define TCFG_AUDIO_EFX_D186_RUN_MODE EFx_BW_16t16 // PCSPK
#define TCFG_AUDIO_EFX_1ECD_RUN_MODE EFx_BW_16t16 // SRC
#define TCFG_AUDIO_EFX_FB00_RUN_MODE EFx_BW_UNUSED // SteroMix
#define TCFG_AUDIO_EFX_8934_RUN_MODE EFx_BW_UNUSED // Surround Effect
#define TCFG_AUDIO_EFX_F538_RUN_MODE EFx_BW_UNUSED // Spectrum
#define TCFG_AUDIO_EFX_3BE6_RUN_MODE EFx_BW_UNUSED // SpeakerEQ
#define TCFG_AUDIO_EFX_88E5_RUN_MODE EFx_BW_UNUSED // Stereo Widener
#define TCFG_AUDIO_EFX_FB3B_RUN_MODE EFx_BW_UNUSED // SPDIF
#define TCFG_AUDIO_EFX_603A_RUN_MODE EFx_BW_UNUSED // Sink
#define TCFG_AUDIO_EFX_EB56_RUN_MODE EFx_BW_UNUSED // Source
#define TCFG_AUDIO_EFX_9412_RUN_MODE EFx_BW_UNUSED // SPDIF_OUT
#define TCFG_AUDIO_EFX_F28A_RUN_MODE EFx_BW_UNUSED // Spectrum Advance
#define TCFG_AUDIO_EFX_9E7B_RUN_MODE EFx_BW_UNUSED // Stereo Mtaps Echo
#define TCFG_AUDIO_EFX_2357_RUN_MODE EFx_BW_16t16 // Switch
#define TCFG_AUDIO_EFX_3845_RUN_MODE EFx_BW_16t16 | EFx_BW_16t32 // SW EQ
#define TCFG_AUDIO_EFX_BAB1_RUN_MODE EFx_BW_UNUSED // test_group
#define TCFG_AUDIO_EFX_8C21_RUN_MODE EFx_BW_UNUSED // ThreeD
#define TCFG_AUDIO_EFX_B0D5_RUN_MODE EFx_BW_UNUSED // Virtual Bass
#define TCFG_AUDIO_EFX_7293_RUN_MODE EFx_BW_UNUSED // Voice Changer
#define TCFG_AUDIO_EFX_2F7A_RUN_MODE EFx_BW_UNUSED // Vocal Remover
#define TCFG_AUDIO_EFX_320E_RUN_MODE EFx_BW_UNUSED // Voice Changer Adv
#define TCFG_AUDIO_EFX_2FE1_RUN_MODE EFx_BW_UNUSED // Zero Active
#define TCFG_AUDIO_EFX_8346_RUN_MODE EFx_BW_16t16 // 按键音
#define TCFG_AUDIO_EFX_6FEC_RUN_MODE EFx_BW_16t16 // 本地音乐
#define TCFG_AUDIO_EFX_0A2C_RUN_MODE EFx_BW_16t16 // 编码器
#define TCFG_AUDIO_EFX_9B3B_RUN_MODE EFx_BW_16t16 // 播放同步
#define TCFG_AUDIO_EFX_E76E_RUN_MODE EFx_BW_UNUSED // 串口打印
#define TCFG_AUDIO_EFX_DBF5_RUN_MODE EFx_BW_UNUSED // 单MIC+DNS
#define TCFG_AUDIO_EFX_D0BC_RUN_MODE EFx_BW_16t16 // 单MIC通话
#define TCFG_AUDIO_EFX_ED7F_RUN_MODE EFx_BW_16t16 // 丢包修复PLC
#define TCFG_AUDIO_EFX_8D63_RUN_MODE EFx_BW_UNUSED // 分频器 两段
#define TCFG_AUDIO_EFX_BF28_RUN_MODE EFx_BW_UNUSED // 分频器 三段
#define TCFG_AUDIO_EFX_E2CB_RUN_MODE EFx_BW_16t16 // 封装
#define TCFG_AUDIO_EFX_68F2_RUN_MODE EFx_BW_UNUSED // 话务双MIC+DNS
#define TCFG_AUDIO_EFX_90F9_RUN_MODE EFx_BW_UNUSED // 话务双MIC通话
#define TCFG_AUDIO_EFX_A9CE_RUN_MODE EFx_BW_UNUSED // 回声消除AEC
#define TCFG_AUDIO_EFX_D3C9_RUN_MODE EFx_BW_UNUSED // 回音压制NLP
#define TCFG_AUDIO_EFX_69BD_RUN_MODE EFx_BW_UNUSED // 降噪NS
#define TCFG_AUDIO_EFX_1A85_RUN_MODE EFx_BW_16t16 // 解码器
#define TCFG_AUDIO_EFX_A576_RUN_MODE EFx_BW_16t16 // 蓝牙音频同步
#define TCFG_AUDIO_EFX_CADC_RUN_MODE EFx_BW_16t16 // 铃声
#define TCFG_AUDIO_EFX_BC6F_RUN_MODE EFx_BW_UNUSED // 神经网络降噪DNS
#define TCFG_AUDIO_EFX_A724_RUN_MODE EFx_BW_UNUSED // 声道拆分
#define TCFG_AUDIO_EFX_503D_RUN_MODE EFx_BW_UNUSED // 声道组合
#define TCFG_AUDIO_EFX_420E_RUN_MODE EFx_BW_UNUSED // 双MIC+DNS
#define TCFG_AUDIO_EFX_2115_RUN_MODE EFx_BW_UNUSED // 双MIC通话
#define TCFG_AUDIO_EFX_768A_RUN_MODE EFx_BW_16t16 // 提示音
#define TCFG_AUDIO_EFX_76EF_RUN_MODE EFx_BW_UNUSED // 通话第三方算法
#define TCFG_AUDIO_EFX_23C1_RUN_MODE EFx_BW_16t16 // 写文件
#define TCFG_AUDIO_EFX_74E3_RUN_MODE EFx_BW_16t16 // 音量控制器
#define TCFG_AUDIO_EFX_D911_RUN_MODE EFx_BW_16t16 // 音频分流器
#define TCFG_AUDIO_EFX_1E07_RUN_MODE EFx_BW_16t16 // VIDEO_DEC
// ------------流程图节点位宽定义------------
// ------------流程图EQ节点类型宏定义------------
#define EQ_CFG_TYPE_HIGH_PASS 0 // High Pass
#define EQ_CFG_TYPE_LOW_PASS 0 // Low Pass
#define EQ_CFG_TYPE_PEAKING 1 // Peaking
#define EQ_CFG_TYPE_HIGH_SHELF 0 // High Shelf
#define EQ_CFG_TYPE_LOW_SHELF 0 // Low Shelf
#define EQ_CFG_TYPE_HIGH_SHELF_Q 0 // High Shelf Q
#define EQ_CFG_TYPE_LOW_SHELF_Q 0 // Low Shelf Q
#define EQ_CFG_TYPE_HP 0 // Hp
#define EQ_CFG_TYPE_LP 0 // Lp
// ------------流程图EQ节点类型宏定义------------
#endif
+29
View File
@@ -0,0 +1,29 @@
/**
* 注意点:
* 0.此文件变化,在工具端会自动同步修改到工具配置中
* 1.功能块通过【---------xxx------】和 【#endif // xxx 】,是工具识别的关键位置,请勿随意改动
* 2.目前工具暂不支持非文件已有的C语言语法,此文件应使用文件内已有的语法增加业务所需的代码,避免产生不必要的bug
* 3.修改该文件出现工具同步异常或者导出异常时,请先检查文件内语法是否正常
**/
// ------------蓝牙配置.json------------
const int CONFIG_A2DP_DELAY_TIME_SBC = 0x12c; // A2DP延时SBC(msec)
const int CONFIG_A2DP_DELAY_TIME_SBC_LO = 0x64; // A2DP低延时SBC(msec)
const int CONFIG_A2DP_DELAY_TIME_AAC = 0x12c; // A2DP延时AAC(msec)
const int CONFIG_A2DP_DELAY_TIME_AAC_LO = 0x64; // A2DP低延时AAC(msec)
const int CONFIG_A2DP_ADAPTIVE_MAX_LATENCY = 0x226; // A2DP自适应最大延时(msec)
#if TCFG_USER_BLE_ENABLE
const int CONFIG_EDR_INIT_TIMEOUT = 0xea60; // 超时时间
#endif // TCFG_USER_BLE_ENABLE
// ------------蓝牙配置.json------------
// ------------升级配置.json------------
#if TCFG_UPDATE_ENABLE
const int CONFIG_UPDATE_STORAGE_DEV_EN = 0x1; // 设备升级
const int CONFIG_UPDATE_BLE_TEST_EN = 0x0; // ble蓝牙升级
const int CONFIG_UPDATE_BT_LMP_EN = 0x1; // edr蓝牙升级
#endif // TCFG_UPDATE_ENABLE
// ------------升级配置.json------------
+345
View File
@@ -0,0 +1,345 @@
/**
* 注意点:
* 0.此文件变化,在工具端会自动同步修改到工具配置中
* 1.功能块通过【---------xxx------】和 【#endif // xxx 】,是工具识别的关键位置,请勿随意改动
* 2.目前工具暂不支持非文件已有的C语言语法,此文件应使用文件内已有的语法增加业务所需的代码,避免产生不必要的bug
* 3.修改该文件出现工具同步异常或者导出异常时,请先检查文件内语法是否正常
**/
#ifndef SDK_CONFIG_H
#define SDK_CONFIG_H
#include "jlstream_node_cfg.h"
// ------------板级配置.json------------
#define TCFG_DEBUG_UART_ENABLE 1 // 调试串口
#if TCFG_DEBUG_UART_ENABLE
#define TCFG_DEBUG_UART_TX_PIN IO_PORTB_03 // 输出IO
#define TCFG_DEBUG_UART_BAUDRATE 2000000 // 波特率
#define TCFG_EXCEPTION_LOG_ENABLE 1 // 打印异常信息
#define TCFG_EXCEPTION_RESET_ENABLE 0 // 异常自动复位
#define TCFG_CONFIG_DEBUG_RECORD_ENABLE 0 // 异常存flash
#define TCFG_EXCEPTION_CODE_AT_RAM 1 // 异常代码放RAM
#endif // TCFG_DEBUG_UART_ENABLE
#define TCFG_CFG_TOOL_ENABLE 0 // FW编辑、在线调音
#if TCFG_CFG_TOOL_ENABLE
#define TCFG_ONLINE_TX_PORT IO_PORT_DP // 串口引脚TX
#define TCFG_ONLINE_RX_PORT IO_PORT_DM // 串口引脚RX
#define TCFG_COMM_TYPE TCFG_USB_COMM // 通信方式
#endif // TCFG_CFG_TOOL_ENABLE
#define CONFIG_SPI_DATA_WIDTH 4 // flash通信
#define CONFIG_SPI_MODE 1 // flash模式
#define CONFIG_FLASH_SIZE 0x800000 // flash容量
#define TCFG_VM_SIZE 32 // VM大小(K
#define CONFIG_FLASH_DTR_EN 1 // flash-dtr使能
#define CONFIG_FLASH_WPS_EN 0 // flash-上电写保护使能
#define CONFIG_VOTP_SIZE 256 // votp sizeByte
#define TCFG_NORFLASH_DEV_ENABLE 0 // 外挂flash使能
#define CONFIG_EXTERN_FLASH_SIZE 0 // 外挂flash容量
#define TCFG_PSRAM_DEV_ENABLE 0 // PSRAM 使能
#define TCFG_PSRAM_SIZE 0 // PSRAM容量
#define TCFG_NANDFLASH_DEV_ENABLE 0 //nandflash
#define TCFG_SD0_ENABLE 0 // SD配置
#if TCFG_SD0_ENABLE
#define TCFG_SD0_DAT_MODE 1 // 线数设置
#define TCFG_SD0_DET_MODE SD_IO_DECT // 检测方式
#define TCFG_SD0_CLK 12000000 // SD时钟频率
#define TCFG_SD0_DET_IO NO_CONFIG_PORT // 检测IO
#define TCFG_SD0_DET_IO_LEVEL 0 // IO检测方式
#define TCFG_SD_ALWAY_ONLINE_ENABLE 1 // 卡检测功耗优化
#define TCFG_SD0_POWER_SEL SD_PWR_NULL // SD卡电源
#define TCFG_SDX_CAN_OPERATE_MMC_CARD 0 // 支持MMC卡
#define TCFG_KEEP_CARD_AT_ACTIVE_STATUS 0 // 保持卡活跃状态
#define TCFG_SD0_POWER_PORT IO_PORTC_10 // SD卡电源(非sdpg
#define TCFG_SD0_PORT_CMD IO_PORTB_04 // SD_PORT_CMD
#define TCFG_SD0_PORT_CLK IO_PORTB_03 // SD_PORT_CLK
#define TCFG_SD0_PORT_DA0 IO_PORTB_06 // SD_PORT_DATA0
#define TCFG_SD0_PORT_DA1 NO_CONFIG_PORT // SD_PORT_DATA1
#define TCFG_SD0_PORT_DA2 NO_CONFIG_PORT // SD_PORT_DATA2
#define TCFG_SD0_PORT_DA3 NO_CONFIG_PORT // SD_PORT_DATA3
#endif // TCFG_SD0_ENABLE
#define FUSB_MODE 1 // USB工作模式
#define TCFG_USB_HOST_ENABLE 0 // USB主机总开关
#define USB_H_MALLOC_ENABLE 1 // 主机使用malloc
#define TCFG_USB_HOST_MOUNT_RESET 40 // usb reset时间
#define TCFG_USB_HOST_MOUNT_TIMEOUT 50 // 握手超时时间
#define TCFG_USB_HOST_MOUNT_RETRY 3 // 枚举失败重试次数
#define TCFG_UDISK_ENABLE 1 // U盘使能
#define USB_MALLOC_ENABLE 1 // 从机使用malloc
#define TCFG_USB_SLAVE_MSD_ENABLE 1 // 读卡器使能
#define TCFG_USB_SLAVE_HID_ENABLE 1 // HID使能
#define MSD_BLOCK_NUM 1 // MSD缓存块数
#define USB_AUDIO_VERSION USB_AUDIO_VERSION_1_0 // UAC协议版本
#define TCFG_USB_SLAVE_AUDIO_SPK_ENABLE 1 // USB扬声器使能
#define SPK_AUDIO_RATE_NUM 1 // SPK采样率列表
#define SPK_AUDIO_RES 16 // SPK位宽1
#define SPK_AUDIO_RES_2 0 // SPK位宽2
#define TCFG_USB_SLAVE_AUDIO_MIC_ENABLE 1 // USB麦克风使能
#define MIC_AUDIO_RATE_NUM 1 // MIC采样率列表
#define MIC_AUDIO_RES 16 // MIC位宽1
#define MIC_AUDIO_RES_2 0 // MIC位宽2
#define TCFG_SW_I2C0_CLK_PORT IO_PORTA_09 // 软件iic-0 CLK脚
#define TCFG_SW_I2C0_DAT_PORT IO_PORTA_10 // 软件iic-0 DATA脚
#define TCFG_SW_I2C0_DELAY_CNT 50 // iic-0 延时
#define TCFG_SW_I2C1_CLK_PORT NO_CONFIG_PORT // 软件iic-1 CLK脚
#define TCFG_SW_I2C1_DAT_PORT NO_CONFIG_PORT // 软件iic-1 DATA脚
#define TCFG_SW_I2C1_DELAY_CNT 50 // iic-1 延时
#define TCFG_HW_I2C0_CLK_PORT IO_PORTA_06 // 硬件iic-0 CLK脚
#define TCFG_HW_I2C0_DAT_PORT IO_PORTA_05 // 硬件iic-0 DATA脚
#define TCFG_HW_I2C0_CLK 100000 // 硬件iic-0波特率
#define TCFG_HW_I2C1_CLK_PORT IO_PORTB_02 // 硬件iic-1 CLK脚
#define TCFG_HW_I2C1_DAT_PORT IO_PORTB_01 // 硬件iic -1DATA脚
#define TCFG_HW_I2C1_CLK 100000 // 硬件iic-1波特率
#define TCFG_HW_SPI1_ENABLE 1 // 硬件SPI1
#if TCFG_HW_SPI1_ENABLE
#define TCFG_HW_SPI1_PORT_CLK IO_PORTA_07 // SPI1 CLK脚
#define TCFG_HW_SPI1_PORT_DO IO_PORTA_08 // SPI1 DO脚
#define TCFG_HW_SPI1_PORT_DI NO_CONFIG_PORT // SPI1 DI脚
#define TCFG_HW_SPI1_MODE SPI_MODE_BIDIR_1BIT // SPI1 模式
#define TCFG_HW_SPI1_ROLE SPI_ROLE_MASTER // SPI1 ROLE
#define TCFG_HW_SPI1_BAUD 24000000 // SPI1 时钟
#endif // TCFG_HW_SPI1_ENABLE
#define TCFG_HW_SPI2_ENABLE 1 // 硬件SPI2
#if TCFG_HW_SPI2_ENABLE
#define TCFG_HW_SPI2_PORT_CLK IO_PORTC_00// SPI2 CLK脚
#define TCFG_HW_SPI2_PORT_DO IO_PORTC_10// SPI2 DO脚
#define TCFG_HW_SPI2_PORT_DI IO_PORTC_02// SPI2 DI脚(D1脚)
#define TCFG_HW_SPI2_PORT_D2 IO_PORTC_03//SPI2 D2脚
#define TCFG_HW_SPI2_PORT_D3 IO_PORTA_13//SPI2 D3脚
#define TCFG_HW_SPI2_MODE SPI_MODE_BIDIR_1BIT // SPI2 模式
#define TCFG_HW_SPI2_ROLE SPI_ROLE_MASTER // SPI2 ROLE
#define TCFG_HW_SPI2_BAUD 32000000 // SPI2 时钟
#endif // TCFG_HW_SPI2_ENABLE
// ------------板级配置.json------------
// ------------功能配置.json------------
#define TCFG_APP_BT_EN 1 // 蓝牙模式
#define TCFG_APP_MUSIC_EN 0 // 音乐模式
#define TCFG_APP_LINEIN_EN 0 // LINEIN模式
#define TCFG_APP_FM_EN 0 // FM模式
#define TCFG_APP_PC_EN 0 // PC模式
#define TCFG_APP_RECORD_EN 0 // 录音模式
#define TCFG_MIC_EFFECT_ENABLE 0 // 混响使能
#define TCFG_DEC_ID3_V2_ENABLE 0 // ID3_V2
#define TCFG_DEC_ID3_V1_ENABLE 0 // ID3_V1
#define FILE_DEC_REPEAT_EN 0 // 无缝循环播放
#define FILE_DEC_DEST_PLAY 0 // 指定时间播放
#define FILE_DEC_AB_REPEAT_EN 0 // AB点复读
#define TCFG_DEC_DECRYPT_ENABLE 0 // 加密文件播
#define TCFG_DEC_DECRYPT_KEY 0x12345678 // 加密KEY
#define MUSIC_PLAYER_CYCLE_ALL_DEV_EN 0 // 循环播放模式是否循环所有设备
#define MUSIC_PLAYER_PLAY_FOLDER_PREV_FIRST_FILE_EN 0 // 切换文件夹播放时从第一首歌开始
#define TCFG_MUSIC_DEVICE_TONE_EN 0 // 设备提示音
#define TWFG_APP_POWERON_IGNORE_DEV 4000 // 设备忽略时间(单位:ms
#define TCFG_FIX_CLOCK_FREQ 0 // 固定时钟频率
#define TCFG_MIX_RECORD_ENABLE 0 // 本地混响录音使能
#define TCFG_RECORD_AUDIO_REPLAY_EN 0 // 本地录音回播使能
#define TCFG_AI_VOICE_ENABLE 0 // AI VOICE录音使能
// ------------功能配置.json------------
// ------------按键配置.json------------
#define TCFG_LONG_PRESS_RESET_ENABLE 0 // 非按键长按复位配置
#if TCFG_LONG_PRESS_RESET_ENABLE
#define TCFG_LONG_PRESS_RESET_PORT IO_PORTB_01 // 复位IO
#define TCFG_LONG_PRESS_RESET_TIME 8 // 复位时间
#define TCFG_LONG_PRESS_RESET_LEVEL 1 // 复位电平
#define TCFG_LONG_PRESS_RESET_INSIDE_PULL_UP_DOWN 0 // 使用IO内置上下拉
#endif // TCFG_LONG_PRESS_RESET_ENABLE
#define TCFG_IOKEY_ENABLE 0 // IO按键配置
#define TCFG_ADKEY_ENABLE 1 // AD按键配置
#define TCFG_IRKEY_ENABLE 0 // IR按键配置
// ------------按键配置.json------------
// ------------电源配置.json------------
#define TCFG_CLOCK_OSC_HZ 24000000 // 晶振频率
#define TCFG_LOWPOWER_POWER_SEL PWR_DCDC15 // 电源模式
#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC // 低功耗时钟源
#define TCFG_CLOCK_MODE CLOCK_MODE_ADAPTIVE // 时钟模式
#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_32V // IOVDD
#define TCFG_LOWPOWER_VDDIOW_LEVEL VDDIOM_VOL_26V // 弱IOVDD
#define CONFIG_LVD_LEVEL 2.5v // LVD档位
#define TCFG_LOWPOWER_LOWPOWER_SEL 2 // 低功耗模式
#define TCFG_AUTO_POWERON_ENABLE 1 // 上电自动开机
#define TCFG_SYS_LVD_EN 1 // 电池电量检测
#if TCFG_SYS_LVD_EN
#define TCFG_POWER_OFF_VOLTAGE 3500 // 关机电压(mV)
#define TCFG_POWER_WARN_VOLTAGE 3600 // 低电电压(mV)
#endif // TCFG_SYS_LVD_EN
#define TCFG_CHARGE_ENABLE 0 // 充电配置
#if TCFG_CHARGE_ENABLE
#define TCFG_CHARGE_TRICKLE_MA CHARGE_mA_20 // 涓流电流
#define TCFG_CHARGE_MA CHARGE_mA_200 // 恒流电流
#define TCFG_CHARGE_FULL_MA 20 // 截止电流(mA)
#define TCFG_CHARGE_FULL_V CHARGE_FULL_V_4200_4P2V // 截止电压
#define TCFG_CHARGE_POWERON_ENABLE 1 // 开机充电
#define TCFG_CHARGE_OFF_POWERON_EN 1 // 拔出开机
#define TCFG_CHARGE_NVDC_EN 1 // NVDC架构使能
#define TCFG_RECHARGE_ENABLE 0 // 复充使能
#define TCFG_RECHARGE_VOLTAGE 4000 // 复充电压(mV)
#define TCFG_LDOIN_PULLDOWN_EN 1 // 下拉电阻开关
#define TCFG_LDOIN_PULLDOWN_LEV CHARGE_PULLDOWN_200K // 下拉电阻档位
#define TCFG_LDOIN_PULLDOWN_KEEP 0 // 下拉电阻保持开关
#define TCFG_LDOIN_ON_FILTER_TIME 100 // 入舱滤波时间(ms)
#define TCFG_LDOIN_OFF_FILTER_TIME 200 // 出舱滤波时间(ms)
#define TCFG_LDOIN_KEEP_FILTER_TIME 440 // 维持电压滤波时间(ms)
#endif // TCFG_CHARGE_ENABLE
#define TCFG_BATTERY_CURVE_ENABLE 1 // 电池曲线配置
// ------------电源配置.json------------
// ------------LCD_UI配置.json------------
#define TCFG_UI_ENABLE 1 // UI配置
#if TCFG_UI_ENABLE
#define CONFIG_JL_UI_ENABLE 1 // 杰理UI
#define CONFIG_LVGL_UI_ENABLE 0 // LVGL
#define TCFG_LCD_PIN_RESET IO_PORTC_03 // LCD RESET
#define TCFG_LCD_PIN_CS IO_PORTA_07 // LCD CS
#define TCFG_LCD_PIN_BL IO_LCD_PG // LCD BLCKLIGHT
#define TCFG_LCD_PIN_DC IO_PORTA_02 // LCD DC
#define TCFG_LCD_PIN_EN NO_CONFIG_PORT // LCD EN
#define TCFG_LCD_PIN_TE IO_PORTC_00 // LCD TE
#endif // TCFG_UI_ENABLE
// ------------LCD_UI配置.json------------
// ------------蓝牙配置.json------------
#define TCFG_BT_NAME_SEL_BY_AD_ENABLE 0 // 蓝牙名(AD采样)
#define TCFG_USER_BT_CLASSIC_ENABLE 1 // 经典蓝牙开关
#define TCFG_BT_PAGE_TIMEOUT 8 // 单次回连时间(s)
#define TCFG_BT_POWERON_PAGE_TIME 30 // 开机回连超时(s)
#define TCFG_BT_TIMEOUT_PAGE_TIME 120 // 超距断开回连超时(s)
#define TCFG_DUAL_CONN_INQUIRY_SCAN_TIME 120 // 开机可被发现时间 (s)
#define TCFG_AUTO_SHUT_DOWN_TIME 0 // 无连接关机时间(s)
#define TCFG_BT_VOL_SYNC_ENABLE 1 // 音量同步
#define TCFG_BT_MUSIC_INFO_ENABLE 1 // 歌曲信息显示
#define TCFG_BT_DISPLAY_BAT_ENABLE 0 // 电量显示
#define TCFG_BT_INBAND_RING 1 // 手机铃声
#define TCFG_BT_PHONE_NUMBER_ENABLE 0 // 来电报号
#define TCFG_BT_SUPPORT_AAC 0 // AAC
#define TCFG_BT_MSBC_EN 1 // MSBC
#define TCFG_BT_SBC_BITPOOL 38 // sbcBitPool
#define TCFG_AAA_BITRATE 320000 // AAC码率
#define TCFG_BT_SUPPORT_HFP 1 // HFP
#define TCFG_BT_SUPPORT_AVCTP 1 // AVRCP
#define TCFG_BT_SUPPORT_A2DP 1 // A2DP
#define TCFG_BT_SUPPORT_HID 1 // HID
#define TCFG_BT_SUPPORT_SPP 1 // SPP
#define TCFG_BT_SUPPORT_PNP 1 // PNP
#define TCFG_BT_SUPPORT_PBAP 0 // PBAP
#define TCFG_BT_SUPPORT_MAP 1 // MAP
#define TCFG_BT_SUPPORT_OPP 0 // OPP
#define TCFG_BT_BACKGROUND_ENABLE 1 // 蓝牙后台
#define TCFG_BT_SUPPORT_PBAP_LIST 1 // pbap单条查询
#define TCFG_BT_CALL_PHONE_BY_WATCH 1 // 通话拦截
#define TCFG_USER_EMITTER_ENABLE 0 // 发射器开关
#define CONFIG_BT_MODE 1 // 模式选择
#define TCFG_NORMAL_SET_DUT_MODE 0 // NORMAL模式下使能DUT测试
#define TCFG_BT_SNIFF_ENABLE 1 // sniff
#if TCFG_BT_SNIFF_ENABLE
#define TCFG_SNIFF_CHECK_TIME 5 // 检测时间
#define CONFIG_LRC_WIN_SIZE 400 // LRC窗口初值
#define CONFIG_LRC_WIN_STEP 400 // LRC窗口步进
#define CONFIG_OSC_WIN_SIZE 400 // OSC窗口初值
#define CONFIG_OSC_WIN_STEP 400 // OSC窗口步进
#endif // TCFG_BT_SNIFF_ENABLE
#define TCFG_USER_BLE_ENABLE 1 // BLE
#if TCFG_USER_BLE_ENABLE
#define TCFG_BT_BLE_TX_POWER 5 // 最大发射功率
#define TCFG_BT_BLE_BREDR_SAME_ADDR 1 // 与2.1同地址
#define TCFG_BLE_BRIDGE_EDR_ENALBE 1 // CTKD一键连接
#define TCFG_USER_BLE_CTRL_BREDR_EN 1 // BLE控制EDR
#define TCFG_BLE_ADV_DYNAMIC_SWITCH 1 // BLE广播动态调整
#endif // TCFG_USER_BLE_ENABLE
#define TCFG_BT_AI_ENABLE 1 // AI配置
#if TCFG_BT_AI_ENABLE
#define TCFG_BT_AI_SEL_PROTOCOL RCSP_MODE_EN // AI协议选择
#endif // TCFG_BT_AI_ENABLE
// ------------蓝牙配置.json------------
// ------------升级配置.json------------
#define TCFG_UPDATE_ENABLE 1 // 升级选择
#if TCFG_UPDATE_ENABLE
#define TCFG_TEST_BOX_ENABLE 0 // 测试盒串口升级
#define TCFG_UPDATE_UART_IO_EN 0 // 普通io串口升级
#define TCFG_UPDATE_UART_ROLE 0 // 串口升级主从机选择
#define TCFG_DEV_UPDATE_EN 0 // 设备升级(USB、SD卡)
#define TCFG_COMPELTE_UFW_NAND_EN 0 // 升级文件存放本地触发升级(nandflash)
#define TCFG_COMPELTE_UFW_NOR_EN 0 // 升级文件存放本地触发升级(norflash升级)
#define TCFG_COMPELTE_UFW_LC_EN 0 // 升级文件存放本地触发升级(内置flash升级)
#define TCFG_NORFLASH_UPDATE_EN 0 // norflash_flash升级,目前功能没用到
#define TCFG_UPDATE_RESOURCE_EN 1 // 升级资源(除代码以外的其他部分)
#define TCFG_TEST_BOX_WIRELESS_EN 1 // 测试盒无线升级
#define TCFG_APP_UPDATE_EN 1 // APP升级
#endif // TCFG_UPDATE_ENABLE
// ------------升级配置.json------------
// ------------音频配置.json------------
#define TCFG_AUDIO_VCM_LEVEL 1 // VCM电压等级
#define TCFG_AUDIO_VCM_CAP_EN 0 // VCM电容
#define TCFG_AUDIO_CLASSD_OUTPUT 1 // 输出模式
#define TCFG_AUDIO_CLASSD_BUFFER_TIME_MS 50 // 缓冲长度(ms)
#define TCFG_AUDIO_ADC_ENABLE 1 // ADC配置
#if TCFG_AUDIO_ADC_ENABLE
#define TCFG_AUDIO_MIC_LDO_VSEL 4 // MIC LDO 电压
#define TCFG_ADC_PERFORMANCE_MODE 0 // 性能模式
#define TCFG_AUDIO_PLNK_SCLK_PIN NO_CONFIG_PORT // SCLK_IO
#define TCFG_AUDIO_PLNK_DAT0_PIN NO_CONFIG_PORT // DAT0_IO
#define TCFG_AUDIO_PLNK_DAT1_PIN NO_CONFIG_PORT // DAT1_IO
#define TCFG_AUDIO_PLNK_PWR_PORT NO_CONFIG_PORT // IO供电选择
#define TCFG_ADC0_ENABLE 1 // 使能
#define TCFG_ADC0_MODE 2 // 模式
#define TCFG_ADC0_AIN_SEL 1 // 输入端口
#define TCFG_ADC0_BIAS_SEL 1 // 供电端口
#define TCFG_ADC0_BIAS_RSEL 4 // MIC BIAS上拉电阻挡位
#define TCFG_ADC0_DCC_LEVEL 8 // DCC 档位
#define TCFG_ADC0_POWER_IO 0 // IO供电选择
#endif // TCFG_AUDIO_ADC_ENABLE
#define TCFG_AUDIO_GLOBAL_SAMPLE_RATE 48000 // 全局采样率
#define TCFG_AEC_TOOL_ONLINE_ENABLE 0 // 手机APP在线调试
#define TCFG_AUDIO_CVP_SYNC 0 // 通话上行同步
#define TCFG_AUDIO_DMS_DUT_ENABLE 1 // 通话产测
#define TCFG_ESCO_DL_CVSD_SR_USE_16K 1 // 通话下行固定16K
#define TCFG_AUDIO_SMS_SEL SMS_DEFAULT // 1mic算法选择
#define TCFG_MUSIC_PLC_TYPE 1 // PLC类型选择
#define TCFG_DEC_WAV_ENABLE 0 // WAV
#define TCFG_DEC_MP3_ENABLE 0 // MP3
#define TCFG_DEC_AAC_ENABLE 0 // AAC
#define TCFG_DEC_F2A_ENABLE 0 // F2A
#define TCFG_DEC_WTG_ENABLE 1 // WTG
#define TCFG_DEC_MTY_ENABLE 0 // MTY
#define TCFG_DEC_WTS_ENABLE 0 // WTS
#define TCFG_DEC_JLA_ENABLE 0 // JLA
#define TCFG_DEC_OPUS_ENABLE 0
#define TCFG_DEC_OGG_OPUS_ENABLE 0
#define TCFG_DEC_STREAM_MP3_ENABLE 0
#define TCFG_ENC_MSBC_ENABLE 1 // MSBC
#define TCFG_ENC_CVSD_ENABLE 1 // CVSD
#define TCFG_ENC_JLA_ENABLE 0 // JLA
#define TCFG_ENC_SBC_ENABLE 1 // SBC
#define TCFG_ENC_PCM_ENABLE 0 // PCM
#define TCFG_ENC_OPUS_ENABLE 0 // OPUS
#define TCFG_ENC_SPEEX_ENABLE 0 // SPEEX
#define TCFG_ENC_MP3_ENABLE 0 // MP3
#define TCFG_ENC_MP3_TYPE 0 // MP3格式选择
#define TCFG_ENC_ADPCM_ENABLE 0 // ADPCM
#define TCFG_ENC_ADPCM_TYPE 0 // ADPCM格式选择
// ------------音频配置.json------------
#endif
+151
View File
@@ -0,0 +1,151 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".iokey_config.data.bss")
#pragma data_seg(".iokey_config.data")
#pragma const_seg(".iokey_config.text.const")
#pragma code_seg(".iokey_config.text")
#endif
#include "app_config.h"
#include "utils/syscfg_id.h"
#include "gpio_config.h"
#include "key/iokey.h"
#include "key_driver.h"
struct iokey_info {
u8 len;
u16 key_uuid;
u16 io_uuid;
u8 detect;
u8 long_press_enable;
u8 long_press_time;
} __attribute__((packed));
static struct iokey_port iokey_ports[CONFIG_IOKEY_MAX_NUM];
static struct iokey_platform_data platform_data;
static const u16 key_uuid_table[][2] = {
{ 0x7684, KEY_IO_NUM0 },
{ 0x7685, KEY_IO_NUM1 },
{ 0x7686, KEY_IO_NUM2 },
{ 0x7687, KEY_IO_NUM3 },
{ 0x7688, KEY_IO_NUM4 },
{ 0x7689, KEY_IO_NUM5 },
{ 0x768A, KEY_IO_NUM6 },
{ 0x768B, KEY_IO_NUM7 },
{ 0x768C, KEY_IO_NUM8 },
{ 0x768D, KEY_IO_NUM9 },
{ 0x4755, KEY_IO_NUM10 },
{ 0x4756, KEY_IO_NUM11 },
{ 0x4757, KEY_IO_NUM12 },
{ 0x4758, KEY_IO_NUM13 },
{ 0x4759, KEY_IO_NUM14 },
};
static u8 uuid2keyValue(u16 uuid)
{
for (int i = 0; i < ARRAY_SIZE(key_uuid_table); i++) {
if (key_uuid_table[i][0] == uuid) {
return key_uuid_table[i][1];
}
}
return 0xff;
}
const struct iokey_platform_data *get_iokey_platform_data()
{
struct iokey_info info[CONFIG_IOKEY_MAX_NUM];
if (platform_data.enable) {
return &platform_data;
}
#if FPGA_DEVELOP_IOKEY
printf("[%s] line:%d fpag warn: FIXME", __func__, __LINE__);
platform_data.num = 1;
platform_data.port = iokey_ports;
platform_data.enable = 1;
/*设置io配置*/
iokey_ports[0].connect_way = ONE_PORT_TO_LOW;
iokey_ports[0].key_type.one_io.port = IO_PORTB_00;
iokey_ports[0].key_value = KEY_IO_NUM0;
/* */
/* iokey_ports[1].connect_way = ONE_PORT_TO_LOW; */
/* iokey_ports[1].key_type.one_io.port = IO_PORTB_02; */
/* iokey_ports[1].key_value = KEY_IO_WATCH_UPPER_LEFT; */
/* */
/* iokey_ports[2].connect_way = ONE_PORT_TO_LOW; */
/* iokey_ports[2].key_type.one_io.port = IO_PORTB_03; */
/* iokey_ports[2].key_value = KEY_IO_WATCH_UPPER_RIGHT; */
/*设置io的长按复位功能*/
platform_data.long_press_enable = 0;
/* platform_data.long_press_time = info[i].long_press_time; */
/* platform_data.long_press_port = uuid2gpio(info[i].io_uuid); */
/* platform_data.long_press_level = (info[i].detect == 1) ? 0 : 1; */
#else
int len = syscfg_read(CFG_IOKEY_ID, info, sizeof(info));
if (len <= 0) {
puts("ERR:Can not read the iokey config,total iokeys should <= CONFIG_IOKEY_MAX_NUM\n");
return NULL;
}
printf("iokey_len: %d, %x, %x\n", len, info[0].key_uuid, info[0].io_uuid);
platform_data.num = len / sizeof(struct iokey_info);
platform_data.port = iokey_ports;
platform_data.enable = 1;
printf("iokey numbers: %d\n", platform_data.num);
for (int i = 0; i < platform_data.num; i++) {
if (info[i].detect == 1) {
iokey_ports[i].connect_way = ONE_PORT_TO_LOW;
} else {
iokey_ports[i].connect_way = ONE_PORT_TO_HIGH;
}
iokey_ports[i].key_type.one_io.port = uuid2gpio(info[i].io_uuid);
iokey_ports[i].key_value = uuid2keyValue(info[i].key_uuid);
if (info[i].long_press_enable) {
platform_data.long_press_enable = 1;
platform_data.long_press_time = info[i].long_press_time;
platform_data.long_press_port = uuid2gpio(info[i].io_uuid);
platform_data.long_press_level = (info[i].detect == 1) ? 0 : 1;
}
printf("iokey:%d,prot:%d,value:%d,c_way:%d long_press_en:%d time:%ds\n", i, iokey_ports[i].key_type.one_io.port, iokey_ports[i].key_value, iokey_ports[i].connect_way, info[i].long_press_enable, info[i].long_press_time);
}
#endif
return &platform_data;
}
bool is_iokey_press_down()
{
#if TCFG_IOKEY_ENABLE
int value = 0;
u8 power_key_num = 0; // 默认设置第0个按键为唤醒键,其他请自行更换
if (platform_data.enable == 0) {
return false;
}
value = gpio_read(iokey_ports[power_key_num].key_type.one_io.port);
if (iokey_ports[power_key_num].connect_way == ONE_PORT_TO_LOW) {
return value == 0 ? true : false;
}
return value == 1 ? true : false;
#endif
return false;
}
int get_iokey_power_io()
{
#if TCFG_IOKEY_ENABLE
if (platform_data.enable) {
return iokey_ports[0].key_type.one_io.port;
}
#endif
return -1;
}
+37
View File
@@ -0,0 +1,37 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".rdeckey_config.data.bss")
#pragma data_seg(".rdeckey_config.data")
#pragma const_seg(".rdeckey_config.text.const")
#pragma code_seg(".rdeckey_config.text")
#endif
#include "app_config.h"
#include "rdec.h"
#include "gpio.h"
#include "key_driver.h"
#include "rdec_key.h"
#ifdef TCFG_RDEC_KEY_ENABLE
extern void lvgl_key_event_handler(struct key_event *key);
const struct rdec_device rdeckey_list[CONFIG_RDEC_KEY_MAX_NUM] = {
//RDEC0配置
{
.index = 0,
.sin_portA = TCFG_RDEC0_ECODEA_PORT,
.sin_portA_io_mode = PORT_INPUT_PULLUP_10K,
.sin_portB = TCFG_RDEC0_ECODEB_PORT,
.sin_portB_io_mode = PORT_INPUT_PULLUP_10K,
.scan_time = 100,
.phase_mode = RDEC_PHASE_1,
},
};
const struct rdec_platform_data rdec_key_data = {
.enable = 1,
.num = ARRAY_SIZE(rdeckey_list),
.rdec = rdeckey_list,
};
#endif
+177
View File
@@ -0,0 +1,177 @@
#include "system/includes.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_common.h"
#include "app_main.h"
#include "avctp_user.h"
#include "audio_cvp.h"
#include "data_storage.h"
#include "app_config.h"
static int call_sel = CALL_SEL_BT;
void call_dial_number(int number_len, char *number)
{
#if TCFG_APP_CAT1_EN
int ret = false;
if ((call_sel == CALL_SEL_AUTO) || (call_sel == CALL_SEL_CAT1)) {
ret = cat1_call_number(number_len, number);
}
if (ret == true) {
set_call_log_call_sel(CALL_SEL_CAT1);
return ;
}
if (call_sel == CALL_SEL_CAT1) {
return ;
}
#endif /* #if TCFG_APP_CAT1_EN */
#if TCFG_APP_BT_EN
if (bt_get_connect_status() != BT_STATUS_WAITINT_CONN) {
small_file_call_log_set_sel(CALL_SEL_BT);
#if TCFG_BT_CALL_PHONE_BY_WATCH
set_bt_esco_by_watch(1);
#endif
if (number != NULL) {
bt_cmd_prepare(USER_CTRL_HFP_DIAL_NUMBER, strlen(number), (u8 *)number);
}
}
#endif /* #if TCFG_APP_BT_EN */
}
void call_ctrl_answer()
{
#if TCFG_APP_CAT1_EN
int ret = false;
if ((call_sel == CALL_SEL_AUTO) || (call_sel == CALL_SEL_CAT1)) {
ret = cat1_call_answer();
}
if (ret == true) {
set_call_log_call_sel(CALL_SEL_CAT1);
return ;
}
if (call_sel == CALL_SEL_CAT1) {
return ;
}
#endif /* #if TCFG_APP_CAT1_EN */
#if TCFG_APP_BT_EN
small_file_call_log_set_sel(CALL_SEL_BT);
#if TCFG_BT_CALL_PHONE_BY_WATCH
set_bt_esco_by_watch(1);
#endif
bt_cmd_prepare(USER_CTRL_HFP_CALL_ANSWER, 0, NULL);
#endif /* #if TCFG_APP_BT_EN */
}
void call_ctrl_hangup()
{
#if TCFG_APP_CAT1_EN
int ret = false;
if ((call_sel == CALL_SEL_AUTO) || (call_sel == CALL_SEL_CAT1)) {
ret = cat1_call_hangup();
}
if (ret == true) {
set_call_log_call_sel(CALL_SEL_CAT1);
return ;
}
if (call_sel == CALL_SEL_CAT1) {
return ;
}
#endif
#if TCFG_APP_BT_EN
small_file_call_log_set_sel(CALL_SEL_BT);
bt_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
#endif
}
char *call_ctrl_get_phone_num(void)
{
#if TCFG_APP_CAT1_EN
char *phone_num = NULL;
int ret = false;
if ((call_sel == CALL_SEL_AUTO) || (call_sel == CALL_SEL_CAT1)) {
ret = cat1_get_call_phone_num(&phone_num);
}
if (ret == true) {
return phone_num;
}
if (call_sel == CALL_SEL_CAT1) {
return NULL;
}
#endif /* #if TCFG_APP_CAT1_EN */
#if TCFG_APP_BT_EN
if (g_bt_hdl.phone_num_flag) {
return (char *)g_bt_hdl.income_phone_num;
}
#endif /* #if TCFG_APP_BT_EN */
return NULL;
}
u8 call_ctrl_get_status(void)
{
#if TCFG_APP_CAT1_EN
u8 status;
int ret = false;
if ((call_sel == CALL_SEL_AUTO) || (call_sel == CALL_SEL_CAT1)) {
ret = cat1_get_call_status(&status);
}
if (ret == true) {
return status;
}
if (call_sel == CALL_SEL_CAT1) {
return BT_CALL_HANGUP;
}
#endif /* #if TCFG_APP_CAT1_EN */
#if TCFG_APP_BT_EN
return bt_get_call_status();
#endif /* #if TCFG_APP_BT_EN */
return BT_CALL_HANGUP;
}
void call_ctrl_set_call_sel(int sel)
{
if (sel >= CALL_SEL_MAX) {
return ;
}
call_sel = sel;
if (call_sel != CALL_SEL_AUTO) {
small_file_call_log_set_sel(call_sel);
}
}
int call_ctrl_get_call_sel(void)
{
return call_sel;
}
void call_ctrl_input_mute(u8 mute)
{
#if TCFG_APP_CAT1_EN
if (true == cat1_check_call_enable()) {
cat1_call_input_mute(mute);
} else
#endif /* #if TCFG_APP_CAT1_EN */
{
aec_input_clear_enable(mute);
}
}
int call_ctrl_get_input_mute(void)
{
#if TCFG_APP_CAT1_EN
if (true == cat1_check_call_enable()) {
return cat1_call_get_input_mute_status();
} else
#endif /* #if TCFG_APP_CAT1_EN */
{
return aec_get_input_clear_status();
}
}
@@ -0,0 +1,280 @@
/**
* @file data_call_log_storage.c
* @brief 通话记录存储实现
*/
#include "app_config.h"
#include "sys_time.h"
#include "rtc.h"
#include "timestamp.h"
#include "data_storage.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[CALL-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".call_log_storage.data.bss")
#pragma data_seg(".call_log_storage.data")
#pragma const_seg(".call_log_storage.text.const")
#pragma code_seg(".call_log_storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE
/**********************
* STATIC PROTOTYPES
**********************/
static small_file_call_log_t curr_call_log;
void small_file_call_log_set_name(char *name, int name_len)
{
int len;
if (!name || !name_len) {
return;
}
len = (name_len < CALL_LOG_NAME_LEN) ? name_len : CALL_LOG_NAME_LEN;
memcpy(curr_call_log.name, name, len);
curr_call_log.name[len - 1] = '\0';
}
void small_file_call_log_set_number(char *number, int number_len)
{
int len;
if (!number || !number_len) {
return;
}
memset(curr_call_log.number, 0, CALL_LOG_NUMBER_LEN);
len = (number_len < CALL_LOG_NUMBER_LEN) ? number_len : CALL_LOG_NUMBER_LEN;
memcpy(curr_call_log.number, number, len);
curr_call_log.number[len - 1] = '\0';
}
void small_file_call_log_set_date(void)
{
struct sys_time time;
rtc_read_time(&time);
curr_call_log.utc_time = timestamp_mytime_2_utc_sec(&time);
}
u32 small_file_call_log_get_date(void)
{
return curr_call_log.utc_time;
}
void small_file_call_log_set_type(enum CALL_TYPE type)
{
curr_call_log.type = type;
}
void small_file_call_log_set_sel(enum CALL_SEL call_sel)
{
curr_call_log.sel = call_sel;
}
int small_file_call_log_save(void)
{
#if TCFG_DATA_STORAGE_VM_ENABLE
/*通话记录使用一个vm id, 这里额外处理*/
u32 id = small_file_get_id_by_index(F_TYPE_CALL_LOG, 0);
u8 *tmp_buf = NULL;
int ret = true;
if (id != 0) {
u32 cur_file_size = small_file_get_size_by_id(F_TYPE_CALL_LOG, id);
tmp_buf = zalloc(cur_file_size + SMALL_FILE_CALL_LOG_SIZE);
ret = small_file_read(F_TYPE_CALL_LOG, id, 0, tmp_buf, cur_file_size);
if (ret != cur_file_size) {
log_error("<%s> line:%d", __func__, __LINE__);
ret = false;
goto __end;
}
memcpy(tmp_buf + cur_file_size, &curr_call_log, SMALL_FILE_CALL_LOG_SIZE);
ret = small_file_write(F_TYPE_CALL_LOG, &id, 0, tmp_buf, (cur_file_size + SMALL_FILE_CALL_LOG_SIZE), (cur_file_size + SMALL_FILE_CALL_LOG_SIZE));
memset(&curr_call_log, 0, SMALL_FILE_CALL_LOG_SIZE);
if (ret != (cur_file_size + SMALL_FILE_CALL_LOG_SIZE)) {
log_error("<%s> line:%d", __func__, __LINE__);
ret = false;
goto __end;
}
} else {
ret = small_file_write(F_TYPE_CALL_LOG, &id, 0, &curr_call_log, SMALL_FILE_CALL_LOG_SIZE, SMALL_FILE_CALL_LOG_SIZE);
memset(&curr_call_log, 0, SMALL_FILE_CALL_LOG_SIZE);
if (ret != SMALL_FILE_CALL_LOG_SIZE) {
log_error("<%s> line:%d", __func__, __LINE__);
ret = false;
goto __end;
}
}
__end:
if (tmp_buf) {
free(tmp_buf);
}
return ret;
#else
u32 id = 0;
u32 ret = small_file_write(F_TYPE_CALL_LOG, &id, 0, &curr_call_log, SMALL_FILE_CALL_LOG_SIZE, SMALL_FILE_CALL_LOG_SIZE);
memset(&curr_call_log, 0, SMALL_FILE_CALL_LOG_SIZE);
if (ret != SMALL_FILE_CALL_LOG_SIZE) {
return false;
}
return true;
#endif
}
int ui_small_file_call_log_read_by_index(small_file_call_log_t *call_log, int index)
{
#if TCFG_DATA_STORAGE_VM_ENABLE
/*通话记录使用一个vm id, 这里额外处理*/
int ret;
if (!call_log) {
return false;
}
u32 id = small_file_get_id_by_index(F_TYPE_CALL_LOG, 0);
if (!id) {
return false;
}
u32 size = small_file_get_size_by_id(F_TYPE_CALL_LOG, id);
u32 count = size / SMALL_FILE_CALL_LOG_SIZE;
if (index + 1 > count) {
return false;
}
ret = small_file_read(F_TYPE_CALL_LOG, id, index * SMALL_FILE_CALL_LOG_SIZE, call_log, SMALL_FILE_CALL_LOG_SIZE);
if (ret == SMALL_FILE_CALL_LOG_SIZE) {
return true;
}
log_error("<%s> line:%d", __func__, __LINE__);
return false;
#else
int ret;
if (!call_log) {
return false;
}
u32 id = small_file_get_id_by_index(F_TYPE_CALL_LOG, index);
if (!id) {
return false;
}
ret = small_file_read(F_TYPE_CALL_LOG, id, 0, call_log, sizeof(small_file_call_log_t));
if (ret == sizeof(small_file_call_log_t)) {
return true;
}
return false;
#endif
}
int ui_small_file_call_log_get_count(void)
{
#if TCFG_DATA_STORAGE_VM_ENABLE
/*通话记录使用一个vm id, 这里额外处理*/
u32 id = small_file_get_id_by_index(F_TYPE_CALL_LOG, 0);
if (!id) {
return 0;
}
u32 size = small_file_get_size_by_id(F_TYPE_CALL_LOG, id);
return size / SMALL_FILE_CALL_LOG_SIZE;
#else
return small_file_get_count(F_TYPE_CALL_LOG);
#endif
}
/************************************************
* 测试用例
***********************************************/
#if 0
void watch_data_call_log_test(void)
{
printf("%s %d\n", __FUNCTION__, __LINE__);
small_file_call_log_t call_log;
int ret;
char name[CALL_LOG_DATE_LEN] = "张三李四";
char number[CALL_LOG_NUMBER_LEN] = "123456789123";
for (int i = 0; i < 10; i++) {
small_file_call_log_set_name(name, sizeof(name));
small_file_call_log_set_number(number, sizeof(number));
small_file_call_log_set_date();
small_file_call_log_set_type(1);
small_file_call_log_set_sel(1);
small_file_call_log_save();
printf("count %d\n", ui_small_file_call_log_get_count());
void os_time_dly(int tick);
os_time_dly(100);
}
for (int i = 0; i < 10; i++) {
ret = ui_small_file_call_log_read_by_index(&call_log, i);
printf("i:%d ret:%d", i, ret);
printf("call_log.date:%d", call_log.utc_time);
printf("call_log.name:%s", call_log.name);
printf("call_log.number:%s", call_log.number);
}
char name_1[CALL_LOG_DATE_LEN] = {0};
char number_1[CALL_LOG_NUMBER_LEN] = "98 654 21";
for (int i = 0; i < 5; i++) {
small_file_call_log_set_name(name_1, sizeof(name_1));
small_file_call_log_set_number(number_1, sizeof(number_1));
small_file_call_log_set_date();
small_file_call_log_set_type(1);
small_file_call_log_set_sel(1);
small_file_call_log_save();
printf("count %d\n", ui_small_file_call_log_get_count());
void os_time_dly(int tick);
os_time_dly(100);
}
for (int i = 0; i < 10; i++) {
ret = ui_small_file_call_log_read_by_index(&call_log, i);
printf("i:%d ret:%d", i, ret);
printf("call_log.date:%d", call_log.utc_time);
printf("call_log.name:%s", call_log.name);
printf("call_log.number:%s", call_log.number);
}
printf("%s %d\n", __FUNCTION__, __LINE__);
ASSERT(ret);
}
#endif
#else /* if TCFG_DATA_STORAGE_ENABLE */
void small_file_call_log_set_sel(enum CALL_SEL call_sel)
{
}
int ui_small_file_call_log_read_by_index(small_file_call_log_t *call_log, int index)
{
return 0;
}
int ui_small_file_call_log_get_count(void)
{
return 0;
}
void small_file_call_log_set_type(enum CALL_TYPE type)
{
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,61 @@
#ifndef _WATCH_DATA_CALL_LOG_STORAGE_
#define _WATCH_DATA_CALL_LOG_STORAGE_
/*********************
* DEFINES
*********************/
#define CALL_LOG_NAME_LEN (20)
#define CALL_LOG_NUMBER_LEN (20)
#define CALL_LOG_DATE_LEN (20)
#define SMALL_FILE_CALL_LOG_SIZE (sizeof(small_file_call_log_t))
/**********************
* TYPEDEFS
**********************/
#pragma pack(1)
typedef struct call_log {
u32 utc_time;
char name[CALL_LOG_NAME_LEN];
char number[CALL_LOG_NUMBER_LEN];
u8 type; /*通话类型*/
u8 sel; /*通话设备*/
u32 mask;
} small_file_call_log_t;
#pragma pack()
enum CALL_SEL {
CALL_SEL_AUTO = 0,
CALL_SEL_BT, /*蓝牙通话*/
CALL_SEL_CAT1, /*CAT1通话*/
CALL_SEL_ERA_BLE, /*耳机通话*/
CALL_SEL_MAX,
};
enum CALL_TYPE {
CALL_OUT = 0, /*电话播出*/
CALL_INCOME, /*电话打入*/
CALL_INCOME_REJECT, /*电话打入拒接*/
};
/**********************
* GLOBAL PROTOTYPES
**********************/
/*通话记录接口*/
void small_file_call_log_set_name(char *name, int name_len);
void small_file_call_log_set_number(char *number, int number_len);
void small_file_call_log_set_date(void);
u32 small_file_call_log_get_date(void);
void small_file_call_log_set_type(enum CALL_TYPE type);
void small_file_call_log_set_sel(enum CALL_SEL call_sel);
int small_file_call_log_save(void);
int ui_small_file_call_log_read_by_index(small_file_call_log_t *call_log, int index);
int ui_small_file_call_log_get_count(void);
#endif /*_WATCH_DATA_CALL_LOG_STORAGE_*/
@@ -0,0 +1,342 @@
/**
* @file data_message_storage.c
* @brief 消息存储实现
*/
#include "app_config.h"
#include "sys_time.h"
#include "flashdb.h"
#include "data_storage.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[MSG-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".message_storage.data.bss")
#pragma data_seg(".message_storage.data")
#pragma const_seg(".message_storage.text.const")
#pragma code_seg(".message_storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE
#define WRITE_BIG_U32(a,src) {*((u8*)(a)+0) = (u8)((src)>>24); *((u8*)(a)+1) = (u8)(((src)>>16)&0xff);*((u8*)(a)+2) = (u8)(((src)>>8)&0xff);*((u8*)(a)+3) = (u8)((src)&0xff);}
static u32 ancs_message_uid;
int ui_small_file_message_get_count(void)
{
return small_file_get_count(F_TYPE_MESSAGE);
}
int small_file_message_read_by_index(small_file_message_t *message, int index)
{
/* struct fdb_kv_iterator iterator; */
/* fdb_kv_t cur_kv; */
/* struct fdb_blob blob; */
/* u32 data_size; */
u8 *data_buf;
/* int count = 0; */
u8 T;
u8 *V;
u16 L;
u16 offset = 0;
u32 copy_len;
if (!message) {
return false;
}
u32 id = small_file_get_id_by_index(F_TYPE_MESSAGE, index);
if (!id) {
return false;
}
data_buf = zalloc(512);
if (!data_buf) {
return false;
}
int ret = small_file_read(F_TYPE_MESSAGE, id, 0, data_buf, 512);
if (!ret) {
ASSERT(0);
}
/* put_buf(data_buf, ret); */
while (offset < ret) {
L = (data_buf[offset] << 8) | data_buf[offset + 1];
T = data_buf[offset + 2];
V = &data_buf[offset + 3];
if (T == MESSAGE_TIMESTAMP_TYPE) {
copy_len = (L - 1) > MESSAGE_TIMESTAMP_LEN ? MESSAGE_TIMESTAMP_LEN : (L - 1);
memcpy(&message->timestamp, V, copy_len);
/* printf("TimeStamp:0x%x",message->timestamp); */
} else if (T == MESSAGE_PACKAGENAME_TYPE) {
copy_len = (L - 1) > MESSAGE_PACKAGENAME_LEN ? MESSAGE_PACKAGENAME_LEN : (L - 1);
memset(message->packagename, 0, MESSAGE_PACKAGENAME_LEN);
memcpy(message->packagename, V, copy_len);
/* log_info("packagename:%s", temp_message_buf->packagename); */
} else if (T == MESSAGE_APP_IDENTIFIER_TYPE) {
copy_len = (L - 1) > MESSAGE_APP_IDENTIFIER_LEN ? MESSAGE_APP_IDENTIFIER_LEN : (L - 1);
memcpy(&message->app_identifier, V, copy_len);
/* log_info("AppIdentifier:%d", temp_message_buf->AppIdentifier); */
} else if (T == MESSAGE_TITLE_TYPE) {
copy_len = (L - 1) > MESSAGE_TITLE_LEN ? MESSAGE_TITLE_LEN : (L - 1);
memset(message->title, 0, MESSAGE_TITLE_LEN);
memcpy(message->title, V, copy_len);
/* log_info("title:%s", temp_message_buf->title); */
} else if (T == MESSAGE_CONTENT_TYPE) {
copy_len = (L - 1) > MESSAGE_CONTENT_LEN ? MESSAGE_CONTENT_LEN : (L - 1);
memset(message->content, 0, MESSAGE_CONTENT_LEN);
memcpy(message->content, V, copy_len);
}
offset += L + 2;
}
free(data_buf);
return true;
}
void message_set_info_from_ancs(void *info, void *name, void *data, u16 len)
{
u32 copy_len;
long date_value;
char date_string[9];
char *end;
u32 timestamp = 0;
small_file_message_t *p_msg = info;
ASSERT(p_msg);
if (!strcmp((char *)name, "UID")) {
ancs_message_uid = *(u32 *)data;
} else if (!strcmp((char *)name, "AppIdentifier")) {
copy_len = len > MESSAGE_PACKAGENAME_LEN ? MESSAGE_PACKAGENAME_LEN : len;
memset(p_msg->packagename, 0, MESSAGE_PACKAGENAME_LEN);
memcpy(p_msg->packagename, (u8 *)data, copy_len);
log_debug("packagename:%s", p_msg->packagename);
if (!strcmp((char *)data, PACKAGE_NAME_SYS_MESSAGE_SEND)) {
p_msg->app_identifier = 1;
} else if (!strcmp((char *)data, PACKAGE_NAME_SYS_MESSAGE_RECEIVE)) {
p_msg->app_identifier = 1;
} else if (!strcmp((char *)data, IOS_PACKAGE_NAME_SYS_MESSAGE)) {
p_msg->app_identifier = 1;
} else if (!strcmp((char *)data, IOS_PACKAGE_NAME_WECHAT)) {
p_msg->app_identifier = 2;
} else if (!strcmp((char *)data, IOS_PACKAGE_NAME_QQ)) {
p_msg->app_identifier = 3;
} else if (!strcmp((char *)data, IOS_PACKAGE_NAME_DING_DING)) {
p_msg->app_identifier = 4;
} else {
p_msg->app_identifier = 0;
}
log_debug("app_identifier:%d", p_msg->app_identifier);
} else if (!strcmp((char *)name, "IDTitle")) {
copy_len = len > MESSAGE_TITLE_LEN ? MESSAGE_TITLE_LEN : len;
memset(p_msg->title, 0, MESSAGE_TITLE_LEN);
memcpy(p_msg->title, (u8 *)data, copy_len);
log_debug("%s %d %d\n", data, len, __LINE__);
} else if (!strcmp((char *)name, "IDMessage")) {
copy_len = len > MESSAGE_CONTENT_LEN ? MESSAGE_CONTENT_LEN : len;
memset(p_msg->content, 0, MESSAGE_CONTENT_LEN);
memcpy(p_msg->content, (u8 *)data, copy_len);
log_debug("id_msg:%s %d %d\n", data, len, __LINE__);
} else if (!strcmp((char *)name, "IDDate")) {
/*格式:20240905T174158*/
/*秒*/
snprintf(date_string, (2 + 1), "%s", (char *)data + 13);
date_value = strtol(date_string, &end, 10);
log_debug("msc date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x3f);
/*分*/
snprintf(date_string, (2 + 1), "%s", (char *)data + 11);
date_value = strtol(date_string, &end, 10);
log_debug("min date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x3f) << 6;
/*时*/
snprintf(date_string, (2 + 1), "%s", (char *)data + 9);
date_value = strtol(date_string, &end, 10);
log_debug("hour date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x1f) << 12;
/*日*/
snprintf(date_string, (2 + 1), "%s", (char *)data + 6);
date_value = strtol(date_string, &end, 10);
log_debug("day date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x1f) << 17;
/*月*/
snprintf(date_string, (2 + 1), "%s", (char *)data + 4);
date_value = strtol(date_string, &end, 10);
log_debug("month date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x0f) << 21;
/*年*/
snprintf(date_string, (4 + 1), "%s", (char *)data);
date_value = strtol(date_string, &end, 10) - 2010;
log_debug("year date_string:%s date_value:%d", date_string, date_value);
timestamp |= (date_value & 0x3f) << 26;
WRITE_BIG_U32(&p_msg->timestamp, timestamp);
log_debug("IDDate:%s timestamp:%x, p_msg->timestamp:%x", data, timestamp, p_msg->timestamp);
}
}
void message_add_info_from_ancs(void *info)
{
u32 offset = 0;
u8 *temp_ptr = 0;
small_file_message_t *p_msg = info;
ASSERT(p_msg);
u8 packagename_len = strlen((const char *)p_msg->packagename);
u8 title_len = strlen((const char *)p_msg->title);
u8 content_len = strlen((const char *)p_msg->content);
/* length+type: 3 byte*/
u32 mess_data_len = 3 + MESSAGE_TIMESTAMP_LEN + 3 + packagename_len +
3 + MESSAGE_APP_IDENTIFIER_LEN + 3 + title_len +
3 + content_len;
temp_ptr = zalloc(mess_data_len);
if (!temp_ptr) {
log_error("temp_ptr malloc fail");
return;
}
temp_ptr[offset] = (MESSAGE_TIMESTAMP_LEN + 1) >> 8;
offset++;
temp_ptr[offset] = (MESSAGE_TIMESTAMP_LEN + 1) & 0xff;
offset++;
temp_ptr[offset] = 0;
offset++;
memcpy(&temp_ptr[offset], &p_msg->timestamp, MESSAGE_TIMESTAMP_LEN);
offset += MESSAGE_TIMESTAMP_LEN;
temp_ptr[offset] = (packagename_len + 1) >> 8;
offset++;
temp_ptr[offset] = (packagename_len + 1) & 0xff;
offset++;
temp_ptr[offset] = 1;
offset++;
memcpy(&temp_ptr[offset], p_msg->packagename, packagename_len);
offset += packagename_len;
temp_ptr[offset] = (MESSAGE_APP_IDENTIFIER_LEN + 1) >> 8;
offset++;
temp_ptr[offset] = (MESSAGE_APP_IDENTIFIER_LEN + 1) & 0xff;
offset++;
temp_ptr[offset] = 2;
offset++;
temp_ptr[offset] = p_msg->app_identifier;
offset += MESSAGE_APP_IDENTIFIER_LEN;
temp_ptr[offset] = (title_len + 1) >> 8;
offset++;
temp_ptr[offset] = (title_len + 1) & 0xff;
offset++;
temp_ptr[offset] = 3;
offset++;
memcpy(&temp_ptr[offset], p_msg->title, title_len);
offset += title_len;
temp_ptr[offset] = (content_len + 1) >> 8;
offset++;
temp_ptr[offset] = (content_len + 1) & 0xff;
offset++;
temp_ptr[offset] = 4;
offset++;
memcpy(&temp_ptr[offset], p_msg->content, content_len);
u32 file_id = ancs_message_uid;
small_file_write(F_TYPE_MESSAGE, &file_id, 0, temp_ptr, mess_data_len, mess_data_len);
log_debug("ancs_message_uid:%x, file_id:%x", ancs_message_uid, file_id);
ancs_message_uid = 0;
free(temp_ptr);
// UI SHOW
#ifdef CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE
#if TCFG_UI_MSG_NOTICE
if (ui_small_file_message_get_count() < 10) {
UI_MSG_POST("message_status:event=%4", 1);
} else {
UI_MSG_POST("message_status:event=%4", 3);
}
#endif
#endif
#if 0
if (flash_message_count() < 10) {
UI_MSG_POST("message_status:event=%4", 1);
} else {
UI_MSG_POST("message_status:event=%4", 3);
}
#else
/* u8 cur_task = app_get_curr_task(); */
/* switch (cur_task) { */
/* case APP_POWERON_TASK: */
/* case APP_POWEROFF_TASK: */
/* case APP_WATCH_UPDATE_TASK: */
/* case APP_SMARTBOX_ACTION_TASK: */
/* break; */
/* default: */
/* if (UI_WINDOW_PREEMPTION_CHECK()) { */
/* break; */
/* } */
/* if (get_screen_saver_status()) { */
/* ui_screen_recover(0); */
/* ui_auto_shut_down_enable(); */
/* UI_SHOW_WINDOW(ID_WINDOW_MESS); */
/* } else { */
/* ui_auto_shut_down_re_run(); */
/* if (UI_GET_WINDOW_ID() == ID_WINDOW_MESS) { */
/* if (flash_message_count() < 10) { */
/* UI_MSG_POST("message_status:event=%4", 1); */
/* } else { */
/* UI_MSG_POST("message_status:event=%4", 3); */
/* } */
/* } else { */
/* UI_HIDE_CURR_WINDOW(); */
/* UI_SHOW_WINDOW(ID_WINDOW_MESS); */
/* } */
/* } */
/* break; */
/* } */
#endif
// moto
/* UI_MOTO_RUN(2); */
}
#else /* if TCFG_DATA_STORAGE_ENABLE */
void message_set_info_from_ancs(void *info, void *name, void *data, u16 len)
{
}
void message_add_info_from_ancs(void *info)
{
}
int ui_small_file_message_get_count(void)
{
return 0;
}
int small_file_message_read_by_index(small_file_message_t *message, int index)
{
return 0;
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,56 @@
#ifndef _WATCH_DATA_MESSAGE_STORAGE_
#define _WATCH_DATA_MESSAGE_STORAGE_
/**********************
* TYPEDEFS
**********************/
#define MESSAGE_TIMESTAMP_TYPE (0)
#define MESSAGE_PACKAGENAME_TYPE (1)
#define MESSAGE_APP_IDENTIFIER_TYPE (2)
#define MESSAGE_TITLE_TYPE (3)
#define MESSAGE_CONTENT_TYPE (4)
#define MESSAGE_TIMESTAMP_LEN (4)
#define MESSAGE_PACKAGENAME_LEN (31+1)
#define MESSAGE_APP_IDENTIFIER_LEN (1)
#define MESSAGE_TITLE_LEN (36+1)
#define MESSAGE_CONTENT_LEN (439+1)
#define SMALL_FILE_MESSAGE_SIZE (sizeof(small_file_message_t))
#define SMALL_FILE_MESSAGE_PARTITION_NAME "message"
#define PACKAGE_NAME_SYS_MESSAGE_RECEIVE "MobileSMS_RECEIVE"
#define PACKAGE_NAME_SYS_MESSAGE_SEND "MobileSMS_SEND"
#define IOS_PACKAGE_NAME_SYS_MESSAGE "com.apple.MobileSMS"
#define IOS_PACKAGE_NAME_WECHAT "com.tencent.xin"
#define IOS_PACKAGE_NAME_QQ "com.tencent.mqq"
#define IOS_PACKAGE_NAME_DING_DING "com.laiwang.DingTalk"
#pragma pack(1)
typedef struct message {
u32 timestamp;
char packagename[MESSAGE_PACKAGENAME_LEN];
u8 app_identifier;
u8 title[MESSAGE_TITLE_LEN];
u8 content[MESSAGE_CONTENT_LEN];
} small_file_message_t;
#pragma pack()
int ui_small_file_message_get_count(void);
int small_file_message_read_by_index(small_file_message_t *message, int index);
void message_set_info_from_ancs(void *info, void *name, void *data, u16 len);
void message_add_info_from_ancs(void *info);
#endif /*_WATCH_DATA_MESSAGE_STORAGE_*/
@@ -0,0 +1,166 @@
/**
* @file data_phonebook_storage.c
* @brief 电话本存储相关
*/
#include "app_config.h"
#include "flashdb.h"
#include "fdb_low_lvl.h"
#include "data_storage.h"
#include "data_phonebook_storage.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[PBOOK-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".phonebook_storage.bss")
#pragma data_seg(".phonebook_storage.data")
#pragma const_seg(".phonebook_storage.text.const")
#pragma code_seg(".phonebook_storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE
int ui_small_file_phonebook_get_count(void)
{
int phonebook_count;
u32 file_len = small_file_get_size_by_index(F_TYPE_PHONEBOOK, 0);
phonebook_count = file_len / SMALL_FILE_PHONEBOOK_SIZE;
return phonebook_count;
}
int ui_small_file_phonebook_read_by_index(small_file_phonebook_t *phonebook, int index)
{
int ret;
if (!phonebook) {
return false;
}
u32 id = small_file_get_id_by_index(F_TYPE_PHONEBOOK, 0);
if (!id) {
return false;
}
int phonebook_count = ui_small_file_phonebook_get_count();
if (index >= phonebook_count) {
return false;
}
ret = small_file_read(F_TYPE_PHONEBOOK, id, index * sizeof(struct small_file_phonebook), phonebook, sizeof(struct small_file_phonebook));
/*jlui框架显示文字,数字需要用到结束符。避免app传过来,不带结束符。*/
phonebook->name[PHONEBOOK_NAME_LEN - 1] = 0;
phonebook->number[PHONEBOOK_NUMBER_LEN - 1] = 0 ;
if (ret == sizeof(struct small_file_phonebook)) {
return true;
}
return false;
}
/*电话号码除去空格*/
static int phone_number_neaten(const char *in_number, char *out_number)
{
int out_len = 0;
for (int i = 0; i < PHONEBOOK_NUMBER_LEN - 1; i++) {
if (in_number[i] != ' ') {
out_number[out_len++] = in_number[i];
}
}
out_number[out_len] = 0;
return out_len;
}
int small_file_phonebook_get_name_by_number(char *name, char *number)
{
int phonebook_count;
small_file_phonebook_t phonebook;
char temp_number[PHONEBOOK_NUMBER_LEN];
if (!name || !number) {
return false;
}
phonebook_count = ui_small_file_phonebook_get_count();
if (!phonebook_count) {
memcpy(name, "UNKNOW", strlen("UNKNOW") + 1);
return false;
}
for (int i = 0; i < phonebook_count; i++) {
ui_small_file_phonebook_read_by_index(&phonebook, i);
phone_number_neaten(phonebook.number, temp_number);
if (!strcmp(temp_number, number)) {
memcpy(name, phonebook.name, sizeof(phonebook.name));
return true;
}
}
memcpy(name, "UNKNOW", strlen("UNKNOW") + 1);
return false;
}
/************************************************
* 测试用例
***********************************************/
#if 0
small_file_phonebook_t test_phonebook[] = {
{"aaaaa", "12345678123"},
{"张三", "13452341111"},
{"测试号码", "19507567268"},
{"你好", "546 2563462"},
{"ddddd", "04809234"},
{"李四", "049 852 09348"},
};
void watch_data_phonebook_test(void)
{
/*不带id创建*/
/* u32 create_id = 0; */
/*带id创建*/
u32 create_id = 0x2198abcd;
small_file_write(F_TYPE_PHONEBOOK, &create_id, 0, test_phonebook, sizeof(test_phonebook), sizeof(test_phonebook));
printf("<%s> create_id:%x", __func__, create_id);
u8 *read_phonebook_buf = zalloc(sizeof(test_phonebook));
small_file_read(F_TYPE_PHONEBOOK, create_id, 0, read_phonebook_buf, sizeof(test_phonebook));
put_buf(read_phonebook_buf, sizeof(test_phonebook));
char name[PHONEBOOK_NAME_LEN] = {0};
if (small_file_phonebook_get_name_by_number(name, "13452341111")) {
printf("<%s> find name:%s", __func__, name);
}
small_file_delete_by_id(F_TYPE_PHONEBOOK, create_id);
}
#endif
#else /* if TCFG_DATA_STORAGE_ENABLE */
int ui_small_file_phonebook_get_count(void)
{
return 0;
}
int ui_small_file_phonebook_read_by_index(small_file_phonebook_t *phonebook, int index)
{
return 0;
}
int small_file_phonebook_get_name_by_number(char *name, char *number)
{
return 0;
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,45 @@
#ifndef _WATCH_DATA_PHONEBOOK_STORAGE_
#define _WATCH_DATA_PHONEBOOK_STORAGE_
/*********************
* DEFINES
*********************/
#define PHONEBOOK_NAME_LEN (20)
#define PHONEBOOK_NUMBER_LEN (20)
#define SMALL_FILE_PHONEBOOK_SIZE (sizeof(small_file_phonebook_t))
/**********************
* TYPEDEFS
**********************/
typedef struct small_file_phonebook {
char name[PHONEBOOK_NAME_LEN];
char number[PHONEBOOK_NUMBER_LEN];
} small_file_phonebook_t;
/* ------------------------------------------------------------------------------------*/
/**
* @brief 获取存储的联系人数量
*/
/* ------------------------------------------------------------------------------------*/
int ui_small_file_phonebook_get_count(void);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过index获取对应的联系人信息
*
* @Params phonebook 存储读取到的联系人信息
* @Params index 序号
*
* @Return true or false
*/
/* ------------------------------------------------------------------------------------*/
int ui_small_file_phonebook_read_by_index(small_file_phonebook_t *phonebook, int index);
int small_file_phonebook_get_name_by_number(char *name, char *number);
#endif /*_WATCH_DATA_PHONEBOOK_STORAGE_*/
@@ -0,0 +1,263 @@
#include "app_config.h"
#include "includes.h"
#include "typedef.h"
#include "file_simple_transfer.h"
#include "rcsp_config.h"
#include "data_storage.h"
#include "app_config.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-ADAPTOR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if (RCSP_MODE && TCFG_DEV_MANAGER_ENABLE && JL_RCSP_SIMPLE_TRANSFER)
//*----------------------------------------------------------------------------*/
/**@brief 获取当前类型小文件列表
@param 无
@return 数量*4
@note
*/
/*----------------------------------------------------------------------------*/
static int simple_trans_get_id_table_len(u8 file_type)
{
#if TCFG_DATA_STORAGE_ENABLE
return small_file_get_id_table_len(file_type);
#else
return 0;
#endif
}
static int simple_trans_get_id_table(u8 file_type, u8 *table_data, u16 data_len)
{
#if TCFG_DATA_STORAGE_ENABLE
return small_file_get_id_table(file_type, table_data, data_len);
#else
return 0;
#endif
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief 读取小文件数据
*
* @Return 读取的字节数
*/
/* ------------------------------------------------------------------------------------*/
static int simple_trans_read_file_by_id(u8 file_type, u16 id, u32 data_offset, u8 *data, u16 data_len)
{
#if TCFG_DATA_STORAGE_ENABLE
int rlen;
rlen = small_file_read(file_type, id, data_offset, data, data_len);
log_info_hexdump(data, rlen);
log_info("%s file_type:%d id:%d data_offset:%d data_len:%d rlen:%d\n", __FUNCTION__, file_type, id, data_offset, data_len, rlen);
return rlen;
#else
return 0;
#endif
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief 写入小文件数据
*
* @Return 0:成功 -1:失败
*/
/* ------------------------------------------------------------------------------------*/
static int simple_trans_insert_file_by_id(u8 file_type, u16 *id, u32 data_offset, u8 *data, u16 data_len, u16 file_total_size)
{
log_info("<%s> file_type:%d, id:%x, data_offset:%x, data_len:%x, file_total_size:%x\n", __func__, file_type, *id, data_offset, data_len, file_total_size);
log_info_hexdump(data, data_len);
#if TCFG_DATA_STORAGE_ENABLE
//TODO 判断这个文件剩余空间是否足够
//
//
u32 creat_id;
creat_id = *id;
int ret = small_file_write(file_type, &creat_id, data_offset, data, data_len, file_total_size);
if (ret != data_len) {
*id = 0;
} else {
*id = (u16)creat_id;
}
log_info("<%s> creat id:%d", __func__, *id);
if (ret != data_len) {
log_error("<%s> fail:%d %d", __func__, ret, data_len);
return -1;
}
//TODO ui页面显示
#if TCFG_UI_ENABLE_SMARTWIN|| TCFG_UI_ENABLE_NOTICE
if (file_type == F_TYPE_MESSAGE) {
//灵动岛
UI_MSG_POST("smartwin_status:message=%4", 1);
//消息通知
if (ui_small_file_message_get_count() < 10) {
UI_MSG_POST("message_status:event=%4", 1);
} else {
UI_MSG_POST("message_status:event=%4", 3);
}
}
#endif
#ifdef CONFIG_UI_STYLE_JL_CSC_PUBLIC_MODLS_ENABLE
#if TCFG_UI_MSG_NOTICE
if (ui_small_file_message_get_count() < 10) {
UI_MSG_POST("message_status:event=%4", 1);
} else {
UI_MSG_POST("message_status:event=%4", 3);
}
#endif
#endif
return 0;
#endif
return -1;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief 更新小文件数据
*
* @Return 0:成功 -1:失败
*/
/* ------------------------------------------------------------------------------------*/
static int simple_trans_update_file_by_id(u8 file_type, u16 id, u32 data_offset, u8 *data, u16 data_len, u16 file_total_size)
{
log_info("<%s> id:%d, data_offset:%d, data_len:%d, file_total_size:%d", __func__, id, data_offset, data_len, file_total_size);
log_info_hexdump(data, data_len);
#if TCFG_DATA_STORAGE_ENABLE
//TODO 判断这个文件剩余空间是否足够
u32 creat_id;
creat_id = id;
int ret = small_file_write(file_type, &creat_id, data_offset, data, data_len, file_total_size);
if (ret != data_len) {
return -1;
}
return 0;
//TODO ui页面显示
#else
return -1;
#endif
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief 删除小文件数据
*
* @Return 0:成功 -1:失败
*/
/* ------------------------------------------------------------------------------------*/
static int simple_trans_delete_file_by_id(u8 file_type, u16 id)
{
log_info("<%s> file_type:%d, id:%d", __func__, file_type, id);
#if TCFG_DATA_STORAGE_ENABLE
int ret;
ret = small_file_delete_by_id(file_type, id);
if (ret == false) {
return -1;
}
#if TCFG_UI_MSG_NOTICE ||TCFG_UI_ENABLE_NOTICE
if (file_type == F_TYPE_MESSAGE) {
//消息通知
UI_MSG_POST("message_status:event=%4", 2);
}
#endif
return 0;
#else
return -1;
#endif
}
static const rcsp_simple_trans_opt g_test_trans_opt = {
.get_id_table_len = simple_trans_get_id_table_len,
.get_id_table = simple_trans_get_id_table,
.read_file_by_id = simple_trans_read_file_by_id,
.insert_file_by_id = simple_trans_insert_file_by_id,
.update_file_by_id = simple_trans_update_file_by_id,
.delete_file_by_id = simple_trans_delete_file_by_id,
};
int test_simple_trans(void)
{
rcsp_register_file_simple_transfer_interface((rcsp_simple_trans_opt *)&g_test_trans_opt);
return 0;
}
late_initcall(test_simple_trans);
#endif
#if TCFG_DATA_STORAGE_ENABLE
#if TRANS_ANCS_EN
static small_file_message_t *ancs_message_temp;
void notice_set_info_from_ancs(void *name, void *data, u16 len)
{
if (!ancs_message_temp) {
ancs_message_temp = zalloc(SMALL_FILE_MESSAGE_SIZE);
}
if (!ancs_message_temp) {
log_error("ancs_message_temp is NULL !!!");
return;
}
message_set_info_from_ancs(ancs_message_temp, name, data, len);
}
void notice_add_info_from_ancs()
{
if (!ancs_message_temp) {
log_error("ancs_message_temp must be valid !!!");
return;
}
message_add_info_from_ancs(ancs_message_temp);
if (ancs_message_temp) {
free(ancs_message_temp);
ancs_message_temp = NULL;
}
#if TCFG_UI_ENABLE_SMARTWIN|| TCFG_UI_ENABLE_NOTICE
//灵动岛
UI_MSG_POST("smartwin_status:message=%4", 1);
//消息通知
if (ui_small_file_message_get_count() < 10) {
UI_MSG_POST("message_status:event=%4", 1);
} else {
UI_MSG_POST("message_status:event=%4", 3);
}
#endif
}
void notice_remove_info_from_ancs(u32 uid)
{
if (ui_small_file_message_get_count() == 0) {
log_warn("message null!!!");
return;
}
log_debug("<%s> uid:%x", __func__, uid);
small_file_delete_by_id(F_TYPE_MESSAGE, uid);
#if TCFG_UI_ENABLE_NOTICE
UI_MSG_POST("message_status:event=%4", 2);
#endif
}
#endif //#if TRANS_ANCS_EN
#endif //#if TCFG_DATA_STORAGE_ENABLE
+199
View File
@@ -0,0 +1,199 @@
#ifndef _WATCH_DATA_STORAGE_H
#define _WATCH_DATA_STORAGE_H
/*********************
* INCLUDES
*********************/
#include "data_phonebook_storage.h"
#include "data_call_log_storage.h"
#include "data_message_storage.h"
#include "data_weather_storage.h"
/*********************
* DEFINES
*********************/
/* 小文件类型 */
#define F_TYPE_BASE (1)
#define F_TYPE_PHONEBOOK (F_TYPE_BASE)
#define F_TYPE_SPORTRECORD (F_TYPE_BASE+1)
#define F_TYPE_HEART (F_TYPE_BASE+2)
#define F_TYPE_BLOOD_OXYGEN (F_TYPE_BASE+3)
#define F_TYPE_SLEEP (F_TYPE_BASE+4)
#define F_TYPE_MESSAGE (F_TYPE_BASE+5)
#define F_TYPE_WEATHER (F_TYPE_BASE+6)
#define F_TYPE_CALL_LOG (F_TYPE_BASE+7)
#define F_TYPE_STEP (F_TYPE_BASE+8)
#define F_TYPE_HEART_SINGLE (F_TYPE_BASE+9)
#define F_TYPE_BLOOD_OXYGEN_SINGLE (F_TYPE_BASE+10)
#define F_TYPE_MAX (F_TYPE_BLOOD_OXYGEN_SINGLE)
#define F_TYPE_COUNT (F_TYPE_MAX +1- F_TYPE_BASE)
#define ID_TABLE_ITEM_SIZE 4
/*ID_TABLE 格式:每一项4个字节 低位两个字节file_id 高位两个字节file_size*/
/**********************
* TYPEDEFS
**********************/
struct small_file {
u8 type;
u8 max_item;
u8 storage_sel;
};
int data_small_file_init(void);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过id,读取对应小文件内容
*
* @Params small_file_type 小文件类型
* @Params id 文件id
* @Params buf 存储要读取文件数据的buffer
* @Params len 要读取的数据长度
*
* @Return 读取到的字节数
*/
/* ------------------------------------------------------------------------------------*/
int small_file_read(u8 small_file_type, u32 id, u32 offset, void *buf, u32 len);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 写入小文件数据
*
* @Params small_file_type 小文件类型
* @Params buf_offset 要写入数据的偏移
* @Params buf 存储写入文件数据的buffer
* @Params len 要写入数据的长度
*
* @Return 写入成功 返回u16位大小的id; 写入失败 返回id为0
*/
/* ------------------------------------------------------------------------------------*/
u32 small_file_write(u8 small_file_type, u32 *id, u32 buf_offset, void *buf, u32 len, u32 total_len);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过id,更新对应小文件内容(仅原来内容范围内)
*
* @Params small_file_type 小文件类型
* @Params id 文件id
* @Params buf_offset 要写入数据的偏移
* @Params buf 存储写入文件数据的buffer
* @Params len 要写入数据的长度
*
* @Return 实际写入长度
*/
/* ------------------------------------------------------------------------------------*/
int small_file_update_by_id(u8 small_file_type, u32 id, u32 buf_offset, void *buf, u32 len, u32 total_len);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过id,删除小文件
*
* @Params file_type 小文件类型
* @Params id 文件id
*
* @Return false or true
*/
/* ------------------------------------------------------------------------------------*/
int small_file_delete_by_id(u8 small_file_type, u32 id);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 删除所有小文件
*
* @Return false or true
*/
/* ------------------------------------------------------------------------------------*/
int small_file_del_all(void);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 获取小文件的id_table的大小
*
* @Params small_file_type 小文件类型
*
* @Return length of the id_table
*/
/* ------------------------------------------------------------------------------------*/
int small_file_get_id_table_len(u8 small_file_type);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 获取小文件的id_table
*
* @Params small_file_type
* @Params table_data Pointer to the buffer where the id_table data will be stored.
* @Params data_len The length of the table_data buffer.
*
* @Return false or true
*/
/* ------------------------------------------------------------------------------------*/
int small_file_get_id_table(u8 small_file_type, u8 *table_data, u16 data_len);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 获取小文件的数量
*
* @Params small_file_type 小文件类型
*
*/
/* ------------------------------------------------------------------------------------*/
int small_file_get_count(u8 small_file_type);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过index获取小文件的id
*
* @Params small_file_type 小文件类型
* @Params index 文件存储顺序序号
*
* @Return 文件id
*/
/* ------------------------------------------------------------------------------------*/
u32 small_file_get_id_by_index(u8 small_file_type, int index);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过index获取小文件的大小
*
* @Params small_file_type 小文件类型
* @Params index 文件存储顺序序号
*
* @Return 文件大小
*/
/* ------------------------------------------------------------------------------------*/
u32 small_file_get_size_by_index(u8 small_file_type, int index);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 通过id获取小文件的大小
*
* @Params small_file_type 小文件类型
* @Params index 文件存储顺序序号
*
* @Return 文件大小
*/
/* ------------------------------------------------------------------------------------*/
u32 small_file_get_size_by_id(u8 small_file_type, int id);
/* ------------------------------------------------------------------------------------*/
/**
* @brief 删除某一小文件类型下的文件
*
* @Params small_file_type 小文件类型
*
* @Return false or true
*/
/* ------------------------------------------------------------------------------------*/
int small_file_del_by_file_type(u8 small_file_type);
#endif /*_WATCH_DATA_STORAGE_H*/
@@ -0,0 +1,913 @@
#include "app_config.h"
#include "asm/cpu.h"
#include "device/device.h"
#include "flashdb.h"
#include "data_storage.h"
#include "os/os_api.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[FDB-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".storage.data.bss")
#pragma data_seg(".storage.data")
#pragma const_seg(".storage.text.const")
#pragma code_seg(".storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE && (TCFG_DATA_STORAGE_FDB_ENABLE||TCFG_DATA_STORAGE_FDB_EXFLASH_ENABLE)
static struct small_file_hd *hd;
struct small_file_info {
u8 type; /*文件类型*/
u8 max_item; /*文件数量最大值*/
u8 cur_item; /*当前文件数量*/
u8 storage_sel; /*对应数据库*/
u16 *size_table; /*每个文件对应的大小*/
u32 *table; /*每个文件对应的id*/
};
#define SMALL_FILE_DB_NAME "small_file_kvdb"
#define SMALL_FILE_PARTITION_NAME "small_file_partition"
#define USED_KVDB_MAX 1
#define USED_TSDB_MAX 1
#define USED_KVDB_0 0
#define USED_KVDB_1 1
#define USED_KVDB_2 2
#define USED_KVDB_3 3
#define USED_TSDB_0 4
#define USED_TSDB_1 5
#define USED_TSDB_2 6
#define USED_TSDB_3 7
#define NAME_FILE_LEN 13
struct small_file_hd {
struct small_file_info *child;
struct fdb_kvdb *kvdb[USED_KVDB_MAX];
struct fdb_tsdb *tsdb[USED_TSDB_MAX];
OS_MUTEX db_mutex;
OS_MUTEX mutex;
};
const struct small_file data_small_file_info[] = {
{F_TYPE_PHONEBOOK, 1, USED_KVDB_0},
{F_TYPE_MESSAGE, 10, USED_KVDB_0},
{F_TYPE_SPORTRECORD, 1, USED_KVDB_0},
{F_TYPE_HEART, 1, USED_KVDB_0},
{F_TYPE_BLOOD_OXYGEN, 1, USED_KVDB_0},
{F_TYPE_SLEEP, 1, USED_KVDB_0},
{F_TYPE_WEATHER, 1, USED_KVDB_0},
{F_TYPE_CALL_LOG, 10, USED_KVDB_0},
{F_TYPE_STEP, 1, USED_KVDB_0},
};
extern int small_file_table_init(u8 small_file_type);
#define VM_MASK 0x55
#define VM_MASK_BIT 40//24
#define TYPE_BIT 32//16
static u32 __is_name2mask(char *name)
{
char *end;
char temp[9];
snprintf(temp, NAME_FILE_LEN - sizeof(temp) + 1, "%s", name);
long intValue = strtol(temp, &end, 16);
if (*end == '\0') { // 确保整个字符串都被成功转换
} else {
/* return false; */
}
u8 mask = (intValue >> (VM_MASK_BIT - 32)) & 0xff;
if (mask == VM_MASK) {
return true;
}
return false;
}
static u32 __type_name2id(char *name)
{
char *end;
char temp[9];
snprintf(temp, NAME_FILE_LEN - sizeof(temp) + 1, "%s", name);
long intValue = strtol(temp, &end, 16);
if (*end == '\0') { // 确保整个字符串都被成功转换
/* printf("The integer value of %s is %lx\n", name, intValue); */
} else {
/* printf("Invalid hexadecimal string\n"); */
/* return 0; */
}
u8 mask = (intValue >> (VM_MASK_BIT - 32)) & 0xff;
if (mask == VM_MASK) {
snprintf(temp, sizeof(temp), "%s", name + (NAME_FILE_LEN - sizeof(temp)));
intValue = strtol(temp, &end, 16);
return (intValue) & 0xffffffff;
}
return 0;
}
static u32 __type_name2type(char *name)
{
char *end;
char temp[9];
snprintf(temp, NAME_FILE_LEN - sizeof(temp) + 1, "%s", name);
long intValue = strtol(temp, &end, 16);
if (*end == '\0') { // 确保整个字符串都被成功转换
/* printf("The integer value of %s is %lx\n", name, intValue); */
} else {
/* printf("Invalid hexadecimal string\n"); */
/* return 0; */
}
u8 mask = (intValue >> (VM_MASK_BIT - 32)) & 0xff;
if (mask == VM_MASK) {
return (intValue >> (TYPE_BIT - 32)) & 0xff;
}
return 0;
}
static char *__type_id2name(char *name, u8 file_type, u32 id)
{
sprintf(name, "%02x%02x%08x", (int)VM_MASK, file_type, (u32)id);
return name;
}
static u32 __new_id_create(void *priv, int min, int max)
{
struct small_file_info *file = (struct small_file_info *)priv;
u32 id = min;
/*最小不重复id*/
__again:
for (int index = 0; index < file->cur_item; index++) {
if (file->table[index] == id) {
id ++;
if (!id || id > max) {
id = min;
}
goto __again;
}
}
return id;
}
static u32 __is_new_id(struct small_file_info *info, u32 id)
{
if (!id) {
return true;
}
for (int index = 0; index < info->cur_item; index++) {
if (info->table[index] == id) {
return false;
}
}
return true;
}
static u32 __find_id_index(struct small_file_info *info, u32 id)
{
for (int index = 0; index < info->cur_item; index++) {
if (info->table[index] == id) {
return index;
}
}
return info->cur_item;
}
static fdb_time_t get_time(void)
{
static int counts = 0;
/* Using the counts instead of timestamp.
* Please change this function to return RTC time.
*/
return ++counts;
}
void flashdb_lock(fdb_db_t db)
{
if (hd) {
os_mutex_pend(&hd->db_mutex, 0);
}
}
void flashdb_unlock(fdb_db_t db)
{
if (hd) {
os_mutex_post(&hd->db_mutex);
}
}
int data_small_file_init(void)
{
fdb_err_t result;
if (!hd) {
hd = zalloc(sizeof(struct small_file_hd) \
+ F_TYPE_COUNT * sizeof(struct small_file_info));
}
hd->child = (struct small_file_info *)(hd + 1);
os_mutex_create(&hd->mutex);
os_mutex_create(&hd->db_mutex);
int flag = 0;
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file *file = (struct small_file *)&data_small_file_info[i];
if (!file->type) {
continue;
}
flag |= BIT(file->storage_sel);
hd->child[file->type].type = file->type;
hd->child[file->type].max_item = file->max_item;
hd->child[file->type].storage_sel = file->storage_sel;
hd->child[file->type].table = (u32 *)zalloc(sizeof(u32) * file->max_item);
hd->child[file->type].size_table = (u16 *)zalloc(sizeof(u16) * file->max_item);
}
//先支持单个
if (flag & 0x0f) {
hd->kvdb[0] = (struct fdb_kvdb *)zalloc(sizeof(struct fdb_kvdb) * USED_KVDB_MAX);
result = fdb_kvdb_init(hd->kvdb[0], SMALL_FILE_DB_NAME, SMALL_FILE_PARTITION_NAME, NULL, NULL);
fdb_kvdb_control(hd->kvdb[0], FDB_KVDB_CTRL_SET_LOCK, flashdb_lock);
fdb_kvdb_control(hd->kvdb[0], FDB_KVDB_CTRL_SET_UNLOCK, flashdb_unlock);
if (result != FDB_NO_ERR) {
log_error("kvdb init fail\n");
goto __err;
}
}
if (flag & 0xf0) {
hd->tsdb[0] = (struct fdb_tsdb *)zalloc(sizeof(struct fdb_tsdb) * USED_TSDB_MAX);
result = fdb_tsdb_init(hd->tsdb[0], SMALL_FILE_DB_NAME, SMALL_FILE_PARTITION_NAME, get_time, 128, NULL);
fdb_tsdb_control(hd->tsdb[0], FDB_TSDB_CTRL_SET_LOCK, flashdb_lock);
fdb_tsdb_control(hd->tsdb[0], FDB_TSDB_CTRL_SET_UNLOCK, flashdb_unlock);
if (result != FDB_NO_ERR) {
log_error("tsdb init fail\n");
goto __err;
}
}
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file *file = (struct small_file *)&data_small_file_info[i];
small_file_table_init(file->type);
}
return true;
__err:
return false;
}
u32 small_file_get_id_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
u32 id;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
if (!file->cur_item || index >= file->cur_item) {
return 0;
}
os_mutex_pend(&hd->mutex, 0);
id = file->table[index];
os_mutex_post(&hd->mutex);
return id;
}
int small_file_info_delete_by_index(struct small_file_info *file, int index)
{
fdb_err_t result;
struct fdb_kvdb *kvdb;
if (!hd) {
return 0;
}
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
if (!file->cur_item || index >= file->cur_item) {
return 0;
}
os_mutex_pend(&hd->mutex, 0);
u32 id = file->table[index];
for (; index < file->cur_item - 1; index++) {
file->table[index] = file->table[index + 1];
file->size_table[index] = file->size_table[index + 1];
}
--file->cur_item;
file->table[file->cur_item] = 0;
file->size_table[file->cur_item] = 0;
char name[NAME_FILE_LEN];
__type_id2name(name, file->type, id);
printf(">>>>>>>>>>>>>>>>> %s %s %d\n", __FUNCTION__, name, id);
result = fdb_kv_del(kvdb, name);
if (result != FDB_NO_ERR) {
goto __err;
}
log_info("<%s> id:%d succ!", __func__, id);
os_mutex_post(&hd->mutex);
return true;
__err:
os_mutex_post(&hd->mutex);
return false;
}
int small_file_del_all(void)
{
int flag = 0;
fdb_err_t result;
if (!hd) {
return false;
}
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file *file = (struct small_file *)&data_small_file_info[i];
if (!file->type) {
continue;
}
flag |= BIT(file->storage_sel);
}
os_mutex_pend(&hd->mutex, 0);
//先支持单个
if (flag & 0x0f) {
result = fdb_kv_set_default(hd->kvdb[0]);
if (result != FDB_NO_ERR) {
log_error("kvdb deinit fail\n");
goto __err;
}
}
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file *file = (struct small_file *)&data_small_file_info[i];
if (!file->type) {
continue;
}
hd->child[file->type].cur_item = 0;
memset(hd->child[file->type].table, 0, (sizeof(u32) * file->max_item));
memset(hd->child[file->type].size_table, 0, (sizeof(u16) * file->max_item));
}
log_info("<%s> succ!", __func__);
os_mutex_post(&hd->mutex);
return true;
__err:
log_error("<%s> del small_file error", __func__);
os_mutex_post(&hd->mutex);
return false;
}
int small_file_delete_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
return small_file_info_delete_by_index(file, index);
}
u32 small_file_write(u8 small_file_type, u32 *id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
fdb_err_t result;
struct fdb_blob blob;
struct small_file_info *file;
struct fdb_kv kv;
struct fdb_kvdb *kvdb;
u8 is_new_id = 1;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
if (!*id) {
if (buf_offset) {
ASSERT(file->cur_item);
*id = file->table[file->cur_item - 1];
//临时特殊处理一下app 不发id号
}
}
is_new_id = __is_new_id(file, *id);
while (is_new_id && file->cur_item >= file->max_item) {
small_file_info_delete_by_index(file, 0);
}
if (!*id) {
*id = __new_id_create(file, 0x1, 0xffff);
}
char name[NAME_FILE_LEN];
__type_id2name(name, file->type, *id);
__agin:
if (buf_offset) {
if (fdb_kv_get_obj(kvdb, name, &kv)) {
/* if (kv.value_len >= buf_offset) { */
u8 *temp_data = zalloc(buf_offset + len);
fdb_kv_get_blob(kvdb, name, fdb_blob_make(&blob, temp_data, kv.value_len));
memcpy(&temp_data[buf_offset], buf, len);
result = fdb_kv_set_blob(kvdb, name, fdb_blob_make(&blob, temp_data, buf_offset + len));
free(temp_data);
/* } else { */
/* goto __err; */
/* } */
} else {
goto __err;
}
} else {
result = fdb_kv_set_blob(kvdb, name, fdb_blob_make(&blob, buf, len));
}
if (result != FDB_NO_ERR) {
small_file_delete_by_index(small_file_type, 0);
goto __agin;
}
if (is_new_id) {
file->table[file->cur_item] = *id;
file->size_table[file->cur_item] = len;
file->cur_item++;
} else {
u32 cur_item = __find_id_index(file, *id);
file->table[cur_item] = *id;
file->size_table[cur_item] = buf_offset + len;
if (cur_item == file->cur_item) {
file->cur_item++;
log_info("<%s> id:%d del rwrite", __func__, *id);
}
}
log_info("<%s> id:%d succ!", __func__, *id);
os_mutex_post(&hd->mutex);
return len;
__err:
os_mutex_post(&hd->mutex);
return 0;
}
int small_file_update_by_id(u8 small_file_type, u32 id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
fdb_err_t result;
struct fdb_blob blob;
struct small_file_info *file;
struct fdb_kv kv;
struct fdb_kvdb *kvdb;
u8 is_new_id = 1;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
if (!id) {
return 0;
}
char name[NAME_FILE_LEN];
__type_id2name(name, file->type, id);
__agin:
if (fdb_kv_get_obj(kvdb, name, &kv)) {
if (kv.value_len < (buf_offset + len)) {
goto __err;
}
u8 *temp_data = zalloc(kv.value_len);
fdb_kv_get_blob(kvdb, name, fdb_blob_make(&blob, temp_data, kv.value_len));
memcpy(&temp_data[buf_offset], buf, len);
result = fdb_kv_set_blob(kvdb, name, fdb_blob_make(&blob, temp_data, kv.value_len));
free(temp_data);
} else {
goto __err;
}
if (result != FDB_NO_ERR) {
goto __agin;
}
log_info("<%s> id:%d succ!", __func__, id);
os_mutex_post(&hd->mutex);
return len;
__err:
os_mutex_post(&hd->mutex);
return 0;
}
int small_file_read(u8 small_file_type, u32 id, u32 offset, void *buf, u32 len)
{
int ret = len;
struct fdb_blob blob;
struct fdb_kvdb *kvdb;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
struct small_file_info *file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
if (!file->cur_item) {
goto __err;
}
u8 *temp_data = zalloc(offset + len);
char name[NAME_FILE_LEN];
__type_id2name(name, file->type, id);
/* printf("%s %d %s \n", __FUNCTION__, __LINE__, name); */
fdb_kv_get_blob(kvdb, name, fdb_blob_make(&blob, temp_data, offset + len));
if (blob.saved.len > offset) {
if (blob.saved.len < offset + len) {
ret = blob.saved.len - offset;
}
memcpy(buf, &temp_data[offset], ret);
} else {
ret = 0;
}
free(temp_data);
os_mutex_post(&hd->mutex);
return ret;
__err:
os_mutex_post(&hd->mutex);
return 0;
}
int small_file_delete_by_id(u8 small_file_type, u32 id)
{
fdb_err_t result;
struct small_file_info *file;
struct fdb_kvdb *kvdb;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
os_mutex_pend(&hd->mutex, 0);
if (!file->cur_item) {
goto __err;
}
u32 index = __find_id_index(file, id);
if (index == file->cur_item) {
goto __err;
}
for (; index < file->cur_item - 1; index++) {
file->table[index] = file->table[index + 1];
file->size_table[index] = file->size_table[index + 1];
}
--file->cur_item;
file->table[file->cur_item] = 0;
file->size_table[file->cur_item] = 0;
char name[NAME_FILE_LEN];
__type_id2name(name, file->type, id);
printf(">>>>>>>>>>>>>>>>> %s %s\n", __FUNCTION__, name);
result = fdb_kv_del(kvdb, name);
if (result != FDB_NO_ERR) {
goto __err;
}
log_info("<%s> id:%d succ!", __func__, id);
os_mutex_post(&hd->mutex);
return true;
__err:
os_mutex_post(&hd->mutex);
return false;
}
int small_file_get_id_table_len(u8 small_file_type)
{
return small_file_get_id_table(small_file_type, NULL, 0);
}
int small_file_table_init(u8 small_file_type)
{
int index = 0;
struct small_file_info *file;
struct fdb_kvdb *kvdb;
struct fdb_kv_iterator iterator;
fdb_kv_t cur_kv;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
flashdb_lock(NULL);
fdb_kv_iterator_init(&iterator);
while (fdb_kv_iterate(kvdb, &iterator)) {
cur_kv = &(iterator.curr_kv);
if (!__is_name2mask(cur_kv->name)) {
printf("del name %s \n", cur_kv->name);
fdb_kv_del(kvdb, cur_kv->name);
}
if (__type_name2type(cur_kv->name) == file->type) {
u32 id = __type_name2id(cur_kv->name);
printf("name %s %d \n", cur_kv->name, id);
if (index < file->max_item) {
file->size_table[file->cur_item] = cur_kv->value_len;
file->table[file->cur_item] = id;
file->cur_item++;
index++;
} else {
printf("file over del name %s \n", cur_kv->name);
fdb_kv_del(kvdb, cur_kv->name);
}
}
}
flashdb_unlock(NULL);
os_mutex_post(&hd->mutex);
return index ;
}
int small_file_get_count(u8 small_file_type)
{
int count;
struct small_file_info *file;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
count = file->cur_item;
os_mutex_post(&hd->mutex);
return count;
}
int small_file_get_id_table(u8 small_file_type, u8 *table_data, u16 data_len)
{
int count;
struct small_file_info *file;
if (!hd) {
return 0;
}
u16 id;
u16 file_len;
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
count = file->cur_item;
for (int i = 0; (i < count) && (i * 4 < data_len); i++) {
if (table_data) {
id = (u16)file->table [i];
file_len = (u16)file->size_table [i];
memcpy(table_data, &id, sizeof(u16));
table_data += 2;
memcpy(table_data, &file_len, sizeof(u16));
table_data += 2;
}
}
os_mutex_post(&hd->mutex);
return count * 4;
}
u32 small_file_get_size_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
u32 size;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
if (!file->cur_item || index >= file->cur_item) {
return 0;
}
os_mutex_pend(&hd->mutex, 0);
size = file->size_table[index];
os_mutex_post(&hd->mutex);
return size;
}
u32 small_file_get_size_by_id(u8 small_file_type, int id)
{
struct small_file_info *file;
u32 size = 0;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
os_mutex_pend(&hd->mutex, 0);
for (int index = 0; index < file->cur_item; index++) {
if (file->table[index] == id) {
size = file->size_table[index];
}
}
os_mutex_post(&hd->mutex);
return size;
}
int small_file_del_by_file_type(u8 small_file_type)
{
fdb_err_t result;
struct small_file_info *file;
u32 id;
char name[NAME_FILE_LEN];
struct fdb_kvdb *kvdb;
if (!hd) {
return false;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
kvdb = hd->kvdb[file->storage_sel % USED_KVDB_MAX];
os_mutex_pend(&hd->mutex, 0);
if (!file->cur_item) {
log_error("<%s> file->cur_item is 0", __func__);
goto __err;
}
while (file->cur_item) {
id = file->table[file->cur_item - 1];
__type_id2name(name, file->type, id);
result = fdb_kv_del(kvdb, name);
if (result != FDB_NO_ERR) {
goto __err;
}
file->table[file->cur_item - 1] = 0;
file->size_table[file->cur_item - 1] = 0;
--file->cur_item;
}
log_info("<%s> succ!", __func__);
os_mutex_post(&hd->mutex);
return true;
__err:
log_error("<%s> del small_file error", __func__);
os_mutex_post(&hd->mutex);
return false;
}
/************************************************
* 注册flashDB的分区
***********************************************/
REGISTER_FLASHDB_PARTITION(phonebook_partition) = {
.name = SMALL_FILE_PARTITION_NAME,
.dev_name = TCFG_DATA_DEV_NAME,
.offset = 0,
.len = TCFG_DATA_FLASH_DEV_PATY_SIZE,
};
#endif /* if TCFG_WATCH_DATA_STORAGE_ENABLE */
@@ -0,0 +1,91 @@
#include "app_config.h"
#include "asm/cpu.h"
#include "device/device.h"
#include "flashdb.h"
#include "data_storage.h"
#include "os/os_api.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[NULL-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".storage.data.bss")
#pragma data_seg(".storage.data")
#pragma const_seg(".storage.text.const")
#pragma code_seg(".storage.text")
#endif
#if !TCFG_DATA_STORAGE_ENABLE
int small_file_get_id_table_len(u8 small_file_type)
{
return 0;
}
int small_file_get_id_table(u8 small_file_type, u8 *table_data, u16 data_len)
{
return 0;
}
int small_file_delete_by_id(u8 small_file_type, u32 id)
{
return 0;
}
int small_file_del_all(void)
{
return false;
}
int small_file_read(u8 small_file_type, u32 id, u32 offset, void *buf, u32 len)
{
return 0;
}
u32 small_file_write(u8 small_file_type, u32 *id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
return 0;
}
int small_file_update_by_id(u8 small_file_type, u32 id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
return 0;
}
u32 small_file_get_size_by_index(u8 small_file_type, int index)
{
return 0;
}
u32 small_file_get_size_by_id(u8 small_file_type, int id)
{
return 0;
}
u32 small_file_get_id_by_index(u8 small_file_type, int index)
{
return 0;
}
int small_file_get_count(u8 small_file_type)
{
return 0;
}
int data_small_file_init(void)
{
return false;;
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,876 @@
#include "app_config.h"
#include "asm/cpu.h"
#include "device/device.h"
#include "flashdb.h"
#include "data_storage.h"
#include "os/os_api.h"
#include "syscfg_id.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[VM-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".storage.data.bss")
#pragma data_seg(".storage.data")
#pragma const_seg(".storage.text.const")
#pragma code_seg(".storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE && TCFG_DATA_STORAGE_VM_ENABLE
//================================================//
// 说明
//目前使用vm id数量限制在SMALL_FILE_VM_ITEM_MAX
//
//每条数据存储格式为 |id|len|用户数据|
//
//================================================//
#define SMALL_FILE_VM_ITEM_MAX (VM_SMALL_FILE_END - VM_SMALL_FILE_START + 1)
struct small_file_vm {
u8 type; /*文件类型*/
u8 max_item; /*文件数量最大值*/
u8 vm_max_item; /*使用vm id数量最大值*/
u16 vm_id_table[SMALL_FILE_VM_ITEM_MAX]; /*对应vm id*/
};
struct small_file_vm_storage_info {
u32 id;
u32 len;
};
struct small_file_info {
u8 type; /*文件类型*/
u8 max_item; /*文件数量最大值*/
u8 cur_item; /*当前文件数量*/
u16 *size_table; /*每个文件对应的大小*/
u32 *table; /*每个文件对应的id*/
u8 vm_max_item; /*使用vm id数量最大值*/
u16 *vm_id_table; /*文件用于存储的id号*/
};
struct small_file_hd {
struct small_file_info *child;
OS_MUTEX mutex;
};
/*当前max_item未使用*/
const struct small_file_vm data_small_file_info[] = {
{F_TYPE_PHONEBOOK, 10, 1, {VM_SMALL_FILE_PHONEBOOK}},
{F_TYPE_CALL_LOG, 10, 1, {VM_SMALL_FILE_CALL_LOG}},
{F_TYPE_WEATHER, 1, 1, {VM_SMALL_FILE_WEATHER}},
{F_TYPE_HEART, 1, 1, {VM_SMALL_FILE_HEART}},
{
F_TYPE_MESSAGE, 5, 5, {
VM_SMALL_FILE_MESSAGE_0, VM_SMALL_FILE_MESSAGE_1, \
VM_SMALL_FILE_MESSAGE_2, VM_SMALL_FILE_MESSAGE_3, VM_SMALL_FILE_MESSAGE_4
}
},
{F_TYPE_SPORTRECORD, 2, 2, {VM_SMALL_FILE_SPORTRECORD_0, VM_SMALL_FILE_SPORTRECORD_1}},
{
F_TYPE_BLOOD_OXYGEN, 4, 4, {
VM_SMALL_FILE_BLOOD_OXYGEN_0, VM_SMALL_FILE_BLOOD_OXYGEN_1, \
VM_SMALL_FILE_BLOOD_OXYGEN_2, VM_SMALL_FILE_BLOOD_OXYGEN_3
}
},
{
F_TYPE_SLEEP, 4, 4, {
VM_SMALL_FILE_SLEEP_0, VM_SMALL_FILE_SLEEP_1, \
VM_SMALL_FILE_SLEEP_2, VM_SMALL_FILE_SLEEP_3
}
},
};
static int small_file_info_delete_by_index(struct small_file_info *file, int index);
static int small_file_table_init(u8 small_file_type);
static u32 __is_new_id(struct small_file_info *info, u32 id);
static u32 __new_id_create(void *priv, int min, int max);
static u32 __find_id_index(struct small_file_info *info, u32 id);
static int __get_vm_saved_info(u16 vm_id, struct small_file_vm_storage_info *storage_info);
static int __read_vm_saved_data(u16 vm_id, u8 *buf, u32 len);
static int __write_vm_saved_data(u16 vm_id, u32 stored_id, u8 *buf, u32 len);
static int __del_vm_saved_item(u16 vm_id);
static int __data_small_file_info_init(void);
static int __data_small_file_info_update(void);
static struct small_file_hd *hd;
int data_small_file_init(void)
{
int ret;
if (!hd) {
hd = zalloc(sizeof(struct small_file_hd) \
+ F_TYPE_COUNT * sizeof(struct small_file_info));
}
if (!hd) {
goto __err;
}
hd->child = (struct small_file_info *)(hd + 1);
os_mutex_create(&hd->mutex);
__data_small_file_info_init();
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file_vm *file = (struct small_file_vm *)&data_small_file_info[i];
small_file_table_init(file->type);
}
return true;
__err:
return false;
}
int small_file_get_id_table_len(u8 small_file_type)
{
return small_file_get_id_table(small_file_type, NULL, 0);
}
int small_file_get_id_table(u8 small_file_type, u8 *table_data, u16 data_len)
{
int count;
struct small_file_info *file;
if (!hd) {
return 0;
}
u16 id;
u16 file_len;
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
count = file->cur_item;
for (int i = 0; (i < count) && (i * 4 < data_len); i++) {
if (table_data) {
id = (u16)file->table[i];
file_len = (u16)file->size_table[i];
memcpy(table_data, &id, sizeof(u16));
table_data += 2;
memcpy(table_data, &file_len, sizeof(u16));
table_data += 2;
}
}
os_mutex_post(&hd->mutex);
return count * 4;
}
int small_file_delete_by_id(u8 small_file_type, u32 id)
{
int ret;
u16 vm_id = 0;
u32 index;
struct small_file_info *file;
if (!hd) {
return false;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
os_mutex_pend(&hd->mutex, 0);
if (!file->cur_item) {
goto __err;
}
if (id == 0) {
goto __err;
}
index = __find_id_index(file, id);
if (index >= file->cur_item) {
log_error("<%s> index:%d id:%d", __func__, index, id);
goto __err;
}
/*检查找到index的对应id是否正确*/
if (file->table[index] != id) {
log_error("<%s> index:%d id:%d find_id:%d", __func__, index, id, file->table[index]);
goto __err;
}
vm_id = file->vm_id_table[index];
ret = __del_vm_saved_item(vm_id);
if (ret == false) {
log_error("<%s> line:%d vm write err", __func__, __LINE__);
goto __err;
}
for (; index < file->cur_item - 1; index++) {
file->table[index] = file->table[index + 1];
file->size_table[index] = file->size_table[index + 1];
file->vm_id_table[index] = file->vm_id_table[index + 1];
}
--file->cur_item;
file->table[file->cur_item] = 0;
file->size_table[file->cur_item] = 0;
file->vm_id_table[file->cur_item] = vm_id;
log_info("<%s> file_type:%d id:%d succ!", __func__, file->type, id);
ret = __data_small_file_info_update();
if (ret == false) {
log_error("<%s> __data_small_file_info_update error", __func__);
}
os_mutex_post(&hd->mutex);
return true;
__err:
log_error("<%s> file_type:%d id:%d error!", __func__, file->type, id);
os_mutex_post(&hd->mutex);
return false;
}
int small_file_delete_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
if (!hd) {
return false;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
return small_file_info_delete_by_index(file, index);
}
int small_file_del_all(void)
{
int ret;
if (!hd) {
return false;
}
os_mutex_pend(&hd->mutex, 0);
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file_vm *file = (struct small_file_vm *)&data_small_file_info[i];
if (!file->type) {
continue;
}
for (int j = 0; j < hd->child[file->type].cur_item; j++) {
ret = __del_vm_saved_item(hd->child[file->type].vm_id_table[j]);
if (ret == false) {
log_error("<%s> line:%d vm del err", __func__, __LINE__);
goto __err;
}
hd->child[file->type].table[j] = 0;
hd->child[file->type].size_table[j] = 0;
}
hd->child[file->type].cur_item = 0;
}
log_info("<%s> succ!", __func__);
ret = __data_small_file_info_update();
if (ret == false) {
log_error("<%s> __data_small_file_info_update error", __func__);
}
os_mutex_post(&hd->mutex);
return true;
__err:
log_error("<%s> del small_file error", __func__);
os_mutex_post(&hd->mutex);
return false;
}
int small_file_read(u8 small_file_type, u32 id, u32 offset, void *buf, u32 len)
{
int read_len = len;
u32 vm_id = 0;
int saved_len = 0;
u32 cur_item = 0;
struct small_file_info *file;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
if (!file->cur_item) {
goto __err;
}
cur_item = __find_id_index(file, id);
if (cur_item >= file->cur_item) {
log_error("<%s> id:%d error", __func__, id);
goto __err;
}
vm_id = file->vm_id_table[cur_item];
u8 *temp_data = zalloc(offset + len);
if (!temp_data) {
log_error("%s temp_data is null", __func__);
goto __err;
}
saved_len = __read_vm_saved_data(vm_id, temp_data, offset + len);
if (saved_len > offset) {
if (saved_len < offset + len) {
read_len = saved_len - offset;
}
memcpy(buf, &temp_data[offset], read_len);
} else {
read_len = 0;
}
free(temp_data);
log_info("<%s> file_type:%d id:%d read succ!", __func__, file->type, id);
os_mutex_post(&hd->mutex);
return read_len;
__err:
log_error("<%s> file_type:%d id:%d read error!", __func__, file->type, id);
os_mutex_post(&hd->mutex);
return 0;
}
u32 small_file_write(u8 small_file_type, u32 *id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
int ret;
u16 vm_id;
u8 *temp_data = NULL;
u8 is_new_id = 1;
u32 cur_item = 0;
struct small_file_info *file;
struct small_file_vm_storage_info stored_data_info;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
if (!file->max_item) {
goto __err;
}
if (!*id) {
if (buf_offset) {
ASSERT(file->cur_item);
*id = file->table[file->cur_item - 1];
//临时特殊处理一下app 不发id号
}
}
is_new_id = __is_new_id(file, *id);
while (is_new_id && file->cur_item >= file->max_item) {
small_file_info_delete_by_index(file, 0);
}
if (!*id) {
*id = __new_id_create(file, 0x1, 0xffff);
}
cur_item = __find_id_index(file, *id);
if (cur_item >= file->cur_item) {
log_error("<%s> id:%d error", __func__, *id);
goto __err;
}
vm_id = file->vm_id_table[cur_item];
if (buf_offset) {
if (__get_vm_saved_info(vm_id, &stored_data_info) == true) {
temp_data = zalloc(buf_offset + len);
if (!temp_data) {
log_error("%s temp_data is null", __func__);
goto __err;
}
ret = __read_vm_saved_data(vm_id, temp_data, stored_data_info.len);
if (ret != stored_data_info.len) {
goto __err;
}
memcpy(&temp_data[buf_offset], buf, len);
ret = __write_vm_saved_data(vm_id, stored_data_info.id, temp_data, buf_offset + len);
if (ret != (buf_offset + len)) {
log_error("<%s> line:%d vm write err", __func__, __LINE__);
goto __err;
}
} else {
goto __err;
}
} else {
ret = __write_vm_saved_data(vm_id, *id, buf, len);
if (ret != len) {
goto __err;
}
}
if (is_new_id) {
file->table[file->cur_item] = *id;
file->size_table[file->cur_item] = len;
file->cur_item++;
} else {
cur_item = __find_id_index(file, *id);
file->table[cur_item] = *id;
file->size_table[cur_item] = buf_offset + len;
if (cur_item == file->cur_item) {
file->cur_item++;
log_info("<%s> id:%d del rwrite", __func__, *id);
}
}
if (temp_data) {
free(temp_data);
}
log_info("<%s> file_type:%d id:%d succ!", __func__, file->type, *id);
ret = __data_small_file_info_update();
if (ret == false) {
log_error("<%s> __data_small_file_info_update error", __func__);
}
os_mutex_post(&hd->mutex);
return len;
__err:
if (temp_data) {
free(temp_data);
}
log_info("<%s> file_type:%d id:%d error!", __func__, file->type, *id);
os_mutex_post(&hd->mutex);
return 0;
}
int small_file_update_by_id(u8 small_file_type, u32 id, u32 buf_offset, void *buf, u32 len, u32 total_len)
{
int ret;
u16 vm_id;
u32 cur_item = 0;
u8 *temp_data = NULL;
struct small_file_info *file;
struct small_file_vm_storage_info stored_data_info;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
cur_item = __find_id_index(file, id);
if (cur_item >= file->cur_item) {
log_error("<%s> id:%d error", __func__, id);
goto __err;
}
vm_id = file->vm_id_table[cur_item];
if (__get_vm_saved_info(vm_id, &stored_data_info) == true) {
if (stored_data_info.len < (buf_offset + len)) {
goto __err;
}
temp_data = zalloc(stored_data_info.len);
if (!temp_data) {
log_error("%s temp_data is null", __func__);
goto __err;
}
ret = __read_vm_saved_data(vm_id, temp_data, stored_data_info.len);
if (ret != stored_data_info.len) {
goto __err;
}
memcpy(&temp_data[buf_offset], buf, len);
ret = __write_vm_saved_data(vm_id, stored_data_info.id, temp_data, stored_data_info.len);
if (ret != stored_data_info.len) {
log_error("<%s> line:%d vm write err", __func__, __LINE__);
goto __err;
}
} else {
goto __err;
}
free(temp_data);
log_info("<%s> file_type:%d id:%d succ!", __func__, file->type, id);
ret = __data_small_file_info_update();
if (ret == false) {
log_error("<%s> __data_small_file_info_update error", __func__);
}
os_mutex_post(&hd->mutex);
return len;
__err:
if (temp_data) {
free(temp_data);
}
os_mutex_post(&hd->mutex);
return 0;
}
u32 small_file_get_size_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
u32 size;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
if (!file->cur_item || index >= file->cur_item) {
return 0;
}
os_mutex_pend(&hd->mutex, 0);
size = file->size_table[index];
os_mutex_post(&hd->mutex);
return size;
}
u32 small_file_get_size_by_id(u8 small_file_type, int id)
{
struct small_file_info *file;
u32 size = 0;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
os_mutex_pend(&hd->mutex, 0);
for (int index = 0; index < file->cur_item; index++) {
if (file->table[index] == id) {
size = file->size_table[index];
}
}
os_mutex_post(&hd->mutex);
return size;
}
u32 small_file_get_id_by_index(u8 small_file_type, int index)
{
struct small_file_info *file;
u32 id;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
file = &hd->child[small_file_type];
if (!file->cur_item || index >= file->cur_item) {
return 0;
}
os_mutex_pend(&hd->mutex, 0);
id = file->table[index];
os_mutex_post(&hd->mutex);
return id;
}
int small_file_get_count(u8 small_file_type)
{
int count;
struct small_file_info *file;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
count = file->cur_item;
os_mutex_post(&hd->mutex);
return count;
}
static int small_file_info_delete_by_index(struct small_file_info *file, int index)
{
u16 vm_id = 0;
int ret;
if (!hd) {
return false;
}
if (!file->cur_item || index >= file->cur_item) {
return false;
}
os_mutex_pend(&hd->mutex, 0);
vm_id = file->vm_id_table[index];
for (; index < file->cur_item - 1; index++) {
file->table[index] = file->table[index + 1];
file->size_table[index] = file->size_table[index + 1];
file->vm_id_table[index] = file->vm_id_table[index + 1];
}
--file->cur_item;
file->table[file->cur_item] = 0;
file->size_table[file->cur_item] = 0;
file->vm_id_table[file->cur_item] = vm_id;
ret = __del_vm_saved_item(vm_id);
if (ret == false) {
log_error("<%s> line:%d vm write err", __func__, __LINE__);
goto __err;
}
log_info("<%s> file_type:%d index:%d succ!", __func__, file->type, index);
ret = __data_small_file_info_update();
if (ret == false) {
log_error("<%s> __data_small_file_info_update error", __func__);
}
os_mutex_post(&hd->mutex);
return true;
__err:
os_mutex_post(&hd->mutex);
return false;
}
static int small_file_table_init(u8 small_file_type)
{
int ret;
int count = 0;
u32 id;
struct small_file_info *file;
struct small_file_vm_storage_info file_storage_info;
if (!hd) {
return 0;
}
ASSERT(small_file_type < F_TYPE_COUNT);
os_mutex_pend(&hd->mutex, 0);
file = &hd->child[small_file_type];
for (int i = 0; i < file->vm_max_item; i++) {
ret = __get_vm_saved_info(file->vm_id_table[i], &file_storage_info);
if (ret == false) {
continue;
}
file->size_table[file->cur_item] = file_storage_info.len;
file->table[file->cur_item] = file_storage_info.id;
file->cur_item++;
++count;
}
os_mutex_post(&hd->mutex);
return count;
}
static u32 __is_new_id(struct small_file_info *info, u32 id)
{
if (!id) {
return true;
}
for (int index = 0; index < info->cur_item; index++) {
if (info->table[index] == id) {
return false;
}
}
return true;
}
static u32 __new_id_create(void *priv, int min, int max)
{
struct small_file_info *file = (struct small_file_info *)priv;
u32 id = min;
/*最小不重复id*/
__again:
for (int index = 0; index < file->cur_item; index++) {
if (file->table[index] == id) {
id ++;
if (!id || id > max) {
id = min;
}
goto __again;
}
}
return id;
}
static u32 __find_id_index(struct small_file_info *info, u32 id)
{
for (int index = 0; index < info->cur_item; index++) {
if (info->table[index] == id) {
return index;
}
}
return info->cur_item;
}
static int __get_vm_saved_info(u16 vm_id, struct small_file_vm_storage_info *storage_info)
{
int ret;
ret = syscfg_read(vm_id, storage_info, sizeof(struct small_file_vm_storage_info));
if (ret != sizeof(struct small_file_vm_storage_info)) {
return false;
}
return true;
}
static int __read_vm_saved_data(u16 vm_id, u8 *buf, u32 len)
{
int saved_len = 0;
u32 read_len = sizeof(struct small_file_vm_storage_info) + len;
u8 *read_buf = zalloc(read_len);
if (!read_buf) {
log_error("%s read_buf is null", __func__);
return 0;
}
saved_len = syscfg_read(vm_id, read_buf, read_len);
if (saved_len <= sizeof(struct small_file_vm_storage_info)) {
free(read_buf);
return 0;
}
saved_len -= sizeof(struct small_file_vm_storage_info);
memcpy(buf, &read_buf[sizeof(struct small_file_vm_storage_info)], saved_len);
free(read_buf);
return saved_len;
}
static int __write_vm_saved_data(u16 vm_id, u32 stored_id, u8 *buf, u32 len)
{
int ret;
struct small_file_vm_storage_info *storage_info;
u32 saved_len = sizeof(struct small_file_vm_storage_info) + len;
u8 *saved_buf = zalloc(saved_len);
if (!saved_buf) {
log_error("%s saved_buf is null", __func__);
return 0;
}
storage_info = (struct small_file_vm_storage_info *)saved_buf;
storage_info->id = stored_id;
storage_info->len = len;
memcpy(&saved_buf[sizeof(struct small_file_vm_storage_info)], buf, len);
ret = syscfg_write(vm_id, saved_buf, saved_len);
if (ret != saved_len) {
free(saved_buf);
return 0;
}
free(saved_buf);
return len;
}
static int __del_vm_saved_item(u16 vm_id)
{
int ret;
u8 data = 0;
ret = syscfg_write(vm_id, &data, sizeof(data));
if (ret != sizeof(data)) {
return false;
}
return true;
}
static int __data_small_file_info_init(void)
{
int ret;
if (!hd) {
return false;
}
struct small_file_vm *temp_data = (struct small_file_vm *)zalloc(sizeof(data_small_file_info));
if (!temp_data) {
log_error("%s temp_data is null", __func__);
return false;
}
ret = syscfg_read(VM_SMALL_FILE_MANAGER, temp_data, sizeof(data_small_file_info));
if (ret == sizeof(data_small_file_info)) {
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file_vm *file = (struct small_file_vm *)&temp_data[i];
if (!file->type) {
continue;
}
hd->child[file->type].type = file->type;
hd->child[file->type].max_item = file->max_item;
hd->child[file->type].vm_max_item = file->vm_max_item;
hd->child[file->type].table = (u32 *)zalloc(sizeof(u32) * file->vm_max_item);
hd->child[file->type].size_table = (u16 *)zalloc(sizeof(u16) * file->vm_max_item);
hd->child[file->type].vm_id_table = (u16 *)zalloc(sizeof(u16) * file->vm_max_item);
ASSERT(hd->child[file->type].table && hd->child[file->type].size_table && hd->child[file->type].vm_id_table);
memcpy((char *)hd->child[file->type].vm_id_table, (const char *)file->vm_id_table, sizeof(u16) * file->vm_max_item);
}
} else {
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file_vm *file = (struct small_file_vm *)&data_small_file_info[i];
if (!file->type) {
continue;
}
hd->child[file->type].type = file->type;
hd->child[file->type].max_item = file->max_item;
hd->child[file->type].vm_max_item = file->vm_max_item;
hd->child[file->type].table = (u32 *)zalloc(sizeof(u32) * file->vm_max_item);
hd->child[file->type].size_table = (u16 *)zalloc(sizeof(u16) * file->vm_max_item);
hd->child[file->type].vm_id_table = (u16 *)zalloc(sizeof(u16) * file->vm_max_item);
ASSERT(hd->child[file->type].table && hd->child[file->type].size_table && hd->child[file->type].vm_id_table);
memcpy((char *)hd->child[file->type].vm_id_table, (const char *)file->vm_id_table, sizeof(u16) * file->vm_max_item);
}
}
free(temp_data);
return true;
}
static int __data_small_file_info_update(void)
{
int ret;
if (!hd) {
return false;
}
struct small_file_vm *temp_file;
struct small_file_vm *temp_data = (struct small_file_vm *)zalloc(sizeof(data_small_file_info));
if (!temp_data) {
log_error("%s temp_data is null", __func__);
return false;
}
for (int i = 0; i < ARRAY_SIZE(data_small_file_info); i++) {
struct small_file_vm *file = (struct small_file_vm *)&data_small_file_info[i];
temp_file = &temp_data[i];
if (!file->type) {
continue;
}
temp_file->type = hd->child[file->type].type;
temp_file->max_item = hd->child[file->type].max_item;
temp_file->vm_max_item = hd->child[file->type].vm_max_item;
memcpy((char *)temp_file->vm_id_table, (const char *)hd->child[file->type].vm_id_table, sizeof(u16) * hd->child[file->type].vm_max_item);
}
ret = syscfg_write(VM_SMALL_FILE_MANAGER, temp_data, sizeof(data_small_file_info));
free(temp_data);
if (ret != sizeof(data_small_file_info)) {
return false;
}
return true;
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,135 @@
/**
* @file data_weater_storage.c
* @brief 电话本存储相关
*/
#include "app_config.h"
#include "flashdb.h"
#include "fdb_low_lvl.h"
#include "data_storage.h"
#include "data_weather_storage.h"
#define LOG_TAG_CONST DATA_STORAGE
#define LOG_TAG "[WEATER-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".weater_storage.bss")
#pragma data_seg(".weater_storage.data")
#pragma const_seg(".weater_storage.text.const")
#pragma code_seg(".weater_storage.text")
#endif
#if TCFG_DATA_STORAGE_ENABLE
int ui_small_file_weather_get_count(void)
{
return small_file_get_count(F_TYPE_WEATHER);
}
int ui_small_file_weather_get_size_by_index(int index)
{
return small_file_get_size_by_index(F_TYPE_WEATHER, index);
}
int ui_small_file_weather_read_by_index(void *buf, u32 len, int index)
{
int ret;
if (!buf) {
return FALSE;
}
u32 id = small_file_get_id_by_index(F_TYPE_WEATHER, index);
if (!id) {
return FALSE;
}
ret = small_file_read(F_TYPE_WEATHER, id, 0, buf, len);
if (ret == len) {
return TRUE;
}
return FALSE;
}
int ui_small_file_weather_get_singel_info(struct weather_single_info *info, int index)
{
ASSERT(info);
u32 id = small_file_get_id_by_index(F_TYPE_WEATHER, index);
if (!id) {
return FALSE;
}
int file_size = small_file_get_size_by_index(F_TYPE_WEATHER, index);
int offset = file_size - 9;
if (file_size < 9) {
return FALSE;
}
u8 rbuf[2] = {0};
int rlen = 2;
int ret = small_file_read(F_TYPE_WEATHER, id, offset, rbuf, rlen);
if (ret == rlen) {
info->weather = rbuf[0];
info->temperature = (s8)rbuf[1];
printf("%s info->weather:%d tmep:%d", __func__, info->weather, info->temperature);
return TRUE;
}
return FALSE;
}
/************************************************
* 测试用例
***********************************************/
#if 0
u8 test_weather_info_buf[] = {
0x06, 0xE5, 0xB9, 0xBF, 0xE4, 0xB8, 0x9C, 0x06, 0xE7, 0x8F, 0xA0, 0xE6, 0xB5, 0xB7, 0x03, 0x18,
0x40, 0x05, 0x06, 0x2D, 0x52, 0xE2, 0x4C,
};
void watch_data_weather_test(void)
{
u32 create_id = 0;
small_file_write(F_TYPE_WEATHER, &create_id, 0, &test_weather_info_buf, sizeof(test_weather_info_buf), sizeof(test_weather_info_buf));
printf("<%s> create_id:%d", __func__, create_id);
create_id = 0;
small_file_write(F_TYPE_WEATHER, &create_id, 0, &test_weather_info_buf, sizeof(test_weather_info_buf), sizeof(test_weather_info_buf));
printf("<%s> create_id:%d", __func__, create_id);
int file_count = ui_small_file_weather_get_count();
int file_size;
u8 *read_weather_info_buf;
for (int i = 0; i < file_count; i++) {
file_size = ui_small_file_weather_get_size_by_index(i);
read_weather_info_buf = zalloc(file_size);
printf("i:%d file_size:%d", i, file_size);
ui_small_file_weather_read_by_index(read_weather_info_buf, file_size, i);
put_buf(read_weather_info_buf, file_size);
free(read_weather_info_buf);
}
}
#endif
#else /* if TCFG_DATA_STORAGE_ENABLE */
int ui_small_file_weather_get_count(void)
{
return 0;
}
int ui_small_file_weather_get_size_by_index(int index)
{
return 0;
}
int ui_small_file_weather_read_by_index(void *buf, u32 len, int index)
{
return 0;
}
#endif /* if TCFG_DATA_STORAGE_ENABLE */
@@ -0,0 +1,33 @@
#ifndef __WEATHER_H__
#define __WEATHER_H__
#include "generic/typedef.h"
/**********************
* TYPEDEFS
**********************/
struct __WEATHER_INFO {
u8 province_name_len;
u8 *province;
u8 city_name_len;
u8 *city;
u8 weather;
s8 temperature;
u8 humidity;
u8 wind_direction;
u8 wind_power;
u32 update_time;
};
struct weather_single_info {
u8 weather;
s8 temperature;
};
//获取简单信息的接口,不耗ram
int ui_small_file_weather_get_singel_info(struct weather_single_info *info, int index);
int ui_small_file_weather_get_count(void);
int ui_small_file_weather_get_size_by_index(int index);
int ui_small_file_weather_read_by_index(void *buf, u32 len, int index);
#endif
+269
View File
@@ -0,0 +1,269 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".pbg_demo.data.bss")
#pragma data_seg(".pbg_demo.data")
#pragma const_seg(".pbg_demo.text.const")
#pragma code_seg(".pbg_demo.text")
#endif
#include "system/includes.h"
#include "string.h"
#include "circular_buf.h"
#include "btstack/avctp_user.h"
#include "app_config.h"
#include "bt_tws.h"
#include "bt_common.h"
#include "syscfg_id.h"
#include "pbg_user.h"
#include "audio_cvp.h"
#define PBG_DEMO_EN 0//enalbe pbg_demo
#if (PBG_DEMO_EN&&TCFG_USER_TWS_ENABLE)
#define log_info(x, ...) printf("\n[###pbg_demo@@@]" x " ", ## __VA_ARGS__)
typedef struct {
// linked list - assert: first field
void *offset_item;
// data is contained in same memory
u32 service_record_handle;
u8 *service_record;
} service_record_item_t;
#define SDP_RECORD_HANDLER_REGISTER(handler) \
const service_record_item_t handler \
sec(.sdp_record_item)
//---------
enum {
PBG_EVENT_CONNECT = 1,
PBG_EVENT_DISCONNECT,
PBG_EVENT_MONITOR_START,//监听开始
PBG_EVENT_PACKET_HANDLER = 7,
};
enum {
PBG_USER_ST_NULL = 0x0,
PBG_USER_ST_CONNECT,
PBG_USER_ST_DISCONN,
};
enum {
PBG_USER_ERR_NONE = 0x0,
PBG_USER_ERR_SEND_BUFF_BUSY,
PBG_USER_ERR_SEND_OVER_LIMIT,
PBG_USER_ERR_SEND_FAIL,
};
//--------------------------------------------------------------------------------------------------
//---------
u8 pbg_profile_support = 1; //enable libs profile success
//---------
#define USER_SEND_POOL_SIZE (256L)
static u8 user_send_pool[USER_SEND_POOL_SIZE];
static u8 user_send_busy;
static u8 user_state;
u32 pbg_user_send(void *priv, u8 *buf, u32 len);
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
//示例添加SDP服务表,注意不要跟bt_profile_config.c的定义有重复和冲突!!!!!!
//标准sdp结构表,以PNP服务示例定义,表末端增加 0x00,0x00 为结束符
/* static const u8 sdp_pnp_service_data[] = { */
/* 0x36, 0x00, 0x34, 0x09, 0x00, 0x00, 0x0A, 0x50, 0x01, 0x10, 0x00, 0x09, 0x00, 0x01, 0x36, 0x00, */
/* 0x03, 0x19, 0x12, 0x00, 0x09, 0x02, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x05, 0xD6, */
/* 0x09, 0x02, 0x02, 0x09, 0x00, 0x0A, 0x09, 0x02, 0x03, 0x09, 0x02, 0x40, 0x09, 0x02, 0x04, 0x28, */
/* 0x01, 0x09, 0x02, 0x05, 0x09, 0x00, 0x01, 0x00, 0x00 */
/* }; */
/* SDP_RECORD_HANDLER_REGISTER(pnp_sdp_record_item) = { */
/* .service_record = (u8 *)sdp_pnp_service_data, */
/* .service_record_handle = 0x50011000, */
/* }; */
//--------------------------------------------------------------------------------------------------
//发送数据接口,注意返回值;确定OK
//数据真正发送成功,以接口user_pbg_send_ok_callback 回调为准
u32 pbg_user_send(void *priv, u8 *buf, u32 len)
{
if (user_state != PBG_USER_ST_CONNECT) {
return PBG_USER_ERR_SEND_FAIL;
}
log_info("send_data(%d)\n", len);
put_buf(buf, len);
if (user_send_busy == 1) {
log_info("ERR_SEND_BUFF_BUSY\n");
return PBG_USER_ERR_SEND_BUFF_BUSY;
}
if (user_send_pool == NULL) {
return PBG_USER_ERR_SEND_FAIL;
}
if (len) {
if (len > USER_SEND_POOL_SIZE) {
log_info("ERR_SEND_OVER_LIMIT\n");
return PBG_USER_ERR_SEND_OVER_LIMIT;
}
user_send_busy = 1;
memcpy(user_send_pool, buf, len);
u32 ret = bt_cmd_prepare(USER_CTRL_PBG_SEND_DATA, len, user_send_pool);
if (ret) {
user_send_busy = 0;
return PBG_USER_ERR_SEND_FAIL;
}
}
return PBG_USER_ERR_NONE;
}
void user_pbg_send_ok_callback(int err_code)
{
user_send_busy = 0;
log_info("send_ok\n");
}
static void user_pbg_packet_handler(u8 packet_type, u16 ch, u8 *packet, u16 size)
{
u32 tmp32;
switch (packet_type) {
case PBG_EVENT_PACKET_HANDLER:
log_info("pbg packet_data(%d):");
put_buf(packet, size);
/* test_pbg_cmd_send(packet);//for test */
break;
case PBG_EVENT_CONNECT:
user_state = PBG_USER_ST_CONNECT;
log_info("pbg connect #############\n");
break;
case PBG_EVENT_DISCONNECT:
user_state = PBG_USER_ST_DISCONN;
log_info("pbg disconnect #############\n");
break;
case PBG_EVENT_MONITOR_START:
log_info("pbg monitor start #############\n");
break;
default:
break;
}
}
#define PSM_BrowseGroupDescriptor (0x1001)
void pbg_demo_init(void)
{
log_info("pbg_demo_init\n");
pbg_profile_init(PSM_BrowseGroupDescriptor);//input PSM ID
pbg_event_handler_register(user_pbg_packet_handler);
user_state = PBG_USER_ST_DISCONN;
user_send_busy = 0;
}
static int pbg_btstack_event_handler(int *msg)
{
struct bt_event *bt = (struct bt_event *)msg;
switch (bt->event) {
case BT_STATUS_INIT_OK:
pbg_demo_init();
break;
}
return 0;
}
APP_MSG_HANDLER(pbg_stack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = pbg_btstack_event_handler,
};
static int pbg_tws_event_handler(int *msg)
{
struct tws_event *evt = (struct tws_event *)msg;
switch (evt->event) {
case TWS_EVENT_CONNECTED:
pbg_user_set_tws_state(1);
break;
case TWS_EVENT_SEARCH_TIMEOUT:
case TWS_EVENT_CONNECTION_TIMEOUT:
case TWS_EVENT_CONNECTION_DETACH:
case TWS_EVENT_REMOVE_PAIRS:
pbg_user_set_tws_state(0);
break;
}
}
APP_MSG_HANDLER(pbg_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = pbg_tws_event_handler,
};
#else
void pbg_demo_init(void)
{
/* printf("pbg not enable...\n"); */
}
void pbg_user_battery_level_sync(u8 *dev_bat)
{
//add code
}
void pbg_user_ear_pos_sync(u8 left, u8 right)
{
//add code
}
/*bool pbg_user_key_vaild(u8 *key_msg, struct sys_event *event)
{
//add code
return false;
}*/
void pbg_user_event_deal(struct pbg_event *evt)
{
//add code
}
void pbg_user_set_tws_state(u8 conn_flag)
{
//add code
}
void pbg_user_mic_fixed_deal(u8 mode)
{
//add code
}
void pbg_user_recieve_sync_info(u8 *sync_info)
{
//add code
}
int pbg_user_is_connected(void)
{
//add code
//return PBG服务是否已连上,区分安卓和苹果,是否持续广播
return 1;//不支持PBG服务,return 1
}
//----------------------------------------
#endif
+245
View File
@@ -0,0 +1,245 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".trans_data_demo.data.bss")
#pragma data_seg(".trans_data_demo.data")
#pragma const_seg(".trans_data_demo.text.const")
#pragma code_seg(".trans_data_demo.text")
#endif
#include "app_config.h"
#include "bt.h"
#include "app_main.h"
#include "update_tws.h"
#include "3th_profile_api.h"
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "bt_tws.h"
#include "spp_trans_data.h"
#include "spp_user.h"
#if (BT_AI_SEL_PROTOCOL & TRANS_DATA_EN)
#define LOG_TAG "[TRANS_DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
u8 ble_adv_miss_flag = 0;
u8 ble_adv_poweron_flag = 0;
int trans_data_earphone_state_tws_connected(int first_pair, u8 *comm_addr)
{
#if 0
if (first_pair) {
/* bt_ble_adv_enable(0); */
u8 tmp_ble_addr[6] = {0};
bt_make_ble_address(tmp_ble_addr, comm_addr);
le_controller_set_mac(tmp_ble_addr);//将ble广播地址改成公共地址
bt_update_mac_addr(comm_addr);
/* bt_ble_adv_enable(1); */
/*新的连接,公共地址改变了,要重新将新的地址广播出去*/
if (tws_api_get_role() == TWS_ROLE_MASTER) {
printf("\nNew Connect Master!!!\n\n");
ble_app_disconnect();
bt_ble_adv_enable(0);
bt_ble_adv_enable(1);
} else {
printf("\nConnect Slave!!!\n\n");
/*从机ble关掉*/
ble_app_disconnect();
bt_ble_adv_enable(0);
}
}
#endif
return 0;
}
int trans_data_earphone_state_enter_soft_poweroff()
{
bt_ble_exit();
return 0;
}
void trans_data_bt_tws_event_handler(struct bt_event *bt)
{
int role = bt->args[0];
int phone_link_connection = bt->args[1];
int reason = bt->args[2];
switch (bt->event) {
case TWS_EVENT_CONNECTED:
//bt_ble_adv_enable(1);
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
//master enable
printf("\nConnect Slave!!!\n\n");
/*从机ble关掉*/
ble_app_disconnect();
bt_ble_adv_enable(0);
}
break;
case TWS_EVENT_PHONE_LINK_DETACH:
/*
* 跟手机的链路LMP层已完全断开, 只有tws在连接状态才会收到此事件
*/
break;
case TWS_EVENT_CONNECTION_DETACH:
/*
* TWS连接断开
*/
if (app_var.goto_poweroff_flag) {
break;
}
if (get_app_connect_type() == 0) {
printf("\ntws detach to open ble~~~\n\n");
bt_ble_adv_enable(1);
}
set_ble_connect_type(TYPE_NULL);
break;
case TWS_EVENT_SYNC_FUN_CMD:
break;
case TWS_EVENT_ROLE_SWITCH:
break;
}
#if OTA_TWS_SAME_TIME_ENABLE
tws_ota_app_event_deal(bt->event);
#endif
}
int trans_data_sys_event_handler_specific(struct sys_event *event)
{
switch (event->type) {
case SYS_BT_EVENT:
#if 0
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
}
#if TCFG_USER_TWS_ENABLE
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
trans_data_bt_tws_event_handler(&event->u.bt);
}
#endif
#if OTA_TWS_SAME_TIME_ENABLE
else if (((u32)event->arg == SYS_BT_OTA_EVENT_TYPE_STATUS)) {
bt_ota_event_handler(&event->u.bt);
}
#endif
#endif
break;
case SYS_DEVICE_EVENT:
break;
}
return 0;
}
int user_spp_state_specific(u8 packet_type)
{
#if 0
switch (packet_type) {
case 1:
bt_ble_adv_enable(0);
set_app_connect_type(TYPE_SPP);
break;
case 2:
set_app_connect_type(TYPE_NULL);
#if TCFG_USER_TWS_ENABLE
if (!(tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
ble_module_enable(1);
} else {
if (tws_api_get_role() == TWS_ROLE_MASTER) {
ble_module_enable(1);
}
}
#else
ble_module_enable(1);
#endif
break;
}
#endif
return 0;
}
static int trans_data_earphone_state_init()
{
transport_spp_init();
bt_ble_init();
return 0;
}
static int trans_data_btstack_event_handler(int *_event)
{
struct bt_event *event = (struct bt_event *)_event;
switch (event->event) {
case BT_STATUS_INIT_OK:
#if TCFG_NORMAL_SET_DUT_MODE
break;
#endif
printf("trans_data_earphone_state_init\n");
trans_data_earphone_state_init();
return 0;
case BT_STATUS_FIRST_CONNECTED:
break;
case BT_STATUS_SECOND_CONNECTED:
break;
}
return 0;
}
APP_MSG_HANDLER(trans_data_stack_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_BT_STACK,
.handler = trans_data_btstack_event_handler,
};
static int trans_data_tws_event_handler(int *_event)
{
struct tws_event *event = (struct tws_event *)_event;
int role = event->args[0];
int reason = event->args[2];
switch (event->event) {
case TWS_EVENT_CONNECTED:
if (role == TWS_ROLE_MASTER) {
} else {
}
break;
case TWS_EVENT_CONNECTION_DETACH:
if (app_var.goto_poweroff_flag) {
break;
}
break;
case TWS_EVENT_ROLE_SWITCH:
break;
}
return 0;
}
APP_MSG_HANDLER(trans_data_tws_msg_entry) = {
.owner = 0xff,
.from = MSG_FROM_TWS,
.handler = trans_data_tws_event_handler,
};
#endif
@@ -0,0 +1,145 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#include "sensor_hub.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-ALGO_GSENSOR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#if (TCFG_SPORT_HEALTH_ENABLE&& TCFG_SPORT_HEALTH_ALGO_GSENSOR)
#define SPORT_HEALTH_ALGO_TEST_ENABLE (!TCFG_SENSOR_HUB)
static algo_out gsensor_algo_info = {0};
static void shm_algo_test(algo_out *algo)
{
log_debug("%s %d", __func__, __LINE__);
algo->steps ++;
algo->calories = algo->steps * 0.03;
algo->distance = 80 * algo->steps;
algo->step_frequency = 60;
}
static int shm_algo_gsensor_init()
{
int ret = SHM_ERR_OK;
//get personal info from vm
log_debug("%s %d", __func__, __LINE__);
#if !SPORT_HEALTH_ALGO_TEST_ENABLE
sensor_service_motion_init();
#endif
return ret;
}
static int shm_algo_gsensor_release()
{
int ret = SHM_ERR_OK;
return ret;
}
static int shm_algo_gsensor_enable()
{
int ret = SHM_ERR_OK;
return ret;
}
static int shm_algo_gsensor_disable()
{
int ret = SHM_ERR_OK;
return ret;
}
static int shm_algo_gsensor_update()
{
int ret = SHM_ERR_OK;
#if SPORT_HEALTH_ALGO_TEST_ENABLE
shm_algo_test(&gsensor_algo_info);
#else
sensor_service_motion_get(&gsensor_algo_info);
#endif
return ret;
}
static int shm_algo_gsensor_set(void *priv)
{
int ret = SHM_ERR_OK;
//更新配置信息
#if !SPORT_HEALTH_ALGO_TEST_ENABLE
sensor_service_motion_cfg_update();
#endif
return ret;
}
static int shm_algo_gsensor_io_crtl(int cmd, void *priv)
{
log_debug("%s %d", __func__, __LINE__);
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INIT:
ret = shm_algo_gsensor_init();
break;
case SHM_CMD_RELEASE:
ret = shm_algo_gsensor_release();
break;
case SHM_CMD_ENABLE:
ret = shm_algo_gsensor_enable();
break;
case SHM_CMD_DISABLE:
ret = shm_algo_gsensor_disable();
break;
case SHM_CMD_UPDATE:
case SHM_CMD_UPDATE_SEC:
case SHM_CMD_UPDATE_ALL:
ret = shm_algo_gsensor_update();
break;
case SHM_CMD_INFO_SET:
ret = shm_algo_gsensor_set(priv);
break;
default:
/* ret = -SHE_ERR_MOD_NO_THIS_CMD; */
break;
}
return ret;
}
static int shm_algo_gsensor_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_INFO:
if (priv != NULL) {
memcpy(priv, &gsensor_algo_info, sizeof(algo_out));
} else {
ret = -SHM_ERR_MOD_INVALID_PARAM;
}
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(gsensor_algo)
{
.module = SHM_MOD_GSENSOR_ALGO,
.io_ctrl = shm_algo_gsensor_io_crtl,
.get_value = shm_algo_gsensor_get_value,
};
#endif
@@ -0,0 +1,376 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "clock_manager/clock_manager.h"
#include "health_manager/health_manager.h"
#include "sensor_hub.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-ALGO_GSENSOR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#define SPORT_HEALTH_MANAGER_TASK "health_manager"
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_value_get 获取模块数据
*
* @param module 模块
* @param type 获取数据类型
* @param priv
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_health_manager_value_get(int module, int type, void *priv)
{
int rets;
__asm__ volatile("%0 = rets":"=r"(rets));
int ret = -SHM_ERR_MOD_NOT_FIND;
if (module >= SHM_MOD_END) {
goto __ret;
}
if (type >= SHM_GET_TYPE_MAX) {
ret = -SHM_ERR_TYPE_NOT_DEFINE;
goto __ret;
}
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
if (mod->module == module) {
if (mod->get_value) {
ret = mod->get_value(type, priv);
} else {
ret = - SHM_ERR_MOD_CB_NOT_DEFINE;
goto __ret;
}
}
}
__ret:
if (ret) {
log_error("%s err:%d rets:0x%x", __func__, ret, rets);
}
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_alloc 申请内存接口
*
* @param size
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
void *sport_health_alloc(u32 size)
{
//debug info
return zalloc(size);
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_free 释放内存
*
* @param p
*/
/* ------------------------------------------------------------------------------------*/
void sport_health_free(void *p)
{
free(p);
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_msg_post_self 发送消息给其他模块执行
*
* @param module
* @param cmd
* @param priv
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_health_manager_msg_post_self(int module, int cmd, void *priv)
{
int rets;
__asm__ volatile("%0 = rets":"=r"(rets));
int ret = SHM_ERR_OK;
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
if (mod->module == module) {
if (mod->io_ctrl) {
mod->io_ctrl(cmd, priv);
}
continue;
}
}
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_msg_post post消息给健康模块
*
* @param module
* @param cmd
* @param priv
* @param need_pend 是否阻塞
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_health_manager_msg_post(int module, int cmd, void *priv, int need_pend)
{
int rets;
__asm__ volatile("%0 = rets":"=r"(rets));
int pnd = need_pend;
if (cpu_in_irq()) {
pnd = 0;
} else {
if (!strcmp(os_current_task(), SPORT_HEALTH_MANAGER_TASK)) {
pnd = 0;
}
}
int ret = SHM_ERR_OK;
static OS_SEM sem;
int msg[4] = {0};
msg[0] = cmd;
msg[1] = (int)priv;
if (pnd) {
os_sem_create(&sem, 0);
msg[2] = (int)&sem;
} else {
msg[2] = 0;
}
log_debug("%s mod:%d cmd:%d pnd:%d", __func__, module, cmd, need_pend);
int err = os_taskq_post_type(SPORT_HEALTH_MANAGER_TASK, module, 3, msg);
if (err) {
log_warn("%s cmd:0x%x os_err:%d rets:0x%x\n", __func__, cmd, err, rets);
ret = -SHM_ERR_OS_ERR;
} else {
if (pnd) {
os_sem_pend(&sem, 0);
}
}
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_module_init 初始化所有模块
*/
/* ------------------------------------------------------------------------------------*/
static void sport_health_module_init()
{
log_debug("%s %d 0x%x 0x%x", __func__, __LINE__, sport_health_module_begin, sport_health_module_end);
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
log_debug("%s %d", __func__, mod->module);
if (mod->io_ctrl) {
mod->io_ctrl(SHM_CMD_INIT, NULL);
}
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_module_release 注销所有模块
*/
/* ------------------------------------------------------------------------------------*/
static void sport_health_module_release()
{
log_debug("%s %d 0x%x 0x%x", __func__, __LINE__, sport_health_module_begin, sport_health_module_end);
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
log_debug("%s %d", __func__, mod->module);
if (mod->io_ctrl) {
mod->io_ctrl(SHM_CMD_RELEASE, NULL);
}
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_update_sec_all 每秒更新模块
*/
/* ------------------------------------------------------------------------------------*/
static void sport_health_manager_update_sec_all()
{
for (int module = SHM_MOD_BEGIN + 1; module < SHM_MOD_END; module++) {
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
if (mod->module == module) {
if (mod->io_ctrl) {
mod->io_ctrl(SHM_CMD_UPDATE_SEC, NULL);
}
break;
}
}
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_update_timer_cb timer回调
*/
/* ------------------------------------------------------------------------------------*/
static void sport_health_manager_update_timer_cb()
{
sport_health_manager_msg_post(SHM_MOD_BEGIN, SHM_CMD_UPDATE_ALL, NULL, 0);
}
#if TCFG_ACCELER_SLEEP_ENABLE
void sensor_driver_irq_handle(P33_IO_WKUP_EDGE edge)
{
sport_health_manager_msg_post(SHM_MOD_GSENSOR_ALGO, SHM_CMD_INIT, NULL, 0);
}
//只读配置,用户后续新增io唤醒、ad唤醒注意使用const修饰,节约静态ram
static const struct _p33_io_wakeup_config sensor_irq = {
.pullup_down_mode = PORT_INPUT_PULLUP_10K,
.filter = PORT_FLT_DISABLE,
.edge = RISING_EDGE,
.gpio = IO_PORTB_03,
.callback = sensor_driver_irq_handle,
};
void sensor_irq_init(void)
{
p33_io_wakeup_port_init(&sensor_irq);
p33_io_wakeup_enable(IO_PORTB_03, 1);
}
#endif
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_task 运动健康管理主线程
*/
/* ------------------------------------------------------------------------------------*/
void sport_health_manager_task()
{
log_debug("%s %d", __func__, __LINE__);
//todo
int ret;
int msg[32];
#if TCFG_SENSOR_HUB
sensor_driver_check();
#endif
#if TCFG_ACCELER_SLEEP_ENABLE
sensor_irq_init();
#endif
sport_health_module_init();
sys_s_hi_timer_add(NULL, sport_health_manager_update_timer_cb, 1000);
while (1) {
/* memset(msg, 0, 32); */
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
if (ret != OS_TASKQ) {
continue;
}
int module = msg[0];
int module_cmd = msg[1];
int module_priv = msg[2];
int msg_pnd = msg[3];
log_debug("taskloop module:%d cmd:%d", module, module_cmd);
ASSERT(module < SHM_MOD_END);
ASSERT(module_cmd < SHM_CMD_MAX);
if (module_cmd == SHM_CMD_UPDATE_ALL) {
sport_health_manager_update_sec_all();
if (msg_pnd) {
os_sem_post((OS_SEM *)msg_pnd);
}
continue;
}
struct sport_health_module *mod;
list_for_each_sport_health_module(mod) {
if (mod->module == module) {
if (mod->io_ctrl) {
mod->io_ctrl(module_cmd, (void *)module_priv);
}
break;
}
}
if (msg_pnd) {
os_sem_post((OS_SEM *)msg_pnd);
}
}
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_init 运动健康管理初始化
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_health_manager_init()
{
#if TCFG_SPORT_HEALTH_ENABLE
log_debug("%s %d", __func__, __LINE__);
clock_alloc("health", 8 * MHz);
//init probe todo
int ret = SHM_ERR_OK;
int err = task_create(sport_health_manager_task, NULL, SPORT_HEALTH_MANAGER_TASK);
if (err) {
log_warn("%s os_err:%d \n", __func__, err);
ret = -SHM_ERR_OS_ERR;
}
return ret;
#else
return 0;
#endif
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_manager_release
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_health_manager_release()
{
int ret = SHM_ERR_OK;
#if TCFG_SPORT_HEALTH_ENABLE
sport_health_module_release();
clock_free("health");
/* #if 0 */
/* int err = task_kill(SPORT_HEALTH_MANAGER_TASK); */
/* if (err) { */
/* log_warn("%s os_err:%d \n", __func__, err); */
/* ret = -SHM_ERR_OS_ERR; */
/* } */
/* #endif */
#endif
return ret;
}
@@ -0,0 +1,429 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-ALGO_GSENSOR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#define BIG_LITTLE_SWAP16(x) ( (((*(u16*)x) & 0xff00) >> 8) | \
(((*(u16*)x) & 0x00ff) << 8) )
#define BIG_LITTLE_SWAP32(x) ( (((*(u32*)x) & 0xff000000) >> 24) | \
(((*(u32*)x) & 0x00ff0000) >> 8) | \
(((*(u32*)x) & 0x0000ff00) << 8) | \
(((*(u32*)x) & 0x000000ff) << 24) )
void sport_health_common_swapX(const uint8_t *src, uint8_t *dst, int32_t len)
{
if (len == 2) {
BIG_LITTLE_SWAP16(dst);
} else if (len == 4) {
BIG_LITTLE_SWAP32(dst);
} else {
ASSERT(0);
}
}
int sport_health_get_value_daily_active(struct daily_active *data)
{
ASSERT(data);
return sport_health_manager_value_get(SHM_MOD_DAILY_ACTIVE, SHM_GET_TYPE_INFO, data);
}
int sport_health_get_value_daily_steps()
{
struct daily_active data;
if (!sport_health_get_value_daily_active(&data)) {
return data.steps;
}
return 0;
}
int sport_health_get_value_daily_calories()
{
struct daily_active data;
if (!sport_health_get_value_daily_active(&data)) {
return data.calories;
}
return 0;
}
int sport_health_get_value_daily_distance()
{
struct daily_active data;
if (!sport_health_get_value_daily_active(&data)) {
return data.distance / 100; //转m
}
return 0;
}
int sport_health_get_value_daily_stand_times()
{
/* struct daily_active data; */
/* if(!sport_health_get_value_daily_active(&data)){ */
/* return data.stand_times; */
/* } */
return 0;
}
int sport_health_get_value_daily_active_target(struct daily_active *data)
{
ASSERT(data);
return sport_health_manager_value_get(SHM_MOD_DAILY_ACTIVE, SHM_GET_TYPE_TARGET, data);
}
int sport_health_get_value_daily_target_steps()
{
struct daily_active data;
if (!sport_health_get_value_daily_active_target(&data)) {
return data.steps;
}
return 0;
}
int sport_health_get_value_daily_target_calories()
{
struct daily_active data;
if (!sport_health_get_value_daily_active_target(&data)) {
return data.calories;
}
return 0;
}
int sport_health_get_value_daily_target_distance()
{
struct daily_active data;
if (!sport_health_get_value_daily_active_target(&data)) {
return data.distance;
}
return 0;
}
int sport_health_get_value_daily_target_stand_times()
{
/* struct daily_active data; */
/* if(!sport_health_get_value_daily_active_target(&data)){ */
/* return data.stand_times; */
/* } */
return 0;
}
int sport_health_set_daily_active_target(struct daily_active *data)
{
return sport_health_manager_msg_post(SHM_MOD_DAILY_ACTIVE, SHM_CMD_TARGET_SET, (void *)data, 1);
}
int sport_health_ctrl_sport_start_with_type(int type)
{
//设置运动类型
int ret = sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_INFO_SET, (void *)type, 1);
ASSERT(!ret, "ret:%d", ret);
//开始运动
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_START, NULL, 1);
}
int sport_health_ctrl_sport_start()
{
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_START, NULL, 1);
}
int sport_health_ctrl_sport_pause()
{
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_PAUSE, NULL, 1);
}
int sport_health_ctrl_sport_continue()
{
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_CONTINUE, NULL, 1);
}
int sport_health_ctrl_sport_stop()
{
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_STOP, NULL, 1);
}
int sport_health_set_sport_type(int type)
{
return sport_health_manager_msg_post(SHM_MOD_SPORT, SHM_CMD_INFO_SET, (void *)type, 1);
}
int sport_health_get_sport_info(struct sport_value *data)
{
ASSERT(data);
return sport_health_manager_value_get(SHM_MOD_SPORT, SHM_GET_TYPE_INFO, (void *)data);
}
int sport_health_get_sport_status()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.status;
}
return 0;
}
int sport_health_get_sport_type()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.type;
}
return 0;
}
int sport_health_get_sport_steps()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.steps_c;
}
return 0;
}
int sport_health_get_sport_calories()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.calories_c;
}
return 0;
}
/*根据rcsp协议,单位统一为0.01公里*/
int sport_health_get_sport_distance()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.distance_c / 1000;
}
return 0;
}
int sport_health_get_sport_freq()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.step_freq_c;
}
return 0;
}
int sport_health_get_sport_time()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.run_sec;
}
return 0;
}
int sport_health_get_sport_file_total()
{
int total = 0;
sport_health_manager_value_get(SHM_MOD_SPORT, SHM_GET_TYPE_STORAGE_TOTAL, &total);
return total;
}
int sport_health_get_sport_file_value(struct sport_value *value)
{
return sport_health_manager_value_get(SHM_MOD_SPORT, SHM_GET_TYPE_INFO_STORAGE, value);
}
int sport_health_get_sport_hr_real()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.heart_real;
}
return 0;
}
int sport_health_get_sport_hr_max()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.heart_max;
}
return 0;
}
int sport_health_get_sport_hr_min()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.heart_min;
}
return 0;
}
int sport_health_get_sport_hr_arg()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.heart_val;
}
return 0;
}
int sport_health_get_sport_speed()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.speed_c * 3.6; //cm/s to 0.01km/h
}
return 0;
}
int sport_health_get_sport_step_stride()
{
struct sport_value info;
int ret = sport_health_get_sport_info(&info);
if (!ret) {
return info.step_stride_c;
}
return 0;
}
int sport_health_get_sport_file_id()
{
u16 file_id = 0;
sport_health_manager_value_get(SHM_MOD_SPORT, SHM_GET_TYPE_STORAGE_ID, &file_id);
return file_id;
}
int sport_health_get_sport_file_size()
{
u16 file_id = 0;
sport_health_manager_value_get(SHM_MOD_SPORT, SHM_GET_TYPE_STORAGE_ID, &file_id);
if (file_id) {
void *fp = sport_health_file_open(F_TYPE_SPORTRECORD, file_id);
int file_len = 0;
if (fp) {
file_len = sport_health_file_get_len(fp);
sport_health_file_close(fp);
}
return file_len;
}
return 0;
}
int sport_health_gsensor_algo_cfg_update()
{
return sport_health_manager_msg_post(SHM_MOD_GSENSOR_ALGO, SHM_CMD_INFO_SET, NULL, 1);
}
int sport_health_heart_rate_module_enable()
{
return sport_health_manager_msg_post(SHM_MOD_HEART_RATE, SHM_CMD_ENABLE, NULL, 1);
}
int sport_health_heart_rate_module_disable()
{
return sport_health_manager_msg_post(SHM_MOD_HEART_RATE, SHM_CMD_DISABLE, NULL, 1);
}
int sport_health_heart_rate_module_clr()
{
return sport_health_manager_msg_post(SHM_MOD_HEART_RATE, SHM_CMD_CLEAR_VALUE, NULL, 1);
}
int sport_health_heart_rate_get_cur()
{
int heart_rate = 0;
sport_health_manager_value_get(SHM_MOD_HEART_RATE, SHM_GET_TYPE_REAL_VALUE, &heart_rate);
return heart_rate;
}
int sport_health_heart_rate_get_min()
{
int heart_rate = 0;
sport_health_manager_value_get(SHM_MOD_HEART_RATE, SHM_GET_TYPE_MIN_VALUE, &heart_rate);
return heart_rate;
}
int sport_health_heart_rate_get_max()
{
int heart_rate = 0;
sport_health_manager_value_get(SHM_MOD_HEART_RATE, SHM_GET_TYPE_MAX_VALUE, &heart_rate);
return heart_rate;
}
int sport_health_heart_rate_get_avg()
{
int heart_rate = 0;
sport_health_manager_value_get(SHM_MOD_HEART_RATE, SHM_GET_TYPE_AVG_VALUE, &heart_rate);
return heart_rate;
}
int sport_health_heart_rate_get_rec(struct health_file_data_info *info)
{
return sport_health_manager_value_get(SHM_MOD_HEART_RATE, SHM_GET_TYPE_REC_VALUE, info);
}
int sport_health_blood_oxygen_module_enable()
{
return sport_health_manager_msg_post(SHM_MOD_BLOOD_OXYGEN, SHM_CMD_ENABLE, NULL, 1);
}
int sport_health_blood_oxygen_module_disable()
{
return sport_health_manager_msg_post(SHM_MOD_BLOOD_OXYGEN, SHM_CMD_DISABLE, NULL, 1);
}
int sport_health_blood_oxygen_module_clr()
{
return sport_health_manager_msg_post(SHM_MOD_BLOOD_OXYGEN, SHM_CMD_CLEAR_VALUE, NULL, 1);
}
int sport_health_blood_oxygen_get_cur()
{
int blood_oxygen = 0;
sport_health_manager_value_get(SHM_MOD_BLOOD_OXYGEN, SHM_GET_TYPE_REAL_VALUE, &blood_oxygen);
return blood_oxygen;
}
int sport_health_blood_oxygen_get_min()
{
int blood_oxygen = 0;
sport_health_manager_value_get(SHM_MOD_BLOOD_OXYGEN, SHM_GET_TYPE_MIN_VALUE, &blood_oxygen);
return blood_oxygen;
}
int sport_health_blood_oxygen_get_max()
{
int blood_oxygen = 0;
sport_health_manager_value_get(SHM_MOD_BLOOD_OXYGEN, SHM_GET_TYPE_MAX_VALUE, &blood_oxygen);
return blood_oxygen;
}
int sport_health_blood_oxygen_get_avg()
{
int blood_oxygen = 0;
sport_health_manager_value_get(SHM_MOD_BLOOD_OXYGEN, SHM_GET_TYPE_AVG_VALUE, &blood_oxygen);
return blood_oxygen;
}
int sport_health_blood_oxygen_get_rec(struct health_file_data_info *info)
{
return sport_health_manager_value_get(SHM_MOD_BLOOD_OXYGEN, SHM_GET_TYPE_REC_VALUE, info);
}
int sport_health_sleep_data_get(struct sleep_data_analysis *info, int analysis_en, struct sys_time *time)
{
if (!time) {
rtc_read_time(&info->file_time);
} else {
memcpy(&info->file_time, time, sizeof(struct sys_time));
}
int ret = sport_health_manager_value_get(SHM_MOD_SLEEP, SHM_GET_TYPE_INFO_STORAGE, (void *)info);
if (ret) {
return ret;
}
if (analysis_en) {
ret = sport_health_manager_value_get(SHM_MOD_SLEEP, SHM_GET_TYPE_DATA_ANALYSIS, (void *)info);
}
return ret;
}
@@ -0,0 +1,224 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#include "data_storage/data_storage.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-FILE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#define SHM_FILE_MAGIC 0X5a
struct shm_file_hd {
u8 magic;
u8 type;
u16 id;
};
#if TCFG_DATA_STORAGE_ENABLE
static void *__sport_health_file_open(u8 type, u16 id)
{
struct shm_file_hd *hd = zalloc(sizeof(struct shm_file_hd));
hd->type = type;
hd->id = id;
hd->magic = SHM_FILE_MAGIC;
log_debug("[open] id:%d", id);
return (void *)hd;
}
static int __sport_health_file_write(void *hd, u8 *buf, int offset, int len)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
u32 file_id = fp->id;
log_debug("[write]type:%d id:%d offset:%d len:%d", fp->type, file_id, offset, len);
u32 ret = small_file_write(fp->type, &file_id, offset, (void *)buf, len, 0);
fp->id = file_id;
ret += offset;
return ret;
}
static int __sport_health_file_update(void *hd, u8 *buf, int offset, int len)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
log_debug("[update]type:%d id:%d offset:%d len:%d", fp->type, fp->id, offset, len);
u32 ret = small_file_update_by_id(fp->type, fp->id, offset, (void *)buf, len, 0);
return ret;
}
static int __sport_health_file_read(void *hd, u8 *buf, int offset, int len)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
log_debug("[read]type:%d id:%d offset:%d len:%d", fp->type, fp->id, offset, len);
return small_file_read(fp->type, fp->id, offset, (void *)buf, len);
}
static int __sport_health_file_close(void *hd)
{
if (hd) {
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
log_debug("[close]type:%d id:%d ", fp->type, fp->id);
free(hd);
/* hd = NULL; */
}
return 0;
}
static int __sport_health_file_get_len(void *hd)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
log_debug("[len]type:%d id:%d ", fp->type, fp->id);
return small_file_get_size_by_id(fp->type, fp->id);
}
static int __sport_health_file_get_total(u8 type)
{
log_debug("[total]type:%d ", type);
return small_file_get_count(type);
}
static int __sport_health_file_delete(void *hd)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
log_debug("[delete]type:%d id:%d ", fp->type, fp->id);
return small_file_delete_by_id(fp->type, fp->id);
}
static int __sport_health_file_get_id(void *hd, u8 index)
{
struct shm_file_hd *fp = (struct shm_file_hd *)hd;
ASSERT(fp->magic == SHM_FILE_MAGIC);
fp->id = small_file_get_id_by_index(fp->type, index);
log_debug("[get_id]type:%d id:%d index:%d ", fp->type, fp->id, index);
return fp->id;
}
static void *__sport_health_file_open_by_time(u8 type, u16 year, u8 month, u8 day)
{
log_debug("[open]type:%d [%d-%d-%d]", type, year, month, day);
if ((type == F_TYPE_SLEEP) || (type == F_TYPE_HEART) || (type == F_TYPE_BLOOD_OXYGEN)) {
struct shm_file_hd *fp = (struct shm_file_hd *)__sport_health_file_open(type, 0);
if (!fp) {
return NULL;
}
int total = __sport_health_file_get_total(type);
for (int i = 0; i < total; i++) {
fp->id = __sport_health_file_get_id((void *)fp, i);
struct health_file_total_head total_head;
__sport_health_file_read(fp, (u8 *)&total_head, 0, sizeof(struct health_file_total_head));
sport_health_common_swapX((const u8 *)&total_head.year, (u8 *)&total_head.year, 2);
if ((total_head.year == year) && (total_head.month == month) && (total_head.day == day)) {
log_debug("[open]suc type:%d id:%d", fp->type, fp->id);
return (void *)fp;
}
}
__sport_health_file_close((void *)fp);
}
return NULL;
}
const struct shm_file_ops __shm_file_ops = {
.open = __sport_health_file_open,
.write = __sport_health_file_write,
.open_by_time = __sport_health_file_open_by_time,
.read = __sport_health_file_read,
.update = __sport_health_file_update,
.close = __sport_health_file_close,
.delete = __sport_health_file_delete,
.total = __sport_health_file_get_total,
.len = __sport_health_file_get_len,
.get_id = __sport_health_file_get_id,
};
#else
const struct shm_file_ops __shm_file_ops = {0};
#endif
void *sport_health_file_open_by_time(u8 type, u16 year, u8 month, u8 day)
{
if (__shm_file_ops.open_by_time) {
return __shm_file_ops.open_by_time(type, year, month, day);
}
return NULL;
}
void *sport_health_file_open(u8 type, u16 id)
{
if (__shm_file_ops.open) {
return __shm_file_ops.open(type, id);
}
return NULL;
}
int sport_health_file_write(void *hd, u8 *buf, int offset, int len)
{
if (__shm_file_ops.write) {
return __shm_file_ops.write(hd, buf, offset, len);
}
return 0;
}
int sport_health_file_update(void *hd, u8 *buf, int offset, int len)
{
if (__shm_file_ops.update) {
return __shm_file_ops.update(hd, buf, offset, len);
}
return 0;
}
int sport_health_file_read(void *hd, u8 *buf, int offset, int len)
{
if (__shm_file_ops.read) {
return __shm_file_ops.read(hd, buf, offset, len);
}
return 0;
}
int sport_health_file_close(void *hd)
{
if (__shm_file_ops.close) {
return __shm_file_ops.close(hd);
}
return 0;
}
int sport_health_file_get_len(void *hd)
{
if (__shm_file_ops.len) {
return __shm_file_ops.len(hd);
}
return 0;
}
int sport_health_file_get_total(u8 type)
{
if (__shm_file_ops.total) {
return __shm_file_ops.total(type);
}
return 0;
}
int sport_health_file_delete(void *hd)
{
if (__shm_file_ops.delete) {
return __shm_file_ops.delete(hd);
}
return 0;
}
int sport_health_file_get_id(void *hd, u8 index)
{
if (__shm_file_ops.get_id) {
return __shm_file_ops.get_id(hd, index);
}
return 0;
}
@@ -0,0 +1,142 @@
#include "app_config.h"
#include "sport_info_opt.h"
#include "utils/syscfg_id.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-INFO-STORAGE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".shm_info_storage.data.bss")
#pragma data_seg(".shm_info_storage.data")
#pragma const_seg(".shm_info_storage.text.const")
#pragma code_seg(".shm_info_storage.text")
#endif
static u32 g_sport_info_switch_record = 0;
static u8 g_sport_info_mode_record[SPORT_INFO_MODE_TYPE_MAX + 1] = {0};
// 读vm
int sport_info_write_vm(int vm_id, u8 *data, u16 data_len)
{
u8 *tmp_var = zalloc(data_len);
if (NULL == tmp_var) {
goto __sport_info_write_vm_end;
}
syscfg_read(vm_id, tmp_var, data_len);
if (0 != memcmp(tmp_var, data, data_len)) {
syscfg_write(vm_id, data, data_len);
}
__sport_info_write_vm_end:
if (tmp_var) {
free(tmp_var);
}
return 0;
}
// 写vm
int sport_info_read_vm(int vm_id, u8 *data, u16 data_len)
{
int ret = 0;
u8 *tmp_var = zalloc(data_len);
if (NULL == tmp_var) {
log_error("no enough ram\n");
goto __sport_info_read_vm_end;
}
if (data_len == syscfg_read(vm_id, tmp_var, data_len)) {
memcpy(data, tmp_var, data_len);
ret = data_len;
}
__sport_info_read_vm_end:
if (tmp_var) {
free(tmp_var);
}
return ret;
}
// 更新开关
void sport_info_switch_record_update(u8 switch_type, u8 switch_state, u8 write_vm)
{
if (switch_state) {
g_sport_info_switch_record |= BIT(switch_type);
} else {
g_sport_info_switch_record &= ~BIT(switch_type);
}
if (write_vm) {
sport_info_write_vm(VM_SPORT_INFO_SWITCH_FLAG, (u8 *)&g_sport_info_switch_record, sizeof(g_sport_info_switch_record));
}
}
// 获取开关信息
u32 sport_info_swtich_record_get(u8 switch_type)
{
u32 sport_info_switch_record = 0;
if (sport_info_read_vm(VM_SPORT_INFO_SWITCH_FLAG, (u8 *)&g_sport_info_switch_record, sizeof(g_sport_info_switch_record))) {
sport_info_switch_record = g_sport_info_switch_record;
}
if (switch_type < SPORT_INFO_SWTICH_TYPE_MAX) {
return (sport_info_switch_record & BIT(switch_type));
}
return sport_info_switch_record;
}
// 更新模式
void sport_info_mode_record_update(u8 mode_type, u8 mode)
{
g_sport_info_mode_record[0] = sizeof(g_sport_info_mode_record) - 1;
g_sport_info_mode_record[mode_type + 1] = mode;
sport_info_write_vm(VM_SPORT_INFO_MODE_FLAG, g_sport_info_mode_record, sizeof(g_sport_info_mode_record));
}
// 获取模式信息
u16 sport_info_record_get(u8 mode_type, u8 *mode_data[])
{
u16 data_len = sport_info_read_vm(VM_SPORT_INFO_MODE_FLAG, g_sport_info_mode_record, sizeof(g_sport_info_mode_record));
*mode_data = g_sport_info_mode_record;
if (mode_type < SPORT_INFO_MODE_TYPE_MAX) {
*mode_data += mode_type + 1;
data_len = 1;
}
return data_len;
}
int sport_exercise_heart_rate_get(e_heart_rate *heart_rate)
{
return sport_info_read_vm(VM_SPORT_INFO_EXERCISE_HEART_RATE, (u8 *)heart_rate, sizeof(e_heart_rate));
}
int sport_fall_detection_get(fall_detection_t *fall_detect)
{
return sport_info_read_vm(VM_SPORT_INFO_FALL_DETECTION, (u8 *)fall_detect, sizeof(fall_detection_t));
}
int sport_personal_info_get(personal_information *info)
{
return sport_info_read_vm(VM_SPORT_INFO_PERSONAL_INFO_FLAG, (u8 *)info, sizeof(personal_information));
}
int sport_raise_wrist_get(raise_wrist_t *raise_wrist)
{
return sport_info_read_vm(VM_SPORT_INFO_RAISE_WRIST, (u8 *)raise_wrist, sizeof(raise_wrist_t));
}
int sport_sedentary_get(sedentary_t *sedentary)
{
return sport_info_read_vm(VM_SPORT_INFO_SEDENTARY, (u8 *)sedentary, sizeof(sedentary_t));
}
int sport_sleep_detection_get(sleep_detection_t *sleep_detection)
{
return sport_info_read_vm(VM_SPORT_INFO_SLEEP_DETECTION, (u8 *)sleep_detection, sizeof(sleep_detection_t));
}
@@ -0,0 +1,66 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-DET-MENSE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_DET_MENSE)
int mense_resp_check();
static int shm_det_sec_deal()
{
#ifdef CONFIG_UI_STYLE_JL_PUBLIC_MODLS_ENABLE
mense_resp_check();
#endif
return true;
}
static int shm_det_mense_io_ctrl(int cmd, void *priv)
{
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INIT:
break;
case SHM_CMD_RELEASE:
break;
case SHM_CMD_UPDATE_SEC:
shm_det_sec_deal();
break;
case SHM_CMD_TARGET_SET:
break;
case SHM_CMD_CLEAR_VALUE:
break;
case SHM_CMD_SAVE_SINGLE:
case SHM_CMD_SAVE_CONTINUE:
break;
default:
/* ret = -SHE_ERR_MOD_NO_THIS_CMD; */
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(det_mense)
{
.module = SHM_MOD_DET_MENSE,
.io_ctrl = shm_det_mense_io_ctrl,
.get_value = NULL,
};
#endif
@@ -0,0 +1,308 @@
#ifndef __HEALTH_MANAGER__
#define __HEALTH_MANAGER__
#include "app_config.h"
#include "system/includes.h"
#include "data_storage/data_storage.h"
typedef enum {
SHM_MOD_BEGIN, //开始
//algo_mod
SHM_MOD_GSENSOR_ALGO, //GSENSOR
SHM_MOD_HEART_RATE_ALGO, //心率算法
SHM_MOD_SPO2_ALGO, //血氧算法
//app_mod
SHM_MOD_DAILY_ACTIVE, //活动量
SHM_MOD_SPORT, //运动
SHM_MOD_HEART_RATE, //心率
SHM_MOD_BLOOD_OXYGEN, //血氧
SHM_MOD_WEAR_DETECTION, //佩戴检测
SHM_MOD_BLOOD_PRESSURE, //血压
SHM_MOD_HEAT, //压力
SHM_MOD_AIR_PRESSURE, //气压
SHM_MOD_ALTITUDE, //海拔
SHM_MOD_COMPASS, //指南针
SHM_MOD_TEMPERATURE, //体温
SHM_MOD_SLEEP, //睡眠
//DET_MOD
SHM_MOD_DET_SEDENTARY, //久坐
SHM_MOD_DET_FALL, //跌倒
SHM_MOD_DET_WRIST, //翻腕
SHM_MOD_DET_HEART_RATE_HIGH, //心率过高
SHM_MOD_DET_BLOOD_OXYGEN_LOW, //血氧过低
SHM_MOD_DET_DRINK, //喝水提醒
SHM_MOD_DET_MENSE, //女性健康
SHM_MOD_END, //结束
} SHM_MOD;/*update sec 时 按BEGIN -> END顺序执行*/
typedef enum {
SHM_CMD_INIT,
SHM_CMD_RELEASE,
SHM_CMD_ENABLE,
SHM_CMD_DISABLE,
SHM_CMD_REC_ENABLE,
SHM_CMD_REC_DISABLE,
// SHM_CMD_UPDATE_PREB,
SHM_CMD_UPDATE,
SHM_CMD_UPDATE_SEC,
SHM_CMD_UPDATE_ALL,
// SHM_CMD_UPDATE_AFTER,
SHM_CMD_CLEAR_VALUE,
SHM_CMD_CLEAR_VALUE_DAY,
SHM_CMD_START,
SHM_CMD_CONTINUE,
SHM_CMD_PAUSE,
SHM_CMD_STOP,
SHM_CMD_SAVE_CONTINUE,
SHM_CMD_SAVE_SINGLE,
SHM_CMD_INFO_SET,
SHM_CMD_TARGET_SET,
SHM_CMD_PRIV,
SHM_CMD_MAX,
} SHM_CMD;
typedef enum {
SHM_GET_TYPE_REAL_VALUE, //当前/实时数据
SHM_GET_TYPE_MAX_VALUE, //最大
SHM_GET_TYPE_MIN_VALUE, //最小
SHM_GET_TYPE_AVG_VALUE, //平均
SHM_GET_TYPE_INFO, //信息
SHM_GET_TYPE_INFO_STORAGE, //存储文件信息
SHM_GET_TYPE_STORAGE_TOTAL, //存储文件数量
SHM_GET_TYPE_REC_VALUE, //记录数据
SHM_GET_TYPE_TARGET, //目标
SHM_GET_TYPE_STORAGE_ID, //存储文件id
SHM_GET_TYPE_WEEK_DATA, //周数据
SHM_GET_TYPE_DATA_ANALYSIS, //数据分析
SHM_GET_TYPE_MAX,
} SHM_TYPE;
typedef enum {
SHM_ERR_OK,
SHM_ERR_OS_ERR, //1
SHM_ERR_MOD_NOT_FIND, //2
SHM_ERR_MOD_CB_NOT_DEFINE, //3
SHM_ERR_TYPE_NOT_DEFINE, //4
SHM_ERR_MOD_NO_THIS_CMD, //5
SHM_ERR_MOD_NO_THIS_TYPE, //6
SHM_ERR_MOD_NOR_INIT, //7
SHM_ERR_MOD_NOT_ENABLE, //8
SHM_ERR_MOD_ALLOC, //9
SHM_ERR_FILE_NOT_FIND, //10
SHM_ERR_MOD_STA_ERR, //11
SHM_ERR_DATA_ERR, //12
SHM_ERR_MOD_INVALID_PARAM, //13
} SHM_ERR;
enum {
SHM_SPORT_STATUS_NONE,
SHM_SPORT_STATUS_RUN,
SHM_SPORT_STATUS_PAUSE,
SHM_SPORT_STATUS_CONTINUE,
SHM_SPORT_STATUS_STOP,
SHM_SPORT_STATUS_START = SHM_SPORT_STATUS_RUN,
};
enum {
SHM_MOD_STA_NOT_INIT,
SHM_MOD_STA_INIT,
SHM_MOD_STA_DISABLE,
SHM_MOD_STA_DATA_UPDATE_NULL,
SHM_MOD_STA_ENABLE,
SHM_MOD_STA_DATA_UPDATE_SUCC,
};
#if 0 //不使用杰理算法库时,定义结构体传参
struct algo_value {
int steps; //步数
int sedentary; //久坐时间,单位 秒
int calories; //卡路里 = 基础代谢率(BMR) + 活动代谢率(AMR) 单位 卡
int calories_amr; //活动代谢率(AMR 单位 卡
int activity; //活动类型,参考 activity_type
int distance; //距离, 单位cm
int step_frequency; //步频,单位spm (步/分钟)
int sleep; //睡眠, 参考sleep_type
int shake; //摇晃次数
};
#else
#include "sensor_algorithm_jl_motion.h"
// typedef algo_out struct algo_value;
#endif
#define DISTANCE_MAP(dist) ((dist))
struct daily_active {
u32 steps: 17; //步数预留13万步
u32 calories: 12; //热量 4096kc
u32 distance: 17; //距离130km
u32 stand_times: 5; //有效站立次数
u32 day: 5; //日期
u32 init: 1; //
u32 reserve: 7; //保留位可拓展
};
struct sport_value {
u8 run_status; //
u8 status; //
u8 type; //类型
u32 steps_c; //步数
u32 calories_c; //热量
u32 distance_c; //距离 cm
u32 step_freq_c; //
u16 speed_c; //速度cm/s
u16 step_stride_c; //步幅cm/步
u32 run_sec; //sec
u8 heart_real; //实时心率
u8 heart_val; //平均心率
u8 heart_max; //最大心率
u8 heart_min; //最小心率
u32 steps_s; //步数
u32 calories_s; //热量
u32 distance_s; //距离
u32 pause_sec; //sec
u32 tmp_sec; //sec
u16 last_data_time;
u16 file_pack_num;
void *file_hd;
u8 file_index;
u32 file_len;
struct sys_time start_time; //sec
};
#define SPORT_MODE_OUTDOOR 0
#define SPORT_MODE_INDOOR 1
enum {
SHM_SPORT_TYPE_NONE, //非运动
SHM_SPORT_TYPE_OUTDOOR_RUNNING, //户外跑
SHM_SPORT_TYPE_INDOOR_RUNNING, //室内跑步
//expand 需要跟app协商序号
SHM_SPORT_TYPE_OUTDOOR_WALIING, //健走
SHM_SPORT_TYPE_OUTDOOR_RIDE, //户外骑行
SHM_SPORT_TYPE_MOUNTAINEERING, //爬山
SHM_SPORT_TYPE_BADMINTON, //羽毛球
SHM_SPORT_TYPE_VOLLEYBALL, //排球
SHM_SPORT_TYPE_SKIING, //滑雪
SHM_SPORT_TYPE_SPEED_SKATING, //速滑
SHM_SPORT_TYPE_INDOOR_RIDE, //室内骑行
SHM_SPORT_TYPE_STRENGTH_TRAINING, //力量训练
SHM_SPORT_TYPE_ABDOMINAL_CURL, //仰卧起坐
SHM_SPORT_TYPE_PUSH_UP, //俯卧撑
SHM_SPORT_TYPE_AEROBIC_EXERCISE, //有氧运动
SHM_SPORT_TYPE_CALLISTHENICS, //健身操
SHM_SPORT_TYPE_YOGA, //瑜伽
SHM_SPORT_TYPE_DANCE, //跳舞
SHM_SPORT_TYPE_ROPE_SKIPPING, //跳绳
SHM_SPORT_TYPE_POOL_SWIMMING, //泳池游泳
SHM_SPORT_TYPE_FREE_TIME, //自由活动
};
enum {
SP_DATA_STEPS,
SP_DATA_DISTANCE,
SP_DATA_CALORIES,
SP_DATA_TIME,
SP_DATA_HR,
};
#pragma pack(1) //非对齐编译
struct health_file_total_head {
u8 type;
u16 year;
u8 month;
u8 day;
u16 crc;
u8 version;
u8 interval;
u16 reserve;
};
struct health_file_data_head {
u8 hour;
u8 min;
u16 len;
};
#pragma pack(0) //对齐编译
struct health_file_data_info {
struct sys_time file_time;
int rlen;
int interval;
u8 *rbuf;
};
struct sleep_data_analysis {
struct sys_time file_time;
int total_min;
int awake_min;
int light_min;
int deep_min;
int rem_min;
void *data;
};
struct sport_health_module {
u8 module;
int(*io_ctrl)(int cmd, void *priv);
int (*get_value)(int type, void *pirv);
};
#define REGISTER_SPORT_HEALTH_MODULE(target) \
const struct sport_health_module sport_health_##target sec(.sport_health_module) =
extern const struct sport_health_module sport_health_module_begin[];
extern const struct sport_health_module sport_health_module_end[];
#define list_for_each_sport_health_module(p) \
for (p =(struct sport_health_module*)sport_health_module_begin; p < (struct sport_health_module*)sport_health_module_end; p++)
struct shm_file_ops {
void *(*open)(u8 type, u16 index);
int (*write)(void *hd, u8 *buf, int offset, int len);
int (*read)(void *hd, u8 *buf, int offset, int len);
int (*delete)(void *hd);
int (*update)(void *hd, u8 *buf, int offset, int len);
int (*close)(void *hd);
void *(*open_by_time)(u8 type, u16 year, u8 month, u8 day);
int (*len)(void *hd);
int (*total)(u8 type);
int (*get_id)(void *hd, u8 index);
};
int sport_health_manager_init();
int sport_health_manager_release();
int sport_health_manager_value_get(int module, int type, void *priv);
int sport_health_manager_msg_post(int module, int cmd, void *priv, int need_pend);
int sport_health_manager_msg_post_self(int module, int cmd, void *priv);
void *sport_health_alloc(u32 size);
void sport_health_free(void *p);
void rtc_read_time(struct sys_time *time);
void *sport_health_file_open(u8 type, u16 id);
int sport_health_file_update(void *hd, u8 *buf, int offset, int len);
int sport_health_file_write(void *hd, u8 *buf, int offset, int len);
int sport_health_file_read(void *hd, u8 *buf, int offset, int len);
void *sport_health_file_open_by_time(u8 type, u16 year, u8 month, u8 day);
int sport_health_file_close(void *hd);
int sport_health_file_get_len(void *hd);
int sport_health_file_get_total(u8 type);
int sport_health_file_delete(void *hd);
int sport_health_file_get_id(void *hd, u8 index);
#include "health_manager/shm_common_api.h"
#endif//undef __HEALTH_MANAGER__
@@ -0,0 +1,354 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM_BO]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_BLOOD_OXYGEN)
#define HEALTH_RATE_DATA_TEST 1
#define HEALTH_FILE_TYPE F_TYPE_BLOOD_OXYGEN
#define HEALTH_FILE_INVERVAL (5)
#define HEALTH_FILE_TEST 0
struct blood_oxygen_data {
u8 status;
u8 bo_cur;
u8 bo_max;
u8 bo_min;
u8 bo_avg;
u16 avg_cnt;
#if HEALTH_FILE_INVERVAL
u16 rec_timer_id;
#endif
};
#define BO_MAX_DEFAULT (0x0)
#define BO_MIN_DEFAULT (0xff)
#define BO_CUR_DEFAULT (0x0)
static struct blood_oxygen_data __info = {0};
/* ------------------------------------------------------------------------------------*/
/**
* @brief bo_mod_value_clr 重置统计数据
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int bo_mod_value_clr()
{
/* if(__info.status == SHM_MOD_STA_ENABLE){ */
/* return -SHM_ERR_MOD_STA_ERR; */
/* } */
__info.bo_cur = BO_CUR_DEFAULT;
__info.bo_min = BO_MIN_DEFAULT;
__info.bo_max = BO_MAX_DEFAULT;
__info.bo_avg = BO_CUR_DEFAULT;
__info.avg_cnt = 0;
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief bo_mode_file_read 读取文件记录
*
* @param p
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int bo_mode_file_read(struct health_file_data_info *p)
{
struct sys_time time;
#if 0//只读当天
rtc_read_time(&time);
#else//由句柄指定日期
memcpy(&time, &p->file_time, sizeof(struct sys_time));
#endif
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
if (!fp) {
return -SHM_ERR_FILE_NOT_FIND;
}
int file_len = sport_health_file_get_len(fp);
int data_offset = sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
struct health_file_total_head file_total_head;
sport_health_file_read(fp, (u8 *)&file_total_head, 0, sizeof(struct health_file_total_head));
p->interval = file_total_head.interval;
p->rlen = file_len - data_offset;
p->rbuf = zalloc(p->rlen);
sport_health_file_read(fp, p->rbuf, data_offset, p->rlen);
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief bo_mode_file_save 保存数据到文件
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int bo_mode_file_save()
{
int file_len = 0;
struct sys_time time;
rtc_read_time(&time);
int data_offset = 0;
int time_offset = 0;
time_offset = (time.hour * 60 + time.min) / HEALTH_FILE_INVERVAL;
log_info("%s %d %d %d", __func__, time.hour, time.min, time_offset);
struct health_file_total_head file_head = {
.type = HEALTH_FILE_TYPE,
.year = time.year,
.month = time.month,
.day = time.day,
.crc = 0xffff,
.version = 0,
.reserve = 0,
.interval = HEALTH_FILE_INVERVAL,
};
struct health_file_data_head data_head = {
.hour = 0,
.min = 0,
.len = time_offset + 1,
};
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
if (!fp) {
fp = sport_health_file_open(HEALTH_FILE_TYPE, 0);
sport_health_common_swapX((u8 *) &file_head.year, (u8 *) &file_head.year, 2);
file_len = sport_health_file_write(fp, (u8 *) &file_head, file_len, sizeof(struct health_file_total_head));
sport_health_common_swapX((u8 *) &data_head.len, (u8 *) &data_head.len, 2);
file_len = sport_health_file_write(fp, (u8 *) &data_head, file_len, sizeof(struct health_file_data_head));
//写入数据
data_offset = time_offset + sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
file_len = sport_health_file_write(fp, (u8 *) &__info.bo_cur, data_offset, 1);
//更新校验值//只需要crc不同,即可,不做实际校验。
file_head.crc = time_offset;
sport_health_file_update(fp, (u8 *) &file_head, 0, sizeof(struct health_file_total_head));
} else {
//续写
file_len = sport_health_file_get_len(fp);
data_offset = time_offset + sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
if (data_offset > file_len) {
//写入数据
file_len = sport_health_file_write(fp, (u8 *) &__info.bo_cur, data_offset, 1);
if (file_len <= 0) {
sport_health_file_close(fp);
return -SHM_ERR_FILE_WRITE_FAIL;
}
//更新校验值//只需要crc不同,即可,不做实际校验。
file_head.crc = time_offset;
sport_health_common_swapX((u8 *) &file_head.year, (u8 *) &file_head.year, 2);
sport_health_file_update(fp, (u8 *) &file_head, 0, sizeof(struct health_file_total_head));
sport_health_common_swapX((u8 *) &data_head.len, (u8 *) &data_head.len, 2);
file_len = sport_health_file_write(fp, (u8 *) &data_head, file_len, sizeof(struct health_file_data_head));
if (file_len <= 0) {
sport_health_file_close(fp);
return -SHM_ERR_FILE_WRITE_FAIL;
}
}
}
#if 0
file_len = sport_health_file_get_len(fp);
u8 *rw_buf = zalloc(file_len);
sport_health_file_read(fp, rw_buf, 0, file_len);
put_buf(rw_buf, file_len);
free(rw_buf);
#endif
if (fp) {
sport_health_file_close(fp);
}
return 0;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief bo_mode_update_sec_deal 测量时更新数据
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int bo_mode_update_sec_deal()
{
u8 blood_oxygen = 0;
int ret = sport_health_manager_value_get(SHM_MOD_SPO2_ALGO, SHM_GET_TYPE_REAL_VALUE, &blood_oxygen);
#if HEALTH_RATE_DATA_TEST
blood_oxygen = 80 + rand32() % 30;
#endif//HEALTH_RATE_DATA_TEST
if (blood_oxygen) {
__info.bo_cur = blood_oxygen;
__info.bo_max = (__info.bo_cur > __info.bo_max) ? __info.bo_cur : __info.bo_max;
__info.bo_min = (__info.bo_cur < __info.bo_min) ? __info.bo_cur : __info.bo_min;
if (__info.avg_cnt) {
u32 bo_sum = __info.bo_avg * __info.avg_cnt + __info.bo_cur;
__info.avg_cnt ++;
__info.bo_avg = bo_sum / __info.avg_cnt;
} else {
__info.avg_cnt ++;
__info.bo_avg = __info.bo_cur;
}
__info.status = SHM_MOD_STA_DATA_UPDATE_SUCC;
}
log_debug("%s bo:%d bo_cur:%d min:%d max:%d avg:%d", __func__, blood_oxygen, __info.bo_cur, __info.bo_min, __info.bo_max, __info.bo_avg);
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief bo_save_continue_cb 存储时更新数据回调
*
* @param p
*/
/* ------------------------------------------------------------------------------------*/
static void bo_save_continue_cb(void *p)
{
sport_health_manager_msg_post(SHM_MOD_HEART_RATE, SHM_CMD_SAVE_CONTINUE, NULL, 0);
}
static int bo_mod_io_ctrl(int cmd, void *priv)
{
log_info("%s cmd=%d status:%d", __func__, cmd, __info.status);
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INIT:
bo_mod_value_clr();
#if 1
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE, SHM_CMD_REC_ENABLE, NULL);
#endif
break;
case SHM_CMD_ENABLE:
//todo
sport_health_manager_msg_post_self(SHM_MOD_SPO2_ALGO, SHM_CMD_ENABLE, NULL);
__info.status = SHM_MOD_STA_ENABLE;
break;
case SHM_CMD_DISBALE:
__info.status = SHM_MOD_STA_DISABLE;
//todo
sport_health_manager_msg_post_self(SHM_MOD_SPO2_ALGO, SHM_CMD_DISBALE, NULL);
break;
case SHM_CMD_REC_ENABLE:
if (!__info.rec_timer_id) {
__info.rec_timer_id = usr_timer_add(NULL, bo_save_continue_cb, HEALTH_FILE_INVERVAL * 60 * 1000, 0);
}
break;
case SHM_CMD_REC_DISABLE:
if (__info.rec_timer_id) {
usr_timer_del(__info.rec_timer_id);
__info.rec_timer_id = 0;
}
break;
case SHM_CMD_UPDATE:
case SHM_CMD_UPDATE_SEC:
if (__info.status == SHM_MOD_STA_ENABLE || (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) || (__info.status == SHM_MOD_STA_DATA_UPDATE_NULL)) {
//TODO
bo_mode_update_sec_deal();
}
break;
case SHM_CMD_SAVE_CONTINUE:
#if HEALTH_FILE_INVERVAL
{
int sensor_close = (__info.status == SHM_MOD_STA_DISABLE) ? 1 : 0;
if (sensor_close) {
sport_health_manager_msg_post_self(SHM_MOD_SPO2_ALGO, SHM_CMD_ENABLE, NULL);
__info.status = SHM_MOD_STA_ENABLE;
}
bo_mode_update_sec_deal();
bo_mode_file_save();
if (sensor_close) {
__info.status = SHM_MOD_STA_DISABLE;
//todo
sport_health_manager_msg_post_self(SHM_MOD_SPO2_ALGO, SHM_CMD_DISBALE, NULL);
}
}
#endif
break;
case SHM_CMD_CLEAR_VALUE:
__info.status = SHM_MOD_STA_DATA_UPDATE_NULL;
//todo
bo_mod_value_clr();
break;
default:
break;
}
return ret;
}
static int bo_mod_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_REAL_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.bo_cur, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_MAX_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.bo_max, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_MIN_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.bo_min, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_AVG_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.bo_avg, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_REC_VALUE: {
ret = bo_mode_file_read((struct health_file_data_info *)priv);
}
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(blood_oxygen)
{
.module = SHM_MOD_BLOOD_OXYGEN,
.io_ctrl = bo_mod_io_ctrl,
.get_value = bo_mod_get_value,
};
#endif
@@ -0,0 +1,192 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-DAILY]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_DAILY_ACTIVE)
static struct daily_active daily_active_value;
static struct daily_active daily_active_storage;
static struct daily_active daily_active_target = {
.steps = 50000,
.calories = 200,
.distance = 40000,
.stand_times = 14,
};
#define __value (&daily_active_value)
#define __storage (&daily_active_storage)
#define __target (&daily_active_target)
static int shm_daily_active_init()
{
int ret = SHM_ERR_OK;
int len;
struct daily_active tmp;
struct sys_time time;
rtc_read_time(&time);
len = syscfg_read(VM_SHM_DAILY_ACTIVE, &tmp, sizeof(struct daily_active));
log_info("%s %d %d %d %d", __func__, len, (u32)sizeof(struct daily_active), tmp.day, time.day);
if ((len == sizeof(struct daily_active)) && (tmp.day == time.day)) {
memcpy(__storage, &tmp, sizeof(struct daily_active));
} else {
memset(__storage, 0, sizeof(struct daily_active));
}
len = syscfg_read(VM_SHM_DAILY_ACTIVE_TARGET, &tmp, sizeof(struct daily_active));
if (len == sizeof(struct daily_active)) {
memcpy(__target, &tmp, sizeof(struct daily_active));
}
memset(__value, 0, sizeof(struct daily_active));
__value->day = time.day;
__value->init = 1;
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
log_debug("fun:<%s> storage steps:%d cal:%d dist:%d day:%d\n", \
__func__, __storage->steps, __storage->calories, __storage->distance, __storage->day);
log_debug("fun:<%s> target steps:%d cal:%d dist:%d \n", \
__func__, __target->steps, __target->calories, __target->distance);
return ret;
}
static int shm_daily_active_release()
{
syscfg_write(VM_SHM_DAILY_ACTIVE, __value, sizeof(struct daily_active));
__value->init = 0;
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
return SHM_ERR_OK;
}
static int shm_daily_active_save()
{
syscfg_write(VM_SHM_DAILY_ACTIVE, __value, sizeof(struct daily_active));
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
return SHM_ERR_OK;
}
static int shm_daily_active_update()
{
int ret;
struct algo_value algo_out_value;
struct sys_time time;
rtc_read_time(&time);
ret = sport_health_manager_value_get(SHM_MOD_GSENSOR_ALGO, SHM_GET_TYPE_INFO, &algo_out_value);
if ((__storage->day) && (time.day != __storage->day)) {
memset(__storage, 0, sizeof(struct daily_active));
}
if (!ret) {
__value->steps = __storage->steps + algo_out_value.steps;
__value->calories = __storage->calories + algo_out_value.calories;
__value->distance = __storage->distance + DISTANCE_MAP(algo_out_value.distance);
__value->day = time.day;
}
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
log_debug("fun:<%s> storage steps:%d cal:%d dist:%d day:%d\n", \
__func__, __storage->steps, __storage->calories, __storage->distance, __storage->day);
return ret;
}
static int shm_daily_active_target_set(void *priv)
{
int ret = SHM_ERR_OK;
memcpy(__target, priv, sizeof(struct daily_active));
syscfg_write(VM_SHM_DAILY_ACTIVE_TARGET, __target, sizeof(struct daily_active));
log_debug("fun:<%s> target steps:%d cal:%d dist:%d \n", \
__func__, __target->steps, __target->calories, __target->distance);
return ret;
}
static int shm_daily_active_clear_value()
{
int ret = SHM_ERR_OK;
memset(__storage, 0, sizeof(struct daily_active));
memset(__value, 0, sizeof(struct daily_active));
struct sys_time time;
rtc_read_time(&time);
__value->day = time.day;
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
return ret;
}
static int shm_daily_active_io_crtl(int cmd, void *priv)
{
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INIT:
ret = shm_daily_active_init();
break;
case SHM_CMD_RELEASE:
ret = shm_daily_active_release();
break;
case SHM_CMD_UPDATE_SEC:
ret = shm_daily_active_update();
break;
case SHM_CMD_TARGET_SET:
ret = shm_daily_active_target_set(priv);
break;
case SHM_CMD_CLEAR_VALUE:
ret = shm_daily_active_clear_value();
break;
case SHM_CMD_SAVE_SINGLE:
case SHM_CMD_SAVE_CONTINUE:
ret = shm_daily_active_save();
break;
default:
/* ret = -SHE_ERR_MOD_NO_THIS_CMD; */
break;
}
return ret;
}
static int shm_daily_active_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_INFO:
memcpy(priv, __value, sizeof(struct daily_active));
log_debug("fun:<%s> real value steps:%d cal:%d dist:%d day:%d\n", \
__func__, __value->steps, __value->calories, __value->distance, __value->day);
break;
case SHM_GET_TYPE_TARGET:
memcpy(priv, __target, sizeof(struct daily_active));
log_debug("fun:<%s> target steps:%d cal:%d dist:%d \n", \
__func__, __target->steps, __target->calories, __target->distance);
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(daily_active)
{
.module = SHM_MOD_DAILY_ACTIVE,
.io_ctrl = shm_daily_active_io_crtl,
.get_value = shm_daily_active_get_value,
};
#endif
@@ -0,0 +1,350 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM_HR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_HEART_RATE)
#define HEALTH_RATE_DATA_TEST 1 //使用模拟数据测试
#define HEALTH_FILE_TYPE F_TYPE_HEART
#define HEALTH_FILE_INVERVAL (5) //5分钟记录一次数据
#define HEALTH_FILE_TEST 0 //
struct heart_rate_data {
u8 status;
u8 hr_cur;
u8 hr_max;
u8 hr_min;
u8 hr_avg;
u16 avg_cnt;
#if HEALTH_FILE_INVERVAL
u16 rec_timer_id;
#endif
};
#define HR_MAX_DEFAULT (0x0)
#define HR_MIN_DEFAULT (0xff)
#define HR_CUR_DEFAULT (0x0)
static struct heart_rate_data __info = {0};
/* ------------------------------------------------------------------------------------*/
/**
* @brief hr_mod_value_clr 重置统计数据
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int hr_mod_value_clr()
{
/* if(__info.status == SHM_MOD_STA_ENABLE){ */
/* return -SHM_ERR_MOD_STA_ERR; */
/* } */
__info.hr_cur = HR_CUR_DEFAULT;
__info.hr_min = HR_MIN_DEFAULT;
__info.hr_max = HR_MAX_DEFAULT;
__info.hr_avg = HR_CUR_DEFAULT;
__info.avg_cnt = 0;
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief hr_mode_file_read 读取文件记录
*
* @param p
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int hr_mode_file_read(struct health_file_data_info *p)
{
struct sys_time time;
#if 0//只读当天
rtc_read_time(&time);
#else//由句柄指定日期
memcpy(&time, &p->file_time, sizeof(struct sys_time));
#endif
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
if (!fp) {
return -SHM_ERR_FILE_NOT_FIND;
}
int file_len = sport_health_file_get_len(fp);
int data_offset = sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
struct health_file_total_head file_total_head;
sport_health_file_read(fp, (u8 *)&file_total_head, 0, sizeof(struct health_file_total_head));
p->interval = file_total_head.interval;
p->rlen = file_len - data_offset;
p->rbuf = zalloc(p->rlen);
sport_health_file_read(fp, p->rbuf, data_offset, p->rlen);
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief hr_mode_file_save 保存数据到文件
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int hr_mode_file_save()
{
int file_len = 0;
struct sys_time time;
rtc_read_time(&time);
int data_offset = 0;
int time_offset = 0;
time_offset = (time.hour * 60 + time.min) / HEALTH_FILE_INVERVAL;
log_info("%s %d %d %d", __func__, time.hour, time.min, time_offset);
struct health_file_total_head file_head = {
.type = HEALTH_FILE_TYPE,
.year = time.year,
.month = time.month,
.day = time.day,
.crc = 0xffff,
.version = 0,
.reserve = 0,
.interval = HEALTH_FILE_INVERVAL,
};
struct health_file_data_head data_head = {
.hour = 0,
.min = 0,
.len = time_offset + 1,
};
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
if (!fp) {
fp = sport_health_file_open(HEALTH_FILE_TYPE, 0);
sport_health_common_swapX((u8 *) &file_head.year, (u8 *) &file_head.year, 2);
file_len = sport_health_file_write(fp, (u8 *) &file_head, file_len, sizeof(struct health_file_total_head));
sport_health_common_swapX((u8 *) &data_head.len, (u8 *) &data_head.len, 2);
file_len = sport_health_file_write(fp, (u8 *) &data_head, file_len, sizeof(struct health_file_data_head));
//写入数据
data_offset = time_offset + sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
file_len = sport_health_file_write(fp, (u8 *) &__info.hr_cur, data_offset, 1);
//更新校验值//只需要crc不同,即可,不做实际校验。
file_head.crc = time_offset;
sport_health_file_update(fp, (u8 *) &file_head, 0, sizeof(struct health_file_total_head));
} else {
//续写
file_len = sport_health_file_get_len(fp);
data_offset = time_offset + sizeof(struct health_file_total_head) + sizeof(struct health_file_data_head);
if (data_offset > file_len) {
//写入数据
file_len = sport_health_file_write(fp, (u8 *) &__info.hr_cur, data_offset, 1);
//更新校验值//只需要crc不同,即可,不做实际校验。
file_head.crc = time_offset;
sport_health_common_swapX((u8 *) &file_head.year, (u8 *) &file_head.year, 2);
sport_health_file_update(fp, (u8 *) &file_head, 0, sizeof(struct health_file_total_head));
sport_health_common_swapX((u8 *) &data_head.len, (u8 *) &data_head.len, 2);
file_len = sport_health_file_write(fp, (u8 *) &data_head, file_len, sizeof(struct health_file_data_head));
}
}
#if 0
file_len = sport_health_file_get_len(fp);
u8 *rw_buf = zalloc(file_len);
sport_health_file_read(fp, rw_buf, 0, file_len);
printf("%s %d", __func__, __LINE__);
put_buf(rw_buf, file_len);
free(rw_buf);
struct health_file_data_info *finfo = zalloc(sizeof(struct health_file_data_info));
hr_mode_file_read(finfo);
printf("%s %d", __func__, __LINE__);
put_buf(finfo->rbuf, finfo->rlen);
free(finfo->rbuf);
free(finfo);
#endif
if (fp) {
sport_health_file_close(fp);
}
return 0;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief hr_mode_update_sec_deal 测量时更新数据
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int hr_mode_update_sec_deal()
{
u8 heart_rate = 0;
int ret = sport_health_manager_value_get(SHM_MOD_HEART_RATE_ALGO, SHM_GET_TYPE_REAL_VALUE, &heart_rate);
#if HEALTH_RATE_DATA_TEST
heart_rate = 80 + rand32() % 30;
#endif//HEALTH_RATE_DATA_TEST
if (heart_rate) {
__info.hr_cur = heart_rate;
__info.hr_max = (__info.hr_cur > __info.hr_max) ? __info.hr_cur : __info.hr_max;
__info.hr_min = (__info.hr_cur < __info.hr_min) ? __info.hr_cur : __info.hr_min;
if (__info.avg_cnt) {
u32 hr_sum = __info.hr_avg * __info.avg_cnt + __info.hr_cur;
__info.avg_cnt ++;
__info.hr_avg = hr_sum / __info.avg_cnt;
} else {
__info.avg_cnt ++;
__info.hr_avg = __info.hr_cur;
}
__info.status = SHM_MOD_STA_DATA_UPDATE_SUCC;
}
log_debug("%s hr:%d hr_cur:%d min:%d max:%d avg:%d", __func__, heart_rate, __info.hr_cur, __info.hr_min, __info.hr_max, __info.hr_avg);
return ret;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief hr_save_continue_cb 存储时更新数据回调
*
* @param p
*/
/* ------------------------------------------------------------------------------------*/
static void hr_save_continue_cb(void *p)
{
sport_health_manager_msg_post(SHM_MOD_HEART_RATE, SHM_CMD_SAVE_CONTINUE, NULL, 0);
}
static int hr_mod_io_ctrl(int cmd, void *priv)
{
log_info("%s cmd=%d status:%d", __func__, cmd, __info.status);
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INIT:
hr_mod_value_clr();
#if 1
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE, SHM_CMD_REC_ENABLE, NULL);
#endif
break;
case SHM_CMD_ENABLE:
//todo
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE_ALGO, SHM_CMD_ENABLE, NULL);
__info.status = SHM_MOD_STA_ENABLE;
break;
case SHM_CMD_DISBALE:
__info.status = SHM_MOD_STA_DISABLE;
//todo
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE_ALGO, SHM_CMD_DISBALE, NULL);
break;
case SHM_CMD_REC_ENABLE:
if (!__info.rec_timer_id) {
__info.rec_timer_id = usr_timer_add(NULL, hr_save_continue_cb, HEALTH_FILE_INVERVAL * 60 * 1000, 0);
}
break;
case SHM_CMD_REC_DISABLE:
if (__info.rec_timer_id) {
usr_timer_del(__info.rec_timer_id);
__info.rec_timer_id = 0;
}
break;
case SHM_CMD_UPDATE:
case SHM_CMD_UPDATE_SEC:
if (__info.status == SHM_MOD_STA_ENABLE || (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) || (__info.status == SHM_MOD_STA_DATA_UPDATE_NULL)) {
//TODO
hr_mode_update_sec_deal();
}
break;
case SHM_CMD_SAVE_CONTINUE:
#if HEALTH_FILE_INVERVAL
{
int sensor_close = (__info.status == SHM_MOD_STA_DISABLE) ? 1 : 0;
if (sensor_close) {
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE_ALGO, SHM_CMD_ENABLE, NULL);
__info.status = SHM_MOD_STA_ENABLE;
}
hr_mode_update_sec_deal();
hr_mode_file_save();
if (sensor_close) {
__info.status = SHM_MOD_STA_DISABLE;
//todo
sport_health_manager_msg_post_self(SHM_MOD_HEART_RATE_ALGO, SHM_CMD_DISBALE, NULL);
}
}
#endif
break;
case SHM_CMD_CLEAR_VALUE:
__info.status = SHM_MOD_STA_DATA_UPDATE_NULL;
//todo
hr_mod_value_clr();
break;
default:
break;
}
return ret;
}
static int hr_mod_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_REAL_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.hr_cur, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_MAX_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.hr_max, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_MIN_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.hr_min, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_AVG_VALUE:
if (__info.status == SHM_MOD_STA_DATA_UPDATE_SUCC) {
memcpy(priv, &__info.hr_avg, 1);
} else {
ret = SHM_ERR_DATA_ERR;
}
break;
case SHM_GET_TYPE_REC_VALUE: {
ret = hr_mode_file_read((struct health_file_data_info *)priv);
}
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(heart_rate)
{
.module = SHM_MOD_HEART_RATE,
.io_ctrl = hr_mod_io_ctrl,
.get_value = hr_mod_get_value,
};
#endif
@@ -0,0 +1,482 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "timestamp/timestamp.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM_SLEEP]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_SLEEP)
//睡眠记录配置
#define HEALTH_FILE_TYPE F_TYPE_SLEEP
#define HEALTH_FILE_VERSION (0) //协议约定
#define HEALTH_FILE_INTERVAL (0Xff) //协议约定
#define TCFG_SPORT_HEALTH_AWAKE_MAX_LEN 30 //30min的清醒数据将被过滤
//测试数据配置
#define TCFG_SPORT_HEALTH_SLEEP_TEST 0
#define TCFG_SPORT_HEALTH_SLEEP_TEST_YEAR 2024
#define TCFG_SPORT_HEALTH_SLEEP_TEST_MONTH 9
#define TCFG_SPORT_HEALTH_SLEEP_TEST_DAY 7
#define TCFG_SPORT_HEALTH_SLEEP_TARGET_MIN (8*60*60)//7h
#pragma pack(1)//
struct sleep_storage_data {
u8 stage;
u8 sleep_min;//min
};
#pragma pack()//
static void motion_sleep_data_test_get(sleep_data *out);
/* ------------------------------------------------------------------------------------*/
/**
* @brief motion_sleep_data_get_switch 睡眠数据选择接口
*
* @param out 数据
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int motion_sleep_data_get_switch(sleep_data *out)
{
//使用模拟测试数据
#if TCFG_SPORT_HEALTH_SLEEP_TEST
motion_sleep_data_test_get(out);
#else
//使用JL算法数据
//若当前处于睡眠,则拒绝数据获取
if (!algo_motion_sleep_is_terminated()) {
return false;
}
//获取数据
algo_motion_sleep_get(out);
#endif
return true;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_sleep_data_stroage 睡眠数据存储
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int sport_health_sleep_data_stroage()
{
sleep_data out = {0};
//获取睡眠数据
if (!motion_sleep_data_get_switch(&out)) {
//需要忽略本次数据
return SHM_ERR_OK;
}
//没有数据,或者只有清醒数据,忽略
if ((out.blocks == 0) || ((out.blocks == 1) && (out.chart[0].stage == SLEEP_STAGE_AWAKE))) {
return SHM_ERR_OK;
}
//获取系统时间
struct sys_time time;
rtc_read_time(&time);
#if TCFG_SPORT_HEALTH_SLEEP_TEST //测试使用
struct sys_time _time = {
.year = TCFG_SPORT_HEALTH_SLEEP_TEST_YEAR,
.month = TCFG_SPORT_HEALTH_SLEEP_TEST_MONTH,
.day = TCFG_SPORT_HEALTH_SLEEP_TEST_DAY + 1,
.hour = 22,
.min = 30,
};
memcpy(&time, &_time, sizeof(struct sys_time));
#endif
//获取文件句柄
int file_len = 0;
int swap_days = 0;
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
#if TCFG_SPORT_HEALTH_SLEEP_TEST//测试使用
if (fp) {
sport_health_file_delete(fp);
sport_health_file_close(fp);
fp = NULL;
}
#endif
if (!fp) {
//若句柄不存在,则新建文件
struct health_file_total_head file_head = {
.type = HEALTH_FILE_TYPE,
.year = time.year,
.month = time.month,
.day = time.day,
.crc = 0,
.interval = HEALTH_FILE_INTERVAL,
.version = HEALTH_FILE_VERSION,
.reserve = 0,
};
sport_health_common_swapX((u8 *)&file_head.year, (u8 *)&file_head.year, 2);
fp = sport_health_file_open(HEALTH_FILE_TYPE, 0);
file_len = sport_health_file_write(fp, (u8 *)&file_head, file_len, sizeof(struct health_file_total_head));
} else {
//否则续写
file_len = sport_health_file_get_len(fp);
}
u8 valid_point_num = 0;
u8 data_head_flag = 0;
struct health_file_data_head data_head = {0};
for (int i = 0; i < out.blocks - 1; i++) {
//数据开头的清醒数据不需要记录
if ((i == 0) && (out.chart[i].stage == SLEEP_STAGE_AWAKE)) {
continue;
}
//写入数据包头
if (!data_head_flag) {
struct sys_time start_time;
timestamp_utc_sec_2_mytime(out.chart[i].timestamp, &start_time);
data_head .hour = start_time.hour;
data_head .min = start_time.min;
data_head .len = 0xffff;
file_len = sport_health_file_write(fp, (u8 *)&data_head, file_len, sizeof(struct health_file_data_head));
data_head_flag = 1;
}
//按格式写入数据到文件
int block_len = out.chart[i + 1].timestamp - out.chart[i].timestamp;
struct sys_time block_time_begin;
timestamp_utc_sec_2_mytime(out.chart[i].timestamp, &block_time_begin);
struct sys_time block_time_end;
timestamp_utc_sec_2_mytime(out.chart[i + 1].timestamp, &block_time_end);
struct sleep_storage_data sleep_block = {
.stage = (out.chart[i].stage == SLEEP_STAGE_AWAKE) ? 0xff : out.chart[i].stage,
};
log_debug("[%d:%d]~[%d %d]", block_time_begin.hour, block_time_begin.min, block_time_end.hour, block_time_end.min);
if (block_time_end.hour * 60 + block_time_end.min < block_time_begin.hour * 60 + block_time_begin.min) {
//存在跨天数据,则在0点分段写入,方便绘图
swap_days = 1;
int sleep_min = 24 * 60 - (block_time_begin.hour * 60 + block_time_begin.min);
do {
//睡眠时间超过255分钟时,需要分段写入
if (sleep_min > 255) {
sleep_block.sleep_min = 255;
log_debug("[1]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
sleep_min -= 255;
} else {
sleep_block.sleep_min = sleep_min;
log_debug("[2]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
}
} while (sleep_min > 255);
sleep_min = block_time_end.hour * 60 + block_time_end.min;
do {
//睡眠时间超过255分钟时,需要分段写入
if (sleep_min > 255) {
sleep_block.sleep_min = 255;
log_debug("[3]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
sleep_min -= 255;
} else {
sleep_block.sleep_min = sleep_min;
log_debug("[4]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
}
} while (sleep_min > 255);
} else { //正常写入
int sleep_min = (out.chart[i + 1].timestamp - out.chart[i].timestamp + 30) / 60;
do {
//睡眠时间超过255分钟时,需要分段写入
if (sleep_min > 255) {
sleep_block.sleep_min = 255;
log_debug("[5]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
sleep_min -= 255;
} else {
sleep_block.sleep_min = sleep_min;
log_debug("[6]index:%d stage:%d len:%d", valid_point_num, sleep_block.stage, sleep_block.sleep_min);
file_len = sport_health_file_write(fp, (u8 *)&sleep_block, file_len, sizeof(struct sleep_storage_data));
valid_point_num++;
}
} while (sleep_min > 255);
}
}
//记录数据长度
data_head.len = valid_point_num * 2;
sport_health_common_swapX((u8 *) & (data_head.len), (u8 *) & (data_head.len), 2);
sport_health_file_update(fp, (u8 *)&data_head, sizeof(struct health_file_total_head), sizeof(struct health_file_data_head));
//更新文件头的crc和跨天信息
struct health_file_total_head re_file_head;
sport_health_file_read(fp, (u8 *)& re_file_head, 0, sizeof(struct health_file_total_head));
for (int i = 0; i < 16; i++) {
//用reserve区记录分段信息
re_file_head.reserve |= (swap_days << re_file_head.crc);
//CRC做强制校验,有差异即可
re_file_head.crc++;
}
sport_health_file_update(fp, (u8 *)&re_file_head, 0, sizeof(struct health_file_total_head));
//关闭文件,结束记录
sport_health_file_close(fp);
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_sleep_rec_data_get 获取记录数据
*
* @param value 句柄
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int sport_health_sleep_rec_data_get(struct sleep_data_analysis *value)
{
sleep_data *out = (sleep_data *)value->data;
//获取日期
struct sys_time time;
#if 0//只读当天
rtc_read_time(&time);
#else//由句柄指定日期
memcpy(&time, &value->file_time, sizeof(struct sys_time));
#endif
//打开文件
void *fp = sport_health_file_open_by_time(HEALTH_FILE_TYPE, time.year, time.month, time.day);
if (!fp) {
out->blocks = 0;
//文件不存在
return -SHM_ERR_FILE_NOT_FIND;
}
/* int block_idx = 0; */
int file_total = sport_health_file_get_len(fp);
int file_offset = 0;
//读取文件头
struct health_file_total_head total_head;
sport_health_file_read(fp, (u8 *)&total_head, 0, sizeof(struct health_file_total_head));
sport_health_common_swapX((u8 *)&total_head.year, (u8 *)&total_head.year, 2);
file_offset += sizeof(struct health_file_total_head);
struct sys_time start_time;
u32 timestamp_start;
u32 timestamp_block;
//分段读睡眠数据
int sleep_data_cnt = 0;
do {
//数据包头
struct health_file_data_head data_head;
sport_health_file_read(fp, (u8 *)&data_head, file_offset, sizeof(struct health_file_data_head));
file_offset += sizeof(struct health_file_data_head);
start_time.year = total_head.year;
start_time.month = total_head.month;
start_time.day = total_head.day;
start_time.hour = data_head.hour;
start_time.min = data_head.min;
start_time.sec = 0;
timestamp_start = timestamp_mytime_2_utc_sec(&start_time);
//数据跨天
if (total_head.reserve & BIT(sleep_data_cnt)) {
timestamp_start -= 24 * 60 * 60;
}
timestamp_block = timestamp_start;
u16 blocks = data_head.len;
//异常数据退出
if (blocks == 0xffff) {
break;
}
sport_health_common_swapX((u8 *)&blocks, (u8 *)&blocks, 2);
u8 *rbuf = zalloc(blocks);
sport_health_file_read(fp, rbuf, file_offset, blocks);
file_offset += blocks;
struct sleep_storage_data *p = (struct sleep_storage_data *)rbuf;
//读取该段数据
for (int i = 0; i < blocks / 2; i++) {
//记录睡眠的状态和起始时间戳
p->stage = (p->stage == 0xff) ? SLEEP_STAGE_AWAKE : p->stage;
out->chart[out->blocks].stage = p->stage;
out->chart[out->blocks].timestamp = timestamp_block;
#if 0 //debug使用
struct sys_time block_t;
timestamp_utc_sec_2_mytime(out->chart[out->blocks].timestamp, &block_t);
printf("[SLEEP_TEST_READ]%d STA:%d [%4d-%2d-%2d-%2d:%2d:%2d]", out->blocks, out->chart[out->blocks].stage,
block_t.year, block_t.month, block_t.day, block_t.hour, block_t.min, block_t.sec);
#endif//TCFG_SPORT_HEALTH_SLEEP_TEST
//sw下一段睡眠
timestamp_block += p->sleep_min * 60;
out->blocks++;
p++;
}
//清醒作为包尾,用特殊值标记,跟清醒数据区分
out->chart[out->blocks].stage = SLEEP_STAGE_BLOCK_END;
out->chart[out->blocks].timestamp = timestamp_block;
out->blocks++;
free(rbuf);
} while (file_offset < file_total);
sport_health_file_close(fp);
return SHM_ERR_OK;
}
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_health_sleep_data_analysis 解析睡眠数据
*
* @param value 句柄
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
static int sport_health_sleep_data_analysis(struct sleep_data_analysis *value)
{
sleep_data *data = (sleep_data *)value->data;
for (int i = 0; i < data->blocks - 1; i++) {
int time_len = data->chart[i + 1].timestamp - data->chart[i].timestamp;
//统计各类型睡眠的时长
if (data->chart[i].stage == SLEEP_STAGE_DEEP) {
value->deep_min += time_len;
} else if (data->chart[i].stage == SLEEP_STAGE_LIGHT) {
value->light_min += time_len;
} else if (data->chart[i].stage == SLEEP_STAGE_REM) {
value->rem_min += time_len;
} else if (data->chart[i].stage == SLEEP_STAGE_AWAKE) {
//可能包含有较长的清醒数据,根据项目需求进行过滤
#if TCFG_SPORT_HEALTH_AWAKE_MAX_LEN
time_len = time_len > TCFG_SPORT_HEALTH_AWAKE_MAX_LEN ? 0 : time_len;
#endif
value->awake_min += time_len;
} else {
time_len = 0;
}
value->total_min += time_len;
}
return SHM_ERR_OK;
}
static int shm_sleep_io_crtl(int cmd, void *priv)
{
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_SAVE_SINGLE:
ret = sport_health_sleep_data_stroage();
break;
default:
/* ret = -SHE_ERR_MOD_NO_THIS_CMD; */
break;
}
return ret;
}
static int shm_sleep_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_INFO:
break;
case SHM_GET_TYPE_INFO_STORAGE:
//get date from file
ret = sport_health_sleep_rec_data_get((struct sleep_data_analysis *)priv);
break;
case SHM_GET_TYPE_DATA_ANALYSIS:
ret = sport_health_sleep_data_analysis((struct sleep_data_analysis *)priv);
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(sleep)
{
.module = SHM_MOD_SLEEP,
.io_ctrl = shm_sleep_io_crtl,
.get_value = shm_sleep_get_value,
};
/*****************************************************************************************************/
#if TCFG_SPORT_HEALTH_SLEEP_TEST
/* ------------------------------------------------------------------------------------*/
/**
* @brief motion_sleep_data_test_get 模拟数据
*
* @param out
*/
/* ------------------------------------------------------------------------------------*/
static void motion_sleep_data_test_get(sleep_data *out)
{
struct sys_time time = {
.year = TCFG_SPORT_HEALTH_SLEEP_TEST_YEAR,
.month = TCFG_SPORT_HEALTH_SLEEP_TEST_MONTH,
.day = TCFG_SPORT_HEALTH_SLEEP_TEST_DAY,
.hour = 22,
.min = 30,
};
struct sys_time block_t;
int timestamp_tmp = timestamp_mytime_2_utc_sec(&time);
int sleep_time = 0;
out->blocks = 0;
do {
out->chart[out->blocks].stage = rand32() % 3;
out->chart[out->blocks].timestamp = timestamp_tmp;
timestamp_utc_sec_2_mytime(out->chart[out->blocks].timestamp, &block_t);
int len = rand32() % 3000 + 10 * 60;
printf("[SLEEP_TEST_GET]%d STA:%d [%4d-%2d-%2d-%2d:%2d:%2d]len:%d \n", out->blocks, out->chart[out->blocks].stage,
block_t.year, block_t.month, block_t.day, block_t.hour, block_t.min, block_t.sec, len);
timestamp_tmp += len;
sleep_time += len;
out->blocks++;
} while (sleep_time < TCFG_SPORT_HEALTH_SLEEP_TARGET_MIN);
}
static sleep_data_analysis value = {
.file_time.year = TCFG_SPORT_HEALTH_SLEEP_TEST_YEAR,
.file_time.month = TCFG_SPORT_HEALTH_SLEEP_TEST_MONTH,
.file_time.day = TCFG_SPORT_HEALTH_SLEEP_TEST_DAY + 1,
.file_time.hour = 22,
.file_time.min = 30,
.file_time.blocks = 0,
};
int sleep_data_test()
{
sport_health_sleep_data_stroage();
sport_health_sleep_rec_data_get(&value);
return 0;
}
#endif//TCFG_SPORT_HEALTH_SLEEP_TEST
#endif// SPORT_HEALTH_MANAGE_SLEEP_ENABLE
@@ -0,0 +1,601 @@
#include "app_config.h"
#include "app_task.h"
#include "system/timer.h"
#include "app_main.h"
#include "system/includes.h"
#include "key_event_deal.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[SHM-SPORT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".health_manager.data.bss")
#pragma data_seg(".health_manager.data")
#pragma const_seg(".health_manager.text.const")
#pragma code_seg(".health_manager.text")
#endif
struct sport_type_map {
u32 mode: 3; //outdoor indoor other
u32 index: 7; //列表索引
u32 sport_type: 8; //运动类型
u32 data_cfg: 18; //数据配置
};
struct sport_type_map sport_type_map_tab[] = {
{SPORT_MODE_OUTDOOR , 0, SHM_SPORT_TYPE_OUTDOOR_WALIING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 1, SHM_SPORT_TYPE_OUTDOOR_RUNNING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 2, SHM_SPORT_TYPE_OUTDOOR_RIDE, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 3, SHM_SPORT_TYPE_MOUNTAINEERING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 4, SHM_SPORT_TYPE_VOLLEYBALL, BIT(SP_DATA_STEPS) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 5, SHM_SPORT_TYPE_BADMINTON, BIT(SP_DATA_STEPS) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 6, SHM_SPORT_TYPE_SKIING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_OUTDOOR , 7, SHM_SPORT_TYPE_SPEED_SKATING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 0, SHM_SPORT_TYPE_INDOOR_RUNNING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 1, SHM_SPORT_TYPE_INDOOR_RIDE, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 2, SHM_SPORT_TYPE_STRENGTH_TRAINING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 3, SHM_SPORT_TYPE_ABDOMINAL_CURL, BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 4, SHM_SPORT_TYPE_PUSH_UP, BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 5, SHM_SPORT_TYPE_AEROBIC_EXERCISE, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 6, SHM_SPORT_TYPE_CALLISTHENICS, BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 7, SHM_SPORT_TYPE_YOGA, BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 8, SHM_SPORT_TYPE_DANCE, BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 9, SHM_SPORT_TYPE_ROPE_SKIPPING, BIT(SP_DATA_STEPS) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 10, SHM_SPORT_TYPE_POOL_SWIMMING, BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{SPORT_MODE_INDOOR , 11, SHM_SPORT_TYPE_FREE_TIME, BIT(SP_DATA_STEPS) | BIT(SP_DATA_DISTANCE) | BIT(SP_DATA_CALORIES) | BIT(SP_DATA_TIME) | BIT(SP_DATA_HR)},
{0, 0, 0, 0},
};
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_type_map_get
*
* @param sport_mode
* @param list_index
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
int sport_type_map_get_type(u8 sport_mode, u8 list_index)
{
for (int i = 0; i < ARRAY_SIZE(sport_type_map_tab); i++) {
log_debug("%s i:%d spmode:%d listindex:%d tabmode:%d tab_index:%d",
__func__, i, sport_mode, list_index, sport_type_map_tab[i].mode, sport_type_map_tab[i].index);
if ((sport_mode == sport_type_map_tab[i].mode) && (list_index == sport_type_map_tab[i].index)) {
log_debug("%s type:%d", __func__, sport_type_map_tab[i].sport_type);
return sport_type_map_tab[i].sport_type;
}
}
log_error("%s sp_mode:%d list_1index:%d", __func__, sport_mode, list_index);
return -1;
}
#if (TCFG_SPORT_HEALTH_ENABLE&&TCFG_SPORT_HEALTH_SPORT)
#pragma pack(1)//平台非对齐编译
struct sport_file_head {
u8 type; //
u8 version; //0
u8 interval; //0~180s 基础包的时间间隔
u8 mask; //0xee
u32 block_num: 15; //数据块
u32 file_size: 17; //文件大小
u8 reserved[5];//5
};
struct sport_file_data {
u8 flag; //1
u8 len;
u8 hr; //he
u16 step_freq; //steps/min
u16 speed; //0.01km/h
}; //非必须
struct sport_file_start {
u8 flag; //0
u8 len; //
u32 time; //time
};
struct sport_file_pause {
u8 flag; //2
u8 len; //
u32 time; //time
};
struct sport_file_stop {
u8 flag; //0xff
u8 len; //
u32 time; //time
};
struct sport_file_end {
u16 run_time; //运动时长
u32 reserved; //保留位
u16 distance; //运动距离
u16 calories; //热量
u32 steps; //步数
u8 recover_hour; //运动恢复时间 小时
u8 recover_min; //运动恢复时间 分钟
};
#pragma pack()//平台对齐编译
#define SPORT_FILE_FLAG_START (0x0)
#define SPORT_FILE_FLAG_DATA (0x1)
#define SPORT_FILE_FLAG_PAUSE (0x2)
#define SPORT_FILE_FLAG_END (0xff)
#define SPORT_FILE_SIZEOF_START (4)
#define SPORT_FILE_SIZEOF_DATA (5)
#define SPORT_FILE_SIZEOF_PAUSE (4)
#define SPORT_FILE_SIZEOF_END (4)
#define SPORT_FILE_VERSION (0)
#define SPORT_FILE_INTERVAL (0)
#define SPORT_FILE_MASK_CREATE (0XFF)
#define SPORT_FILE_MASK_END (0XEE)
struct sport_value *__sport_value = NULL;
#define __value (__sport_value)
/* ------------------------------------------------------------------------------------*/
/**
* @brief sport_type_map_get_data_cfg
*
* @param sport_type
*
* @return
*/
/* ------------------------------------------------------------------------------------*/
u32 sport_type_map_get_data_cfg(u8 sport_type)
{
for (int i = 0; i < ARRAY_SIZE(sport_type_map_tab); i++) {
if (sport_type == sport_type_map_tab[i].sport_type) {
return sport_type_map_tab[i].data_cfg;
}
}
log_error("%s sp_type:%d ", __func__, sport_type);
return -1;
}
static int __time2int(struct sys_time *time)
{
int t;
/* printf("time : %d-%d-%d,%d:%d:%d\n", time->year, time->month, time->day, time->hour, time->min, time->sec); */
ASSERT(time->year >= 2010 && time->year <= 2010 + 0x3f, "input year need >= 2010 && <= 2073 \n");
t = (time->sec & 0x3f) | ((time->min & 0x3f) << 6) | ((time->hour & 0x1f) << 12) | ((time->day & 0x1f) << 17) | ((time->month & 0xf) << 22) | (((time->year - 2010) & 0x3f) << 26);
/* __int2time(t, time); */
return t;
}
static void sport_value_dump(const char *func, struct sport_value *value)
{
log_debug("fun:<%s> sta:%d type:%d c(steps:%d dist:%d cal:%d sfreq:%d) s(step:%d dist:%d cal:%d) pt:%d TIME(%04d-%02d-%02d %02d:%02d:%02d) file_len:%d hr(%d ~%d~ %d)\n", \
func, value->run_status, value->type, value->steps_c, value->distance_c, value->calories_c, value->step_freq_c, value->steps_s, value->distance_s, value->calories_s, value->pause_sec, value->start_time.year, value->start_time.month, value->start_time.day, value->start_time.hour, value->start_time.min, value->start_time.sec, value->file_len, value->heart_val, value->heart_min, value->heart_max);
}
static int shm_sport_type_set(u32 type)
{
if (__value) {
sport_health_free(__value);
}
__value = sport_health_alloc(sizeof(struct sport_value));
if (!__value) {
return -SHM_ERR_MOD_ALLOC;
}
__value->type = type;
return SHM_ERR_OK;
}
static int shm_sport_start()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
int type = __value->type;
memset(__value, 0, sizeof(struct sport_value));
__value->type = type;
rtc_read_time(&__value->start_time);
struct algo_value algo_out_value;
int ret = sport_health_manager_value_get(SHM_MOD_GSENSOR_ALGO, SHM_GET_TYPE_INFO, &algo_out_value);
ASSERT(!ret);
__value->steps_s = algo_out_value.steps;
__value->calories_s = algo_out_value.calories;
__value->distance_s = DISTANCE_MAP(algo_out_value.distance);
__value->heart_min = 0xff;
__value->heart_max = 0;
__value->run_status = SHM_SPORT_STATUS_RUN;
__value->status = SHM_SPORT_STATUS_START;
sport_value_dump(__func__, __value);
return SHM_ERR_OK;
}
static int shm_sport_continue()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
struct algo_value algo_out_value;
int ret = sport_health_manager_value_get(SHM_MOD_GSENSOR_ALGO, SHM_GET_TYPE_INFO, (void *)&algo_out_value);
ASSERT(!ret);
__value->steps_s = algo_out_value.steps;
__value->calories_s = algo_out_value.calories;
__value->distance_s = DISTANCE_MAP(algo_out_value.distance);
__value->pause_sec += (jiffies_msec() / 1000 - __value->tmp_sec);
__value->run_status = SHM_SPORT_STATUS_RUN;
__value->status = SHM_SPORT_STATUS_CONTINUE;
sport_value_dump(__func__, __value);
return SHM_ERR_OK;
}
static int shm_sport_pause()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
__value->tmp_sec = jiffies_msec() / 1000;
__value->run_status = SHM_SPORT_STATUS_PAUSE;
__value->status = SHM_SPORT_STATUS_PAUSE;
sport_value_dump(__func__, __value);
return SHM_ERR_OK;
}
static int shm_sport_stop()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
__value->run_status = SHM_SPORT_STATUS_PAUSE;
__value->status = SHM_SPORT_STATUS_STOP;
sport_value_dump(__func__, __value);
return SHM_ERR_OK;
}
static int shm_sport_free()
{
if (__value) {
sport_health_free(__value);
__value = NULL;
}
return SHM_ERR_OK;
}
static int shm_sport_update()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
if (__value->run_status == SHM_SPORT_STATUS_RUN) {
struct algo_value algo_out_value;
int ret = sport_health_manager_value_get(SHM_MOD_GSENSOR_ALGO, SHM_GET_TYPE_INFO, &algo_out_value);
ASSERT(!ret);
if (__value->steps_s > algo_out_value.steps) { /*跨天,可能存在1s的计数误差,忽略*/
__value->steps_s = 0;
__value->calories_s = 0;
__value->distance_s = 0;
}
//两次统计作差,记录增量
int distance_dt = (DISTANCE_MAP(algo_out_value.distance) - __value->distance_s);
int step_dt = (algo_out_value.steps - __value->steps_s);
int calories_dt = (algo_out_value.calories - __value->calories_s);
__value->steps_c += step_dt;
__value->calories_c += calories_dt ;
__value->distance_c += distance_dt;
__value->step_freq_c = algo_out_value.step_frequency;
__value->speed_c = distance_dt;
__value->step_stride_c = (step_dt) ? distance_dt / step_dt : 0;
//记录当前值用于下次作差使用
__value->steps_s += step_dt;
__value->calories_s += calories_dt;
__value->distance_s += distance_dt;
//心率计算
u8 hr_curr = 90 + rand32() % 20;
u32 hr_tmp = __value->heart_val * __value->run_sec + hr_curr;
__value->run_sec ++; //可以用rtc和pause_sec校准
__value->heart_val = hr_tmp / __value->run_sec;
__value->heart_max = (__value->heart_max > hr_curr) ? __value->heart_max : hr_curr;
__value->heart_min = (__value->heart_min < hr_curr) ? __value->heart_min : hr_curr;
sport_value_dump(__func__, __value);
} else {
__value->step_freq_c = 0;
}
return SHM_ERR_OK;
}
static int shm_sport_file_start()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
__value->file_hd = sport_health_file_open(F_TYPE_SPORTRECORD, 0);
//文件头
struct sport_file_head file_head = {
.type = __value->type,
.version = SPORT_FILE_VERSION,
.interval = SPORT_FILE_INTERVAL,
.mask = SPORT_FILE_MASK_CREATE,
.block_num = -1,
.file_size = -1,
};
sport_health_file_write(__value->file_hd, (u8 *)&file_head, __value->file_len, sizeof(struct sport_file_head));
__value->file_len += sizeof(struct sport_file_head);
//开始包
struct sys_time time;
rtc_read_time(&time);
struct sport_file_start file_start = {
.flag = SPORT_FILE_FLAG_START,
.len = SPORT_FILE_SIZEOF_START,
.time = __time2int(&time),
};
sport_health_file_write(__value->file_hd, (u8 *)&file_start, __value->file_len, sizeof(struct sport_file_start));
__value->file_len += sizeof(struct sport_file_start);
__value->file_pack_num ++;
return SHM_ERR_OK;
}
static int shm_sport_file_pause()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
//暂停包
struct sys_time time;
rtc_read_time(&time);
struct sport_file_pause file_pause = {
.flag = SPORT_FILE_FLAG_PAUSE,
.len = SPORT_FILE_SIZEOF_PAUSE,
.time = __time2int(&time),
};
sport_health_file_write(__value->file_hd, (u8 *)&file_pause, __value->file_len, sizeof(struct sport_file_pause));
__value->file_len += sizeof(struct sport_file_pause);
__value->file_pack_num ++;
return SHM_ERR_OK;
}
static int shm_sport_file_continue()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
//开始包
struct sys_time time;
rtc_read_time(&time);
struct sport_file_start file_start = {
.flag = SPORT_FILE_FLAG_START,
.len = SPORT_FILE_SIZEOF_START,
.time = __time2int(&time),
};
sport_health_file_write(__value->file_hd, (u8 *)&file_start, __value->file_len, sizeof(struct sport_file_start));
__value->file_len += sizeof(struct sport_file_start);
__value->file_pack_num ++;
return SHM_ERR_OK;
}
static int shm_sport_file_stop()
{
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
//结束
struct sys_time time;
rtc_read_time(&time);
struct sport_file_stop file_stop = {
.flag = SPORT_FILE_FLAG_END,
.len = SPORT_FILE_SIZEOF_END,
.time = __time2int(&time),
};
sport_health_file_write(__value->file_hd, (u8 *)&file_stop, __value->file_len, sizeof(struct sport_file_stop));
__value->file_len += sizeof(struct sport_file_stop);
__value->file_pack_num ++;
//文件尾
struct sport_file_end file_end = {
.run_time = __value->run_sec,
.distance = __value->distance_c,
.calories = __value->calories_c,
.steps = __value->steps_c,
.recover_hour = 0xff,
.recover_min = 0,
.reserved = 0xffffffff,
};
put_buf((u8 *)&file_end, sizeof(struct sport_file_end));
sport_health_file_write(__value->file_hd, (u8 *)&file_end, __value->file_len, sizeof(struct sport_file_end));
__value->file_len += sizeof(struct sport_file_end);
#if 0
{
void *fp = sport_health_file_open(F_TYPE_SPORTRECORD, 0);
int id = sport_health_file_get_id(fp, 0);
int rlen = sport_health_file_get_len(fp);
u8 *rbuf = zalloc(rlen);
sport_health_file_read(fp, rbuf, 0, rlen);
printf("%s %d rlen:%d flen:%d", __func__, __LINE__, rlen, __value->file_len);
put_buf(rbuf, rlen);
}
#endif
//文件头
struct sport_file_head file_head = {
.type = __value->type,
.version = SPORT_FILE_VERSION,
.interval = SPORT_FILE_INTERVAL,
.mask = SPORT_FILE_MASK_END,
.block_num = __value->file_pack_num,
.file_size = __value->file_len,
};
sport_health_file_update(__value->file_hd, (u8 *)&file_head, 0, sizeof(struct sport_file_head));
sport_health_file_close(__value->file_hd);
sport_value_dump(__func__, __value);
#if 0
{
void *fp = sport_health_file_open(F_TYPE_SPORTRECORD, 0);
int id = sport_health_file_get_id(fp, 0);
int rlen = sport_health_file_get_len(fp);
u8 *rbuf = zalloc(rlen);
sport_health_file_read(fp, rbuf, 0, rlen);
printf("%s %d len:%d", __func__, __LINE__, rlen);
put_buf(rbuf, rlen);
}
#endif
return SHM_ERR_OK;
}
static int shm_sport_file_data()
{
#if SPORT_FILE_INTERVAL
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
u32 curr_sec = jiffies_msec() / 1000;
if ((!__value->last_data_time) || (curr_sec - __value->last_data_time >= SPORT_FILE_INTERVAL)) {
struct sport_file_data file_data = {
.flag = SPORT_FILE_FLAG_DATA,
.len = SPORT_FILE_SIZEOF_DATA,
};
//只需要接入数据,再删除
#error need writ data to file_data
sport_health_file_write(__value->file_hd, (u8 *)&file_data, __value->file_len, sizeof(struct sport_file_data));
__value->file_len += sizeof(struct sport_file_data);
__value->file_pack_num ++;
}
#endif
return SHM_ERR_OK;
}
static int shm_sport_file_get_rec_by_index(struct sport_value *value, u8 index)
{
int ret = SHM_ERR_OK;
struct sport_file_head file_head;
void *fp = sport_health_file_open(F_TYPE_SPORTRECORD, 0);
int id = sport_health_file_get_id(fp, index);
if (!id) {
ret = SHM_ERR_FILE_NOT_FIND;
sport_health_file_close(fp); //
return ret;
}
ret = sport_health_file_read(fp, (u8 *)&file_head, 0, sizeof(struct sport_file_head));
ASSERT(ret);
put_buf((u8 *)&file_head, sizeof(struct sport_file_head));
struct sport_file_end file_end;
int file_len = sport_health_file_get_len(fp);
ret = sport_health_file_read(fp, (u8 *)&file_end, file_len - sizeof(struct sport_file_end), sizeof(struct sport_file_end));
ASSERT(ret);
log_info("%s %d ", __func__, (u32)sizeof(struct sport_file_end));
log_info_hexdump((u8 *)&file_end, sizeof(struct sport_file_end));
value->type = file_head.type;
value->steps_c = file_end.steps;
value->calories_c = file_end.calories;
value->distance_c = file_end.distance;
value->run_sec = file_end.run_time;
sport_health_file_close(fp);
sport_value_dump(__func__, value);
return ret;
}
static int shm_sport_io_crtl(int cmd, void *priv)
{
int ret = SHM_ERR_OK;
switch (cmd) {
case SHM_CMD_INFO_SET:
ret = shm_sport_type_set((int)priv);
break;
case SHM_CMD_START:
ret = shm_sport_start();
shm_sport_update();
if (!ret) {
ret = shm_sport_file_start();
}
break;
case SHM_CMD_CONTINUE:
ret = shm_sport_continue();
if (!ret) {
ret = shm_sport_file_continue();
}
break;
case SHM_CMD_PAUSE:
ret = shm_sport_pause();
if (!ret) {
ret = shm_sport_file_pause();
}
break;
case SHM_CMD_STOP:
ret = shm_sport_stop();
if (!ret) {
ret = shm_sport_file_stop();
}
shm_sport_free();
break;
case SHM_CMD_UPDATE_SEC:
ret = shm_sport_update();
if (!ret) {
ret = shm_sport_file_data();
}
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_CMD;
break;
}
return ret;
}
static int shm_sport_get_value(int type, void *priv)
{
int ret = SHM_ERR_OK;
switch (type) {
case SHM_GET_TYPE_INFO:
if (!__value) {
return -SHM_ERR_MOD_NOR_INIT;
}
memcpy(priv, __value, sizeof(struct sport_value));
sport_value_dump(__func__, __value);
break;
case SHM_GET_TYPE_INFO_STORAGE:
//get date from file
struct sport_value *sv = (struct sport_value *)priv;
ret = shm_sport_file_get_rec_by_index(sv, sv->file_index);
break;
case SHM_GET_TYPE_STORAGE_TOTAL: {
u8 total = sport_health_file_get_total(F_TYPE_SPORTRECORD);
memcpy(priv, &total, 1);
}
break;
case SHM_GET_TYPE_STORAGE_ID: {
u8 total = sport_health_file_get_total(F_TYPE_SPORTRECORD);
if (total) {
void *fp = sport_health_file_open(F_TYPE_SPORTRECORD, 0);
u16 id = sport_health_file_get_id(fp, total - 1);
sport_health_file_close(fp);
memcpy(priv, &id, 2);
} else {
memset(priv, 0, 2);
}
}
break;
default:
ret = -SHM_ERR_MOD_NO_THIS_TYPE;
break;
}
return ret;
}
REGISTER_SPORT_HEALTH_MODULE(sport)
{
.module = SHM_MOD_SPORT,
.io_ctrl = shm_sport_io_crtl,
.get_value = shm_sport_get_value,
};
#endif
@@ -0,0 +1,52 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_bt_disconn.data.bss")
#pragma data_seg(".sport_info_bt_disconn.data")
#pragma const_seg(".sport_info_bt_disconn.text.const")
#pragma code_seg(".sport_info_bt_disconn.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_bt_disconn.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_bt_disconn_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 bt_reminder_switch = data[0];
u8 bt_reminder_mode = data[1];
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_BT_DISCONN, bt_reminder_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_BT_DISCONN, bt_reminder_mode);
}
u32 sport_info_bt_disconn_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 bt_reminder_data[2] = {0};
bt_reminder_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_BT_DISCONN);
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_BT_DISCONN, &mode_data);
if (mode_data && mode_len) {
bt_reminder_data[1] = mode_data[0];
}
rlen = add_one_attr(buf, buf_size, offset, attr, bt_reminder_data, sizeof(bt_reminder_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,12 @@
#ifndef __RCSP_SPORT_INFO_BT_DISCONN_H__
#define __RCSP_SPORT_INFO_BT_DISCONN_H__
#include "typedef.h"
#include "app_config.h"
void sport_info_bt_disconn_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_bt_disconn_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,67 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_continuous_heart_rate.data.bss")
#pragma data_seg(".sport_info_continuous_heart_rate.data")
#pragma const_seg(".sport_info_continuous_heart_rate.text.const")
#pragma code_seg(".sport_info_continuous_heart_rate.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_continuous_heart_rate.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_continuous_heart_rate_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 heart_rate_switch = data[0];
u8 heart_rate_mode = data[1];
/* #if C_HEART_TEST */
/* u8 test_switch = data[2]; */
/* printf("%s test_switch=%d", __func__, test_switch); */
/* extern void c_heart_rate(u8 enable); */
/* c_heart_rate(test_switch); */
/* #endif */
/* struct watch_algo __watch_algo; */
/* watch_algo_handle_get(&__watch_algo); */
/* int arg[5]; */
/* arg[0] = CONTINUE_HEART_RATE; */
/* arg[1] = heart_rate_switch; */
/* arg[2] = SCREEN_LIGHT; */
/* arg[3] = heart_rate_mode; */
/* __watch_algo.detection_ioctrl(4, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_CONTINUOUS_HEART_RATE, heart_rate_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_CONTINUOUS_HEART_RATE, heart_rate_mode);
}
u32 sport_info_continuous_heart_rate_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 heart_rate_data[2] = {0};
heart_rate_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_CONTINUOUS_HEART_RATE);
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_CONTINUOUS_HEART_RATE, &mode_data);
if (mode_data && mode_len) {
heart_rate_data[1] = mode_data[0];
}
rlen = add_one_attr(buf, buf_size, offset, attr, heart_rate_data, sizeof(heart_rate_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,12 @@
#ifndef __RCSP_SPORT_CONTINUOUS_HEART_RATE_H__
#define __RCSP_SPORT_CONTINUOUS_HEART_RATE_H__
#include "typedef.h"
#include "app_config.h"
void sport_info_continuous_heart_rate_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_continuous_heart_rate_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,60 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_exercise_heart_rate.data.bss")
#pragma data_seg(".sport_info_exercise_heart_rate.data")
#pragma const_seg(".sport_info_exercise_heart_rate.text.const")
#pragma code_seg(".sport_info_exercise_heart_rate.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_exercise_heart_rate.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_exercise_heart_rate_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 heart_rate_switch = data[0];
e_heart_rate heart_rate = {0};
memcpy(&heart_rate, data + 1, sizeof(heart_rate));
/* struct watch_algo __watch_algo; */
/* watch_algo_handle_get(&__watch_algo); */
/* int arg[5]; */
/* arg[0] = EXERCISE_HEART_RATE; */
/* arg[1] = heart_rate_switch; */
/* arg[2] = SCREEN_LIGHT; */
/* arg[3] = heart_rate.heart_rate_type; */
/* arg[4] = heart_rate.max_heart_rate; */
/* __watch_algo.detection_ioctrl(5, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_EXERCISE_HEART_RATE, heart_rate_switch, 1);
sport_info_write_vm(VM_SPORT_INFO_EXERCISE_HEART_RATE, (u8 *)&heart_rate, sizeof(e_heart_rate));
}
u32 sport_info_exercise_heart_rate_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 heart_rate_data[3] = {0};
heart_rate_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_EXERCISE_HEART_RATE);
sport_exercise_heart_rate_get((e_heart_rate *)(heart_rate_data + 1));
rlen = add_one_attr(buf, buf_size, offset, attr, heart_rate_data, sizeof(heart_rate_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,11 @@
#ifndef __RCSP_SPORT_EXERCISE_HEART_RATE_H__
#define __RCSP_SPORT_EXERCISE_HEART_RATE_H__
#include "typedef.h"
void sport_info_exercise_heart_rate_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_exercise_heart_rate_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,86 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_fall_detection.data.bss")
#pragma data_seg(".sport_info_fall_detection.data")
#pragma const_seg(".sport_info_fall_detection.text.const")
#pragma code_seg(".sport_info_fall_detection.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_fall_detection.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_fall_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 fall_switch = data[0];
u8 fall_mode = data[1];
fall_detection_t fall_detection = {0};
if (2 == fall_mode) {
memcpy(&fall_detection, data + 2, data[2] + 1);
}
/* struct watch_algo algo_hd; */
/* watch_algo_handle_get(&algo_hd); */
/* int arg[6]; */
/* arg[0] = FALL; */
/* arg[1] = fall_switch; */
/* arg[2] = fall_mode; */
/* arg[3] = 0; */
/* algo_hd.detection_ioctrl(3, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_FALL_DETECTION, fall_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_FALL_DETECTION, fall_mode);
if (2 == fall_mode) {
sport_info_write_vm(VM_SPORT_INFO_FALL_DETECTION, (u8 *)&fall_detection, sizeof(fall_detection_t));
/* set_emergency_contact_number((u8 *)&fall_detection.phone_num, fall_detection.phone_len); //保存联系人 */
}
}
u32 sport_info_fall_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 *fall_data = zalloc(2 + 21);
fall_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_FALL_DETECTION);
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_FALL_DETECTION, &mode_data);
if (mode_data && mode_len) {
fall_data[1] = mode_data[0];
}
log_info("motion_type=%d-- %d", fall_data[0], fall_data[1]);
mode_len = 2;
if (2 == fall_data[1]) {
sport_fall_detection_get((fall_detection_t *)(fall_data + 2));
mode_len += sizeof(fall_detection_t);
}
rlen = add_one_attr(buf, buf_size, offset, attr, fall_data, mode_len);
if (fall_data) {
free(fall_data);
}
log_info("%s %d", __func__, __LINE__);
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,9 @@
#ifndef __RCSP_SPORT_FALL_DETECTION_H__
#define __RCSP_SPORT_FALL_DETECTION_H__
#include "typedef.h"
void sport_info_fall_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_fall_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,55 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_personal_info.data.bss")
#pragma data_seg(".sport_info_personal_info.data")
#pragma const_seg(".sport_info_personal_info.text.const")
#pragma code_seg(".sport_info_personal_info.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_personal_info.h"
#include "health_manager/health_manager.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_personal_info_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
personal_information info = {0};
memcpy(&info, data, sizeof(personal_information));
info.height = ((u8 *)&info.height)[0] << 8 | ((u8 *)&info.height)[1];
info.weight = ((u8 *)&info.weight)[0] << 8 | ((u8 *)&info.weight)[1];
info.birth_y = ((u8 *)&info.birth_y)[0] << 8 | ((u8 *)&info.birth_y)[1];
//更新到vm
sport_info_write_vm(VM_SPORT_INFO_PERSONAL_INFO_FLAG, (u8 *)&info, sizeof(personal_information));
//通知算法更新参数
sport_health_gsensor_algo_cfg_update();
}
u32 sport_info_personal_info_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
personal_information info = {0};
if (sport_personal_info_get(&info)) {
info.height = ((u8 *)&info.height)[0] << 8 | ((u8 *)&info.height)[1];
info.weight = ((u8 *)&info.weight)[0] << 8 | ((u8 *)&info.weight)[1];
info.birth_y = ((u8 *)&info.birth_y)[0] << 8 | ((u8 *)&info.birth_y)[1];
}
rlen = add_one_attr(buf, buf_size, offset, attr, (u8 *)&info, sizeof(personal_information));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,11 @@
#ifndef __RCSP_SPORT_PERSONAL_INFO_H__
#define __RCSP_SPORT_PERSONAL_INFO_H__
#include "typedef.h"
void sport_info_personal_info_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_personal_info_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,53 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_pressure_detection.data.bss")
#pragma data_seg(".sport_info_pressure_detection.data")
#pragma const_seg(".sport_info_pressure_detection.text.const")
#pragma code_seg(".sport_info_pressure_detection.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_pressure_detection.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_pressure_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 press_switch = data[0];
u8 press_mode = data[1];
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_PRESSURE_DETECTION, press_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_PRESSURE_DETECTION, press_mode);
}
u32 sport_info_pressure_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 press_data[2] = {0};
press_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_PRESSURE_DETECTION);
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_PRESSURE_DETECTION, &mode_data);
if (mode_data && mode_len) {
press_data[1] = mode_data[0];
}
rlen = add_one_attr(buf, buf_size, offset, attr, press_data, sizeof(press_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,12 @@
#ifndef __RCSP_SPORT_PRESSURE_DETECTION_H__
#define __RCSP_SPORT_PRESSURE_DETECTION_H__
#include "typedef.h"
#include "app_config.h"
void sport_info_pressure_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_pressure_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,86 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_raise_wrist.data.bss")
#pragma data_seg(".sport_info_raise_wrist.data")
#pragma const_seg(".sport_info_raise_wrist.text.const")
#pragma code_seg(".sport_info_raise_wrist.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_raise_wrist.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
enum {
SPORT_INFO_RAISE_WRIST_TURN_OFF,
SPORT_INFO_RAISE_WRIST_TURN_ON_ALL_DATA,
SPORT_INFO_RAISE_WRIST_TURN_CUSTOM_TIME_PERIOD,
};
void sport_info_raise_wrist_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
put_buf(data, len);
u8 raise_wrist_switch = data[0];
u8 raise_wrist_mode = data[1];
raise_wrist_t raise_wrist = {0};
memcpy(&raise_wrist, data + 2, sizeof(raise_wrist_t));
/* u8 time[4]; */
/* time[0] = raise_wrist.begin_time_hour; */
/* time[1] = raise_wrist.begin_time_min; */
/* time[2] = raise_wrist.end_time_hour; */
/* time[3] = raise_wrist.end_time_min; */
/* struct watch_algo algo_hd; */
/* watch_algo_handle_get(&algo_hd); */
/* int arg[6]; */
/* arg[0] = WRIST; */
/* arg[1] = raise_wrist_switch; */
/* arg[2] = raise_wrist_mode; */
/* arg[3] = (time[0] << 24 | time[1] << 16 | time[2] << 8 | time[3]); */
/* algo_hd.detection_ioctrl(4, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_RAISE_WRIST, SPORT_INFO_RAISE_WRIST_TURN_ON_ALL_DATA == raise_wrist_switch, 0);
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_RAISE_WRIST_CUSTOMIZE, SPORT_INFO_RAISE_WRIST_TURN_CUSTOM_TIME_PERIOD == raise_wrist_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_RAISE_WRIST, raise_wrist_mode);
sport_info_write_vm(VM_SPORT_INFO_RAISE_WRIST, (u8 *)&raise_wrist, sizeof(raise_wrist_t));
}
u32 sport_info_raise_wrist_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 raise_wrist_data[2 + 4] = {0};
if (sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_RAISE_WRIST)) {
raise_wrist_data[0] = SPORT_INFO_RAISE_WRIST_TURN_ON_ALL_DATA;
} else if (sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_RAISE_WRIST_CUSTOMIZE)) {
raise_wrist_data[0] = SPORT_INFO_RAISE_WRIST_TURN_CUSTOM_TIME_PERIOD;
}
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_RAISE_WRIST, &mode_data);
if (mode_data && mode_len) {
raise_wrist_data[1] = mode_data[0];
}
sport_raise_wrist_get((raise_wrist_t *)(raise_wrist_data + 2));
rlen = add_one_attr(buf, buf_size, offset, attr, raise_wrist_data, sizeof(raise_wrist_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,10 @@
#ifndef __RCSP_SPORT_RAISE_WRIST_H__
#define __RCSP_SPORT_RAISE_WRIST_H__
#include "typedef.h"
void sport_info_raise_wrist_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_raise_wrist_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,65 @@
#include "app_config.h"
#include "sport_info_opt.h"
#include "ui/ui_api.h"
#include "system/init.h"
#include "sport_info_bt_disconn.h"
#include "sport_info_continuous_heart_rate.h"
#include "sport_info_exercise_heart_rate.h"
#include "sport_info_fall_detection.h"
#include "sport_info_personal_info.h"
#include "sport_info_pressure_detection.h"
#include "sport_info_raise_wrist.h"
#include "sport_info_sedentary.h"
#include "sport_info_sensor_opt.h"
#include "sport_info_sleep_detection.h"
#if JL_RCSP_SENSORS_DATA_OPT
static const attr_get_func target_common_sport_info_get_tab[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_MAX] = {
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RESERVE] = NULL,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SENSOR_OPT] = sport_info_sensor_opt_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SEDENTARY] = sport_info_sedentary_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_CONTINUOUS_HEART_RATE] = sport_info_continuous_heart_rate_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_EXERCISE_HEART_RATE] = sport_info_exercise_heart_rate_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PRESSURE_DETECTION] = sport_info_pressure_detection_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SLEEP_DETECTION] = sport_info_sleep_detection_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_FALL_DETECTION] = sport_info_fall_detection_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RAISE_WRIST] = sport_info_raise_wrist_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PERSONAL_INFO] = sport_info_personal_info_attr_get,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_BT_DISCONN] = sport_info_bt_disconn_attr_get,
};
static const attr_set_func target_common_sport_info_set_tab[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_MAX] = {
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RESERVE] = NULL,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SENSOR_OPT] = sport_info_sensor_opt_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SEDENTARY] = sport_info_sedentary_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_CONTINUOUS_HEART_RATE] = sport_info_continuous_heart_rate_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_EXERCISE_HEART_RATE] = sport_info_exercise_heart_rate_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PRESSURE_DETECTION] = sport_info_pressure_detection_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_SLEEP_DETECTION] = sport_info_sleep_detection_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_FALL_DETECTION] = sport_info_fall_detection_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_RAISE_WRIST] = sport_info_raise_wrist_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_PERSONAL_INFO] = sport_info_personal_info_attr_set,
[SPORTS_INFO_OPT_FUNC_ATTR_TYPE_BT_DISCONN] = sport_info_bt_disconn_attr_set,
};
static const rcsp_sport_info_opt_t rcsp_sport_info_opt = {
.sport_info_get_tab = target_common_sport_info_get_tab,
.sport_info_get_tab_num = SPORTS_INFO_OPT_FUNC_ATTR_TYPE_MAX,
.sport_info_set_tab = target_common_sport_info_set_tab,
.sport_info_set_tab_num = SPORTS_INFO_OPT_FUNC_ATTR_TYPE_MAX,
};
int rcsp_sport_info_trans(void)
{
rcsp_register_sport_info_opt_interface((rcsp_sport_info_opt_t *)&rcsp_sport_info_opt);
return 0;
}
late_initcall(rcsp_sport_info_trans);
#endif /* if (TCFG_SPORT_HEALTH_ENABLE && JL_RCSP_SENSORS_DATA_OPT) */
@@ -0,0 +1,74 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_sedentary.data.bss")
#pragma data_seg(".sport_info_sedentary.data")
#pragma const_seg(".sport_info_sedentary.text.const")
#pragma code_seg(".sport_info_sedentary.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_sedentary.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_sedentary_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 sedentary_switch = data[0];
u8 sedentary_mode = data[1];
sedentary_t sedentary = {0};
memcpy(&sedentary, data + 2, sizeof(sedentary_t));
sedentary.nop_mode = data [2];
/* u8 time[4]; */
/* time[0] = sedentary.begin_time_hour; */
/* time[1] = sedentary.begin_time_min; */
/* time[2] = sedentary.end_time_hour; */
/* time[3] = sedentary.end_time_min; */
/* struct watch_algo algo_hd; */
/* watch_algo_handle_get(&algo_hd); */
/* int arg[6]; */
/* arg[0] = SEDENTARY; */
/* arg[1] = sedentary_switch; */
/* arg[2] = sedentary_mode; */
/* arg[3] = (time[0] << 24 | time[1] << 16 | time[2] << 8 | time[3]); */
/* arg[4] = sedentary.nop_mode; */
/* algo_hd.detection_ioctrl(5, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_SEDENTARY, sedentary_switch, 1);
sport_info_mode_record_update(SPORT_INFO_MODE_TYPE_SEDENTARY, sedentary_mode);
sport_info_write_vm(VM_SPORT_INFO_SEDENTARY, (u8 *)&sedentary, sizeof(sedentary_t));
}
u32 sport_info_sedentary_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 sedentary_data[2 + 5] = {0};
sedentary_data[0] = !!sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_SEDENTARY);
u8 *mode_data = NULL;
u16 mode_len = sport_info_record_get(SPORT_INFO_MODE_TYPE_SEDENTARY, &mode_data);
if (mode_data && mode_len) {
sedentary_data[1] = mode_data[0];
}
sport_sedentary_get((sedentary_t *)(sedentary_data + 2));
rlen = add_one_attr(buf, buf_size, offset, attr, sedentary_data, sizeof(sedentary_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,10 @@
#ifndef __RCSP_SPORT_INFO_SEDENTARY_H__
#define __RCSP_SPORT_INFO_SEDENTARY_H__
#include "typedef.h"
void sport_info_sedentary_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_sedentary_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,58 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_sensor_opt.data.bss")
#pragma data_seg(".sport_info_sensor_opt.data")
#pragma const_seg(".sport_info_sensor_opt.text.const")
#pragma code_seg(".sport_info_sensor_opt.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_sensor_opt.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
void sport_info_sensor_opt_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 func_switch = data[0];
u8 sensors_switch = data[1];
log_info("sensor-switch %x", sensors_switch);
/* struct watch_algo __algo_hd; */
/* watch_algo_handle_get(&__algo_hd); */
for (u8 i = SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER; i <= (SPORT_INFO_SWTICH_TYPE_SENSOR_ALTITUDE_RECORD - SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER + 1); i++) {
/* __algo_hd.sensor_switch_set((i), sensors_switch & BIT(i - 1)); */
sport_info_switch_record_update(i, sensors_switch & BIT(i - 1), 1);
}
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_SENSOR, func_switch, 1);
}
u32 sport_info_sensor_opt_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u32 switch_record = sport_info_swtich_record_get(-1);
u8 switch_data[2] = {0};
switch_data[0] = !!(switch_record & BIT(SPORT_INFO_SWTICH_TYPE_SENSOR));
for (u8 i = 0; i <= (SPORT_INFO_SWTICH_TYPE_SENSOR_ALTITUDE_RECORD - SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER); i++) {
if (switch_record & BIT(SPORT_INFO_SWTICH_TYPE_SENSOR_PEDOMETER + i)) {
switch_data[1] |= BIT(i);
}
}
rlen = add_one_attr(buf, buf_size, offset, attr, switch_data, sizeof(switch_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,13 @@
#ifndef __RCSP_SPORT_INFO_SENSOR_OPT_H__
#define __RCSP_SPORT_INFO_SENSOR_OPT_H__
#include "typedef.h"
#include "app_config.h"
void sport_info_sensor_opt_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_sensor_opt_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,83 @@
#ifdef SUPPORT_MS_EXTENSIONS
#pragma bss_seg(".sport_info_sleep_detection.data.bss")
#pragma data_seg(".sport_info_sleep_detection.data")
#pragma const_seg(".sport_info_sleep_detection.text.const")
#pragma code_seg(".sport_info_sleep_detection.text")
#endif
#include "rcsp_config.h"
#include "sport_info_opt.h"
#include "rcsp_event.h"
#include "rcsp_manage.h"
#include "sport_info_sleep_detection.h"
#include "health_manager/shm_info_storage.h"
#define LOG_TAG_CONST RCSP_ADAPTOR
#define LOG_TAG "[RCSP-SPORT-DATA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if JL_RCSP_SENSORS_DATA_OPT
enum {
SPORT_INFO_SLEEP_DETECTION_TURN_OFF,
SPORT_INFO_SLEEP_DETECTION_TURN_ON_ALL_DATA,
SPORT_INFO_SLEEP_DETECTION_CUSTOM_TIME_PERIOD,
};
void sport_info_sleep_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
log_info("<%s>", __func__);
u8 sleep_switch = data[0];
sleep_detection_t sleep_detection = {0};
memcpy(&sleep_detection, data + 1, sizeof(sleep_detection_t));
/* #if 0 */
/* extern void sleep_file_test(void); */
/* extern void step_test(void); */
/* if (sleep_switch == 1) { */
/* sleep_file_test(); */
/* step_test(); */
/* } */
/* #endif */
/* u8 time[4]; */
/* time[0] = sleep_detection.begin_time_hour; */
/* time[1] = sleep_detection.begin_time_min; */
/* time[2] = sleep_detection.end_time_hour; */
/* time[3] = sleep_detection.end_time_min; */
/* struct watch_algo algo_hd; */
/* watch_algo_handle_get(&algo_hd); */
/* int arg[6]; */
/* arg[0] = SLEEP; */
/* arg[1] = sleep_switch; */
/* arg[2] = -1; */
/* arg[3] = (time[0] << 24 | time[1] << 16 | time[2] << 8 | time[3]); */
/* algo_hd.detection_ioctrl(4, arg); */
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION, SPORT_INFO_SLEEP_DETECTION_TURN_ON_ALL_DATA == sleep_switch, 0);
sport_info_switch_record_update(SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION_CUSTOMIZE, SPORT_INFO_SLEEP_DETECTION_CUSTOM_TIME_PERIOD == sleep_switch, 1);
sport_info_write_vm(VM_SPORT_INFO_SLEEP_DETECTION, (u8 *)&sleep_detection, sizeof(sleep_detection_t));
}
u32 sport_info_sleep_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset)
{
log_info("<%s>", __func__);
u32 rlen = 0;
u8 press_data[1 + 4] = {0};
if (sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION)) {
press_data[0] = SPORT_INFO_SLEEP_DETECTION_TURN_ON_ALL_DATA;
} else if (sport_info_swtich_record_get(SPORT_INFO_SWTICH_TYPE_SLEEP_DETECTION_CUSTOMIZE)) {
press_data[0] = SPORT_INFO_SLEEP_DETECTION_CUSTOM_TIME_PERIOD;
}
sport_sleep_detection_get((sleep_detection_t *)(press_data + 1));
rlen = add_one_attr(buf, buf_size, offset, attr, press_data, sizeof(press_data));
return rlen;
}
#endif /* if JL_RCSP_SENSORS_DATA_OPT */
@@ -0,0 +1,9 @@
#ifndef __RCSP_SPORT_SLEEP_DETECTION_H__
#define __RCSP_SPORT_SLEEP_DETECTION_H__
#include "typedef.h"
void sport_info_sleep_detection_attr_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr);
u32 sport_info_sleep_detection_attr_get(void *priv, u8 attr, u8 *buf, u16 buf_size, u32 offset);
#endif
@@ -0,0 +1,51 @@
#include "app_config.h"
#include "sport_data_func.h"
#include "ui/ui_api.h"
#include "system/init.h"
#if (JL_RCSP_SENSORS_DATA_OPT)
__attribute__((weak))
void data_func_attr_weather_set(void *priv, u8 attr, u8 *data, u16 len, u16 ble_con_handle, u8 *spp_remote_addr)
{
}
static const sport_attr_get_func target_common_sport_func_get_tab[SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX] = {
/* [SPORTS_DATA_FUNC_ATTR_TYPE_HEART_RATE ] = sport_data_func_attr_heart_rate_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_AIR_PRESSURE ] = sport_data_func_attr_air_pressure_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_ALTITUDE ] = sport_data_func_attr_altitude_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_EXERCISE_STEPS ] = sport_data_func_attr_exercise_steps_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_PRESSURE_DETECTION ] = sport_data_func_attr_pressure_detection_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_BLOOD_OXYGEN ] = sport_data_func_attr_blood_oxygen_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_TRAINING_LOAD ] = sport_data_func_attr_training_load_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_MAX_OXYGEN_UPTAKE ] = sport_data_func_attr_max_oxygen_uptake_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_EXERCISE_RECOVERY_TIME ] = sport_data_func_attr_exercise_recovery_time_get, */
/* [SPORTS_DATA_FUNC_ATTR_TYPE_SPORTS_INFORMATION ] = sport_data_func_attr_sports_information_get, */
};
static const attr_set_func target_common_func_set_tab[DATA_FUNC_ATTR_TYPE_SET_MAX] = {
[DATA_FUNC_ATTR_TYPE_LOCATION ] = NULL,
[DATA_FUNC_ATTR_TYPE_WEATHER ] = data_func_attr_weather_set,
[DATA_FUNC_ATTR_TYPE_NOTICE ] = NULL,
[DATA_FUNC_ATTR_TYPE_NOTICE_REMOVE ] = NULL,
};
static const rcsp_sport_data_opt_t rcsp_sport_data_opt = {
.sport_data_get_tab = target_common_sport_func_get_tab,
.sport_data_get_tab_num = SPORTS_DATA_FUNC_ATTR_TYPE_GET_MAX,
.sport_data_set_tab = target_common_func_set_tab,
.sport_data_set_tab_num = DATA_FUNC_ATTR_TYPE_SET_MAX,
};
int rcsp_sport_data_trans(void)
{
rcsp_register_sport_data_opt_interface((rcsp_sport_data_opt_t *)&rcsp_sport_data_opt);
return 0;
}
late_initcall(rcsp_sport_data_trans);
#endif /* if (TCFG_SPORT_HEALTH_ENABLE && JL_RCSP_SENSORS_DATA_OPT) */
@@ -0,0 +1,228 @@
#include "app_config.h"
#include "sport_info_sync.h"
#include "ui/ui_api.h"
#include "system/init.h"
#include "health_manager/health_manager.h"
#define LOG_TAG_CONST SPORT_HEALTH_MANAGE
#define LOG_TAG "[sport]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if (JL_RCSP_SENSORS_DATA_OPT)
static void sport_ui_show(u8 status)
{
switch (status) {
case RCSP_SPORT_STATUS_START:
UI_SHOW_WINDOW(ID_WINDOW_SPORTING);
break;
case RCSP_SPORT_STATUS_PAUSE:
if (UI_GET_WINDOW_ID() != ID_WINDOW_SPORTING) {
UI_SHOW_WINDOW(ID_WINDOW_SPORTING);
}
UI_MSG_POST("sport_pause", NULL);
break;
case RCSP_SPORT_STATUS_CONTINNUE:
if (UI_GET_WINDOW_ID() != ID_WINDOW_SPORTING) {
UI_SHOW_WINDOW(ID_WINDOW_SPORTING);
}
UI_MSG_POST("sport_continue", NULL);
break;
case RCSP_SPORT_STATUS_STOP:
UI_SHOW_WINDOW(ID_WINDOW_SPORT_RESULT);
break;
}
}
int execise_ctrl_status_set(unsigned char sport_mode, unsigned char status)
{
log_info("sport_mode=%d status= %d", sport_mode, status);
switch (status) {
case RCSP_SPORT_STATUS_START:
sport_health_ctrl_sport_start_with_type(sport_mode);
break;
case RCSP_SPORT_STATUS_PAUSE:
sport_health_ctrl_sport_pause();
break;
case RCSP_SPORT_STATUS_CONTINNUE:
sport_health_ctrl_sport_continue();
break;
case RCSP_SPORT_STATUS_STOP:
sport_health_ctrl_sport_stop();
break;
}
sport_ui_show(status);
return 0;
}
u8 execise_ctrl_status_get(void)
{
u8 run_status = sport_health_get_sport_status();
log_info("%s %d", __func__, run_status);
return run_status;
}
int execise_ctrl_status_clr(void)
{
return 0;
}
u8 execise_mode_get(void)
{
u8 mode = sport_health_get_sport_type();
log_info("%s %d", __func__, mode);
if (mode > 2) {
mode = 2;
}
return mode;
}
int execise_info_get_data(u8 info_type)
{
int result;
switch (info_type) {
case RCSP_SPORT_DATA_STEPS:
result = sport_health_get_sport_steps();
break;
case RCSP_SPORT_DATA_DISTANCE:
result = sport_health_get_sport_distance();
break;
case RCSP_SPORT_DATA_KCAL:
result = sport_health_get_sport_calories();
break;
case RCSP_SPORT_DATA_EXERCISE_INTENSITY:
int hr_arg = sport_health_get_sport_hr_arg();
if (hr_arg > 150) {
result = 5;
} else if (hr_arg > 140) {
result = 4;
} else if (hr_arg > 130) {
result = 3;
} else if (hr_arg > 110) {
result = 2;
} else if (hr_arg > 90) {
result = 1;
} else {
result = 0;
}
break;
case RCSP_SPORT_DATA_HR:
result = sport_health_get_sport_hr_real();
break;
case RCSP_SPORT_DATA_STEP_STRIDE:
result = sport_health_get_sport_step_stride();
break;
case RCSP_SPORT_DATA_STEP_FREQ:
result = sport_health_get_sport_freq();
break;
case RCSP_SPORT_DATA_MOTION_TIME:
result = sport_health_get_sport_time();
break;
case RCSP_SPORT_DATA_SPEED:
result = sport_health_get_sport_speed();
break;
default:
result = 0;
/* log_error("%s %d",__func__,info_type); */
break;
}
return result;
}
void execise_info_clr(void)
{
}
u32 get_sport_start_time(struct sys_time *t)
{
u32 time;
struct sys_time *stime = malloc(sizeof(struct sys_time));
rtc_read_time(stime);
time = ((stime->sec & 0x3F) | \
((stime->min & 0x3F) << 6) | \
((stime->hour & 0x1F) << 12) | \
((stime->day & 0x1F) << 17) | \
((stime->month & 0x0F) << 22) | \
((stime->year & 0x3F) << 26));
free(stime);
return time;
}
u32 get_sport_end_time(struct sys_time *t)
{
return 0;
}
u16 get_sport_recode_id(void)
{
return sport_health_get_sport_file_id();
}
u16 get_sport_recode_size(void)
{
return sport_health_get_sport_file_size();
}
//运动总时间
int ui_sport_get_total_time(struct sys_time *t)
{
return 0;
}
int heart_rate_last_data_get(void)
{
return 0;
}
int execise_info_get_intensity_time(int *intensity_time, int intensity_time_size)
{
return 0;
}
struct rcsp_watch_execise watch_execise_hd = {
//设置运动开始/暂停/继续/结束,输入参数为运动类型
.execise_ctrl_status_set = execise_ctrl_status_set,
//获取当前运动状态,用于APP与UI同步
.execise_ctrl_status_get = execise_ctrl_status_get,
//清除当前运动状态,结束后调用
.execise_ctrl_status_clr = execise_ctrl_status_clr,
//获取当前运动类型,户外、室内
.execise_mode_get = execise_mode_get,
//运动开始到结束累积的数据
.execise_info_get_data = execise_info_get_data,
.execise_info_clr = execise_info_clr,
//清除缓存运动数据
.get_sport_start_time = get_sport_start_time,
.get_sport_end_time = get_sport_end_time,
.get_sport_recode_id = get_sport_recode_id,
.get_sport_recode_size = get_sport_recode_size,
.ui_sport_get_total_time = ui_sport_get_total_time,
.heart_rate_last_data_get = heart_rate_last_data_get,
.execise_info_get_intensity_time = execise_info_get_intensity_time,
};
int rcsp_sport_data_sync(void)
{
rcsp_register_sport_info_sync_interface(&watch_execise_hd);
return 0;
}
late_initcall(rcsp_sport_data_sync);
#endif /* if (TCFG_SPORT_HEALTH_ENABLE && JL_RCSP_SENSORS_DATA_OPT) */
@@ -0,0 +1,148 @@
#ifndef __SHM_COMMON_API__
#define __SHM_COMMON_API__
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 活动量
*/
/* ------------------------------------------------------------------------------------*/
//获取活动量数据
int sport_health_get_value_daily_active(struct daily_active *data);
//活动量--步数
int sport_health_get_value_daily_steps();
//活动量--热量
int sport_health_get_value_daily_calories();
//活动量--距离
int sport_health_get_value_daily_distance();
//设置活动量目标
int sport_health_set_daily_active_target(struct daily_active *data);
//获取活动量目标
int sport_health_get_value_daily_active_target(struct daily_active *data);
//活动量目标--步数
int sport_health_get_value_daily_target_steps();
//活动量目标--热量
int sport_health_get_value_daily_target_calories();
//活动量目标--距离
int sport_health_get_value_daily_target_distance();
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 运动
*/
/* ------------------------------------------------------------------------------------*/
//设置运动类型
int sport_health_set_sport_type(int type);
//开启运动附带运动类型
int sport_health_ctrl_sport_start_with_type(int type);
//开启运动
int sport_health_ctrl_sport_start();
//暂停运动
int sport_health_ctrl_sport_pause();
//继续运动
int sport_health_ctrl_sport_continue();
//结束运动
int sport_health_ctrl_sport_stop();
//获取运动时的信息
int sport_health_get_sport_info(struct sport_value *data);
//运动--状态:开始、暂停、继续、结束
int sport_health_get_sport_status();
//运动--运动类型
int sport_health_get_sport_type();
//运动--步数
int sport_health_get_sport_steps();
//运动--热量
int sport_health_get_sport_calories();
//运动--距离
int sport_health_get_sport_distance();
//运动--步频
int sport_health_get_sport_freq();
//运动--时长(不含暂停时间)
int sport_health_get_sport_time();
//运动--步幅
int sport_health_get_sport_step_stride();
//运动--速度
int sport_health_get_sport_speed();
//运动--心率均值
int sport_health_get_sport_hr_arg();
//运动--心率最小值
int sport_health_get_sport_hr_min();
//运动--心率最大值
int sport_health_get_sport_hr_max();
//运动--心率实时值
int sport_health_get_sport_hr_real();
//运动类型转换
int sport_type_map_get_type(u8 sport_mode, u8 list_index);
//运动类型所需的数据配置
u32 sport_type_map_get_data_cfg(u8 sport_type);
//运动文件数量
int sport_health_get_sport_file_total();
//运动文件数据
int sport_health_get_sport_file_value(struct sport_value *value);
//运动文件idnew
int sport_health_get_sport_file_id();
//运动文件大小(new
int sport_health_get_sport_file_size();
//更新算法配置
int sport_health_gsensor_algo_cfg_update();
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 心率
*/
/* ------------------------------------------------------------------------------------*/
//开启心率测量
int sport_health_heart_rate_module_enable();
//关闭心率测量
int sport_health_heart_rate_module_disable();
//清除心率
int sport_health_heart_rate_module_clr();
//心率--获取当前值
int sport_health_heart_rate_get_cur();
//心率--获取最小值
int sport_health_heart_rate_get_min();
//心率--获取最大值
int sport_health_heart_rate_get_max();
//心率--获取平均值
int sport_health_heart_rate_get_avg();
//心率--获取心率文件数据
int sport_health_heart_rate_get_rec(struct health_file_data_info *info);
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 血氧
*/
/* ------------------------------------------------------------------------------------*/
//开启血氧测量
int sport_health_blood_oxygen_module_enable();
//关闭血氧测量
int sport_health_blood_oxygen_module_disable();
//清除血氧
int sport_health_blood_oxygen_module_clr();
//血氧--获取当前值
int sport_health_blood_oxygen_get_cur();
//血氧--获取最小值
int sport_health_blood_oxygen_get_min();
//血氧--获取最大值
int sport_health_blood_oxygen_get_max();
//血氧--获取平均值
int sport_health_blood_oxygen_get_avg();
//血氧--获取血氧文件数据
int sport_health_blood_oxygen_get_rec(struct health_file_data_info *info);
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 睡眠
*/
/* ------------------------------------------------------------------------------------*/
//获取睡眠数据
int sport_health_sleep_data_get(struct sleep_data_analysis *info, int analysis_en, struct sys_time *time);
/* ------------------------------------------------------------------------------------*/
/**
* @TYPE 其他
*/
/* ------------------------------------------------------------------------------------*/
void sport_health_common_swapX(const uint8_t *src, uint8_t *dst, int32_t len);
#endif// __SHM_COMMON_API__
@@ -0,0 +1,68 @@
#ifndef __SHM_INFO_STORAGE_H__
#define __SHM_INFO_STORAGE_H__
#include "typedef.h"
typedef struct exercise_heart_rate_mode {
u8 max_heart_rate;
u8 heart_rate_type;
} e_heart_rate;
typedef struct fall_detection_mode {
u8 phone_len;
u8 phone_num[20];
} fall_detection_t;
#pragma pack(1)
typedef struct sport_info_personal_info {
u16 height;
u16 weight;
u16 birth_y;
u8 birth_m;
u8 birth_d;
u8 gender;
} personal_information;
#pragma pack()
typedef struct raise_wrist_mode {
u8 begin_time_hour;
u8 begin_time_min;
u8 end_time_hour;
u8 end_time_min;
} raise_wrist_t;
typedef struct sedentary_mode {
u8 nop_mode;
u8 begin_time_hour;
u8 begin_time_min;
u8 end_time_hour;
u8 end_time_min;
} sedentary_t;
typedef struct sleep_detection_mode {
u8 begin_time_hour;
u8 begin_time_min;
u8 end_time_hour;
u8 end_time_min;
} sleep_detection_t;
int sport_info_write_vm(int vm_id, u8 *data, u16 data_len);
int sport_info_read_vm(int vm_id, u8 *data, u16 data_len);
void sport_info_switch_record_update(u8 switch_type, u8 switch_state, u8 write_vm);
u32 sport_info_swtich_record_get(u8 switch_type);
void sport_info_mode_record_update(u8 mode_type, u8 mode);
u16 sport_info_record_get(u8 mode_type, u8 *mode_data[]);
int sport_exercise_heart_rate_get(e_heart_rate *heart_rate);
int sport_fall_detection_get(fall_detection_t *fall_detect);
int sport_personal_info_get(personal_information *info);
int sport_raise_wrist_get(raise_wrist_t *raise_wrist);
int sport_sedentary_get(sedentary_t *sedentary);
int sport_sleep_detection_get(sleep_detection_t *sleep_detection);
#endif
@@ -0,0 +1,25 @@
#ifndef __AI_AUDIO_H__
#define __AI_AUDIO_H__
#include "typedef.h"
#include "app_config.h"
enum {
AI_AUDIO_EVENT_ERR_REC_START = 1,
AI_AUDIO_EVENT_ERR_REC_STOP,
AI_AUDIO_EVENT_ERR_REC_DATA,
};
// 初始化
int ai_audio_init(void (* evt_cb)(int event));
// 启动录音
int ai_audio_start(void);
// 停止录音
// cancel1-取消
int ai_audio_stop(int cancel);
#endif//__AI_AUDIO_H__
@@ -0,0 +1,16 @@
#ifndef __AI_INTERACTION_H__
#define __AI_INTERACTION_H__
#include "typedef.h"
#include "app_config.h"
void ai_interaction_init(void);
int ai_interaction_rec_start(void);
int ai_interaction_rec_stop(void);
void ai_interaction_release(void);
#endif//__AI_INTERACTION_H__
@@ -0,0 +1,29 @@
#ifndef __AI_TEXT_H__
#define __AI_TEXT_H__
#include "typedef.h"
#include "app_config.h"
// 初始化
// rx_text()返回true代表外面已经处理,内部不再保存数据
int ai_text_init(int (* rx_text)(u8 ai_text, u8 *data, int len));
// 释放
void ai_text_release(void);
// 启动APP文本转语音
int ai_text_local_to_tts(void);
int ai_text_ai_to_tts(void);
// 临界区保护
void ai_text_enter_critical(void);
void ai_text_exit_critical(void);
// 获取文本,*buf为文本数据,返回值为文本长度。
// 获取文件数据接口及文本数据的使用应该在临界区保护范围内
int ai_text_get_local_text(u8 **buf);
int ai_text_get_ai_text(u8 **buf);
#endif//__AI_TEXT_H__
+112
View File
@@ -0,0 +1,112 @@
#ifndef __ALARM_H__
#define __ALARM_H__
#define RTC_ALM_EN 1
#include "typedef.h"
#include "system/includes.h"
#pragma pack(1)
typedef struct _RTC_TIME {
u16 dYear; ///<年份
u8 bMonth; ///<月份
u8 bDay; ///<天数
u8 bHour; ///<时
u8 bMin; ///<分
u8 bSec; ///<秒
// u8 bWeekday; ///<星期几
} RTC_TIME;
#pragma pack()
typedef struct __ALARM__ {
u8 index;
u8 sw;
u8 mode;
struct sys_time time;
u8 name_len;
} T_ALARM, *PT_ALARM;
typedef struct __alarm_vm__ {
u16 head;
T_ALARM alarm;
} T_ALARM_VM, *PT_ALARM_VM;
enum {
E_ALARM_WRITE_VM_ERR = 0x00,
E_ALARM_WRITE_VM_SUCC,
};
enum {
E_ALARM_MODE_ONCE = 0x00,
E_ALARM_MODE_EVERY_DAY = 0x01,
E_ALARM_MODE_EVERY_MONDAY = 0x02,
E_ALARM_MODE_EVERY_TUESDAY = 0x04,
E_ALARM_MODE_EVERY_WEDNESDAY = 0x08,
E_ALARM_MODE_EVERY_THURSDAY = 0x10,
E_ALARM_MODE_EVERY_FRIDAY = 0x20,
E_ALARM_MODE_EVERY_SATURDAY = 0x40,
E_ALARM_MODE_EVERY_SUNDAY = 0x80,
};
enum {
E_WEEK_MONDAY = 0x01,
E_WEEK_TUESDAY,
E_WEEK_WEDNESDAY,
E_WEEK_THURSDAY,
E_WEEK_FRIDAY,
E_WEEK_SATURDAY,
E_WEEK_SUNDAY,
};
typedef enum {
TIME_MEMBER_YEAR = 0x0,
TIME_MEMBER_MONTH,
TIME_MEMBER_DAY,
TIME_MEMBER_HOUR,
TIME_MEMBER_MIN,
TIME_MEMBER_SEC,
TIME_MEMBER_MAX,
} TIME_MEMBER_ENUM;
enum {
E_SUCCESS = 0x00,
E_FAILURE,
};
/* macro */
#define M_MAX_SNOOZE_ALARM_NUM 1//目前贪睡闹钟只支持一个,该值不能修改
#define M_MAX_ALARM_NUMS 5
#define M_MAX_ALARM_NAME_LEN 32
#define M_MAX_ALARM_INDEX (M_MAX_ALARM_NUMS-1)
#define M_MAX_ALARM_MODE (0xFE)
void alarm_init();
u8 alarm_get_info(PT_ALARM p, u8 index);
void rtc_update_time_api(struct sys_time *time);
void alarm_ring_start();
void alarm_active_flag_set(u8 flag);
u8 alarm_active_flag_get(void);
u8 rtc_calculate_week_val(struct sys_time *data_time);
void rtc_calculate_next_few_day(struct sys_time *data_time, u8 days); //未来几天的日期
u16 month_for_day(u8 month, u16 year);
void *is_sys_time_online();
void alarm_update_info_after_isr(void);
// void alarm_event_handler(struct sys_event *event, void *priv);
u8 alarm_add(PT_ALARM p, u8 index);
void alarm_stop(u8 reason);
void alarm_delete(u8 index);
void alarm_delete_all(void);
u8 alarm_get_active_index(void);
u8 alarm_get_total(void);
u8 get_alarm_number2table(u8 num, u8 *table);
void alarm_print_all_info(void);
void alarm_snooze();
void alm_wakeup_isr(void);
#endif //end of __ALARM_H__
+27
View File
@@ -0,0 +1,27 @@
#ifndef APP_ACTION_H
#define APP_ACTION_H
// #define ACTION_EARPHONE_MAIN 0x0001
// #define ACTION_A2DP_START 0x0002
// #define ACTION_ESCO_START 0x0003
// #define ACTION_BY_KEY_MODE 0x0004
//
// #define ACTION_IDLE_MAIN 0x0010
// #define ACTION_IDLE_POWER_OFF 0x0011
//
// #define ACTION_MUSIC_MAIN 0x0020
// #define ACTION_MUSIC_TWS_RX 0x0021
//
// #define ACTION_PC_MAIN 0x0030
//
// #define APP_NAME_BT "earphone"
// #define APP_NAME_IDLE "idle"
// #define APP_NAME_PC "pc"
// #define APP_NAME_MUSIC "music"
//
//
// #define ACTION_DO_NOTHING 0x0a1b2c02
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef _APP_ANCBOX_H_
#define _APP_ANCBOX_H_
#include "typedef.h"
#include "system/event.h"
extern u8 ancbox_get_status(void);
extern void ancbox_clear_status(void);
#endif //_APP_CHARGESTORE_H_
+12
View File
@@ -0,0 +1,12 @@
#ifndef _APP_ANCTOOL_H_
#define _APP_ANCTOOL_H_
#include "typedef.h"
#include "anctool.h"
u8 app_anctool_spp_rx_data(u8 *packet, u16 size);
void app_anctool_spp_connect(void);
void app_anctool_spp_disconnect(void);
#endif //_APP_CHARGESTORE_H_
+36
View File
@@ -0,0 +1,36 @@
#ifndef _APP_CHARGE_H_
#define _APP_CHARGE_H_
#include "typedef.h"
#include "system/event.h"
#define LDO5V_OFF_TYPE_NORMAL_ON 0 //正常拔出开机
#define LDO5V_OFF_TYPE_NORMAL_OFF 1 //正常拔出关机
#define LDO5V_OFF_TYPE_LOWPOWER_OFF 2 //低电关机
#define LDO5V_OFF_TYPE_CHARGESTORE_OFF 3 //智能充电舱关机
struct app_charge_handler {
int (*handler)(int msg, int type);
};
#define APP_CHARGE_HANDLER(charge_handler, prio) \
const struct app_charge_handler charge_handler sec(.app_charge_handler.prio)
extern const struct app_charge_handler app_charge_handler_begin[];
extern const struct app_charge_handler app_charge_handler_end[];
#define for_each_app_charge_handler(p) \
for (p = app_charge_handler_begin; p < app_charge_handler_end; p++)
extern void charge_close_deal(void);
extern void charge_start_deal(void);
extern void ldo5v_keep_deal(void);
extern void charge_full_deal(void);
extern void charge_ldo5v_in_deal(void);
extern void charge_ldo5v_off_deal(void);
extern u8 get_charge_full_flag(void);
extern void app_charge_power_off_keep_mode();
#endif //_APP_CHARGE_H_
+87
View File
@@ -0,0 +1,87 @@
#ifndef _APP_CHARGESTORE_H_
#define _APP_CHARGESTORE_H_
#include "typedef.h"
#include "system/event.h"
//LDOIN升级口命令定义
#define CMD_TWS_CHANNEL_SET 0x01
#define CMD_TWS_REMOTE_ADDR 0x02
#define CMD_TWS_ADDR_DELETE 0x03
#define CMD_BOX_TWS_CHANNEL_SEL 0x04//测试盒获取地址
#define CMD_BOX_TWS_REMOTE_ADDR 0x05//测试盒交换地址
#define CMD_POWER_LEVEL_OPEN 0x06//开盖充电舱报告/获取电量
#define CMD_POWER_LEVEL_CLOSE 0x07//合盖充电舱报告/获取电量
#define CMD_RESTORE_SYS 0x08//恢复出厂设置
#define CMD_ENTER_DUT 0x09//进入测试模式
#define CMD_EX_FIRST_READ_INFO 0x0A//F95读取数据首包信息
#define CMD_EX_CONTINUE_READ_INFO 0x0B//F95读取数据后续包信息
#define CMD_EX_FIRST_WRITE_INFO 0x0C//F95写入数据首包信息
#define CMD_EX_CONTINUE_WRITE_INFO 0x0D//F95写入数据后续包信息
#define CMD_EX_INFO_COMPLETE 0x0E//F95完成信息交换
#define CMD_TWS_SET_CHANNEL 0x0F//F95设置左右声道信息
#define CMD_BOX_UPDATE 0x20//测试盒升级
#define CMD_BOX_MODULE 0x21//测试盒一级命令
#define CMD_SHUT_DOWN 0x80//充电舱关机,充满电关机,或者是低电关机
#define CMD_CLOSE_CID 0x81//充电舱盒盖
#define CMD_ANC_MODULE 0x90//ANC一级命令
#define CMD_FAIL 0xfe//失败
#define CMD_UNDEFINE 0xff//未知命令回复
struct chargestore_event {
u8 event;
u8 size;
u8 *packet;
};
enum {
TWS_CHANNEL_LEFT = 1, //左耳
TWS_CHANNEL_RIGHT, //右耳
};
enum {
TWS_DEL_TWS_ADDR = 1, //删除对箱地址
TWS_DEL_PHONE_ADDR,//删除手机地址
TWS_DEL_ALL_ADDR,//删除手机与对箱地址
};
struct _CHARGE_STORE_INFO {
u8 tws_local_addr[6];
u8 tws_remote_addr[6];
u8 tws_mac_addr[6];
u32 search_aa;
u32 pair_aa;
u8 local_channel;
u16 device_ind;
u16 reserved_data;
} _GNU_PACKED_;
typedef struct _CHARGE_STORE_INFO CHARGE_STORE_INFO;
extern u8 chargestore_get_power_level(void);
extern u8 chargestore_get_power_status(void);
extern u8 chargestore_get_cover_status(void);
extern u8 chargestore_get_sibling_power_level(void);
extern void chargestore_set_bt_init_ok(u8 flag);
extern u8 chargestore_get_earphone_online(void);
extern u8 chargestore_get_earphone_pos(void);
extern int chargestore_sync_chg_level(void);
extern void chargestore_set_power_level(u8 power);
extern void chargestore_set_sibling_chg_lev(u8 chg_lev);
extern void chargestore_set_phone_disconnect(void);
extern void chargestore_set_phone_connect(void);
extern u8 chargestore_check_going_to_poweroff(void);
extern void chargestore_shutdown_reset(void);
extern void testbox_set_testbox_tws_paired(u8 flag);
extern u8 testbox_get_testbox_tws_paired(void);
extern u8 testbox_get_touch_trim_en(u8 *sec);
extern u8 testbox_get_softpwroff_after_paired(void);
void chargestore_set_tws_channel_info(u8 channel);
bool chargestore_set_tws_remote_info(u8 *data, u8 len);
u16 chargestore_get_tws_remote_info(u8 *data);
#endif //_APP_CHARGESTORE_H_
+11
View File
@@ -0,0 +1,11 @@
#ifndef __APP_COMMON_H__
#define __APP_COMMON_H__
#include "typedef.h"
#include "call/call_common.h"
extern u8 app_common_key_var_2_event(u32 key_var);
void set_bt_esco_by_watch(bool flag);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,45 @@
#ifndef APP_DEFAULT_MSG_HANDLER_H
#define APP_DEFAULT_MSG_HANDLER_H
#include "system/includes.h"
#include "system/event.h"
u8 get_sys_aduio_mute_statu(void);
void app_default_msg_handler(int *msg);
void app_common_key_msg_handler(int *msg);
void app_common_device_event_handler(int *msg);
#endif
+119
View File
@@ -0,0 +1,119 @@
#ifndef APP_MAIN_H
#define APP_MAIN_H
#include "app_msg.h"
#include "app_task.h"
#include "app_mode_manager/app_mode_manager.h"
#include "app_mode.h"
#include "poweroff.h"
#include "app_config.h"
#include "app_music.h"
#include "app_default_msg_handler.h"
#include "bt_background.h"
enum {
SYS_POWERON_BY_KEY = 1,
SYS_POWERON_BY_OUT_BOX,
};
enum {
SYS_POWEROFF_BY_KEY = 1,
SYS_POWEROFF_BY_IN_BOX,
SYS_POWEROFF_BY_TIMEOUT,
};
typedef struct _APP_VAR {
u8 volume_def_state;
s16 bt_volume;
s16 dev_volume;
s16 music_volume;
s16 call_volume;
s16 wtone_volume;
u8 opid_play_vol_sync;
u8 aec_dac_gain;
u8 aec_mic_gain;
u8 aec_mic1_gain;
u8 aec_mic2_gain;
u8 aec_mic3_gain;
u8 rf_power;
u8 goto_poweroff_flag;
u16 goto_poweroff_cnt;
u8 poweroff_sametime_flag;
u8 play_poweron_tone;
u8 remote_dev_company;
u8 siri_stu;
u8 cycle_mode;
u8 have_mass_storage;
u8 poweron_reason;
u8 poweroff_reason;
int auto_stop_page_scan_timer; //用于1拖2时,有一台连接上后,超过三分钟自动关闭Page Scan
u16 auto_off_time;
u16 warning_tone_v;
u16 poweroff_tone_v;
u16 phone_dly_discon_time;
u8 usb_mic_gain;
int wait_timer_do;
u32 start_time;
u8 pitch_mode;
s16 mic_eff_volume;
u8 goto_reboot_flag;
u8 a2dp_source_open_flag;
} APP_VAR;
struct bt_mode_var {
//phone
u8 phone_ring_flag; //来电响铃标志
u8 phone_num_flag; //通话号码获取标志
u8 phone_income_flag; //来电标志
u8 phone_call_dec_begin; //来电esco解码标志
u8 phone_ring_sync_tws; //tws来电铃声同步标志
u8 phone_ring_addr[6]; //响铃的手机地址
u8 inband_ringtone; //带内铃声,表示支不支持手机端铃声
u8 phone_vol; //手机音量
u16 phone_timer_id; //查询手机号码定时器
u8 last_call_type;
u8 income_phone_num[30]; //通话手机号码
u8 income_phone_len; //通话手机号码长度
s32 auto_connection_counter; //回链设备的总时间
int auto_connection_timer; //回连定时器
u8 auto_connection_addr[6]; //回连地址
int tws_con_timer;
u8 tws_start_con_cnt;
u8 tws_conn_state; //tws连接状态
bool search_tws_ing;
int sniff_timer; //进入sniff模式定时器
bool fast_test_mode;
u16 exit_check_timer;
u8 init_start; //蓝牙协议栈已经开始初始化标志位
u8 init_ok; //蓝牙初始化完成标志
u8 exiting; //蓝牙正在退出
u8 wait_exit; //蓝牙等待退出
u32 get_music_player_timer;
u8 ignore_discon_tone; // 1-退出蓝牙模式, 不响应discon提示音
u8 bt_close_bredr; //edr状态
u8 bt_direct_init; //蓝牙直接初始化
background_var background; //蓝牙后台相关变量
u8 smartbox_watch_upgrade_flag; //当手机app与手表传输过程中不能响应通话事件
u8 a2dp_en;// 手表控制a2dp 出声
u8 emitter_or_receiver;
};
typedef struct _BT_USER_COMM_VAR {
} BT_USER_COMM_VAR;
extern APP_VAR app_var;
extern struct bt_mode_var g_bt_hdl;
#define earphone (&bt_user_priv_var)
void app_power_off(void *priv);
void bt_bredr_enter_dut_mode(u8 mode, u8 inquiry_scan_en);
void bt_bredr_exit_dut_mode();
struct app_mode *app_mode_switch_handler(int *msg);
#endif
+14
View File
@@ -0,0 +1,14 @@
#ifndef __APP_MODE_H__
#define __APP_MODE_H__
extern const struct key_remap_table bt_mode_key_table[];
extern const struct key_remap_table spdif_mode_key_table[];
extern const struct key_remap_table fm_mode_key_table[];
extern const struct key_remap_table idle_mode_key_table[];
extern const struct key_remap_table linein_mode_key_table[];
extern const struct key_remap_table music_mode_key_table[];
extern const struct key_remap_table pc_mode_key_table[];
extern const struct key_remap_table record_mode_key_table[];
extern const struct key_remap_table rtc_mode_key_table[];
#endif
+21
View File
@@ -0,0 +1,21 @@
#ifndef APP_MODE_UPDATE_H
#define APP_MODE_UPDATE_H
#include "app_mode_manager/app_mode_manager.h"
struct app_mode *app_enter_update_mode(int arg);
#endif
+288
View File
@@ -0,0 +1,288 @@
#ifndef APP_MSG_H
#define APP_MSG_H
#include "os/os_api.h"
enum {
MSG_FROM_KEY = Q_MSG + 1,
MSG_FROM_TWS,
MSG_FROM_BT_STACK,
MSG_FROM_BT_HCI,
MSG_FROM_EARTCH,
MSG_FROM_BATTERY,
MSG_FROM_CHARGE_STORE,
MSG_FROM_TESTBOX,
MSG_FROM_ANCBOX,
MSG_FROM_TONE,
MSG_FROM_APP,
MSG_FROM_AUDIO,
MSG_FROM_CI_UART,
MSG_FROM_CDC,
MSG_FROM_CDC_DATA,
MSG_FROM_CFGTOOL_TWS_SYNC,
MSG_FROM_DEVICE,
MSG_FROM_RCSP,
MSG_FROM_RCSP_BT,
MSG_FROM_TWS_UPDATE_NEW,
MSG_FROM_CHGBOX,
MSG_FROM_CHGBOX_EAR,
};
struct app_msg_handler {
int owner;
int from;
int (*handler)(int *msg);
};
#define APP_MSG_PROB_HANDLER(msg_handler) \
const struct app_msg_handler msg_handler sec(.app_msg_prob_handler)
extern const struct app_msg_handler app_msg_prob_handler_begin[];
extern const struct app_msg_handler app_msg_prob_handler_end[];
#define for_each_app_msg_prob_handler(p) \
for (p = app_msg_prob_handler_begin; p < app_msg_prob_handler_end; p++)
#define APP_MSG_HANDLER(msg_handler) \
const struct app_msg_handler msg_handler sec(.app_msg_handler)
extern const struct app_msg_handler app_msg_handler_begin[];
extern const struct app_msg_handler app_msg_handler_end[];
#define for_each_app_msg_handler(p) \
for (p = app_msg_handler_begin; p < app_msg_handler_end; p++)
#define APP_KEY_MSG_FROM_TWS 1
#define APP_MSG_KEY 0x010000
#define APP_MSG_FROM_KEY(msg) (msg & APP_MSG_KEY)
#define APP_MSG_KEY_VALUE(msg) ((msg >> 8) & 0xff)
#define APP_MSG_KEY_ACTION(msg) (msg & 0xff)
#define APP_KEY_MSG_REMAP(key_value, key_action) \
(APP_MSG_KEY | (key_value << 8) | key_action)
enum {
APP_MSG_NULL = 0,
APP_MSG_KEY_POWER_ON,
APP_MSG_KEY_POWER_ON_HOLD,
APP_MSG_KEY_POWER_OFF,
APP_MSG_KEY_POWER_OFF_HOLD,
APP_MSG_KEY_POWER_OFF_RELEASE,
APP_MSG_KEY_POWER_OFF_INSTANTLY,
APP_MSG_WRITE_RESFILE_START,
APP_MSG_WRITE_RESFILE_STOP,
APP_MSG_MUSIC_PP,
APP_MSG_MUSIC_PREV,
APP_MSG_MUSIC_NEXT,
APP_MSG_MUSIC_CHANGE_DEV,
APP_MSG_MUSIC_AUTO_NEXT_DEV,
APP_MSG_MUSIC_PLAYE_NEXT_FOLDER,
APP_MSG_MUSIC_PLAYE_PREV_FOLDER,
APP_MSG_MUSIC_PLAY_FIRST,
APP_MSG_MUSIC_PLAY_REC_FOLDER_SWITCH,
APP_MSG_MUSIC_MOUNT_PLAY_START,
APP_MSG_MUSIC_PLAY_START,
APP_MSG_MUSIC_PLAY_START_BY_SCLUST,
APP_MSG_MUSIC_PLAY_START_BY_DEV,
APP_MSG_MUSIC_FR,
APP_MSG_MUSIC_FF,
APP_MSG_MUSIC_DEC_ERR,
APP_MSG_MUSIC_PLAYER_END,
APP_MSG_MUSIC_CHANGE_REPEAT,
APP_MSG_MUSIC_SPEED_UP,
APP_MSG_MUSIC_SPEED_DOWN,
APP_MSG_MUSIC_PLAYER_AB_REPEAT_SWITCH,
APP_MSG_MUSIC_MUTE,
APP_MSG_MUSIC_CHANGE_EQ,
APP_MSG_MUSIC_PLAY_BY_NUM,
APP_MSG_MUSIC_PLAY_START_AT_DEST_TIME,
APP_MSG_CALL_HANGUP,
APP_MSG_CALL_LAST_NO,
APP_MSG_CALL_THREE_WAY_ANSWER1,
APP_MSG_CALL_THREE_WAY_ANSWER2,
APP_MSG_CALL_SWITCH,
APP_MSG_HID_CONTROL,
APP_MSG_OPEN_SIRI,
APP_MSG_VOL_UP,
APP_MSG_VOL_DOWN,
APP_MSG_MAX_VOL,
APP_MSG_MIN_VOL,
APP_MSG_LOW_LANTECY,
APP_MSG_ADD_LINEIN_STREAM, //叠加linein数据流
APP_MSG_POWER_KEY_LONG,
APP_MSG_POWER_KEY_HOLD,
APP_MSG_SYS_MUTE,
APP_MSG_CEC_MUTE,
APP_MSG_CEC_VOL_UP,
APP_MSG_CEC_VOL_DOWN,
APP_MSG_PITCH_UP,
APP_MSG_PITCH_DOWN,
APP_MSG_SYS_TIMER,
APP_MSG_POWER_ON,
APP_MSG_POWER_OFF,
APP_MSG_GOTO_MODE,
APP_MSG_GOTO_NEXT_MODE,
APP_MSG_ENTER_MODE,
APP_MSG_EXIT_MODE,
APP_MSG_BT_GET_CONNECT_ADDR,
APP_MSG_BT_OPEN_PAGE_SCAN,
APP_MSG_BT_CLOSE_PAGE_SCAN,
APP_MSG_BT_ENTER_SNIFF,
APP_MSG_BT_EXIT_SNIFF,
APP_MSG_BT_A2DP_PAUSE,
APP_MSG_BT_A2DP_PLAY,
APP_MSG_BT_A2DP_START,
APP_MSG_BT_PAGE_DEVICE,
APP_MSG_BT_IN_PAIRING_MODE,
APP_MSG_TWS_PAIRED,
APP_MSG_TWS_UNPAIRED,
APP_MSG_TWS_PAIR_SUSS,
APP_MSG_TWS_CONNECTED,
APP_MSG_TWS_WAIT_PAIR, // 等待配对
APP_MSG_TWS_START_PAIR, // 手动发起配对
APP_MSG_TWS_START_CONN, // 开始回连TWS
APP_MSG_TWS_REMOVE_PAIR, // 取消配对
APP_MSG_TWS_START_REMOVE_PAIR, // 如果没有配对则发起配对,如果配对了则取消配对
APP_MSG_TWS_WAIT_CONN, // 等待TWS连接
APP_MSG_TWS_START_PAIR_AND_CONN_PROCESS, // 执行配对和连接的默认流程
APP_MSG_TWS_POWERON_PAIR_TIMEOUT, // TWS开机配对超时
APP_MSG_TWS_POWERON_CONN_TIMEOUT, // TWS开机回连超时
APP_MSG_TWS_START_PAIR_TIMEOUT,
APP_MSG_TWS_START_CONN_TIMEOUT,
APP_MSG_FM_SCAN_ALL,
APP_MSG_FM_SCAN_ALL_DOWN,
APP_MSG_FM_SCAN_ALL_UP,
APP_MSG_FM_SCAN_DOWN,
APP_MSG_FM_SCAN_UP,
APP_MSG_FM_PREV_STATION,
APP_MSG_FM_NEXT_STATION,
APP_MSG_FM_PREV_FREQ,
APP_MSG_FM_NEXT_FREQ,
APP_MSG_LINEIN_START,
APP_MSG_SPDIF_START,
APP_MSG_SPDIF_SWITCH_SOURCE,
APP_MSG_RTC_UP,
APP_MSG_RTC_DOWN,
APP_MSG_RTC_SW,
APP_MSG_RTC_SW_POS,
APP_MSG_REC_PP,
APP_MSG_REC_PAUSE, //暂停录音
APP_MSG_REC_DEL_CUR_FILE, //删除当前录音文件
APP_MSG_ENC_START,
APP_MSG_REVERB_OPNE,
APP_MSG_MIC_VOL_UP,
APP_MSG_MIC_VOL_DOWN,
APP_MSG_MIC_BASS_UP,
APP_MSG_MIC_BASS_DOWN,
APP_MSG_MIC_TREBLE_UP,
APP_MSG_MIC_TREBLE_DOWN,
APP_MSG_CHANGE_MODE,
APP_MSG_SWITCH_SOUND_EFFECT,
APP_MSG_MIC_EFFECT_ON_OFF,
APP_MSG_SWITCH_MIC_EFFECT,
APP_MSG_VOCAL_REMOVE,
//IR_NUM中间不允许插入msg
APP_MSG_IR_NUM0,
APP_MSG_IR_NUM1,
APP_MSG_IR_NUM2,
APP_MSG_IR_NUM3,
APP_MSG_IR_NUM4,
APP_MSG_IR_NUM5,
APP_MSG_IR_NUM6,
APP_MSG_IR_NUM7,
APP_MSG_IR_NUM8,
APP_MSG_IR_NUM9,
//IR_NUM中间不允许插入msg
APP_MSG_VOL_CHANGED,
APP_MSG_MUSIC_FILE_NUM_CHANGED,
APP_MSG_REPEAT_MODE_CHANGED,
APP_MSG_FM_INIT_OK,
APP_MSG_FM_REFLASH,
APP_MSG_FM_STATION,
APP_MSG_MUSIC_PLAY_STATUS,
APP_MSG_LINEIN_PLAY_STATUS,
APP_MSG_INPUT_FILE_NUM,
APP_MSG_RTC_SET,
APP_MSG_EQ_CHANGED,
APP_MSG_MUTE_CHANGED,
APP_MSG_LCD_OK,
APP_MSG_LCD_MENU,
APP_MSG_LCD_UP,
APP_MSG_LCD_DOWN,
APP_MSG_LCD_VOL_INC,
APP_MSG_LCD_VOL_DEC,
APP_MSG_LCD_MODE,
APP_MSG_LCD_POWER,
APP_MSG_LCD_POWER_START,
APP_MSG_SMART_VOICE_EVENT,
APP_MSG_JL_UI_HOME,
APP_MSG_JL_UI_SHORTCUT,
APP_MSG_JL_UI_POWEROFF,
APP_MSG_ALIPAY_A2U,
APP_MSG_ALIPAY_U2A,
APP_MSG_BT_EMITTER_PLAY,
APP_MSG_BT_EMITTER_PAUSE,
APP_MSG_PC_AUDIO_PLAY_OPEN,
APP_MSG_PC_AUDIO_PLAY_CLOSE,
APP_MSG_PC_AUDIO_MIC_OPEN,
APP_MSG_PC_AUDIO_MIC_CLOSE,
};
struct key_remap_table {
u8 key_value;
const int *remap_table;
int (*remap_func)(int *event);
};
int app_send_message(int msg, int arg);
int app_send_message2(int _msg, int arg1, int arg2);
int app_send_message_from(int from, int argc, int *msg);
int app_key_event_remap(const struct key_remap_table *table, int *_event);
int app_get_message(int *msg, int max_num, const struct key_remap_table *key_table);
#endif

Some files were not shown because too many files have changed in this diff Show More