#include "include.h" #include "api.h" #include "func.h" #include "app_variable.h" #include "bsp_sys.h" bsp_bt_t bt_cb; void bsp_bt_init(void) { //更新配置工具的设置 cfg_bt_rf_def_txpwr = 0; //xcfg_cb.bt_txpwr; cfg_bt_page_inq_txpwr = xcfg_cb.bt_rf_txpwr_recon; cfg_bt_support_profile = (PROF_HFP*BT_HFP_EN*xcfg_cb.bt_sco_en)\ | (PROF_SPP*BT_SPP_EN*(xcfg_cb.bt_spp_en||xcfg_cb.eq_dgb_spp_en)) | (PROF_HID*BT_HID_EN) | (PROF_HSP*BT_HSP_EN*xcfg_cb.bt_sco_en)\ | (PROF_PBAP*BT_PBAP_EN) | (PROF_MAP*BT_MAP_EN); #if BT_A2DP_PROFILE_DEFAULT_EN cfg_bt_support_profile |= (PROF_A2DP*BT_A2DP_EN*xcfg_cb.bt_a2dp_en); #endif #if BT_A2DP_VOL_CTRL_EN if(!xcfg_cb.bt_a2dp_vol_ctrl_en) { cfg_bt_a2dp_feature &= ~A2DP_VOL_CTRL; } else { cfg_bt_a2dp_feature |= A2DP_VOL_CTRL; } #endif cfg_bt_dual_mode = BT_DUAL_MODE_EN * xcfg_cb.ble_en; cfg_bt_max_acl_link = 1; #if BT_HFP_EN if(!xcfg_cb.bt_hfp_ring_number_en) { cfg_bt_hfp_feature &= ~HFP_RING_NUMBER_EN; } #endif #if BT_FCC_TEST_EN bt_fcc_init(); #endif #if BT_PBAP_EN bt_pbap_param_reset(); #endif memset(&bt_cb, 0, sizeof(bsp_bt_t)); bt_cb.disp_status = 0xfe; bt_cb.need_pairing = 1; //开机若回连不成功,需要播报pairing bt_cb.hid_menu_flag = 1; bt_setup(); } //是否支持根据AVRCP快速上报播放暂停状态,避免支持播放暂停快速切换功能导致ios播放微信小视频无声 bool bt_emit_music_status_according_to_avrcp(void) { return true; } void bsp_bt_close(void) { } void bsp_bt_vol_change(void) { #if BT_A2DP_VOL_CTRL_EN if((xcfg_cb.bt_a2dp_vol_ctrl_en && (bt_get_status() >= BT_STA_CONNECTED))) { bt_music_vol_change(); //通知手机音量已调整 } #endif } uint bsp_bt_get_hfp_vol(uint hfp_vol) { uint vol; vol = (hfp_vol + 1) * sys_cb.hfp2sys_mul; if (vol > VOL_MAX) { vol = VOL_MAX; } return vol; } #if RECONNECT_FIX static co_timer_t reconnect_timer; static u16 reconnect_count = 0; /** * 蓝牙回连回调函数,当蓝牙因为超距断开时,设备端发起蓝牙回连一共20次,5S执行一次 */ static void reconnect_process(co_timer_t *timer, void *param) { // 如果重连次数大于0 if(reconnect_count){ // 重连次数减1 reconnect_count--; // 调用bt_connect函数进行重连 bt_connect(1); } else { // 如果重连次数为0,则删除重连定时器 co_timer_del(&reconnect_timer); } } void recconect_disable(void) { co_timer_del(&reconnect_timer); reconnect_count = 0; } u16 reconnect_fix_get(void) { return reconnect_count; } #endif void bt_emit_notice(uint evt, u32 param) { switch(evt) { case BT_NOTICE_INIT_FINISH: #if WORK_MODE != MODE_BQB_RF if(bt_nor_get_link_info_addr_ex() && SysVariable.bt_state_set == false){ bt_connect(BT_POWER_UP_RECONNECT_TIMES); } #endif break; case BT_NOTICE_DISCONNECT: bt_cb.warning_status |= BT_WARN_DISCON; bt_redial_reset(((u8 *)param)[0] & 0x01); break; case BT_NOTICE_CONNECTED: // printf("BT_NOTICE_CONNECTED\n"); #if RECONNECT_FIX recconect_disable(); #endif #ifdef TJD_SETTING_AUDIO_SWITCH if (SysVariable.bt_a2dp_profile_state) bt_a2dp_profile_en(); else bt_a2dp_profile_dis(); if (SysVariable.bt_hfp_profile_state) bt_hfp_profile_en(); else bt_hfp_profile_dis(); #endif bt_cb.warning_status |= BT_WARN_CON; bt_redial_reset(((u8 *)param)[0] & 0x01); sys_cb.reconnect_flag = false; break; case BT_NOTICE_SCO_SETUP: break; case BT_NOTICE_SCO_KILL: bt_cb.call_type = CALL_TYPE_NONE; break; case BT_NOTICE_LOSTCONNECT: #if BT_TIME_OUT_RECONNECT_TIMES && RECONNECT_FIX co_timer_set(&reconnect_timer, 5000, TIMER_REPEAT, LEVEL_LOW_PRI, reconnect_process, NULL); co_timer_set_sleep(&reconnect_timer, false); reconnect_count = BT_TIME_OUT_RECONNECT_TIMES; #endif break; // case BT_NOTICE_INCOMING: // case BT_NOTICE_RING: // case BT_NOTICE_OUTGOING: // case BT_NOTICE_CALL: // break; case BT_NOTICE_NETWORK_CALL: // printf("BT_NOTICE_NETWORK_CALL\n"); bt_cb.call_type = CALL_TYPE_NETWORK; break; case BT_NOTICE_PHONE_CALL: // printf("BT_NOTICE_PHONE_CALL\n"); bt_cb.call_type = CALL_TYPE_PHONE; break; case BT_NOTICE_SET_XOSC_CAP: break; case BT_NOTICE_SET_SPK_GAIN: if(param != SysVariable.hfp_vol) { SysVariable.hfp_vol = param; msg_enqueue(EVT_HFP_SET_VOL); } break; case BT_NOTICE_MUSIC_PLAY: msg_enqueue(EVT_A2DP_MUSIC_PLAY); if(bt_is_ios_device()){ bt_hid_finger_select_ios(); } else{ bt_hid_finger_select_andriod(); } break; case BT_NOTICE_MUSIC_STOP: if (bt_get_disp_status() > BT_STA_PLAYING) { break; } msg_enqueue(EVT_A2DP_MUSIC_STOP); break; case BT_NOTICE_MUSIC_CHANGE_VOL: // if(param == 0) { // msg_enqueue(KU_VOL_DOWN); // } else { // msg_enqueue(KU_VOL_UP); // } break; case BT_NOTICE_HID_CONN_EVT: #if BT_HID_MENU_EN if (xcfg_cb.bt_hid_menu_en) { if (bt_cb.hid_menu_flag == 2) { //按键连接/断开HID Profile完成 if (param) { bt_cb.warning_status |= BT_WARN_HID_CON; } else { bt_cb.warning_status |= BT_WARN_HID_DISCON; } bt_cb.hid_menu_flag = 1; } #if BT_HID_DISCON_DEFAULT_EN else if (bt_cb.hid_menu_flag == 1) { if ((param) & (xcfg_cb.bt_hid_discon_default_en)) { bt_cb.hid_discon_flag = 1; } } #endif // BT_HID_DISCON_DEFAULT_EN } #endif // BT_HID_MENU_EN break; case BT_NOTICE_MUSIC_SET_VOL: // printf("BT_NOTICE_MUSIC_SET_VOL vol = %d\n",SysVariable.vol); param = (param+1) * VOL_MAX / 128; if(param != SysVariable.vol) { SysVariable.vol = param; if (SysVariable.vol > VOL_MAX) { SysVariable.vol = VOL_MAX; } msg_enqueue(EVT_A2DP_SET_VOL); } break; case BT_NOTICE_CONNECT_FAIL: { uint8_t status = ((u8 *)param)[0]; // my_printf("BT_NOTICE_CONNECT_FAIL:0x%x\n", status); #if LE_SM_SC_EN && RECONNECT_FIX if ((status != 0x0B) && (reconnect_count == 0)) { //BB_ERROR_ACL_CON_EXISTS if (sys_cb.bt_reconn_flag) { sys_cb.bt_reconn_flag = false; ble_bt_connect(); //双连接 } } #endif // LE_SM_SC_EN break; } #if BT_PBAP_EN case BT_NOTICE_PBAP_CONNECTED: case BT_NOTICE_PBAP_GET_PHONEBOOK_SIZE_COMPLETE: case BT_NOTICE_PBAP_PULL_PHONEBOOK_COMPLETE: case BT_NOTICE_PBAP_DISCONNECT: bt_pbap_event_handle(evt, param); break; #endif // 1,表示play,2表示pause case BT_NOTICE_FAST_MUSIC_STATUS: my_printf("fast music status(%d)\n",((u8 *)param)[0]); u8 sta = !(((u8 *)param)[0] - 1); bt_set_music_sta(sta); break; default: break; } } ALIGNED(64) u16 bsp_bt_chkclr_warning(u16 bits) { u16 value; GLOBAL_INT_DISABLE(); value = bt_cb.warning_status & bits; if(value != 0) { bt_cb.warning_status &= ~value; GLOBAL_INT_RESTORE(); return value; } GLOBAL_INT_RESTORE(); return value; } void bsp_bt_warning(void) { #if BT_HID_MENU_EN //按键手动断开HID Profile的提示音 if (xcfg_cb.bt_hid_menu_en) { #if BT_HID_DISCON_DEFAULT_EN if (bt_cb.hid_discon_flag) { if (bt_hid_is_ready_to_discon()) { bt_cb.hid_discon_flag = 0; bt_hid_disconnect(); } } #endif // BT_HID_DISCON_DEFAULT_EN } #endif // BT_HID_MENU_EN } void bsp_bt_mp3_res_play(u32 addr, u32 len) { func_bt_mp3_res_play(addr, len); } /** * 开关蓝牙 * 用在可以被用户来回点击打开和关闭的场景;比如点击打开,关闭蓝牙;插拔充电开关蓝牙等; */ static co_timer_t bt_onoff_timer; static bool bt_onoff_timer_sta; static void bt_onoff_timer_callback (co_timer_t *timer, void *param) { // printf("bt_onoff_timer_callback\n"); if(bt_onoff_timer_sta){ bt_onoff_timer_sta = 0; if(bt_get_scan()){ if(!bt_is_connected()){ bt_connect(2); } }else{ bt_abort_reconnect(); bt_disconnect(0); } } } void bsp_bt_trun_on(void) { // printf("bsp_bt_trun_on\n"); bt_scan_enable(); if(bt_onoff_timer.en){ co_timer_set(&bt_onoff_timer, 2000, TIMER_ONE_SHOT, LEVEL_LOW_PRI, bt_onoff_timer_callback, NULL); bt_onoff_timer_sta = 1; }else{ if(bt_onoff_timer_sta == 0){ bt_connect(2); co_timer_set(&bt_onoff_timer, 2000, TIMER_ONE_SHOT, LEVEL_LOW_PRI, bt_onoff_timer_callback, NULL); } } } void bsp_bt_trun_off(void) { // printf("bsp_bt_trun_off\n"); bt_scan_disable(); #if RECONNECT_FIX recconect_disable(); #endif if(bt_onoff_timer.en){ co_timer_set(&bt_onoff_timer, 2000, TIMER_ONE_SHOT, LEVEL_LOW_PRI, bt_onoff_timer_callback, NULL); bt_onoff_timer_sta = 1; }else{ if(bt_onoff_timer_sta == 0){ bt_abort_reconnect(); bt_disconnect(0); co_timer_set(&bt_onoff_timer, 2000, TIMER_ONE_SHOT, LEVEL_LOW_PRI, bt_onoff_timer_callback, NULL); } } } static void bsp_bt_disp_status(void) { uint status = bt_get_disp_status(); if(bt_cb.disp_status != status) { bt_cb.disp_status = status; //if(!bt_is_connected()) { if (0) { en_auto_pwroff(); sys_cb.sleep_en = BT_PAIR_SLEEP_EN; } else { dis_auto_pwroff(); sys_cb.sleep_en = 1; } if(bt_cb.disp_status >= BT_STA_CONNECTED) { bt_cb.need_pairing = 1; } } } AT(.text.func.bt) void bsp_bt_status(void) { bsp_bt_disp_status(); bsp_bt_warning(); }