/*************************************************************************** * * Copyright 2015-2019 BES. * All rights reserved. All unpublished rights reserved. * * No part of this work may be used or reproduced in any form or by any * means, or stored in a database or retrieval system, without prior written * permission of BES. * * Use of this work is governed by a license granted by BES. * This work contains confidential and proprietary information of * BES. which is protected by copyright, trade secret, * trademark and other intellectual property rights. * ****************************************************************************/ #include "bt_drv.h" #include "bt_drv_2300p_internal.h" #include "bt_drv_interface.h" #include "bt_drv_internal.h" #include "bt_drv_reg_op.h" #include "hal_chipid.h" #include "hal_i2c.h" #include "hal_timer.h" #include "hal_uart.h" #include "plat_types.h" #include "tgt_hardware.h" #include // typedef void (*btdrv_config_func_t)(uint8_t parlen, uint8_t *param); extern void btdrv_send_cmd(uint16_t opcode, uint8_t cmdlen, const uint8_t *param); extern void btdrv_write_memory(uint8_t wr_type, uint32_t address, const uint8_t *value, uint8_t length); typedef struct { // btdrv_config_func_t func; uint8_t is_act; uint16_t opcode; uint8_t parlen; const uint8_t *param; } BTDRV_CFG_TBL_STRUCT; #define BTDRV_CONFIG_ACTIVE 1 #define BTDRV_CONFIG_INACTIVE 0 #define BTDRV_INVALID_TRACE_LEVEL 0xFF /* [0][0] = 63, [0][1] = 0,[0][2] = (-80), 472d [1][0] = 51, [2][1] = 0,[2][2] = (-80), 472b [2][0] = 42, [4][1] = 0,[4][2] = (-75), 4722 [3][0] = 36, [6][1] = 0,[6][2] = (-55), c712 [4][0] = 30, [8][1] = 0,[8][2] = (-40), c802 [5][0] = 21,[10][1] = 0,[10][2] = 0x7f, c102 [6][0] = 12,[11][1] = 0,[11][2] = 0x7f, c142 [7][0] = 3,[13][1] = 0,[13][2] = 0x7f, c1c2 [8][0] = -3,[14][1] = 0,[14][2] = 0x7f}; c0c2 */ static uint8_t g_controller_trace_level = BTDRV_INVALID_TRACE_LEVEL; static bool g_lmp_trace_enable = false; const int8_t btdrv_rf_env_2300p[] = { 0x01, 0x00, // rf api 0x01, // rf env 185, // rf length 0x2, // txpwr_max #ifdef __HW_AGC__ -1, // high -2, // low -100, // interf #else -1, /// rssi high thr -2, // rssi low thr -100, // rssi interf thr #endif 0xf, // rssi interf gain thr 2, // wakeup delay 0xe, 0, // skew 0xe8, 0x3, // ble agc inv thr #ifdef __HW_AGC__ 0x1, // hw_sw_agc_flag #else 0x0, // #endif 0xff, // sw gain set 0xff, // sw gain set -70, // bt_inq_page_iscan_pscan_dbm 0x7f, // ble_scan_adv_dbm 1, // sw gain reset factor 1, // bt sw gain cntl enable 0, // ble sw gain cntl en 1, // bt interfere detector en 0, // ble interfere detector en -21, -27, -19, -18, -24, -13, -15, -21, -10, -12, -18, -10, -9, -15, -10, -6, -12, -10, -3, -9, -10, 0, -6, 0, 0x7f, -3, 0x7f, 0x7f, 0, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, // rx hwgain tbl ptr // zhangzhd agc config use default 1216 50, 0, -80, 42, 0, -80, 38, 0, -80, 32, 0, -80, 26, 0, -80, 21, 0, -80, 15, 0, -80, 9, 0, -80, // zhangzhd agc config end 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, // rx gain tbl ptr // zhangzhd agc config use default 1216 -80, -73, -75, -68, -70, -63, -65, -58, -60, -53, -55, -48, -50, -15, // zhangzhd agc config end 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, // rx gain ths tbl ptr 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 2, 0, 2, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, // flpha filter factor ptr -23, -20, -17, -14, -11, -8, -5, -2, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, // tx pw onv tbl ptr }; const int8_t btdrv_afh_env[] = { 0x02, 0x00, // afh env 0x00, // ignore 33, // length 5, // nb_reass_chnl 10, // win_len -70, // rf_rssi_interf_thr 10, // per_thres_bad 20, // reass_int 20, // n_min 20, // afh_rep_intv_max 96, // ths_min 2, // chnl_assess_report_style 15, // chnl_assess_diff_thres 60, // chnl_assess_interfere_per_thres_bad 9, // chnl_assess_stat_cnt_max -9, // chnl_assess_stat_cnt_min 1, 2, 3, 2, 1, // chnl_assess_stat_cnt_inc_mask[5] 1, 2, 3, 2, 1, // chnl_assess_stat_cnt_dec_mask 0xd0, 0x7, // chnl_assess_timer -48, // chnl_assess_min_rssi 0x64, 0, // chnl_assess_nb_pkt 0x32, 0, // chnl_assess_nb_bad_pkt 6, // chnl_reassess_cnt_val 0x3c, 0, // chnl_assess_interfere_per_thres_bad }; const uint8_t lpclk_drift_jitter[] = { 0xfa, 0x00, // drift 250ppm 0x0a, 0x00 // jitter +-10us }; const uint8_t wakeup_timing[] = { 0xe8, 0x3, // exernal_wakeup_time 600us 0xe8, 0x3, // oscillater_wakeup_time 600us 0xe8, 0x3, // radio_wakeup_time 600us // 0xa0,0xf, //wakeup_delay_time }; uint8_t sleep_param[] = { 1, // sleep_en; 0, // exwakeup_en; 0xc8, 0, // lpo_calib_interval; lpo calibration interval 0x32, 0, 0, 0, // lpo_calib_time; lpo count lpc times }; uint8_t unsleep_param[] = { 0, // sleep_en; 0, // exwakeup_en; 0xc8, 0, // lpo_calib_interval; lpo calibration interval 0x32, 0, 0, 0, // lpo_calib_time; lpo count lpc times }; static const uint32_t me_init_param[][2] = { {0xffffffff, 0xffffffff}, }; const uint16_t me_bt_default_page_timeout = 0x2000; const uint8_t sync_config[] = { 1, 1, // sco path config 0:hci 1:pcm 0, // sync use max buff length 0:sync data length= packet length 1:sync // data length = host sync buff len 0, // cvsd bypass 0:cvsd2pcm 1:cvsd transparent }; // pcm general ctrl #define PCM_PCMEN_POS 15 #define PCM_LOOPBCK_POS 14 #define PCM_MIXERDSBPOL_POS 11 #define PCM_MIXERMODE_POS 10 #define PCM_STUTTERDSBPOL_POS 9 #define PCM_STUTTERMODE_POS 8 #define PCM_CHSEL_POS 6 #define PCM_MSTSLV_POS 5 #define PCM_PCMIRQEN_POS 4 #define PCM_DATASRC_POS 0 // pcm phy ctrl #define PCM_LRCHPOL_POS 15 #define PCM_CLKINV_POS 14 #define PCM_IOM_PCM_POS 13 #define PCM_BUSSPEED_LSB 10 #define PCM_SLOTEN_MASK ((uint32_t)0x00000380) #define PCM_SLOTEN_LSB 7 #define PCM_WORDSIZE_MASK ((uint32_t)0x00000060) #define PCM_WORDSIZE_LSB 5 #define PCM_DOUTCFG_MASK ((uint32_t)0x00000018) #define PCM_DOUTCFG_LSB 3 #define PCM_FSYNCSHP_MASK ((uint32_t)0x00000007) #define PCM_FSYNCSHP_LSB 0 /// Enumeration of PCM status enum PCM_STAT { PCM_DISABLE = 0, PCM_ENABLE }; /// Enumeration of PCM channel selection enum PCM_CHANNEL { PCM_CH_0 = 0, PCM_CH_1 }; /// Enumeration of PCM role enum PCM_MSTSLV { PCM_SLAVE = 0, PCM_MASTER }; /// Enumeration of PCM data source enum PCM_SRC { PCM_SRC_DPV = 0, PCM_SRC_REG }; /// Enumeration of PCM left/right channel selection versus frame sync polarity enum PCM_LR_CH_POL { PCM_LR_CH_POL_RIGHT_LEFT = 0, PCM_LR_CH_POL_LEFT_RIGHT }; /// Enumeration of PCM clock inversion enum PCM_CLK_INV { PCM_CLK_RISING_EDGE = 0, PCM_CLK_FALLING_EDGE }; /// Enumeration of PCM mode selection enum PCM_MODE { PCM_MODE_PCM = 0, PCM_MODE_IOM }; /// Enumeration of PCM bus speed enum PCM_BUS_SPEED { PCM_BUS_SPEED_128k = 0, PCM_BUS_SPEED_256k, PCM_BUS_SPEED_512k, PCM_BUS_SPEED_1024k, PCM_BUS_SPEED_2048k }; /// Enumeration of PCM slot enable enum PCM_SLOT { PCM_SLOT_NONE = 0, PCM_SLOT_0, PCM_SLOT_0_1, PCM_SLOT_0_2, PCM_SLOT_0_3 }; /// Enumeration of PCM word size enum PCM_WORD_SIZE { PCM_8_BITS = 0, PCM_13_BITS, PCM_14_BITS, PCM_16_BITS }; /// Enumeration of PCM DOUT pad configuration enum PCM_DOUT_CFG { PCM_OPEN_DRAIN = 0, PCM_PUSH_PULL_HZ, PCM_PUSH_PULL_0 }; /// Enumeration of PCM FSYNC physical shape enum PCM_FSYNC { PCM_FSYNC_LF = 0, PCM_FSYNC_FR, PCM_FSYNC_FF, PCM_FSYNC_LONG, PCM_FSYNC_LONG_16 }; const uint32_t pcm_setting[] = { // pcm_general_ctrl (PCM_DISABLE << PCM_PCMEN_POS) | // enable auto (PCM_DISABLE << PCM_LOOPBCK_POS) | // LOOPBACK test (PCM_DISABLE << PCM_MIXERDSBPOL_POS) | (PCM_DISABLE << PCM_MIXERMODE_POS) | (PCM_DISABLE << PCM_STUTTERDSBPOL_POS) | (PCM_DISABLE << PCM_STUTTERMODE_POS) | (PCM_CH_0 << PCM_CHSEL_POS) | (PCM_MASTER << PCM_MSTSLV_POS) | // BT clock (PCM_DISABLE << PCM_PCMIRQEN_POS) | (PCM_SRC_DPV << PCM_DATASRC_POS), // pcm_phy_ctrl (PCM_LR_CH_POL_RIGHT_LEFT << PCM_LRCHPOL_POS) | (PCM_CLK_FALLING_EDGE << PCM_CLKINV_POS) | (PCM_MODE_PCM << PCM_IOM_PCM_POS) | (PCM_BUS_SPEED_2048k << PCM_BUSSPEED_LSB) | // 8k sample rate; 2048k = slot_num * // sample_rate * bit= 16 * 8k * 16 (PCM_SLOT_0_1 << PCM_SLOTEN_LSB) | (PCM_16_BITS << PCM_WORDSIZE_LSB) | (PCM_PUSH_PULL_0 << PCM_DOUTCFG_LSB) | (PCM_FSYNC_LF << PCM_FSYNCSHP_LSB), }; #if 1 const uint8_t local_feature[] = { #if defined(__3M_PACK__) 0xBF, 0xeE, 0xCD, 0xFe, 0xdb, 0xFd, 0x7b, 0x87 #else 0xBF, 0xeE, 0xCD, 0xFa, 0xdb, 0xbd, 0x7b, 0x87 // 0xBF,0xFE,0xCD,0xFa,0xDB,0xFd,0x73,0x87 // disable simple pairing #endif }; #else // disable simple pairing uint8_t local_feature[] = {0xBF, 0xFE, 0xCD, 0xFE, 0xDB, 0xFd, 0x73, 0x87}; #endif const uint8_t local_ex_feature_page1[] = { 1, // page 0, 0, 0, 0, 0, 0, 0, 0, // page 1 feature }; const uint8_t local_ex_feature_page2[] = { 2, // page 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // page 2 feature }; const uint8_t bt_rf_timing[] = { 0xE, // tx delay 0x13, // rx delay 0x42, // rx pwrup 0x0f, /// tx down 0x56, // tx pwerup }; const uint8_t ble_rf_timing[] = { 0xC, // tx delay tx after rx delay 0x2C, // win count rx window count 0xe, /// ble rtrip delay 0x42, /// ble rx pwrup 0x7, /// ble tx pwerdown 0x40, /// ble tx pwerup }; const uint8_t ble_rl_size[] = { 10, // rl size }; uint8_t bt_setting_2300p[97] = { 0x00, // clk_off_force_even 0x01, // msbc_pcmdout_zero_flag 0x04, // ld_sco_switch_timeout 0x01, // stop_latency2 0x01, // force_max_slot 0xc8, 0x00, // send_connect_info_to 0x20, 0x03, // sco_to_threshold 0x40, 0x06, // acl_switch_to_threshold 0x3a, 0x00, // sync_win_size 0x01, // polling_rxseqn_mode #ifdef __BT_ONE_BRING_TWO__ 0x01, // two_slave_sched_en #else 0x00, // two_slave_sched_en #endif 0xff, // music_playing_link 0x04, // wesco_nego = 2; 0x17, 0x11, 0x00, 0x00, // two_slave_extra_duration_add (7*625); 0x01, // ble_adv_ignore_interval 0x04, // slot_num_diff 0x01, // csb_tx_complete_event_enable 0x04, // csb_afh_update_period 0x00, // csb_rx_fixed_len_enable 0x01, // force_max_slot_acc 0x00, // force_5_slot; #ifdef BT_CONTROLER_DEBUG_TRACE 0x03, // dbg_trace_level #else 0x00, #endif 0x00, // bd_addr_switch 0x00, // force_rx_error 0x08, // data_tx_adjust 0x02, // ble txpower need modify ble tx idx @ bt_drv_config.c; 0x50, // sco_margin 0x78, // acl_margin 0x01, // pca_disable_in_nosync 0x01, // master_2_poll 0x3a, // sync2_add_win 0x5e, // no_sync_add_win 0x09, // rwbt_sw_version_major 0x03, 0x00, // rwbt_sw_version_minor 0x21, 0x00, // rwbt_sw_version_build 0x01, // rwbt_sw_version_sub_build 0x00, // public_key_check; 0x00, // sco_txbuff_en; 0x3f, // role_switch_packet_br; 0x2b, // role_switch_packet_edr; 0x00, // dual_slave_tws_en; 0x07, // dual_slave_slot_add; 0x00, // master_continue_tx_en; 0x20, 0x03, // get_rssi_to_threshold; 0x05, // rssi_get_times; 0x00, // ptt_check; 0x0c, // protect_sniff_slot; 0x00, // power_control_type; #ifdef TX_RX_PCM_MASK 1, // sco_buff_copy #else 0, // sco_buff_copy #endif 0x32, 0x00, // acl_interv_in_snoop_mode; 0x78, 0x00, // acl_interv_in_snoop_sco_mode; 0x06, // acl_slot_in_snoop_mode; 0x01, // calculate_en; 0x00, // check_sniff_en; 0x01, // sco_avoid_ble_en; 0x01, // check_ble_en; 0x01, // ble_slot; 0x00, // same_link_slave_extra; 0x00, // other_link_slave_extra; 0x00, // master_extra; 0x00, // ble_extra; 0x00, // sco_extra; 0x00, // sniff_extra; 0x00, 0x00, 0x00, 0x00, // same_link_duration; 0x00, 0x00, 0x00, 0x00, // other_link_duration; 0x06, // dual_slave; 0x0a, // clk_check_threshold; 0x90, 0x01, // target_clk_add; 0x01, // close_check_sco_to; // 0x00, // 0x00, //chip tports_level (wrong) use // btdrv_2300p_set_tports_level() 0x00, 0x01, //(tports_level)//chip read close_loopbacken_flag 0x01, // chip read based_clk_select 0x01, // chip read check_role_switch 0x00, // chip read rsw_end_prority 0x00, // chip read ecc_enable 0x00, // padding to 97-byte 0x00, // padding to 97-byte 0x00, // padding to 97-byte 0x00, // padding to 97-byte }; //#define ACCEPT_NEW_MOBILE_EN uint8_t bt_setting_2300p_t2[104] = { 0x00, // clk_off_force_even 0x01, // msbc_pcmdout_zero_flag 0x04, // ld_sco_switch_timeout 0x00, // stop_latency2 0x01, // force_max_slot 0xc8, 0x00, // send_connect_info_to 0x20, 0x03, // sco_to_threshold 0x40, 0x06, // acl_switch_to_threshold 0x3a, 0x00, // sync_win_size 0x01, // polling_rxseqn_mode #ifdef __BT_ONE_BRING_TWO__ 0x01, // two_slave_sched_en #else 0x00, // two_slave_sched_en #endif 0xff, // music_playing_link 0x04, // wesco_nego = 2; 0x17, 0x11, 0x00, 0x00, // two_slave_extra_duration_add (7*625); 0x01, // ble_adv_ignore_interval 0x04, // slot_num_diff 0x01, // csb_tx_complete_event_enable 0x04, // csb_afh_update_period 0x00, // csb_rx_fixed_len_enable 0x01, // force_max_slot_acc 0x00, // force_5_slot; 0x00, // dbg_trace_level 0x00, // bd_addr_switch 0x00, // force_rx_error 0x08, // data_tx_adjust 0x02, // ble txpower need modify ble tx idx @ bt_drv_config.c; 0x50, // sco_margin 0x78, // acl_margin 0x01, // pca_disable_in_nosync 0x01, // master_2_poll 0x3a, // sync2_add_win 0x5e, // no_sync_add_win 0x09, // rwbt_sw_version_major 0x03, 0x00, // rwbt_sw_version_minor 0x21, 0x00, // rwbt_sw_version_build 0x01, // rwbt_sw_version_sub_build 0x00, // public_key_check; 0x00, // sco_txbuff_en; 0x3f, // role_switch_packet_br; 0x2b, // role_switch_packet_edr; 0x00, // dual_slave_tws_en; 0x07, // dual_slave_slot_add; 0x00, // master_continue_tx_en; 0x20, 0x03, // get_rssi_to_threshold; 0x05, // rssi_get_times; 0x00, // ptt_check; 0x0c, // protect_sniff_slot; 0x01, // power_control_type; #ifdef TX_RX_PCM_MASK 0x01, // sco_buff_copy #else 0x00, // sco_buff_copy #endif 0x32, 0x00, // acl_interv_in_snoop_mode; 0x48, 0x00, // acl_interv_in_snoop_sco_mode; 0x06, // acl_slot_in_snoop_mode; 0x01, // calculate_en; 0x00, // check_sniff_en; 0x01, // sco_avoid_ble_en; 0x01, // check_ble_en; 0x01, // ble_slot; 0x00, // same_link_slave_extra; 0x00, // other_link_slave_extra; 0x00, // master_extra; 0x00, // ble_extra; 0x00, // sco_extra; 0x00, // sniff_extra; #ifdef __FORCE_SCO_MAX_RETX__ 0x02, 0x00, 0x00, 0x00, // same_link_duration; #else 0x00, 0x00, 0x00, 0x00, // same_link_duration; #endif 0x00, 0x00, 0x00, 0x00, // other_link_duration; 0x06, // dual_slave; 0x14, // clk_check_threshold; 0x90, 0x01, // target_clk_add; 0x01, // close_check_sco_to; 0x00, 0x00, //(tports_level) 0x01, // close_loopbacken_flag 0x1e, // seq_error_num 0x01, // check_role_switch 0x01, // rsw_end_prority #ifdef __FASTACK_ECC_ENABLE__ 0x01, // ecc_enable #else 0x00, // ecc_enable #endif 0x01, // sw_seq_filter_en 0x01, // page_pagescan_coex_en #ifdef ACCEPT_NEW_MOBILE_EN 0x01, // accept_new_mobile_en #else 0x00, #endif 0x64, // reserve_slot_for_send_profile 0x0e, // magic_cal_bitoff 0x00, // sco_role_switch_mode 0x00, // address_reset 0xa6, 0x0e, // adv_duration }; uint8_t bt_setting_ext1_2300p_t3[25] = { 0x00, 0x01, // stop_notif_bit_off_thr 0x32, 0x00, // bit_off_diff 0x00, // bt_wlan_onoff 0x12, // tws_link_in_sco_prio 0x01, // tws_link_rx_traficc 0x00, // tws_link_ignore_1_sco; 0x08, // default_tpoll 0x00, // send_profile_via_ble 0x0a, // swagc_thd 0x98, // swagc_count 0x14, // max_drift_limit 0x00, // sync2_sco_cal_enable #ifdef IBRT 0x00, // accep_remote_bt_roleswitch #else 0x01, #endif 0x01, // hci_auto_accept_tws_link_en 0x00, // enable_assert 0x00, // reserved 0xc8, 0x00, // hci_timeout_sleep 0x50, // link_no_snyc_thd 0xa6, // link_no_sync_rssi(-90dBm) 0x64, 0x00, // link_no_sync_timeout 0x01, // ibrt_role_switch_check_sco }; bool btdrv_get_accept_new_mobile_enable(void) { bool ret = false; if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { BT_DRV_TRACE(1, "BT_DRV_CONFIG:accept_new_mobile enable=%d", bt_setting_2300p_t2[97]); ret = bt_setting_2300p_t2[97]; } return ret; } bool btdrv_get_page_pscan_coex_enable(void) { bool ret = false; if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { BT_DRV_TRACE(1, "BT_DRV_CONFIG:page_pscan_coex enable=%d", bt_setting_2300p_t2[96]); ret = bt_setting_2300p_t2[96]; } return ret; } const uint8_t bt_edr_thr[] = { 30, 0, 60, 0, 5, 0, 60, 0, 0, 1, 30, 0, 60, 0, 5, 0, 60, 0, 1, 1, 30, 0, 60, 0, 5, 0, 60, 0, 1, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; const uint8_t bt_edr_algo[] = { 0, 0, 1, 8, 0, 3, 16, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; const uint8_t bt_rssi_thr[] = { -1, // high -2, // low -100, // interf }; const uint8_t ble_dle_dft_value[] = { 0xfb, 0x00, /// tx octets 0x48, 0x08, /// tx time 0xfb, 0x00, /// rx octets 0x48, 0x08, /// rx time }; uint8_t bt_lmp_record[] = { 0, // en 0, // only opcode }; static BTDRV_CFG_TBL_STRUCT btdrv_cfg_tbl[] = { {BTDRV_CONFIG_INACTIVE, HCI_DBG_LMP_MESSAGE_RECORD_CMD_OPCODE, sizeof(bt_lmp_record), (uint8_t *)&bt_lmp_record}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE, sizeof(local_feature), local_feature}, {BTDRV_CONFIG_INACTIVE, HCI_DBG_SET_BT_SETTING_CMD_OPCODE, sizeof(bt_setting_2300p), bt_setting_2300p}, {BTDRV_CONFIG_INACTIVE, HCI_DBG_SET_BT_SETTING_CMD_OPCODE, sizeof(bt_setting_2300p_t2), bt_setting_2300p_t2}, {BTDRV_CONFIG_INACTIVE, HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE, sizeof(bt_setting_ext1_2300p_t3), bt_setting_ext1_2300p_t3}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_SLEEP_SETTING_CMD_OPCODE, sizeof(sleep_param), sleep_param}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE, 189, (uint8_t *)&btdrv_rf_env_2300p}, //{BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_CUSTOM_PARAM_CMD_OPCODE,sizeof(btdrv_afh_env),(uint8_t //*)&btdrv_afh_env}, // {BTDRV_CONFIG_INACTIVE,HCI_DBG_SET_LPCLK_DRIFT_JITTER_CMD_OPCODE,sizeof(lpclk_drift_jitter),(uint8_t // *)&lpclk_drift_jitter}, // {BTDRV_CONFIG_ACTIVE,HCI_DBG_SET_WAKEUP_TIME_CMD_OPCODE,sizeof(wakeup_timing),(uint8_t // *)&wakeup_timing}, #ifdef _SCO_BTPCM_CHANNEL_ {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_SYNC_CONFIG_CMD_OPCODE, sizeof(sync_config), (uint8_t *)&sync_config}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_PCM_SETTING_CMD_OPCODE, sizeof(pcm_setting), (uint8_t *)&pcm_setting}, #endif {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_RSSI_THRHLD_CMD_OPCODE, sizeof(bt_rssi_thr), (uint8_t *)&bt_rssi_thr}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_LOCAL_EX_FEATURE_CMD_OPCODE, sizeof(local_ex_feature_page2), (uint8_t *)&local_ex_feature_page2}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_BT_RF_TIMING_CMD_OPCODE, sizeof(bt_rf_timing), (uint8_t *)&bt_rf_timing}, {BTDRV_CONFIG_ACTIVE, HCI_DBG_SET_BLE_RF_TIMING_CMD_OPCODE, sizeof(ble_rf_timing), (uint8_t *)&ble_rf_timing}, }; const static POSSIBLY_UNUSED BTDRV_CFG_TBL_STRUCT btdrv_cfg_tbl_2[] = { }; const static POSSIBLY_UNUSED uint32_t mem_config_2300p[][2] = { }; void bt_drv_digital_config_for_ble_adv(bool en) { #ifdef __HW_AGC__ btdrv_hw_agc_stop_mode(BT_SYNCMODE_REQ_USER_BLE, en); #endif } void btdrv_digital_config_init_2300p_t2(void) { // common BTDIGITAL_REG(0xd0350370) |= (1 << 29); // lowpass flt enable BTDIGITAL_REG(0xd0330038) |= (1 << 11); // sel 26m sys BTDIGITAL_REG(0xd0330038) &= 0xffffff3f; // sel 26m sys BTDIGITAL_REG(0xd03300f0) &= ~0x1; // sel 26m sys BTDIGITAL_REG(0xd0350398) = 0x6e4ef79c; BTDIGITAL_REG(0xd03503a8) = 0x15A64E88; // IBRT BTDIGITAL_REG(0xd0220464) &= 0xdfffffff; // fast ack 2M mode dis #ifdef __FASTACK_ECC_ENABLE__ BTDIGITAL_REG(0xd0220468) = 0x04401914; // fast ack timings & fastlock en #else BTDIGITAL_REG(0xd0220468) = 0x10423528; // fast ack timings #endif //__FASTACK_ECC_ENABLE__ #ifdef __FA_RX_GAIN_CTRL__ BTDIGITAL_REG(0xd0220080) &= 0xff00ffff; BTDIGITAL_REG(0xd0220080) |= 0x00770000; // trx pwrup/dn BTDIGITAL_REG(0xd02201e8) |= 1; // second rf spi en BTDIGITAL_REG(0xd0220480) = (BTDIGITAL_REG(0xd0220480) & (~0xff)) | 0xbf; BTDIGITAL_REG(0xd0220484) = (BTDIGITAL_REG(0xd0220484) & (~0xffff)) | 0x9403; // lxd 20191102 fixed ecc receive gain to 1 level #endif #ifdef __CLK_GATE_DISABLE__ BTDIGITAL_REG(0xD0330024) &= (~0x00020); BTDIGITAL_REG(0xD0330024) |= 0x40000; BTDIGITAL_REG(0xD0330038) |= 0x200000; #endif } void btdrv_digital_config_init_2300p_t1(void) { #ifdef BT_RF_OLD_CORR_MODE BTDIGITAL_REG(0xD03503A0) &= (~0x01); // clear bit 0 avoid slave lost data #else BTDIGITAL_REG(0xD03503A0) |= (0x01); #endif BTDIGITAL_REG(0x40000074) = 0x00003100; BTDIGITAL_REG(0x400000F0) = 0xFFFF0002; // open slot en BTDIGITAL_REG(0xd0350240) = 0x0001a407; BTDIGITAL_REG(0xd03502c8) = 0x00000080; // for old ramp BTDIGITAL_REG(0xd03502cc) = 0x00000015; // for old ramp #ifdef __HW_AGC__ BTDIGITAL_REG(0xd0350208) = 0x7fffffff; btdrv_delay(10); BTDIGITAL_REG(0xd0350228) = 0x7f7fffff; BTDIGITAL_REG(0xd03300f0) = 0xffff0008; // hwagc config BTDIGITAL_REG(0xd03503b8) = 0x08000d80; // hwagc config #endif BTDIGITAL_REG(0xd02201e8) = (BTDIGITAL_REG(0xd02201e8) & (~0x7c0)) | 0x380; BTDIGITAL_REG(0xd0350360) = 0x003fe040; BTDIGITAL_REG(0xd0220470) |= 0x40; #ifdef __CLK_GATE_DISABLE__ BTDIGITAL_REG(0xD0330024) &= (~0x00020); BTDIGITAL_REG(0xD0330024) |= 0x40000; BTDIGITAL_REG(0xD0330038) |= 0x200000; #endif #ifdef LBRT BTDIGITAL_REG(0xd0350300) = 0x00000000; BTDIGITAL_REG(0xd0350340) = 0x00000000; #else #ifdef __BDR_EDR_2DB__ BTDIGITAL_REG(0xd0350300) = 0x55; BTDIGITAL_REG(0xd0350308) = 0x00003C0F; #else BTDIGITAL_REG(0xd0350300) = 0x11; #endif BTDIGITAL_REG(0xd0350340) = 0x1; #endif // 0x07 will affect Bluetooth sensitivity // 0x06 will lead to LBRT rx bad in close distance BTDIGITAL_REG(0xd0350280) = 0x00000006; BTDIGITAL_REG(0xd035031c) = 0x00050004; // modulation factor 17/16 BTDIGITAL_REG(0xd0350320) = 0x00350011; // added by xrz 2018.10.10 BTDIGITAL_REG(0xd0220080) = 0x0e571439; // trx pwrup/dn BTDIGITAL_REG(0xd0220280) = 0x0e471445; // add by luobin 2019/05/23 BTDIGITAL_REG(0xd0350210) = 0x00f10040; // add by walker 2018/12/27 BTDIGITAL_REG(0xd03502c4) = 0x127f02ef; // 2M TE time init BTDIGITAL_REG(0xd0350284) = 0x02000200; BTDIGITAL_REG_SET_FIELD(0xd0220200, 7, 0, 3); BTDIGITAL_REG(0xd0350398) = 0xD25EF79C; BTDIGITAL_REG(0xd035039c) = 0x60C6C061; // hwagc config BTDIGITAL_REG(0xd03503a8) = 0x14666E88; // hwagc config BTDIGITAL_REG(0xd0350364) = 0x002EB948; // data sign and iq swap BTDIGITAL_REG(0xd03503a0) = 0x1c070055; // improve 1M RX sensitivity by jiangpeng // for system 2M Band Wide BTDIGITAL_REG(0x4008003c) |= 1; BTDIGITAL_REG(0x40080018) |= 1; BTDIGITAL_REG(0x40080004) |= (1 << 15) | (1 << 30); // osc x4 enable BTDIGITAL_REG(0xd0330038) |= (3 << 6) | (1 << 11); BTDIGITAL_REG(0xd03300f0) |= 1; // for IBRT fast ack BTDIGITAL_REG(0xd0220464) |= 1 << 29; // fast ack 2M mode enable BTDIGITAL_REG(0xd0220468) = 0x00403832; // 2M fast ack timings BTDIGITAL_REG(0xd022046c) &= ~(1 << 31); // enable DM1 empty fastack BTDIGITAL_REG(0xd035020C) = 0x00f1002c; BTDIGITAL_REG(0xD0350210) = 0x00f1082c; // tx guard BTDIGITAL_REG(0xd0220498) = 0x00A01991; // fast ack timeout } extern const uint8_t lmp_sniffer_filter_tab[51]; extern const uint8_t lmp_ext_sniffer_filter_tab[18]; extern const uint8_t lmp_ext_sniffer_fast_cfm_tab[4]; void bt_drv_config_lmp_filter_table(void) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { BTDIGITAL_REG(0xc0000300) = 0xc00070f4; BT_DRV_TRACE(2, "%s: 0x%x", __func__, BTDIGITAL_REG(0xc0000300)); memcpy((uint8_t *)(0xc00070f4), lmp_sniffer_filter_tab, sizeof(lmp_sniffer_filter_tab)); } else if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { BTDIGITAL_REG(0xc0000314 + 4) = 0xC0006e40; memcpy((uint8_t *)(0xC0006e40), lmp_ext_sniffer_filter_tab, sizeof(lmp_ext_sniffer_filter_tab)); BTDIGITAL_REG(0xc0000314 + 0xc) = 0xC0006c9c; BT_DRV_TRACE(3, "%s: 0x%x, 0x%x", __func__, BTDIGITAL_REG(0xc0000314 + 4), BTDIGITAL_REG(0xc0000314 + 0xc)); memcpy((uint8_t *)(0xC0006c9c), lmp_ext_sniffer_fast_cfm_tab, sizeof(lmp_ext_sniffer_fast_cfm_tab)); } } uint32_t ld_ibrt_sco_req_filter_patch[] = { 0x7981b470, /*76c0*/ 0xf1034b0b, 0xe0020410, 0x42a33304, 0x785ad00c, 0xd1f9428a, 0x789a7a06, 0xd1f54296, 0x78da8946, 0xd1f14296, 0xe0002001, 0xbc702000, 0xbf004770, 0xc0007450, // sniffer_sco_filter }; void bt_drv_func_ld_ibrt_sco_req_filter(void) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { memcpy((uint32_t *)(0xc00076c0), ld_ibrt_sco_req_filter_patch, sizeof(ld_ibrt_sco_req_filter_patch)); } } extern void bt_drv_reg_op_controller_mem_log_config(void); void btdrv_config_init(void) { BT_DRV_TRACE(1, "%s", __func__); if (btdrv_get_lmp_trace_enable()) { // enable lmp trace bt_lmp_record[0] = 1; bt_lmp_record[1] = 1; btdrv_cfg_tbl[0].is_act = BTDRV_CONFIG_ACTIVE; ASSERT((btdrv_cfg_tbl[0].opcode == HCI_DBG_LMP_MESSAGE_RECORD_CMD_OPCODE), "lmp config not match"); } if (btdrv_get_controller_trace_level() != BTDRV_INVALID_TRACE_LEVEL) { // enable controller trace bt_setting_2300p[28] = btdrv_get_controller_trace_level(); bt_setting_2300p_t2[28] = btdrv_get_controller_trace_level(); } for (uint8_t i = 0; i < sizeof(btdrv_cfg_tbl) / sizeof(btdrv_cfg_tbl[0]); i++) { if (btdrv_cfg_tbl[i].opcode == HCI_DBG_SET_BT_SETTING_CMD_OPCODE) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0 && btdrv_cfg_tbl[i].parlen == sizeof(bt_setting_2300p)) { btdrv_send_cmd(btdrv_cfg_tbl[i].opcode, btdrv_cfg_tbl[i].parlen, btdrv_cfg_tbl[i].param); btdrv_delay(1); } else if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1 && btdrv_cfg_tbl[i].parlen == sizeof(bt_setting_2300p_t2)) { btdrv_send_cmd(btdrv_cfg_tbl[i].opcode, btdrv_cfg_tbl[i].parlen, btdrv_cfg_tbl[i].param); btdrv_delay(1); } } if (btdrv_cfg_tbl[i].opcode == HCI_DBG_SET_BT_SETTING_EXT1_CMD_OPCODE) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_2 && btdrv_cfg_tbl[i].parlen == sizeof(bt_setting_ext1_2300p_t3)) { btdrv_send_cmd(btdrv_cfg_tbl[i].opcode, btdrv_cfg_tbl[i].parlen, btdrv_cfg_tbl[i].param); btdrv_delay(1); } } // BT other config if (btdrv_cfg_tbl[i].is_act == BTDRV_CONFIG_ACTIVE) { btdrv_send_cmd(btdrv_cfg_tbl[i].opcode, btdrv_cfg_tbl[i].parlen, btdrv_cfg_tbl[i].param); btdrv_delay(1); } } // BT registers config for (uint8_t i = 0; i < sizeof(mem_config_2300p) / sizeof(mem_config_2300p[0]); i++) { btdrv_write_memory(_32_Bit, mem_config_2300p[i][0], (uint8_t *)&mem_config_2300p[i][1], 4); btdrv_delay(1); } if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { btdrv_digital_config_init_2300p_t1(); if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { btdrv_digital_config_init_2300p_t2(); } } if (btdrv_get_controller_trace_dump_enable()) { bt_drv_reg_op_controller_mem_log_config(); } bt_drv_config_lmp_filter_table(); bt_drv_func_ld_ibrt_sco_req_filter(); bt_drv_set_fa_invert_enable(BT_FA_INVERT_EN); } // zhangzhd agc config use default 1216 #define RX_GAIN_STEP0 -77 #define RX_GAIN_STEP1 -72 #define RX_GAIN_STEP2 -67 #define RX_GAIN_STEP3 -62 #define RX_GAIN_STEP4 -57 #define RX_GAIN_STEP5 -52 #define RX_GAIN_STEP6 -47 // zhangzhd agc config use default 1216 end void bt_drv_adaptive_fa_rx_gain(int8_t rssi) { #ifdef __FA_RX_GAIN_CTRL__ uint8_t gain_step = 0xff; static uint8_t old_step = 0xff; if (rssi <= RX_GAIN_STEP0) { gain_step = 0; } else if (rssi <= RX_GAIN_STEP1) { gain_step = 1; } else if (rssi <= RX_GAIN_STEP2) { gain_step = 2; } else if (rssi <= RX_GAIN_STEP3) { gain_step = 3; } else if (rssi <= RX_GAIN_STEP4) { gain_step = 4; } else if (rssi <= RX_GAIN_STEP5) { gain_step = 5; } else if (rssi <= RX_GAIN_STEP6) { gain_step = 6; } else { gain_step = 7; } if (old_step != gain_step) { BT_DRV_TRACE(2, "if rssi = %d,then set fa %d level ", rssi, gain_step); BT_DRV_REG_OP_ENTER(); bt_drv_reg_op_fa_gain_direct_set(gain_step); BT_DRV_REG_OP_EXIT(); old_step = gain_step; } #endif } bool btdrv_is_ecc_enable(void) { bool ret = false; #ifdef __FASTACK_ECC_ENABLE__ ret = true; #endif return ret; } #ifdef LAURENT_ALGORITHM void btdrv_bt_laurent_algorithm_enable(void) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { BT_DRV_TRACE(1, "%s", __func__); BTDIGITAL_REG(0xd03503a8) = 0x14664E88; BTDIGITAL_REG(0xd0350240) = 0x0001A40F; BTDIGITAL_REG(0xd0350364) = 0x202EB948; // lau_gain BTDIGITAL_REG(0xd0350374) = 0x00A40DCD; // c1c2 0x06001e0 BTDIGITAL_REG(0xd0350228) = 0x12040800; // clkmode BTDIGITAL_REG(0xd03503C8) = 0x00840CCD; // train c1c2 BTDIGITAL_REG(0xd03503A0) = 0x1C070065; // new corr en BTDIGITAL_REG(0xd0220460) = 0x039EF088; // mac laurent_en BTDIGITAL_REG(0xd0350370) = 0x6B240A3D; // laurent_en 0x BTDIGITAL_REG(0xd0350280) = 0x00000007; // bt_dfe_forcera BTDIGITAL_REG(0xd03502C4) = 0x127F02E8; // te_timeinit } } void btdrv_ble_laurent_algorithm_enable(void) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { BT_DRV_TRACE(1, "%s", __func__); BTDIGITAL_REG(0xd0350370) = 0x63240A3D; // lp disable BTDIGITAL_REG(0xd0350280) = 0x00000007; // dfe_forceraw=0 psd_avgen=1 } } #endif ////////////////////////////////////////test /// mode//////////////////////////////////////////// void btdrv_sleep_config(uint8_t sleep_en) { sleep_param[0] = sleep_en; btdrv_send_cmd(HCI_DBG_SET_SLEEP_SETTING_CMD_OPCODE, 8, sleep_param); btdrv_delay(1); } void btdrv_feature_default(void) { const uint8_t feature[] = {0xBF, 0xeE, 0xCD, 0xFe, 0xc3, 0xFf, 0x7b, 0x87}; btdrv_send_cmd(HCI_DBG_SET_LOCAL_FEATURE_CMD_OPCODE, 8, feature); btdrv_delay(1); } const uint8_t test_mode_addr[6] = {0x77, 0x77, 0x77, 0x77, 0x77, 0x77}; void btdrv_test_mode_addr_set(void) { return; btdrv_send_cmd(HCI_DBG_SET_BD_ADDR_CMD_OPCODE, sizeof(test_mode_addr), test_mode_addr); btdrv_delay(1); } uint8_t meInit_param_get_entry_idx = 0; int btdrv_meinit_param_init(void) { int size = 0; if ((me_init_param[0][0] == 0xffffffff) && (me_init_param[0][1] == 0xffffffff)) { size = -1; } meInit_param_get_entry_idx = 0; return size; } int btdrv_meinit_param_remain_size_get(void) { int remain_size; if ((me_init_param[0][0] == 0xffffffff) && (me_init_param[0][1] == 0xffffffff)) { return -1; } remain_size = ARRAY_SIZE(me_init_param) - meInit_param_get_entry_idx; return remain_size; } int btdrv_meinit_param_next_entry_get(uint32_t *addr, uint32_t *val) { if (meInit_param_get_entry_idx > (ARRAY_SIZE(me_init_param) - 1)) return -1; *addr = me_init_param[meInit_param_get_entry_idx][0]; *val = me_init_param[meInit_param_get_entry_idx][1]; meInit_param_get_entry_idx++; return 0; } enum { SYNC_IDLE, SYNC_64_ORG, SYNC_68_ORG, SYNC_72_ORG, SYNC_64_NEW, SYNC_68_NEW, SYNC_72_NEW, }; enum { SYNC_64_BIT, SYNC_68_BIT, SYNC_72_BIT, }; uint32_t bt_sync_type = SYNC_IDLE; void btdrv_sync_config(void) { uint32_t corr_mode = BTDIGITAL_REG(0xd0220460); uint32_t dfe_mode = BTDIGITAL_REG(0xd0350360); uint32_t timeinit = BTDIGITAL_REG(0xd03502c4); if (bt_sync_type == SYNC_IDLE) return; corr_mode = (corr_mode & 0xfffffff8); // bit2: enh dfe; [1:0]: bt_corr_mode dfe_mode = (dfe_mode & 0xffffffe0); // bit4: dfe_header_mode_bt; [3:0]: dfe_delay_cycle timeinit = (timeinit & 0xfffff800); //[10:0]: tetimeinit value switch (bt_sync_type) { case SYNC_64_ORG: corr_mode |= 0x0; dfe_mode |= 0x00; timeinit |= 0x2eb; break; case SYNC_68_ORG: corr_mode |= 0x1; dfe_mode |= 0x00; timeinit |= 0x2eb; break; case SYNC_72_ORG: corr_mode |= 0x2; dfe_mode |= 0x00; timeinit |= 0x2b7; break; case SYNC_64_NEW: corr_mode |= 0x4; dfe_mode |= 0x14; timeinit |= 0x2eb; break; case SYNC_68_NEW: corr_mode |= 0x5; dfe_mode |= 0x14; timeinit |= 0x2eb; break; case SYNC_72_NEW: corr_mode |= 0x6; dfe_mode |= 0x10; timeinit |= 0x2b7; break; } BTDIGITAL_REG(0xd0220460) = corr_mode; BTDIGITAL_REG(0xd0350360) = dfe_mode; BTDIGITAL_REG(0xd03502c4) = timeinit; } // HW SPI TRIG #define REG_SPI_TRIG_SELECT_LINK0_ADDR EM_BT_BT_EXT1_ADDR // 114a+66 #define REG_SPI_TRIG_SELECT_LINK1_ADDR \ (EM_BT_BT_EXT1_ADDR + BT_EM_SIZE) // 11b8+66 #define REG_SPI_TRIG_NUM_ADDR 0xd0220400 #define REG_SPI0_TRIG_POS_ADDR 0xd0220454 #define REG_SPI1_TRIG_POS_ADDR 0xd0220458 struct SPI_TRIG_NUM_T { uint32_t spi0_txon_num : 3; // spi0 number of tx rising edge uint32_t spi0_txoff_num : 3; // spi0 number of tx falling edge uint32_t spi0_rxon_num : 2; // spi0 number of rx rising edge uint32_t spi0_rxoff_num : 2; // spi0 number of rx falling edge uint32_t spi0_fast_mode : 1; uint32_t spi0_gap : 4; uint32_t hwspi0_en : 1; uint32_t spi1_txon_num : 3; // spi1 number of tx rising edge uint32_t spi1_txoff_num : 3; // spi1 number of tx falling edge uint32_t spi1_rxon_num : 2; // spi1 number of rx rising edge uint32_t spi1_rxoff_num : 2; // spi1 number of rx falling edge uint32_t spi1_fast_mode : 1; uint32_t spi1_gap : 4; uint32_t hwspi1_en : 1; }; struct SPI_TRIG_POS_T { uint32_t spi_txon_pos : 7; uint32_t spi_txoff_pos : 9; uint32_t spi_rxon_pos : 7; uint32_t spi_rxoff_pos : 9; }; struct spi_trig_data { uint32_t reg; uint32_t value; }; static const struct spi_trig_data spi0_trig_data_tbl[] = { //{addr,data([23:0])} {0xd0220404, 0x8080e9}, // spi0_trig_txdata1 {0xd0220408, 0x000000}, // spi0_trig_txdata2 {0xd022040c, 0x000000}, // spi0_trig_txdata3 {0xd0220410, 0x000000}, // spi0_trig_txdata4 #ifdef __FA_RX_GAIN_CTRL__ {0xd022041c, 0x0094bf}, // spi0_trig_rxdata1 #else {0xd022041c, 0x000000}, // spi0_trig_rxdata1 #endif {0xd0220420, 0x000000}, // spi0_trig_rxdata2 {0xd0220424, 0x000000}, // spi0_trig_rxdata3 {0xd0220428, 0x000000}, // spi0_trig_rxdata4 {0xd0220414, 0x000000}, // spi0_trig_trxdata5 {0xd0220418, 0x000000}, // spi0_trig_trxdata6 }; static const struct spi_trig_data spi1_trig_data_tbl[] = { //{addr,data([23:0])} #ifdef __FA_RX_GAIN_CTRL__ {0xd022042c, 0x8080e9}, // spi1_trig_txdata1 #else {0xd022042c, 0x000000}, // spi1_trig_txdata1 #endif {0xd0220430, 0x000000}, // spi1_trig_txdata2 {0xd0220434, 0x000000}, // spi1_trig_txdata3 {0xd0220438, 0x000000}, // spi1_trig_txdata4 #ifdef __FA_RX_GAIN_CTRL__ {0xd0220444, 0x0094bf}, // spi1_trig_rxdata1 #else {0xd0220444, 0x000000}, // spi1_trig_rxdata1 #endif {0xd0220448, 0x000000}, // spi1_trig_rxdata2 {0xd022044c, 0x000000}, // spi1_trig_rxdata3 {0xd0220450, 0x000000}, // spi1_trig_rxdata4 {0xd022043c, 0x000000}, // spi1_trig_trxdata5 {0xd0220440, 0x000000}, // spi1_trig_trxdata6 }; void btdrv_spi_trig_data_change(uint8_t spi_sel, uint8_t index, uint32_t value) { if (!spi_sel) { BTDIGITAL_REG(spi0_trig_data_tbl[index].reg) = value & 0xFFFFFF; } else { BTDIGITAL_REG(spi1_trig_data_tbl[index].reg) = value & 0xFFFFFF; } } void btdrv_spi_trig_data_set(uint8_t spi_sel) { if (!spi_sel) { for (uint8_t i = 0; i < ARRAY_SIZE(spi0_trig_data_tbl); i++) { BTDIGITAL_REG(spi0_trig_data_tbl[i].reg) = spi0_trig_data_tbl[i].value; } } else { for (uint8_t i = 0; i < ARRAY_SIZE(spi1_trig_data_tbl); i++) { BTDIGITAL_REG(spi1_trig_data_tbl[i].reg) = spi1_trig_data_tbl[i].value; } } } void btdrv_spi_trig_num_set(uint8_t spi_sel, struct SPI_TRIG_NUM_T *spi_trig_num) { uint8_t tx_onoff_total_num; uint8_t rx_onoff_total_num; if (!spi_sel) { tx_onoff_total_num = spi_trig_num->spi0_txon_num + spi_trig_num->spi0_txoff_num; rx_onoff_total_num = spi_trig_num->spi0_rxon_num + spi_trig_num->spi0_rxoff_num; } else { tx_onoff_total_num = spi_trig_num->spi1_txon_num + spi_trig_num->spi1_txoff_num; rx_onoff_total_num = spi_trig_num->spi1_rxon_num + spi_trig_num->spi1_rxoff_num; } ASSERT((tx_onoff_total_num <= 6), "spi trig tx_onoff_total_num>6"); ASSERT((rx_onoff_total_num <= 6), "spi trig rx_onoff_total_num>6"); BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) = *(uint32_t *)spi_trig_num; } void btdrv_spi_trig_pos_set(uint8_t spi_sel, struct SPI_TRIG_POS_T *spi_trig_pos) { if (!spi_sel) { BTDIGITAL_REG(REG_SPI0_TRIG_POS_ADDR) = *(uint32_t *)spi_trig_pos; } else { BTDIGITAL_REG(REG_SPI1_TRIG_POS_ADDR) = *(uint32_t *)spi_trig_pos; } } #ifdef __FA_RX_GAIN_CTRL__ void btdrv_spi_trig_init(void) { struct SPI_TRIG_NUM_T spi_trig_num; struct SPI_TRIG_POS_T spi0_trig_pos; struct SPI_TRIG_POS_T spi1_trig_pos; spi_trig_num.spi0_txon_num = 0; spi_trig_num.spi0_txoff_num = 0; spi_trig_num.spi0_rxon_num = 1; spi_trig_num.spi0_rxoff_num = 0; spi_trig_num.spi0_fast_mode = 0; spi_trig_num.spi0_gap = 4; spi_trig_num.hwspi0_en = 1; spi_trig_num.spi1_txon_num = 0; spi_trig_num.spi1_txoff_num = 1; spi_trig_num.spi1_rxon_num = 1; spi_trig_num.spi1_rxoff_num = 0; spi_trig_num.spi1_fast_mode = 0; spi_trig_num.spi1_gap = 4; spi_trig_num.hwspi1_en = 1; btdrv_spi_trig_num_set(0, &spi_trig_num); btdrv_spi_trig_num_set(1, &spi_trig_num); spi0_trig_pos.spi_txon_pos = 0; spi0_trig_pos.spi_txoff_pos = 0; spi0_trig_pos.spi_rxon_pos = 25; spi0_trig_pos.spi_rxoff_pos = 0; spi1_trig_pos.spi_txon_pos = 0; spi1_trig_pos.spi_txoff_pos = 0; spi1_trig_pos.spi_rxon_pos = 110; spi1_trig_pos.spi_rxoff_pos = 0; btdrv_spi_trig_pos_set(0, &spi0_trig_pos); btdrv_spi_trig_pos_set(1, &spi1_trig_pos); btdrv_spi_trig_data_set(0); btdrv_spi_trig_data_set(1); } #else void btdrv_spi_trig_init(void) { struct SPI_TRIG_NUM_T spi_trig_num; struct SPI_TRIG_POS_T spi0_trig_pos; struct SPI_TRIG_POS_T spi1_trig_pos; spi_trig_num.spi0_txon_num = 0; spi_trig_num.spi0_txoff_num = 1; spi_trig_num.spi0_rxon_num = 0; spi_trig_num.spi0_rxoff_num = 0; spi_trig_num.spi0_fast_mode = 0; spi_trig_num.spi0_gap = 4; spi_trig_num.hwspi0_en = 0; spi_trig_num.spi1_txon_num = 0; spi_trig_num.spi1_txoff_num = 0; spi_trig_num.spi1_rxon_num = 0; spi_trig_num.spi1_rxoff_num = 0; spi_trig_num.spi1_fast_mode = 0; spi_trig_num.spi1_gap = 0; spi_trig_num.hwspi1_en = 0; btdrv_spi_trig_num_set(0, &spi_trig_num); btdrv_spi_trig_num_set(1, &spi_trig_num); spi0_trig_pos.spi_txon_pos = 0; spi0_trig_pos.spi_txoff_pos = 20; spi0_trig_pos.spi_rxon_pos = 0; spi0_trig_pos.spi_rxoff_pos = 0; spi1_trig_pos.spi_txon_pos = 0; spi1_trig_pos.spi_txoff_pos = 0; spi1_trig_pos.spi_rxon_pos = 0; spi1_trig_pos.spi_rxoff_pos = 0; btdrv_spi_trig_pos_set(0, &spi0_trig_pos); btdrv_spi_trig_pos_set(1, &spi1_trig_pos); btdrv_spi_trig_data_set(0); btdrv_spi_trig_data_set(1); } #endif void btdrv_spi_trig_select(uint8_t link_id, bool spi_set) { BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + link_id * BT_EM_SIZE) |= (spi_set << 14); } uint8_t btdrv_get_spi_trig_enable(uint8_t spi_sel) { if (!spi_sel) { return ((BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) & 0x8000) >> 15); } else { return ((BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) & 0x80000000) >> 31); } } void btdrv_set_spi_trig_enable(uint8_t spi_sel) { if (!spi_sel) { BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) |= (1 << 15); // spi0 } else { BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) |= (1 << 31); // spi1 } } void btdrv_clear_spi_trig_enable(uint8_t spi_sel) { if (!spi_sel) { BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) &= ~0x8000; } else { BTDIGITAL_REG(REG_SPI_TRIG_NUM_ADDR) &= ~0x80000000; } } bool btdrv_get_lmp_trace_enable(void) { return g_lmp_trace_enable; } void btdrv_set_lmp_trace_enable(void) { g_lmp_trace_enable = true; } void btdrv_set_controller_trace_enable(uint8_t trace_level) { g_controller_trace_level = trace_level; } uint8_t btdrv_get_controller_trace_level(void) { return g_controller_trace_level; } void btdrv_fast_lock_config(bool fastlock_on) { uint16_t val = 0; if (fastlock_on) { btdrv_read_rf_reg(0x1AE, &val); btdrv_write_rf_reg(0x1AE, val | (1 << 9) | (1 << 11)); BTDIGITAL_REG(0xd0220468) |= 1 << 26; // fast lock enable } else { btdrv_read_rf_reg(0x1AE, &val); btdrv_write_rf_reg(0x1AE, val & (~((1 << 9) | (1 << 11)))); BTDIGITAL_REG(0xd0220468) &= (~(1 << 26)); // fast lock disable } } #ifdef __FASTACK_ECC_ENABLE__ void btdrv_ecc_config(void) { #define INVALID 0xff #define ECC_8PSK 0 #define ECC_DPSK 1 #define ECC_GFSK 2 #define ECC_1BLOCK 0 #define ECC_2BLOCK 1 #define ECC_3BLOCK 2 const uint32_t fa_2m = 0; const uint32_t fastlock_on = 0; const uint32_t bt_sys_52m_en = 0; const uint32_t ecc_mode_enable = 0; const uint32_t ecc_psk_mode = ECC_DPSK; const uint32_t ecc_blk_mode = ECC_3BLOCK; if (bt_sys_52m_en) { BTDIGITAL_REG(0x4008003c) |= 1; BTDIGITAL_REG(0x40080018) |= 1; BTDIGITAL_REG(0x40080004) |= (1 << 15) | (1 << 30); // osc x4 enable BTDIGITAL_REG(0xd0330038) |= (3 << 6) | (1 << 11); BTDIGITAL_REG(0xd03300f0) |= 1; } if (fa_2m) { BTDIGITAL_REG(0xd0220464) |= 1 << 29; // fast ack 2M mode enable 1, disable // 0 } else { BTDIGITAL_REG(0xd0220464) &= (~(1 << 29)); // fast ack 2M mode enable 1, disable 0 } // 1302: RF 0x1AE[9] = 1; // 1402: RF 0x64[15] = 1; BTDIGITAL_REG(0xd0330038) |= (1 << 9); // jiangpeng test result ok btdrv_fast_lock_config(fastlock_on); if (fastlock_on) { if (fa_2m) BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x1914); else BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x1e14); } else { if (fa_2m) BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x3530); else BTDIGITAL_REG_SET_FIELD(0xd0220468, 0xffff, 0, 0x3528); } if (ecc_mode_enable) { BTDIGITAL_REG(0xd0220464) |= (0x1 << 15); ////enable ecc mode BTDIGITAL_REG(0xd0220464) &= ~(0x1F << 24); // ecc time adj BTDIGITAL_REG(0xd0220464) |= (0x1 << 25); ////en ecc time adj if (ecc_psk_mode == ECC_8PSK) { BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 3); // ECC 8PSK } else if (ecc_psk_mode == ECC_DPSK) { BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 2); // ECC DPSK } else if (ecc_psk_mode == ECC_GFSK) { BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 13, 1); // ECC GFSK } if (ecc_blk_mode == ECC_1BLOCK) { BTDIGITAL_REG(0xd022048c) &= ~0x3ff; BTDIGITAL_REG(0xd022048c) |= 0xef; // set ecc len ECC 1 block } else if (ecc_blk_mode == ECC_2BLOCK) { BTDIGITAL_REG(0xd022048c) &= ~0x3ff; BTDIGITAL_REG(0xd022048c) |= 0x1de; // set ecc len, ECC 2 block } else if (ecc_blk_mode == ECC_3BLOCK) { BTDIGITAL_REG(0xd022048c) &= ~0x3ff; BTDIGITAL_REG(0xd022048c) |= 0x2cd; // set ecc len ECC 3 block } } else { BTDIGITAL_REG(0xd0220464) &= (~(0x1 << 15)); ////disable ecc mode } } #endif void btdrv_hw_agc_stop_mode(enum BT_SYNCMODE_REQ_USER_T user, bool hw_agc_mode) { #ifdef __HW_AGC__ static uint8_t bt_syncmode_map = 0; uint32_t lock; lock = int_lock(); uint32_t reg_val = BTDIGITAL_REG(0xd03503a8); if (hw_agc_mode) { if (bt_syncmode_map == 0) { // set bit28 0 : rx win timeout, stop agc reg_val &= ~(1 << 28); BTDIGITAL_REG(0xd03503a8) = reg_val; } bt_syncmode_map |= (1 << user); } else { bt_syncmode_map &= ~(1 << user); if (bt_syncmode_map == 0) { // set bit28 1 : sync find, stop agc reg_val |= (1 << 28); BTDIGITAL_REG(0xd03503a8) = reg_val; } } int_unlock(lock); #endif }