mcu_ab568x/app/platform/bsp/bsp_bt/bsp_bt.c
2025-05-30 18:03:10 +08:00

410 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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表示play2表示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();
}