first
This commit is contained in:
230
apps/common/update/testbox_update.c
Normal file
230
apps/common/update/testbox_update.c
Normal file
@ -0,0 +1,230 @@
|
||||
|
||||
#include "update_loader_download.h"
|
||||
#include "update.h"
|
||||
#include "btctrler_task.h"
|
||||
#include "app_config.h"
|
||||
|
||||
|
||||
#if defined(CONFIG_SPP_AND_LE_CASE_ENABLE) || defined(CONFIG_HID_CASE_ENABLE)
|
||||
#include "lib_profile_cfg.h"
|
||||
#else
|
||||
#include "bt_profile_cfg.h"
|
||||
#endif
|
||||
|
||||
#if (SMART_BOX_EN) && (CONFIG_WATCH_CASE_ENABLE)
|
||||
#include "smartbox/smartbox_task.h"
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "[TEST-UPDATE]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_ERROR_ENABLE
|
||||
#include "system/debug.h"
|
||||
|
||||
extern u8 check_le_conn_disconnet_flag(void);
|
||||
extern void ble_app_disconnect(void);
|
||||
extern void ll_hci_destory(void);
|
||||
extern void ram_protect_close(void);
|
||||
extern void update_close_hw(void *filter_name);
|
||||
extern void btctrler_testbox_update_msg_handle_register(void (*handle)(int));
|
||||
extern void __bt_updata_reset_bt_bredrexm_addr(void);
|
||||
extern int __bt_updata_save_connection_info(void);
|
||||
extern const update_op_api_t lmp_ch_update_op;
|
||||
extern const update_op_api_t ble_ll_ch_update_op;
|
||||
static u8 ble_update_ready_jump_flag = 0;
|
||||
|
||||
#include "asm/power_interface.h"
|
||||
void power_set_mode(u8 mode);
|
||||
|
||||
static void testbox_bt_classic_update_private_param_fill(UPDATA_PARM *p)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void testbox_bt_classic_update_before_jump_handle(int type)
|
||||
{
|
||||
if (UPDATE_MODULE_IS_SUPPORT(UPDATE_BT_LMP_EN)) {
|
||||
#if TCFG_USER_TWS_ENABLE || TCFG_USER_BLE_ENABLE
|
||||
log_info("close ble hw\n");
|
||||
ll_hci_destory();
|
||||
#endif
|
||||
|
||||
update_close_hw("bredr");
|
||||
if (__bt_updata_save_connection_info()) {
|
||||
log_error("bt save conn info fail!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ram_protect_close();
|
||||
//note:last func will not return;
|
||||
power_set_mode(PWR_LDO15);
|
||||
__bt_updata_reset_bt_bredrexm_addr();
|
||||
}
|
||||
}
|
||||
|
||||
static void testbox_bt_classic_update_state_cbk(int type, u32 state, void *priv)
|
||||
{
|
||||
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
|
||||
|
||||
if (ret_code) {
|
||||
log_info("state:%x err:%x\n", ret_code->stu, ret_code->err_code);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case UPDATE_CH_EXIT:
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
log_info("bt update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
} else {
|
||||
log_info("bt update fail\n");
|
||||
update_result_set(UPDATA_DEV_ERR);
|
||||
}
|
||||
} else {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
//update_mode_api(BT_UPDATA);
|
||||
update_mode_api_v2(BT_UPDATA,
|
||||
testbox_bt_classic_update_private_param_fill,
|
||||
testbox_bt_classic_update_before_jump_handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 ble_update_get_ready_jump_flag(void)
|
||||
{
|
||||
return ble_update_ready_jump_flag;
|
||||
}
|
||||
|
||||
static void testbox_ble_update_private_param_fill(UPDATA_PARM *p)
|
||||
{
|
||||
u8 addr[6];
|
||||
extern int le_controller_get_mac(void *addr);
|
||||
if (BT_MODULES_IS_SUPPORT(BT_MODULE_LE) && UPDATE_MODULE_IS_SUPPORT(UPDATE_BLE_TEST_EN)) {
|
||||
le_controller_get_mac(addr);
|
||||
//memcpy(p->parm_priv, addr, 6);
|
||||
update_param_priv_fill(p, addr, sizeof(addr));
|
||||
puts("ble addr:\n");
|
||||
put_buf(p->parm_priv, 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void testbox_ble_update_before_jump_handle(int type)
|
||||
{
|
||||
if (BT_MODULES_IS_SUPPORT(BT_MODULE_LE) && UPDATE_MODULE_IS_SUPPORT(UPDATE_BLE_TEST_EN)) {
|
||||
ll_hci_destory();
|
||||
}
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
y_printf(">>>[test]:latch reset update\n");
|
||||
latch_reset();
|
||||
|
||||
#if 0
|
||||
update_close_hw("null");
|
||||
ram_protect_close();
|
||||
/* save_spi_port(); */
|
||||
extern void __BT_UPDATA_JUMP();
|
||||
y_printf("update jump to __BT_UPDATA ...\n");
|
||||
/* clk_set("sys", 48 * 1000000L); */
|
||||
//跳转到uboot加载完,30ms左右(200410_yzb)
|
||||
__BT_UPDATA_JUMP();
|
||||
#endif
|
||||
#else
|
||||
cpu_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void testbox_ble_update_state_cbk(int type, u32 state, void *priv)
|
||||
{
|
||||
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
|
||||
|
||||
if (ret_code) {
|
||||
printf("ret_code->stu:%d err_code:%d\n", ret_code->stu, ret_code->err_code);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case UPDATE_CH_EXIT:
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
log_info("bt update succ\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
} else {
|
||||
log_info("bt update fail\n");
|
||||
update_result_set(UPDATA_DEV_ERR);
|
||||
}
|
||||
} else {
|
||||
if ((0 == ret_code->stu) && (0 == ret_code->err_code)) {
|
||||
#if TCFG_USER_BLE_ENABLE && (TCFG_BLE_DEMO_SELECT != DEF_BLE_DEMO_NULL) \
|
||||
&&(TCFG_BLE_DEMO_SELECT != DEF_BLE_DEMO_ADV || defined(CONFIG_MESH_CASE_ENABLE))\
|
||||
&& (TCFG_BLE_DEMO_SELECT != DEF_BLE_DEMO_CLIENT)
|
||||
|
||||
ble_update_ready_jump_flag = 1;
|
||||
/* ble_app_disconnect(); */
|
||||
extern void ble_module_enable(u8 en);
|
||||
ble_module_enable(0);
|
||||
u8 cnt = 0;
|
||||
while (!check_le_conn_disconnet_flag()) {
|
||||
log_info("wait discon\n");
|
||||
os_time_dly(2);
|
||||
if (cnt++ > 5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//update_mode_api(BLE_TEST_UPDATA);
|
||||
update_mode_api_v2(BLE_TEST_UPDATA,
|
||||
testbox_ble_update_private_param_fill,
|
||||
testbox_ble_update_before_jump_handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void testbox_update_msg_handle(int msg)
|
||||
{
|
||||
log_info("msg:%x\n", msg);
|
||||
|
||||
switch (msg) {
|
||||
case MSG_BT_UPDATE_LOADER_DOWNLOAD_START:
|
||||
if (UPDATE_MODULE_IS_SUPPORT(UPDATE_BT_LMP_EN)) {
|
||||
#if (SMART_BOX_EN) && (CONFIG_WATCH_CASE_ENABLE)
|
||||
app_smartbox_task_prepare(0, SMARTBOX_TASK_ACTION_WATCH_TRANSFER, 0);
|
||||
#endif
|
||||
update_mode_info_t info = {
|
||||
.type = BT_UPDATA,
|
||||
.state_cbk = testbox_bt_classic_update_state_cbk,
|
||||
.p_op_api = &lmp_ch_update_op,
|
||||
.task_en = 1,
|
||||
};
|
||||
app_active_update_task_init(&info);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START:
|
||||
if (UPDATE_MODULE_IS_SUPPORT(UPDATE_BLE_TEST_EN)) {
|
||||
update_mode_info_t info = {
|
||||
.type = BLE_TEST_UPDATA,
|
||||
.state_cbk = testbox_ble_update_state_cbk,
|
||||
.p_op_api = &ble_ll_ch_update_op,
|
||||
.task_en = 1,
|
||||
};
|
||||
app_active_update_task_init(&info);
|
||||
}
|
||||
break;
|
||||
|
||||
defaut:
|
||||
log_error("not support update msg:%x\n", msg);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testbox_update_init(void)
|
||||
{
|
||||
if (UPDATE_MODULE_IS_SUPPORT(UPDATE_BLE_TEST_EN) || UPDATE_MODULE_IS_SUPPORT(UPDATE_BT_LMP_EN)) {
|
||||
log_info("testbox msg handle reg:%x\n", testbox_update_msg_handle);
|
||||
btctrler_testbox_update_msg_handle_register(testbox_update_msg_handle);
|
||||
}
|
||||
}
|
||||
|
||||
575
apps/common/update/update.c
Normal file
575
apps/common/update/update.c
Normal file
@ -0,0 +1,575 @@
|
||||
#include "update.h"
|
||||
#include "update_loader_download.h"
|
||||
#include "asm/crc16.h"
|
||||
#include "asm/wdt.h"
|
||||
#include "os/os_api.h"
|
||||
#include "app_config.h"
|
||||
#include "cpu.h"
|
||||
#include "syscfg_id.h"
|
||||
#include "btcontroller_modules.h"
|
||||
#include "system/includes.h"
|
||||
#include "uart_update.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
|
||||
#if TCFG_UI_ENABLE
|
||||
#include "ui/ui_api.h"
|
||||
#endif
|
||||
|
||||
#if RCSP_BTMATE_EN
|
||||
#include "rcsp_user_update.h"
|
||||
#elif RCSP_ADV_EN
|
||||
#include "rcsp_adv_user_update.h"
|
||||
#endif
|
||||
|
||||
#ifdef UPDATE_VOICE_REMIND
|
||||
#include "tone_player.h"
|
||||
#include "audio_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef UPDATE_LED_REMIND
|
||||
#include "asm/pwm_led.h"
|
||||
#endif
|
||||
|
||||
#include "custom_cfg.h"
|
||||
|
||||
#define LOG_TAG "[APP-UPDATE]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#define LOG_ERROR_ENABLE
|
||||
#include "system/debug.h"
|
||||
|
||||
#if (JL_SMART_BOX_EXTRA_FLASH_OPT)
|
||||
#include "smartbox_extra_flash_opt.h"
|
||||
#endif
|
||||
|
||||
#define LOADER_NAME "LOADER.BIN"
|
||||
#define DEVICE_UPDATE_KEY_ERR BIT(30)
|
||||
#define DEVICE_FIRST_START BIT(31)
|
||||
|
||||
extern void update_module_init(void (*cbk)(update_mode_info_t *, u32, void *));
|
||||
extern void testbox_update_init(void);
|
||||
extern void ll_hci_destory(void);
|
||||
extern void hci_controller_destory(void);
|
||||
extern const int support_norflash_update_en;
|
||||
extern void ram_protect_close(void);
|
||||
extern void hwi_all_close(void);
|
||||
extern void wifi_det_close();
|
||||
|
||||
__attribute__((weak))
|
||||
void wifi_det_close()
|
||||
{
|
||||
printf("tmp weak func wifi_det_close\n");
|
||||
}
|
||||
extern void *dev_update_get_parm(int type);
|
||||
extern u8 get_ota_status();
|
||||
extern int get_nor_update_param(void *buf);
|
||||
extern bool get_tws_phone_connect_state(void);
|
||||
extern void tws_sniff_controle_check_disable(void);
|
||||
extern void tws_tx_unsniff_req(void);
|
||||
extern void sys_auto_sniff_controle(u8 enable, u8 *addr);
|
||||
extern void app_audio_set_wt_volume(s16 volume);
|
||||
extern u8 get_max_sys_vol(void);
|
||||
extern u8 get_ldo_trim_res(u8 *res);
|
||||
|
||||
|
||||
#ifdef DEV_UPDATE_SUPPORT_JUMP
|
||||
extern void __JUMP_TO_MASKROM();
|
||||
extern void save_spi_port();
|
||||
extern s32 sd1_unmount(void);
|
||||
extern void usb_sie_close_all(void);
|
||||
#endif //endif DEV_UPDATE_SUPPORT_JUMP
|
||||
|
||||
extern const int support_norflash_update_en;
|
||||
const u8 loader_file_path[] = "mnt/norflash/C/"LOADER_NAME"";
|
||||
//升级文件路径必须是短文件名(8+3)结构,仅支持2层目录
|
||||
/* const char updata_file_name[] = "/UPDATA/JL_692X.BFU"; */
|
||||
const char updata_file_name[] = "/*.UFW";
|
||||
static u32 g_updata_flag = 0;
|
||||
static volatile u8 ota_status = 0;
|
||||
static succ_report_t succ_report;
|
||||
|
||||
u16 update_result_get(void)
|
||||
{
|
||||
u16 ret = UPDATA_NON;
|
||||
|
||||
if (!UPDATE_SUPPORT_DEV_IS_NULL()) {
|
||||
UPDATA_PARM *p = UPDATA_FLAG_ADDR;
|
||||
u16 crc_cal;
|
||||
crc_cal = CRC16(((u8 *)p) + 2, sizeof(UPDATA_PARM) - 2); //2 : crc_val
|
||||
if (crc_cal && crc_cal == p->parm_crc) {
|
||||
ret = p->parm_result;
|
||||
}
|
||||
g_updata_flag = ret;
|
||||
g_updata_flag |= ((u32)(p->magic)) << 16;
|
||||
|
||||
memset(p, 0x00, sizeof(UPDATA_PARM));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void update_result_set(u16 result)
|
||||
{
|
||||
if (!UPDATE_SUPPORT_DEV_IS_NULL()) {
|
||||
UPDATA_PARM *p = UPDATA_FLAG_ADDR;
|
||||
|
||||
memset(p, 0x00, sizeof(UPDATA_PARM));
|
||||
p->parm_result = result;
|
||||
p->parm_crc = CRC16(((u8 *)p) + 2, sizeof(UPDATA_PARM) - 2);
|
||||
}
|
||||
#if (RCSP_UPDATE_EN && SMART_BOX_EN && JL_SMART_BOX_EXTRA_FLASH_OPT)
|
||||
if (UPDATA_SUCC == result) {
|
||||
smartbox_eflash_update_flag_set(0);
|
||||
smartbox_eflash_flag_set(0);
|
||||
extern void set_update_ex_flash_flag(u8 update_flag);
|
||||
set_update_ex_flash_flag(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void update_clear_result()
|
||||
{
|
||||
g_updata_flag = 0;
|
||||
}
|
||||
|
||||
bool update_success_boot_check(void)
|
||||
{
|
||||
if (!UPDATE_SUPPORT_DEV_IS_NULL()) {
|
||||
u16 result = g_updata_flag & 0xffff;
|
||||
u16 up_tpye = g_updata_flag >> 16;
|
||||
if ((UPDATA_SUCC == result) && ((SD0_UPDATA == up_tpye) || (SD1_UPDATA == up_tpye) || (USB_UPDATA == up_tpye))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool device_is_first_start()
|
||||
{
|
||||
log_info("g_updata_flag=0x%x\n", g_updata_flag);
|
||||
if ((g_updata_flag & DEVICE_FIRST_START) || (g_updata_flag & DEVICE_UPDATE_KEY_ERR) || (g_updata_flag == UPDATA_SUCC)) {
|
||||
puts("\n=================device_is_first_start=========================\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void led_update_start(void)
|
||||
{
|
||||
#ifdef UPDATE_LED_REMIND
|
||||
puts("led_update_start\n");
|
||||
pwm_led_mode_set(PWM_LED_ALL_OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void led_update_finish(void)
|
||||
{
|
||||
#ifdef UPDATE_LED_REMIND
|
||||
puts("led_update_finish\n");
|
||||
pwm_led_mode_set(PWM_LED0_LED1_FAST_FLASH);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void dev_update_close_ui()
|
||||
{
|
||||
|
||||
#if (TCFG_UI_ENABLE&&(CONFIG_UI_STYLE == STYLE_JL_LED7))
|
||||
u8 count = 0;
|
||||
UI_SHOW_WINDOW(ID_WINDOW_POWER_OFF);
|
||||
__retry:
|
||||
if (UI_GET_WINDOW_ID() != ID_WINDOW_POWER_OFF) {
|
||||
/* os_time_dly(10);//增加延时防止没有关显示,由于此处关了中断,不能用os接口 */
|
||||
delay_2ms(50);//增加延时防止没有关显示
|
||||
count++;
|
||||
if (count < 3) {
|
||||
goto __retry;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef UPDATE_VOICE_REMIND
|
||||
void update_tone_event_clear()
|
||||
{
|
||||
struct sys_event e = {0};
|
||||
e.type = SYS_DEVICE_EVENT;
|
||||
e.arg = (void *)DEVICE_EVENT_FROM_TONE;
|
||||
sys_event_clear(&e);
|
||||
}
|
||||
#endif
|
||||
|
||||
int update_result_deal()
|
||||
{
|
||||
#ifdef CONFIG_FPGA_ENABLE
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
u8 key_voice_cnt = 0;
|
||||
u16 result = 0;
|
||||
result = (g_updata_flag & 0xffff);
|
||||
log_info("<--------update_result_deal=0x%x %x--------->\n", result, g_updata_flag >> 16);
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#if TCFG_APP_BT_EN
|
||||
u8 check_update_param_len(void);
|
||||
ASSERT(check_update_param_len(), "UPDATE_PARAM_LEN ERROR");
|
||||
#endif
|
||||
#endif
|
||||
if (result == UPDATA_NON || 0 == result) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef UPDATE_VOICE_REMIND
|
||||
#endif
|
||||
if (result == UPDATA_SUCC) {
|
||||
#if(JL_EARPHONE_APP_EN && RCSP_UPDATE_EN)
|
||||
u8 clear_update_flag = 0;
|
||||
syscfg_write(VM_UPDATE_FLAG, &clear_update_flag, 1);
|
||||
#endif
|
||||
#ifdef UPDATE_LED_REMIND
|
||||
led_update_finish();
|
||||
#endif
|
||||
}
|
||||
|
||||
int voice_max_cnt = 5;
|
||||
while (1) {
|
||||
wdt_clear();
|
||||
key_voice_cnt++;
|
||||
#ifdef UPDATE_VOICE_REMIND
|
||||
if (result == UPDATA_SUCC) {
|
||||
puts("<<<<<<UPDATA_SUCC");
|
||||
app_audio_set_volume(APP_AUDIO_STATE_WTONE, get_max_sys_vol() / 2, 1);
|
||||
tone_play(TONE_SIN_NORMAL, 1);
|
||||
os_time_dly(25);
|
||||
puts(">>>>>>>>>>>\n");
|
||||
update_tone_event_clear();
|
||||
} else {
|
||||
voice_max_cnt = 20; //区分下升级失败提示音
|
||||
log_info("!!!!!!!!!!!!!!!updata waring !!!!!!!!!!!=0x%x\n", result);
|
||||
app_audio_set_volume(APP_AUDIO_STATE_WTONE, get_max_sys_vol(), 1);
|
||||
tone_play(TONE_SIN_NORMAL, 1);
|
||||
os_time_dly(10);
|
||||
update_tone_event_clear();
|
||||
}
|
||||
#endif
|
||||
if (key_voice_cnt > voice_max_cnt) {
|
||||
key_voice_cnt = 0;
|
||||
puts("enter_sys_soft_poweroff\n");
|
||||
break;
|
||||
//注:关机要慎重,要设置开机键
|
||||
//enter_sys_soft_poweroff();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void clr_update_ram_info(void)
|
||||
{
|
||||
UPDATA_PARM *p = UPDATA_FLAG_ADDR;
|
||||
memset(p, 0x00, sizeof(UPDATA_PARM));
|
||||
}
|
||||
|
||||
void update_close_hw(void *filter_name)
|
||||
{
|
||||
const struct update_target *p;
|
||||
list_for_each_update_target(p) {
|
||||
if (memcmp(filter_name, p->name, strlen(filter_name)) != 0) {
|
||||
printf("close Hw Name : %s\n", p->name);
|
||||
p->driver_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_before_jump_common_handle(UPDATA_TYPE up_type)
|
||||
{
|
||||
dev_update_close_ui();
|
||||
|
||||
#if TCFG_AUDIO_ANC_ENABLE
|
||||
extern void audio_anc_hw_close();
|
||||
audio_anc_hw_close();
|
||||
#endif
|
||||
|
||||
#if (CPU_CORE_NUM == 1) //双核在跳转前关中断lock_set后会和maskrom 初始化中断冲突导致ilock err
|
||||
local_irq_disable();
|
||||
#endif
|
||||
|
||||
hwi_all_close();
|
||||
|
||||
#ifdef CONFIG_SUPPORT_WIFI_DETECT
|
||||
wifi_det_close();
|
||||
#endif
|
||||
/*跳转的时候遇到死掉的情况很可能是硬件模块没关导致,加上保护可以判断哪个异常,保护的地址根据不同SDK而定*/
|
||||
/* u8 inv = 0; */
|
||||
/* mpu_set(1, (u32)&test_pro_addr, (u32)test_pro_addr, inv, "0r", DBG_FM); */
|
||||
}
|
||||
|
||||
//ota.bin 放到exflash升级的方式,parm_priv存放了norflash的参数,对应实际升级方式的参数需要放在norflash参数之后
|
||||
void update_param_priv_fill(UPDATA_PARM *p, void *priv, u16 priv_len)
|
||||
{
|
||||
int parm_offset = 0;
|
||||
if (support_norflash_update_en) {
|
||||
parm_offset = get_nor_update_param(p->parm_priv); //如果loader放在外挂norflash,parm_priv前面放norflash参数,后面才是升级类型本身的参数
|
||||
}
|
||||
memcpy(p->parm_priv + parm_offset, priv, priv_len);
|
||||
}
|
||||
|
||||
void update_param_ext_fill(UPDATA_PARM *p, u8 ext_type, u8 *ext_data, u8 ext_len)
|
||||
{
|
||||
struct ext_arg_t ext_arg;
|
||||
|
||||
ext_arg.type = ext_type;
|
||||
ext_arg.len = ext_len;
|
||||
ext_arg.data = ext_data;
|
||||
|
||||
memcpy((u8 *)p + sizeof(UPDATA_PARM) + p->ext_arg_len, &ext_arg, 2); //2byte:type + len
|
||||
memcpy((u8 *)p + sizeof(UPDATA_PARM) + p->ext_arg_len + 2, ext_arg.data, ext_arg.len);
|
||||
log_info("ext_fill :");
|
||||
log_info_hexdump((u8 *)p + sizeof(UPDATA_PARM) + p->ext_arg_len, ext_arg.len + 2);
|
||||
p->ext_arg_len += (2 + ext_arg.len);
|
||||
p->ext_arg_crc = CRC16((u8 *)p + sizeof(UPDATA_PARM), p->ext_arg_len);
|
||||
}
|
||||
|
||||
//fill common content \ private content \ crc16
|
||||
static void update_param_content_fill(int type, UPDATA_PARM *p, void (*priv_param_fill_hdl)(UPDATA_PARM *P))
|
||||
{
|
||||
u8 ext_len = 0;
|
||||
u8 *ext_data = NULL;
|
||||
|
||||
memset((u8 *)p, 0x00, sizeof(UPDATA_PARM));
|
||||
|
||||
if (support_norflash_update_en) {
|
||||
p->parm_type = NORFLASH_UPDATA; //uboot通过该标识从外挂flash读取ota.bin
|
||||
*((u16 *)((u8 *)p + sizeof(UPDATA_PARM) + 32)) = (u16)type; //将实际的升级类型保存到UPDATA_PARM后
|
||||
} else {
|
||||
p->parm_type = (u16)type;
|
||||
}
|
||||
|
||||
p->parm_result = (u16)UPDATA_READY;
|
||||
p->magic = UPDATE_PARAM_MAGIC;
|
||||
p->ota_addr = succ_report.loader_saddr;
|
||||
|
||||
//支持loader放到外挂flash里ota_addr为0
|
||||
if (0 == p->ota_addr && !support_norflash_update_en) {
|
||||
log_error("ota addr err\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv_param_fill_hdl) {
|
||||
priv_param_fill_hdl(p);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_BR23
|
||||
#if TCFG_APP_BT_EN
|
||||
if (type == BT_UPDATA || type == BLE_APP_UPDATA || type == SPP_APP_UPDATA || type == BLE_TEST_UPDATA) { //D版芯片蓝牙相关的升级需要保存LDO_TRIM_RES
|
||||
ext_data = malloc(128);
|
||||
if (ext_data != NULL) {
|
||||
ext_len = get_ldo_trim_res(ext_data);
|
||||
update_param_ext_fill(p, EXT_LDO_TRIM_RES, ext_data, ext_len);
|
||||
free(ext_data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
u8 ext_flag = 0;
|
||||
ext_len = 1;
|
||||
#if CONFIG_UPDATE_JUMP_TO_MASK
|
||||
ext_flag = 1;
|
||||
#endif
|
||||
update_param_ext_fill(p, EXT_JUMP_FLAG, &ext_flag, ext_len);
|
||||
/* u8 *flag = update_param_ext_get(p, EXT_JUMP_FLAG); */
|
||||
/* r_printf(">>>[test]:flag = %d\n", flag[0]); */
|
||||
|
||||
|
||||
p->parm_crc = CRC16(((u8 *)p) + 2, sizeof(UPDATA_PARM) - 2); //2 : crc_val
|
||||
}
|
||||
|
||||
static void update_param_ram_set(u8 *buf, u16 len)
|
||||
{
|
||||
u8 *update_ram = UPDATA_FLAG_ADDR;
|
||||
memcpy(update_ram, (u8 *)buf, len);
|
||||
}
|
||||
|
||||
void update_mode_api_v2(UPDATA_TYPE type, void (*priv_param_fill_hdl)(UPDATA_PARM *p), void (*priv_update_jump_handle)(int type))
|
||||
{
|
||||
u16 update_param_len = sizeof(UPDATA_PARM) + UPDATE_PRIV_PARAM_LEN;
|
||||
|
||||
UPDATA_PARM *p = malloc(update_param_len);
|
||||
|
||||
if (p) {
|
||||
update_param_content_fill(type, p, priv_param_fill_hdl);
|
||||
|
||||
if (succ_report.update_param_write_hdl) {
|
||||
succ_report.update_param_write_hdl(succ_report.priv_param, (u8 *)p, update_param_len);
|
||||
}
|
||||
|
||||
//临时修改,升级不能跑太快的时钟,否则升级失败
|
||||
clk_set("sys", 48000000);
|
||||
|
||||
#ifdef UPDATE_LED_REMIND
|
||||
led_update_start();
|
||||
#endif
|
||||
|
||||
update_param_ram_set((u8 *)p, update_param_len);
|
||||
|
||||
#if CPU_CORE_NUM > 1 //双核需要把CPU1关掉
|
||||
printf("Before Suspend Current Cpu ID:%d Cpu In Irq?:%d\n", current_cpu_id(), cpu_in_irq());
|
||||
if (current_cpu_id() == 1) {
|
||||
os_suspend_other_core();
|
||||
}
|
||||
ASSERT(current_cpu_id() == 0); //确保跳转前CPU1已经停止运行
|
||||
cpu_suspend_other_core(0x55);
|
||||
extern void cpu1_power_off(void);
|
||||
cpu1_power_off();
|
||||
printf("After Suspend Current Cpu ID:%d\n", current_cpu_id());
|
||||
#endif
|
||||
update_before_jump_common_handle(type);
|
||||
|
||||
if (priv_update_jump_handle) {
|
||||
priv_update_jump_handle(type);
|
||||
}
|
||||
free(p);
|
||||
} else {
|
||||
ASSERT(p, "malloc update param err \n");
|
||||
}
|
||||
}
|
||||
|
||||
int update_check_sniff_en(void)
|
||||
|
||||
{
|
||||
if (!UPDATE_SUPPORT_DEV_IS_NULL()) {
|
||||
if (get_ota_status()) {
|
||||
log_info("ota ing...");
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void set_ota_status(u8 stu)
|
||||
{
|
||||
ota_status = stu;
|
||||
}
|
||||
|
||||
u8 get_ota_status()
|
||||
{
|
||||
return ota_status;
|
||||
}
|
||||
|
||||
static u8 ota_idle_query(void)
|
||||
{
|
||||
return !ota_status;
|
||||
}
|
||||
|
||||
//防止升级过程进入powerdown
|
||||
REGISTER_LP_TARGET(ota_lp_target) = {
|
||||
.name = "ota",
|
||||
.is_idle = ota_idle_query,
|
||||
};
|
||||
|
||||
extern void tws_sync_update_api_register(const update_op_tws_api_t *op);
|
||||
extern update_op_tws_api_t *get_tws_update_api(void);
|
||||
|
||||
extern const int support_dual_bank_update_en;
|
||||
extern int tws_ota_init(void);
|
||||
extern void sys_auto_shut_down_disable(void);
|
||||
extern void sys_auto_shut_down_enable(void);
|
||||
extern void tws_api_auto_role_switch_disable();
|
||||
extern void tws_api_auto_role_switch_enable();
|
||||
|
||||
static void update_init_common_handle(int type)
|
||||
{
|
||||
ota_status = 1;
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
#if TCFG_AUTO_SHUT_DOWN_TIME
|
||||
sys_auto_shut_down_disable();
|
||||
#endif
|
||||
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
tws_api_auto_role_switch_disable();
|
||||
tws_sync_update_api_register(get_tws_update_api());
|
||||
tws_ota_init();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void update_exit_common_handle(int type, void *priv)
|
||||
{
|
||||
update_ret_code_t *ret_code = (update_ret_code_t *)priv;
|
||||
|
||||
#if TCFG_AUTO_SHUT_DOWN_TIME
|
||||
sys_auto_shut_down_enable();
|
||||
#endif
|
||||
|
||||
#if OTA_TWS_SAME_TIME_ENABLE
|
||||
if (UPDATE_DUAL_BANK_IS_SUPPORT()) {
|
||||
tws_api_auto_role_switch_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
ota_status = 0;
|
||||
}
|
||||
|
||||
static void update_common_state_cbk(update_mode_info_t *info, u32 state, void *priv)
|
||||
{
|
||||
int type = info->type;
|
||||
|
||||
log_info("type:%x state:%x code:%x\n", type, state, priv);
|
||||
|
||||
switch (state) {
|
||||
case UPDATE_CH_INIT:
|
||||
memset((u8 *)&succ_report, 0x00, sizeof(succ_report_t));
|
||||
update_init_common_handle(info->type);
|
||||
break;
|
||||
|
||||
case UPDATE_CH_SUCESS_REPORT:
|
||||
log_info("succ report stored\n");
|
||||
memcpy((u8 *)&succ_report, (u8 *)priv, sizeof(succ_report_t));
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->state_cbk) {
|
||||
info->state_cbk(type, state, priv);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case UPDATE_CH_EXIT:
|
||||
update_exit_common_handle(info->type, priv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int app_update_init(void)
|
||||
{
|
||||
update_module_init(update_common_state_cbk);
|
||||
testbox_update_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(app_update_init);
|
||||
|
||||
|
||||
void update_start_exit_sniff(void)
|
||||
{
|
||||
#if TCFG_USER_TWS_ENABLE
|
||||
volatile u8 wait_tws_sniff_exit = 1;
|
||||
if (get_tws_phone_connect_state() == TRUE) {
|
||||
g_printf("exit sniff mode...\n");
|
||||
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
|
||||
} else {
|
||||
tws_tx_unsniff_req();
|
||||
}
|
||||
tws_sniff_controle_check_disable();
|
||||
#else
|
||||
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
|
||||
#endif
|
||||
sys_auto_sniff_controle(0, NULL);
|
||||
}
|
||||
|
||||
void update_param_boot_ram_set(u8 *buf, u16 len)
|
||||
{
|
||||
u8 *boot_ram = (u8 *)BOOT_STATUS_ADDR;
|
||||
memcpy(boot_ram, (u8 *)buf, len);
|
||||
}
|
||||
|
||||
|
||||
763
apps/common/update/update_tws.c
Normal file
763
apps/common/update/update_tws.c
Normal file
@ -0,0 +1,763 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "generic/lbuf.h"
|
||||
#include "init.h"
|
||||
#include "update_tws.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "bt_tws.h"
|
||||
#include "app_config.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "update.h"
|
||||
#include "app_main.h"
|
||||
|
||||
#if (OTA_TWS_SAME_TIME_ENABLE && !OTA_TWS_SAME_TIME_NEW)
|
||||
|
||||
//#define LOG_TAG_CONST EARPHONE
|
||||
#define LOG_TAG "[UPDATE_TWS]"
|
||||
#define log_errorOR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define THIS_TASK_NAME "tws_ota"
|
||||
#define SLAVE_REV_BUF_LEN 1024*2
|
||||
|
||||
extern void sys_enter_soft_poweroff(void *priv);
|
||||
|
||||
void db_update_notify_fail_to_phone();
|
||||
|
||||
struct __tws_ota_var {
|
||||
OS_SEM master_sem;
|
||||
OS_SEM slave_sem;
|
||||
OS_SEM confirm_sem;
|
||||
struct __tws_ota_para para;
|
||||
u8 ota_type;
|
||||
u8 ota_status;
|
||||
u8 ota_remote_status;
|
||||
u8 ota_result;
|
||||
volatile u32 ota_data_len;
|
||||
u16 ota_timer_id;
|
||||
u8 ota_verify_cnt;
|
||||
volatile u32 ota_confirm;
|
||||
cbuffer_t cbuffer;
|
||||
u8 *slave_r_buf;
|
||||
};
|
||||
struct __tws_ota_var tws_ota_var;
|
||||
#define __this (&tws_ota_var)
|
||||
|
||||
void tws_ota_event_post(u32 type, u8 event)
|
||||
{
|
||||
struct sys_event e;
|
||||
e.type = SYS_BT_EVENT;
|
||||
e.arg = (void *)type;
|
||||
e.u.bt.event = event;
|
||||
sys_event_notify(&e);
|
||||
}
|
||||
|
||||
u8 tws_ota_control(int type, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
int role = 0;
|
||||
int value = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, type);
|
||||
|
||||
switch (type) {
|
||||
case OTA_TYPE_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_type = value;
|
||||
break;
|
||||
case OTA_TYPE_GET:
|
||||
ret = __this->ota_type;
|
||||
break;
|
||||
case OTA_STATUS_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_status = value;
|
||||
break;
|
||||
case OTA_STATUS_GET:
|
||||
ret = __this->ota_status;
|
||||
break;
|
||||
case OTA_REMOTE_STATUS_SET:
|
||||
value = va_arg(argptr, int);
|
||||
__this->ota_remote_status = value;
|
||||
break;
|
||||
case OTA_REMOTE_STATUS_GET:
|
||||
ret = __this->ota_remote_status;
|
||||
break;
|
||||
case OTA_RESULT_SET:
|
||||
value = va_arg(argptr, int);
|
||||
role = va_arg(argptr, int);
|
||||
if (value == 1) {
|
||||
__this->ota_result |= BIT(role);
|
||||
} else {
|
||||
__this->ota_result &= ~BIT(role);
|
||||
}
|
||||
break;
|
||||
case OTA_RESULT_GET:
|
||||
ret = __this->ota_result;
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_init(void)
|
||||
{
|
||||
tws_api_auto_role_switch_disable();
|
||||
memset((u8 *)__this, 0, sizeof(struct __tws_ota_var));
|
||||
__this->ota_status = OTA_INIT;
|
||||
__this->ota_type = OTA_TWS;
|
||||
|
||||
if (a2dp_get_status() == BT_MUSIC_STATUS_STARTING) {
|
||||
/* log_info("try pause a2dp music"); */
|
||||
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_PAUSE, 0, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TWS_FUNC_ID_OTA_SYNC TWS_FUNC_ID('O', 'T', 'A', 'S')
|
||||
static void tws_ota_data_read_s_from_m(void *_data, u16 len, bool rx)
|
||||
{
|
||||
if (rx && __this->ota_status == OTA_START && __this->slave_r_buf) {
|
||||
/* r_log_info("Offset:%x r_len:%d\n",__this->ota_data_len,len); */
|
||||
/* put_buf(_data, len); */
|
||||
__this->ota_data_len += len;
|
||||
if (cbuf_is_write_able(&(__this->cbuffer), len)) {
|
||||
cbuf_write(&(__this->cbuffer), _data, len);
|
||||
} else {
|
||||
log_info("ota cbuf write err\n");
|
||||
}
|
||||
os_sem_post(&__this->slave_sem);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(app_ota_sync_stub) = {
|
||||
.func_id = TWS_FUNC_ID_OTA_SYNC,
|
||||
.func = tws_ota_data_read_s_from_m,
|
||||
};
|
||||
|
||||
int tws_ota_data_send_m_to_s(u8 *buf, u16 len)
|
||||
{
|
||||
if (!(tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = tws_api_send_data_to_slave(buf, len, TWS_FUNC_ID_OTA_SYNC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_err_callback(u8 reason)
|
||||
{
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tws_ota_update_loop(void *priv)
|
||||
{
|
||||
u32 total_len = 0;
|
||||
u32 len = 0;
|
||||
u8 *tmp_buf = NULL;
|
||||
int ret = 0;
|
||||
|
||||
u8 sniff_wait_exit_timeout = 30;//3s
|
||||
|
||||
log_info("tws_ota_update_loop\n");
|
||||
|
||||
while (1) {
|
||||
os_sem_pend(&__this->slave_sem, 0);
|
||||
|
||||
if (sniff_wait_exit_timeout) {
|
||||
//wait slave exit sniff
|
||||
extern u8 btstcak_get_bt_mode(void);
|
||||
while (btstcak_get_bt_mode() && sniff_wait_exit_timeout--) {
|
||||
log_info("wait sniff exit \n");
|
||||
os_time_dly(10);
|
||||
}
|
||||
log_info(">>>>>>>sniff timeout:%d \n", sniff_wait_exit_timeout);
|
||||
|
||||
if (!sniff_wait_exit_timeout) {
|
||||
log_info(">>>>>>wait sniff exit timeout !!!! \n");
|
||||
}
|
||||
sniff_wait_exit_timeout = 0;
|
||||
dual_bank_passive_update_init(__this->para.fm_crc16, __this->para.fm_size, __this->para.max_pkt_len, NULL);
|
||||
ret = dual_bank_update_allow_check(__this->para.fm_size);
|
||||
if (ret) {
|
||||
log_info("fm_size:%x can't update\n", __this->para.fm_size);
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
continue;
|
||||
}
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_UPDATE, 400);
|
||||
continue;
|
||||
}
|
||||
|
||||
total_len = cbuf_get_data_size(&(__this->cbuffer));
|
||||
/* log_info("total_len : %d\n",total_len); */
|
||||
while (total_len) {
|
||||
if (total_len > get_dual_bank_passive_update_max_buf()) {
|
||||
len = get_dual_bank_passive_update_max_buf();
|
||||
} else {
|
||||
len = total_len;
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
continue;
|
||||
}
|
||||
tmp_buf = malloc(len);
|
||||
if (tmp_buf) {
|
||||
if (cbuf_read(&(__this->cbuffer), tmp_buf, len) == len) {
|
||||
putchar('D');
|
||||
dual_bank_update_write(tmp_buf, len, NULL);
|
||||
} else {
|
||||
log_error("read err\n");
|
||||
}
|
||||
free(tmp_buf);
|
||||
} else {
|
||||
log_error("malloc err\n");
|
||||
}
|
||||
total_len -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ota_finish_confirm(void *priv)
|
||||
{
|
||||
log_info("ota_finish_confirm:%d\n", __this->ota_confirm);
|
||||
if (!__this->ota_confirm) {
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
}
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_SUCC);
|
||||
|
||||
}
|
||||
|
||||
u16 tws_ota_enter_verify(void *priv)
|
||||
{
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn in verify\n");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_VERIFY, NULL, 0);
|
||||
os_sem_pend(&__this->master_sem, 1000);
|
||||
//这里pend完,要做超时的准备
|
||||
if (__this->ota_status == OTA_VERIFY_ING) {
|
||||
return 0;
|
||||
} else {
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
u16 tws_ota_exit_verify(u8 *res, u8 *up_flg)
|
||||
{
|
||||
//not updata boot info in lib
|
||||
*up_flg = 1;
|
||||
|
||||
u8 tws_ota_result[2];
|
||||
u8 master_result = *res;
|
||||
u8 result = 0;
|
||||
tws_ota_control(OTA_STATUS_SET, OTA_VERIFY_END);
|
||||
tws_ota_control(OTA_RESULT_SET, !master_result, TWS_ROLE_MASTER);
|
||||
__RESTART:
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
db_update_notify_fail_to_phone();
|
||||
return 0;
|
||||
}
|
||||
result = tws_ota_control(OTA_RESULT_GET);
|
||||
tws_ota_result[0] = result;
|
||||
tws_ota_result[1] = tws_ota_control(OTA_STATUS_GET);
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_RESULT_EXCHANGE, (u8 *)&tws_ota_result, 2);
|
||||
|
||||
if ((result & BIT(TWS_ROLE_SLAVE)) && (result & BIT(TWS_ROLE_SLAVE))) {
|
||||
log_info("tws already ota succ1\n");
|
||||
os_sem_set(&__this->master_sem, 0);
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_OVER);
|
||||
return 1;
|
||||
} else if (__this->ota_remote_status == OTA_VERIFY_END || __this->ota_remote_status == OTA_OVER) {
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
return 0;
|
||||
} else {
|
||||
os_sem_pend(&__this->master_sem, 200);
|
||||
goto __RESTART;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
u16 tws_ota_updata_boot_info_over(void *priv)
|
||||
{
|
||||
log_info("master update_burn_boot_info succ\n");
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn, ota open fail");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//等待从机更新完成
|
||||
log_info("1------pend in");
|
||||
os_sem_pend(&__this->confirm_sem, 300);
|
||||
log_info("1------pend out");
|
||||
|
||||
log_info("-------mz01");
|
||||
if (__this->ota_confirm) {
|
||||
log_info("-------mz02");
|
||||
os_sem_set(&__this->confirm_sem, 0);
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM_REQ, NULL, 0);
|
||||
log_info("2------pend in");
|
||||
if (OS_TIMEOUT == os_sem_pend(&__this->confirm_sem, 300)) {
|
||||
__this->ota_confirm = 0;
|
||||
}
|
||||
log_info("2------pend out");
|
||||
}
|
||||
|
||||
if (!__this->ota_confirm) {
|
||||
log_info("-------mz03");
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
return -1;
|
||||
}
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_UPDATE_SUCC); //主机等手机发重启命令*/
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int tws_ota_open(struct __tws_ota_para *para)
|
||||
{
|
||||
int ret = 0;
|
||||
log_info("tws_ota_open\n");
|
||||
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn, ota open fail");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_sem_create(&__this->master_sem, 0);
|
||||
os_sem_create(&__this->slave_sem, 0);
|
||||
os_sem_create(&__this->confirm_sem, 0);
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
extern void bt_check_exit_sniff();
|
||||
bt_check_exit_sniff();
|
||||
//master 发命令给slave启动升级
|
||||
|
||||
|
||||
log_info("master updata info: crc16:%x size:%x max_pkt_len:%d\n", para->fm_crc16, para->fm_size, para->max_pkt_len);
|
||||
if (__this->ota_type == OTA_TWS) {
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_START, (u8 *)para, sizeof(struct __tws_ota_para));
|
||||
log_info("sem pend in ...");
|
||||
os_sem_pend(&__this->master_sem, 600);
|
||||
log_info("sem pend out ...");
|
||||
//判断对耳状态
|
||||
if (__this->ota_status == OTA_START) {
|
||||
log_info("slave has ready");
|
||||
ret = 0;
|
||||
} else {
|
||||
log_info("slave answer timeout");
|
||||
db_update_notify_fail_to_phone();
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log_info("slave updata info: crc16:%x size:%x max_pkt_len:%d\n", para->fm_crc16, para->fm_size, para->max_pkt_len);
|
||||
|
||||
/* tws_api_sync_call_by_uuid('T', SYNC_CMD_START_UPDATE, 100); */
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_UPDATE_READY);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_close(void)
|
||||
{
|
||||
int ret = 0;
|
||||
log_info("%s", __func__);
|
||||
if (__this->slave_r_buf) {
|
||||
free(__this->slave_r_buf);
|
||||
__this->slave_r_buf = 0;
|
||||
task_kill(THIS_TASK_NAME);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ota_verify_timeout(void *priv)
|
||||
{
|
||||
log_info("ota_verify_timeout:%x %x\n", __this->para.fm_size, __this->ota_data_len);
|
||||
if (__this->ota_data_len == __this->para.fm_size) {
|
||||
/* tws_api_sync_call_by_uuid('T', SYNC_CMD_START_VERIFY, 100); */
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_VERIFY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (__this->ota_verify_cnt > 4) {
|
||||
log_info("code len err\n");
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
__this->ota_verify_cnt ++;
|
||||
__this->ota_timer_id = 0;
|
||||
__this->ota_timer_id = sys_timeout_add(NULL, ota_verify_timeout, 500);
|
||||
}
|
||||
|
||||
int tws_ota_get_data_from_sibling(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
u8 tws_ota_result[2];
|
||||
switch (opcode) {
|
||||
//master->slave
|
||||
case TWS_UPDATE_START:
|
||||
log_info("TWS_AI_START_UPDATE:%d\n", opcode);
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
if (__this->slave_r_buf) {
|
||||
tws_ota_close();
|
||||
}
|
||||
tws_ota_init();
|
||||
memcpy((u8 *) & (__this->para), data, len);
|
||||
tws_ota_open(&(__this->para));
|
||||
}
|
||||
break;
|
||||
|
||||
//master->slave
|
||||
case TWS_UPDATE_RESULT_EXCHANGE:
|
||||
log_info("TWS_UPDATE_RESULT_EXCHANGE:%d %d\n", data[0], data[1]);
|
||||
__this->ota_remote_status = data[1];
|
||||
tws_ota_control(OTA_RESULT_SET, (data[0] & BIT(TWS_ROLE_MASTER) ? 1 : 0), TWS_ROLE_MASTER);
|
||||
|
||||
tws_ota_result[0] = __this->ota_result;
|
||||
tws_ota_result[1] = __this->ota_status;
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_RESULT_EXCHANGE_RES, (u8 *)tws_ota_result, 2);
|
||||
log_info("master ota result:%x %d\n", tws_ota_control(OTA_RESULT_GET), __this->ota_status);
|
||||
break;
|
||||
|
||||
//slave->master
|
||||
case TWS_UPDATE_RESULT_EXCHANGE_RES:
|
||||
log_info("TWS_UPDATE_RESULT_EXCHANGE_RES:%d %d\n", data[0], data[1]);
|
||||
__this->ota_remote_status = data[1];
|
||||
tws_ota_control(OTA_RESULT_SET, (data[0] & BIT(TWS_ROLE_SLAVE) ? 1 : 0), TWS_ROLE_SLAVE);
|
||||
log_info("slave ota result:%x %d\n", tws_ota_control(OTA_RESULT_GET), __this->ota_status);
|
||||
|
||||
if (tws_ota_control(OTA_RESULT_GET) & BIT(TWS_ROLE_SLAVE)) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
}
|
||||
break;
|
||||
|
||||
//master->slave
|
||||
case TWS_UPDATE_VERIFY:
|
||||
log_info("TWS_UPDATE_VERIFY\n");
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_START_VERIFY);
|
||||
break;
|
||||
|
||||
case TWS_UPDATE_OVER:
|
||||
log_info("TWS_AI_UPDATE_OVER:%d\n", opcode);
|
||||
__this->ota_status = OTA_OVER;
|
||||
break;
|
||||
|
||||
//slave to master
|
||||
case TWS_UPDATE_OVER_CONFIRM:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM\n");
|
||||
__this->ota_confirm = 1;
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
log_info("1------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
//master->slave
|
||||
case TWS_UPDATE_OVER_CONFIRM_REQ:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM_REQ\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
__this->ota_confirm = 1;
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM_RES, NULL, 0);
|
||||
log_info("2------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
//slave->master
|
||||
case TWS_UPDATE_OVER_CONFIRM_RES:
|
||||
log_info("TWS_UPDATE_OVER_CONFIRM_RES\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
log_info("3------post");
|
||||
os_sem_post(&__this->confirm_sem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tws_ota_send_data_to_sibling(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
extern void tws_data_to_sibling_send(u8 opcode, u8 * data, u8 len);
|
||||
tws_data_to_sibling_send(opcode, data, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
u8 dual_bank_update_burn_boot_info_callback(u8 ret)
|
||||
{
|
||||
if (ret) {
|
||||
log_info("update_burn_boot_info err\n");
|
||||
} else {
|
||||
log_info("slave update_burn_boot_info succ\n");
|
||||
tws_ota_send_data_to_sibling(TWS_UPDATE_OVER_CONFIRM, NULL, 0);
|
||||
|
||||
//not recive master confirm
|
||||
log_info("3------pend in");
|
||||
os_sem_pend(&__this->confirm_sem, 300);
|
||||
log_info("3------pend out");
|
||||
|
||||
if (!__this->ota_confirm) {
|
||||
//ota tws confirm err,earse boot info
|
||||
flash_update_clr_boot_info(CLEAR_APP_UPDATE_BANK);
|
||||
/* ASSERT(0, "ota tws confirm err\n"); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
//确保从机的回复命令送达到主机
|
||||
os_time_dly(50);
|
||||
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_SUCC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//slave ota result
|
||||
static sint32_t gma_ota_slave_result(int crc_res)
|
||||
{
|
||||
u8 ret = crc_res;
|
||||
|
||||
tws_ota_control(OTA_STATUS_SET, OTA_VERIFY_END);
|
||||
|
||||
tws_ota_control(OTA_RESULT_SET, crc_res, TWS_ROLE_SLAVE);
|
||||
|
||||
log_info("gma_ota_slave_result:%d %d\n", crc_res, tws_ota_control(OTA_STATUS_GET));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_ota_sync_cmd(int reason)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
switch (reason) {
|
||||
//slave request
|
||||
case SYNC_CMD_START_UPDATE:
|
||||
log_info("SYNC_CMD_START_UPDATE\n");
|
||||
|
||||
if (__this->ota_status != OTA_INIT) {
|
||||
log_info("tws ota no init");
|
||||
break;
|
||||
}
|
||||
__this->ota_status = OTA_START;
|
||||
__this->ota_data_len = 0;
|
||||
__this->ota_remote_status = OTA_START;
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
|
||||
//slave request
|
||||
case SYNC_CMD_START_VERIFY:
|
||||
log_info("SYNC_CMD_START_VERIFY\n");
|
||||
__this->ota_status = OTA_VERIFY_ING;
|
||||
__this->ota_remote_status = OTA_VERIFY_ING;
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
os_sem_post(&__this->master_sem);
|
||||
} else {
|
||||
dual_bank_update_verify(NULL, NULL, gma_ota_slave_result);
|
||||
}
|
||||
break;
|
||||
|
||||
//master request
|
||||
case SYNC_CMD_UPDATE_OVER:
|
||||
log_info("SYNC_CMD_UPDATE_OVER\n");
|
||||
|
||||
__this->ota_status = OTA_OVER;
|
||||
__this->ota_remote_status = OTA_OVER;
|
||||
if ((__this->ota_result & BIT(TWS_ROLE_MASTER)) && (__this->ota_result & BIT(TWS_ROLE_SLAVE))) {
|
||||
log_info("OTA SUCCESS\n");
|
||||
//update boot info
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
dual_bank_update_burn_boot_info(dual_bank_update_burn_boot_info_callback);
|
||||
}
|
||||
} else {
|
||||
log_info("OTA ERR\n");
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_UPDATE_SUCC); */
|
||||
}
|
||||
break;
|
||||
|
||||
//slave request
|
||||
case SYNC_CMD_UPDATE_ERR:
|
||||
log_info("SYNC_CMD_UPDATE_ERR\n");
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
} else {
|
||||
tws_ota_stop(OTA_STOP_UPDATE_OVER_ERR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tws_ota_app_event_deal(u8 evevt)
|
||||
{
|
||||
if (__this->ota_status == OTA_OVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (evevt) {
|
||||
case TWS_EVENT_CONNECTION_DETACH:
|
||||
/* case TWS_EVENT_PHONE_LINK_DETACH: */
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
log_info("stop ota : %d --1\n", evevt);
|
||||
tws_ota_stop(OTA_STOP_LINK_DISCONNECT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tws_ota_stop(u8 reason)
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
|
||||
if (__this->ota_status != OTA_OVER) {
|
||||
|
||||
//reconnect hfp when start err
|
||||
if (reason == OTA_STOP_APP_DISCONNECT || reason == OTA_STOP_UPDATE_OVER_ERR) {
|
||||
//在更新信息的时候,手机app断开
|
||||
|
||||
/* if(tws_api_get_role() == TWS_ROLE_MASTER) { */
|
||||
/* extern void user_post_key_msg(u8 user_msg); */
|
||||
/* user_post_key_msg(USER_TWS_OTA_RESUME); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
__this->ota_status = OTA_OVER;
|
||||
if (__this->ota_timer_id) {
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
}
|
||||
|
||||
tws_ota_close();
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
#if RCSP_UPDATE_EN
|
||||
extern void rcsp_db_update_fail_deal(); //双备份升级失败处理
|
||||
rcsp_db_update_fail_deal();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int bt_ota_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (bt->event) {
|
||||
case OTA_START_UPDATE:
|
||||
log_info("OTA_START_UPDATE\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_UPDATE, 400);
|
||||
break;
|
||||
case OTA_START_UPDATE_READY:
|
||||
log_info("OTA_START_UPDATE_READY:%x %x %d\n", __this->para.fm_crc16, __this->para.fm_size, __this->para.max_pkt_len);
|
||||
extern void rcsp_before_enter_db_update_mode();
|
||||
#if(RCSP_UPDATE_EN)
|
||||
rcsp_before_enter_db_update_mode();
|
||||
#endif
|
||||
if (__this->slave_r_buf) {
|
||||
ASSERT(0, "tws_ota_update_loop already exit\n");
|
||||
}
|
||||
task_create(tws_ota_update_loop, NULL, THIS_TASK_NAME);
|
||||
__this->slave_r_buf = malloc(SLAVE_REV_BUF_LEN);
|
||||
ASSERT(__this->slave_r_buf, "slave_r_buf malloc err\n");
|
||||
cbuf_init(&(__this->cbuffer), __this->slave_r_buf, SLAVE_REV_BUF_LEN);
|
||||
|
||||
os_sem_post(&__this->slave_sem);
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS,OTA_START_UPDATE); */
|
||||
break;
|
||||
case OTA_START_VERIFY:
|
||||
log_info("OTA_START_VERIFY\n");
|
||||
if (__this->ota_data_len == __this->para.fm_size) {
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_START_VERIFY, 1000);
|
||||
} else {
|
||||
if (__this->ota_timer_id) {
|
||||
sys_timeout_del(__this->ota_timer_id);
|
||||
__this->ota_timer_id = 0;
|
||||
}
|
||||
__this->ota_timer_id = sys_timeout_add(NULL, ota_verify_timeout, 500);
|
||||
}
|
||||
break;
|
||||
case OTA_UPDATE_OVER:
|
||||
log_info("OTA_UPDATE_OVER\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_OVER, 400);
|
||||
break;
|
||||
case OTA_UPDATE_ERR:
|
||||
log_info("OTA_UPDATE_ERR\n");
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_ERR, 400);
|
||||
break;
|
||||
case OTA_UPDATE_SUCC:
|
||||
log_info("OTA_UPDATE_SUCC\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
|
||||
/* update_result_set(UPDATA_SUCC); */
|
||||
/* extern void cpu_reset(); */
|
||||
/* cpu_reset(); */
|
||||
//user_ctl.shutdown_need_adv = 0;
|
||||
sys_enter_soft_poweroff((void *)1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const update_op_tws_api_t update_tws_api = {
|
||||
.tws_ota_start = tws_ota_open,
|
||||
.tws_ota_data_send = tws_ota_data_send_m_to_s,
|
||||
.tws_ota_err = tws_ota_err_callback,
|
||||
.enter_verfiy_hdl = tws_ota_enter_verify,
|
||||
.exit_verify_hdl = tws_ota_exit_verify,
|
||||
.update_boot_info_hdl = tws_ota_updata_boot_info_over,
|
||||
.tws_ota_result_hdl = NULL,
|
||||
.tws_ota_data_send_pend = NULL,
|
||||
};
|
||||
|
||||
update_op_tws_api_t *get_tws_update_api(void)
|
||||
{
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
|
||||
return &update_tws_api;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rcsp_adv_tws_ota_sync_handler(int reason, int err)
|
||||
{
|
||||
tws_ota_sync_cmd(reason);
|
||||
}
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(rcsp_adv_tws_ota_sync) = {
|
||||
.uuid = 0xA2E22223,
|
||||
.task_name = "app_core",
|
||||
.func = rcsp_adv_tws_ota_sync_handler,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
559
apps/common/update/update_tws_new.c
Normal file
559
apps/common/update/update_tws_new.c
Normal file
@ -0,0 +1,559 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "generic/lbuf.h"
|
||||
#include "init.h"
|
||||
#include "update_tws_new.h"
|
||||
#include "dual_bank_updata_api.h"
|
||||
#include "bt_tws.h"
|
||||
#include "app_config.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "update.h"
|
||||
#include "app_main.h"
|
||||
#include "timer.h"
|
||||
|
||||
#if (OTA_TWS_SAME_TIME_ENABLE && OTA_TWS_SAME_TIME_NEW) //(RCSP_ADV_EN || AI_APP_PROTOCOL))
|
||||
//#define LOG_TAG_CONST EARPHONE
|
||||
#define LOG_TAG "[UPDATE_TWS]"
|
||||
#define log_errorOR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
#define THIS_TASK_NAME "tws_ota"
|
||||
|
||||
OS_SEM tws_ota_sem;
|
||||
int tws_ota_timeout_hdl = 0;
|
||||
static u8 sync_update_sn = 1;
|
||||
|
||||
static void (*user_chip_tws_update_handle)(void *data, u32 len) = NULL;
|
||||
static void (*sync_update_crc_init_hdl)(void) = NULL;
|
||||
static u32(*sync_update_crc_calc_hdl)(u32 init_crc, u8 *data, u32 len) = NULL;
|
||||
|
||||
int clk_set(const char *name, int clk);
|
||||
|
||||
__attribute__((weak))
|
||||
void db_update_notify_fail_to_phone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void tws_sync_update_crc_handler_register(void (*crc_init_hdl)(void), u32(*crc_calc_hdl)(u32 init_crc, u8 *data, u32 len))
|
||||
{
|
||||
sync_update_crc_init_hdl = crc_init_hdl;
|
||||
sync_update_crc_calc_hdl = crc_calc_hdl;
|
||||
printf("sync_update_crc_init_hdl:%x\n sync_update_crc_calc_hdl:%x\n", sync_update_crc_init_hdl, sync_update_crc_calc_hdl);
|
||||
}
|
||||
|
||||
void sys_enter_soft_poweroff(void *priv);
|
||||
int tws_ota_close(void);
|
||||
|
||||
int tws_ota_get_data_from_sibling(u8 opcode, u8 *data, u8 len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tws_ota_timeout(void *priv) //从机没收到命令超时就退出升级
|
||||
{
|
||||
tws_ota_close();
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
}
|
||||
|
||||
void tws_ota_timeout_reset(void)
|
||||
{
|
||||
if (tws_ota_timeout_hdl) {
|
||||
sys_timeout_del(tws_ota_timeout_hdl);
|
||||
}
|
||||
tws_ota_timeout_hdl = sys_timeout_add(NULL, tws_ota_timeout, 8000);
|
||||
}
|
||||
|
||||
void tws_ota_timeout_del(void)
|
||||
{
|
||||
if (tws_ota_timeout_hdl) {
|
||||
sys_timeout_del(tws_ota_timeout_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tws_ota_trans_to_sibling(u8 *data, u16 len)
|
||||
{
|
||||
if (!(tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED)) {
|
||||
return -1;
|
||||
}
|
||||
return tws_api_send_data_to_sibling(data, len, TWS_FUNC_ID_OTA_TRANS);
|
||||
}
|
||||
|
||||
u8 dual_bank_update_burn_boot_info_callback(u8 ret)
|
||||
{
|
||||
u8 rsp_data[3] = {0};
|
||||
rsp_data[0] = OTA_TWS_WRITE_BOOT_INFO_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
printf("sync_sn:%d\n", sync_update_sn);
|
||||
if (ret) {
|
||||
log_info("update_burn_boot_info err\n");
|
||||
rsp_data[2] = OTA_TWS_CMD_ERR;
|
||||
return -1;
|
||||
} else {
|
||||
log_info("slave update_burn_boot_info succ\n");
|
||||
rsp_data[2] = OTA_TWS_CMD_SUCC;
|
||||
//确保从机的回复命令送达到主机
|
||||
/* os_time_dly(50); */
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_SUCC); */
|
||||
}
|
||||
if (tws_ota_trans_to_sibling(rsp_data, 3)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_ota_event_handler(struct bt_event *bt)
|
||||
{
|
||||
int ret = 0;
|
||||
switch (bt->event) {
|
||||
case OTA_START_UPDATE:
|
||||
log_info("OTA_START_UPDATE\n");
|
||||
break;
|
||||
case OTA_START_UPDATE_READY:
|
||||
break;
|
||||
case OTA_START_VERIFY:
|
||||
log_info("OTA_START_VERIFY\n");
|
||||
break;
|
||||
case OTA_UPDATE_OVER:
|
||||
log_info("OTA_UPDATE_OVER\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
cpu_reset();
|
||||
//sys_enter_soft_poweroff((void *)1);
|
||||
break;
|
||||
case OTA_UPDATE_ERR:
|
||||
log_info("OTA_UPDATE_ERR\n");
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
//cpu_reset();
|
||||
//sys_enter_soft_poweroff((void *)1);
|
||||
break;
|
||||
case OTA_UPDATE_SUCC:
|
||||
log_info("OTA_UPDATE_SUCC\n");
|
||||
update_result_set(UPDATA_SUCC);
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
sys_enter_soft_poweroff((void *)1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tws_ota_event_post(u32 type, u8 event)
|
||||
{
|
||||
struct sys_event e;
|
||||
e.type = SYS_BT_EVENT;
|
||||
e.arg = (void *)type;
|
||||
e.u.bt.event = event;
|
||||
sys_event_notify(&e);
|
||||
}
|
||||
|
||||
|
||||
int tws_ota_data_send_m_to_s(u8 *buf, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 retry = 5;
|
||||
os_sem_set(&tws_ota_sem, 0);
|
||||
u8 *data = malloc(len + 2);
|
||||
data[0] = OTA_TWS_TRANS_UPDATE_DATA;
|
||||
data[1] = ++ sync_update_sn;
|
||||
memcpy(&data[2], buf, len);
|
||||
while (retry --) {
|
||||
ret = tws_ota_trans_to_sibling(data, len + 2);
|
||||
if (ret < 0 && ret != -1) {
|
||||
os_time_dly(5);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_ota_data_send_pend(void)
|
||||
{
|
||||
if (os_sem_pend(&tws_ota_sem, 300) == OS_TIMEOUT) { //等待收到从机的RSP
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tws_ota_user_chip_update_send_m_to_s(u8 cmd, u8 *buf, u16 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 retry = 5;
|
||||
u8 *data = malloc(len + 3);
|
||||
data[0] = OTA_TWS_USER_CHIP_UPDATE;
|
||||
data[1] = ++ sync_update_sn;
|
||||
data[2] = cmd;
|
||||
memcpy(&data[3], buf, len);
|
||||
while (retry --) {
|
||||
ret = tws_ota_trans_to_sibling(data, len + 3);
|
||||
if (ret < 0 && ret != -1) {
|
||||
os_time_dly(5);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 tws_ota_enter_verify(void *priv)
|
||||
{
|
||||
u8 rsp_data[2];
|
||||
rsp_data[0] = OTA_TWS_VERIFY;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
printf("tws_ota_enter_verify111\n");
|
||||
os_sem_set(&tws_ota_sem, 0);
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn in verify\n");
|
||||
db_update_notify_fail_to_phone();
|
||||
return -1;
|
||||
}
|
||||
if (tws_ota_trans_to_sibling(&rsp_data, 2)) {
|
||||
return -1;
|
||||
}
|
||||
if (os_sem_pend(&tws_ota_sem, 800) == OS_TIMEOUT) {
|
||||
return -1;
|
||||
}
|
||||
printf("tws_ota_enter_verify222\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
u16 tws_ota_exit_verify(u8 *res, u8 *up_flg)
|
||||
{
|
||||
u8 rsp_data[2];
|
||||
rsp_data[0] = OTA_TWS_WRITE_BOOT_INFO;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
|
||||
*up_flg = 1;
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn exit verify\n");
|
||||
db_update_notify_fail_to_phone();
|
||||
return 0;
|
||||
}
|
||||
if (tws_ota_trans_to_sibling(&rsp_data, 2)) {
|
||||
return 0;
|
||||
}
|
||||
if (os_sem_pend(&tws_ota_sem, 300) == OS_TIMEOUT) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tws_ota_result(u8 result)
|
||||
{
|
||||
if (result == 0) {
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_OVER, 400);
|
||||
} else {
|
||||
tws_api_sync_call_by_uuid(0xA2E22223, SYNC_CMD_UPDATE_ERR, 400);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tws_ota_stop(u8 reason)
|
||||
{
|
||||
log_info("%s", __func__);
|
||||
|
||||
tws_ota_close();
|
||||
dual_bank_passive_update_exit(NULL);
|
||||
#if RCSP_UPDATE_EN
|
||||
extern void rcsp_db_update_fail_deal(); //双备份升级失败处理
|
||||
rcsp_db_update_fail_deal();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tws_ota_app_event_deal(u8 evevt)
|
||||
{
|
||||
switch (evevt) {
|
||||
case TWS_EVENT_CONNECTION_DETACH:
|
||||
/* case TWS_EVENT_PHONE_LINK_DETACH: */
|
||||
case TWS_EVENT_REMOVE_PAIRS:
|
||||
log_info("stop ota : %d --1\n", evevt);
|
||||
tws_ota_stop(OTA_STOP_LINK_DISCONNECT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int tws_ota_init(void)
|
||||
{
|
||||
u8 data;
|
||||
log_info("tws_ota_init\n");
|
||||
tws_api_auto_role_switch_disable();
|
||||
os_sem_create(&tws_ota_sem, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_ota_open(struct __tws_ota_para *para)
|
||||
{
|
||||
int ret = 0;
|
||||
tws_api_auto_role_switch_disable();
|
||||
os_sem_create(&tws_ota_sem, 0);
|
||||
u8 *data = malloc(sizeof(struct __tws_ota_para) + 2);
|
||||
if (!data) {
|
||||
ret = -1;
|
||||
goto _ERR_RET;
|
||||
}
|
||||
log_info("tws_ota_open\n");
|
||||
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_DISCONNECTED) {
|
||||
log_info("tws_disconn, ota open fail");
|
||||
db_update_notify_fail_to_phone();
|
||||
ret = -1;
|
||||
goto _ERR_RET;
|
||||
}
|
||||
|
||||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||||
extern void bt_check_exit_sniff();
|
||||
bt_check_exit_sniff();
|
||||
//master 发命令给slave启动升级
|
||||
}
|
||||
|
||||
log_info("tws_ota_open1\n");
|
||||
data[0] = OTA_TWS_START_UPDATE;
|
||||
data[1] = ++ sync_update_sn;
|
||||
memcpy(data + 2, para, sizeof(struct __tws_ota_para));
|
||||
log_info("tws_ota_open2\n");
|
||||
if (tws_ota_trans_to_sibling(data, sizeof(struct __tws_ota_para) + 2)) {
|
||||
ret = -1;
|
||||
goto _ERR_RET;
|
||||
}
|
||||
if (os_sem_pend(&tws_ota_sem, 500) == OS_TIMEOUT) {
|
||||
log_info("tws_ota_open pend timeout\n");
|
||||
ret = -1;
|
||||
goto _ERR_RET;
|
||||
}
|
||||
printf("tws_ota_open succ...\n");
|
||||
_ERR_RET:
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tws_ota_close(void)
|
||||
{
|
||||
int ret = 0;
|
||||
log_info("%s", __func__);
|
||||
task_kill(THIS_TASK_NAME);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int tws_ota_err_callback(u8 reason)
|
||||
{
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 tws_ota_updata_boot_info_over(void *priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_verify_result_hdl(int calc_crc)
|
||||
{
|
||||
u8 rsp_data[3];
|
||||
printf("tws_verify_result_hdl:%d\n", calc_crc);
|
||||
rsp_data[0] = OTA_TWS_VERIFY_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
if (calc_crc == 1) {
|
||||
rsp_data[2] = OTA_TWS_CMD_SUCC;
|
||||
} else {
|
||||
rsp_data[2] = OTA_TWS_CMD_ERR;
|
||||
}
|
||||
if (tws_ota_trans_to_sibling(rsp_data, 3)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tws_trans_data_write_callback(void *priv)
|
||||
{
|
||||
u8 rsp_data[3];
|
||||
rsp_data[0] = OTA_TWS_TRANS_UPDATE_DATA_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
rsp_data[2] = OTA_TWS_CMD_SUCC;
|
||||
tws_ota_trans_to_sibling(rsp_data, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void deal_sibling_tws_ota_trans(void *data, u16 len, bool rx)
|
||||
{
|
||||
static u8 last_sync_update_sn = 0;
|
||||
int ret = 0;
|
||||
u8 rsp_data[3];
|
||||
u8 *recv_data = (u8 *)data;
|
||||
|
||||
if (rx) {
|
||||
if (recv_data[1] == last_sync_update_sn) { //处理同一包数据会出现两次回调的情况
|
||||
g_printf("recv_data == last_sync_update_sn:%d %d %d\n", recv_data[0], recv_data[1], last_sync_update_sn);
|
||||
return;
|
||||
}
|
||||
|
||||
last_sync_update_sn = recv_data[1];
|
||||
/* log_info(">>>%s\n len:%d", __func__, len); */
|
||||
/* put_buf(data, len); */
|
||||
if (tws_api_get_role() == TWS_ROLE_SLAVE) {
|
||||
tws_ota_timeout_reset(); //从机接收命令超时
|
||||
}
|
||||
switch (recv_data[0]) {
|
||||
case OTA_TWS_START_UPDATE:
|
||||
g_printf("MSG_OTA_TWS_START_UPDATE\n");
|
||||
struct __tws_ota_para para;
|
||||
memcpy(¶, recv_data + 2, sizeof(struct __tws_ota_para));
|
||||
printf("crc:%d fm_size:%d max_pkt_len:%d\n", para.fm_crc, para.fm_size, para.max_pkt_len);
|
||||
dual_bank_passive_update_init(para.fm_crc, para.fm_size, para.max_pkt_len, NULL);
|
||||
ret = dual_bank_update_allow_check(para.fm_size);
|
||||
if (ret) {
|
||||
rsp_data[0] = OTA_TWS_START_UPDATE_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
rsp_data[2] = OTA_TWS_CMD_ERR;
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
} else {
|
||||
rsp_data[0] = OTA_TWS_START_UPDATE_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
rsp_data[2] = OTA_TWS_CMD_SUCC;
|
||||
}
|
||||
tws_ota_trans_to_sibling(rsp_data, 3);
|
||||
break;
|
||||
case OTA_TWS_START_UPDATE_RSP:
|
||||
g_printf("MSG_OTA_TWS_START_UPDATE_RSP\n");
|
||||
if (recv_data[2] == OTA_TWS_CMD_SUCC) {
|
||||
os_sem_post(&tws_ota_sem);
|
||||
}
|
||||
break;
|
||||
case OTA_TWS_TRANS_UPDATE_DATA:
|
||||
printf("MSG_OTA_TWS_TRANS_UPDATE_DATA %d\n", recv_data[1]);
|
||||
dual_bank_update_write(recv_data + 2, len - 2, tws_trans_data_write_callback);
|
||||
break;
|
||||
case OTA_TWS_TRANS_UPDATE_DATA_RSP:
|
||||
printf("MSG_OTA_TWS_TRANS_UPDATE_DATA_RSP:%d\n", recv_data[1]);
|
||||
if (recv_data[2] == OTA_TWS_CMD_SUCC) {
|
||||
os_sem_post(&tws_ota_sem);
|
||||
}
|
||||
break;
|
||||
case OTA_TWS_VERIFY:
|
||||
g_printf("MSG_OTA_TWS_VERIFY\n");
|
||||
clk_set("sys", 120 * 1000000L); //提升主频加快CRC校验速度
|
||||
ret = dual_bank_update_verify(sync_update_crc_init_hdl, sync_update_crc_calc_hdl, tws_verify_result_hdl);
|
||||
if (ret) {
|
||||
rsp_data[0] = OTA_TWS_VERIFY_RSP;
|
||||
rsp_data[1] = ++ sync_update_sn;
|
||||
rsp_data[2] = OTA_TWS_CMD_ERR;
|
||||
tws_ota_trans_to_sibling(rsp_data, 2);
|
||||
}
|
||||
break;
|
||||
case OTA_TWS_VERIFY_RSP:
|
||||
g_printf("MSG_OTA_TWS_VERIFY_RSP %d\n", recv_data[1]);
|
||||
if (recv_data[2] == OTA_TWS_CMD_SUCC) {
|
||||
os_sem_post(&tws_ota_sem);
|
||||
}
|
||||
break;
|
||||
case OTA_TWS_WRITE_BOOT_INFO:
|
||||
g_printf("MSG_OTA_TWS_WRITE_BOOT_INFO\n");
|
||||
dual_bank_update_burn_boot_info(dual_bank_update_burn_boot_info_callback);
|
||||
break;
|
||||
case OTA_TWS_WRITE_BOOT_INFO_RSP:
|
||||
g_printf("MSG_OTA_TWS_WRITE_BOOT_INFO_RSP\n");
|
||||
if (recv_data[2] == OTA_TWS_CMD_SUCC) {
|
||||
os_sem_post(&tws_ota_sem);
|
||||
}
|
||||
break;
|
||||
case OTA_TWS_UPDATE_RESULT:
|
||||
g_printf("MSG_OTA_TWS_UPDATE_RESULT\n");
|
||||
if (recv_data[2] == OTA_TWS_CMD_SUCC) {
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_OVER);
|
||||
} else {
|
||||
tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR);
|
||||
}
|
||||
break;
|
||||
|
||||
case OTA_TWS_USER_CHIP_UPDATE:
|
||||
if (user_chip_tws_update_handle) {
|
||||
user_chip_tws_update_handle(recv_data + 2, len - 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tws_ota_sync_cmd(int reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case SYNC_CMD_UPDATE_OVER:
|
||||
g_printf("SYNC_CMD_UPDATE_OVER\n");
|
||||
cpu_reset();
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_OVER); */
|
||||
break;
|
||||
case SYNC_CMD_UPDATE_ERR:
|
||||
g_printf("SYNC_CMD_UPDATE_ERR\n");
|
||||
cpu_reset();
|
||||
/* tws_ota_event_post(SYS_BT_OTA_EVENT_TYPE_STATUS, OTA_UPDATE_ERR); */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rcsp_adv_tws_ota_sync_handler(int reason, int err)
|
||||
{
|
||||
tws_ota_sync_cmd(reason);
|
||||
}
|
||||
|
||||
const update_op_tws_api_t update_tws_api = {
|
||||
.tws_ota_start = tws_ota_open,
|
||||
.tws_ota_data_send = tws_ota_data_send_m_to_s,
|
||||
.tws_ota_err = tws_ota_err_callback,
|
||||
.enter_verfiy_hdl = tws_ota_enter_verify,
|
||||
.exit_verify_hdl = tws_ota_exit_verify,
|
||||
.update_boot_info_hdl = tws_ota_updata_boot_info_over,
|
||||
.tws_ota_result_hdl = tws_ota_result,
|
||||
.tws_ota_data_send_pend = tws_ota_data_send_pend,
|
||||
//for user_chip
|
||||
.tws_ota_user_chip_update_send = tws_ota_user_chip_update_send_m_to_s,
|
||||
};
|
||||
|
||||
update_op_tws_api_t *get_tws_update_api(void)
|
||||
{
|
||||
if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
|
||||
return &update_tws_api;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_TWS_FUNC_STUB(tws_ota_trans) = {
|
||||
.func_id = TWS_FUNC_ID_OTA_TRANS,
|
||||
.func = deal_sibling_tws_ota_trans,
|
||||
};
|
||||
|
||||
TWS_SYNC_CALL_REGISTER(rcsp_adv_tws_ota_sync) = {
|
||||
.uuid = 0xA2E22223,
|
||||
.task_name = "app_core",
|
||||
.func = rcsp_adv_tws_ota_sync_handler,
|
||||
};
|
||||
|
||||
void tws_update_register_user_chip_update_handle(void (*update_handle)(void *data, u32 len))
|
||||
{
|
||||
user_chip_tws_update_handle = update_handle;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user