/*************************************************************************** * * 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_reg_op.h" #include "CrashCatcher.h" #include "bt_drv.h" #include "bt_drv_2300p_internal.h" #include "bt_drv_interface.h" #include "bt_drv_internal.h" #include "cmsis.h" #include "hal_chipid.h" #include "hal_iomux.h" #include "hal_sysfreq.h" #include "hal_trace.h" #include static uint32_t bt_ram_start_addr = 0; static uint32_t hci_fc_env_addr = 0; static uint32_t ld_acl_env_addr = 0; static uint32_t bt_util_buf_env_addr = 0; static uint32_t em_buf_env_addr = 0; static uint32_t sniffer_env_addr = 0; static uint32_t dbg_state_addr = 0; static uint32_t lc_state_addr = 0; static uint32_t task_message_buffer_addr = 0; static uint32_t lmp_message_buffer_addr = 0; static uint32_t ld_sco_env_addr = 0; static uint32_t rx_monitor_addr = 0; static uint32_t lc_env_addr = 0; static uint32_t dbg_bt_setting_addr = 0; static uint32_t lm_nb_sync_active_addr = 0; static uint32_t lm_env_addr = 0; static uint32_t pending_seq_error_link_addr = 0; static uint32_t hci_env_addr = 0; static uint32_t lc_sco_env_addr = 0; static uint32_t llm_le_env_addr = 0; static uint32_t ld_env_addr = 0; static uint32_t rwip_env_addr = 0; static uint32_t MIC_BUFF_addr = 0; static uint32_t g_mem_dump_ctrl_addr = 0; static uint32_t ble_rx_monitor_addr = 0; static uint32_t reconnecting_flag_addr = 0; static uint32_t link_connect_bak_addr = 0; static uint32_t tws_link_id_addr = 0; static uint32_t llc_env_addr = 0; static uint32_t dbg_bt_setting_ext1_addr = 0; static uint32_t rwip_rf_addr = 0; void bt_drv_reg_op_global_symbols_init(void) { bt_ram_start_addr = 0xc0000000; if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { hci_fc_env_addr = 0xC00067c4; ld_acl_env_addr = 0xc000098c; bt_util_buf_env_addr = 0xc00059fc; em_buf_env_addr = 0xc000656c; sniffer_env_addr = 0xc0006358; dbg_state_addr = 0xc00058c4; lc_state_addr = 0xc0005c7c; task_message_buffer_addr = 0xc00007cc; lmp_message_buffer_addr = 0xc0000834; ld_sco_env_addr = 0xc0000980; rx_monitor_addr = 0xc00058fc; lc_env_addr = 0xc0005c70; dbg_bt_setting_addr = 0xc0005854; lm_nb_sync_active_addr = 0xc00007c0; lm_env_addr = 0xc0005afc; hci_env_addr = 0xc0006764; lc_sco_env_addr = 0xc00007a4; llm_le_env_addr = 0xc00063f0; ld_env_addr = 0xc0005d34; rwip_env_addr = 0xc00003d4; MIC_BUFF_addr = 0xc0005920; ble_rx_monitor_addr = 0xc00058ec; llc_env_addr = 0xc00064f8; rwip_rf_addr = 0xc00041a0; } else if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { hci_fc_env_addr = 0xC0006838; ld_acl_env_addr = 0xc0000998; bt_util_buf_env_addr = 0xc0005a18; em_buf_env_addr = 0xc00065e0; sniffer_env_addr = 0xc00063c8; dbg_state_addr = 0xc00058e0; lc_state_addr = 0xc0005ce4; task_message_buffer_addr = 0xc00007c4; lmp_message_buffer_addr = 0xc000082c; ld_sco_env_addr = 0xc000098c; rx_monitor_addr = 0xc0005918; lc_env_addr = 0xc0005cd8; dbg_bt_setting_addr = 0xc0005868; lm_nb_sync_active_addr = 0xc00007b8; lm_env_addr = 0xc0005b64; pending_seq_error_link_addr = 0xc0000335; hci_env_addr = 0xc00067d8; lc_sco_env_addr = 0xc000079c; llm_le_env_addr = 0xc0006460; ld_env_addr = 0xc0005d9c; rwip_env_addr = 0xc00003c8; MIC_BUFF_addr = 0xc000593c; ble_rx_monitor_addr = 0xc0005908; link_connect_bak_addr = 0xc00061c8; llc_env_addr = 0xc0006568; rwip_rf_addr = 0xc00041b4; } else if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { hci_fc_env_addr = 0xC0006940; ld_acl_env_addr = 0xc00009d4; bt_util_buf_env_addr = 0xc0005b24; em_buf_env_addr = 0xc00066e8; sniffer_env_addr = 0xc00064d0; dbg_state_addr = 0xc00059b0; lc_state_addr = 0xc0005df0; task_message_buffer_addr = 0xc0000820; lmp_message_buffer_addr = 0xc0000888; ld_sco_env_addr = 0xc00009e4; rx_monitor_addr = 0xc0005a24; lc_env_addr = 0xc0005de4; dbg_bt_setting_addr = 0xc0005938; lm_nb_sync_active_addr = 0xc0000814; lm_env_addr = 0xc0005c70; pending_seq_error_link_addr = 0xc000034f; hci_env_addr = 0xc00068e0; lc_sco_env_addr = 0xc00007f8; llm_le_env_addr = 0xc0006568; ld_env_addr = 0xc0005ea8; rwip_env_addr = 0xc00003dc; MIC_BUFF_addr = 0xc0005a48; g_mem_dump_ctrl_addr = 0xc00059d4; ble_rx_monitor_addr = 0xc0005a14; reconnecting_flag_addr = 0xc0000a1c; link_connect_bak_addr = 0xc00062d0; tws_link_id_addr = 0xc000034e; llc_env_addr = 0xc0006670; dbg_bt_setting_ext1_addr = 0xc000591c; rwip_rf_addr = 0xc0004268; } } void bt_drv_reg_op_rssi_set(uint16_t rssi) {} void bt_drv_reg_op_scan_intv_set(uint32_t scan_intv) {} void bt_drv_reg_op_encryptchange_errcode_reset(uint16_t hci_handle) {} void bt_drv_reg_op_sco_sniffer_checker(void) {} void bt_drv_reg_op_trigger_time_checker(void) { BT_DRV_REG_OP_ENTER(); BT_DRV_TRACE(1, "BT_REG_OP:0xd02201f0 = %x", *(volatile uint32_t *)0xd02201f0); BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_tws_output_power_fix_separate(uint16_t hci_handle, uint16_t pwr) {} #define SNIFF_IN_SCO 2 /// BD Address structure struct bd_addr { /// 6-byte array address value uint8_t addr[6]; }; /// device info structure struct ld_device_info { struct bd_addr bd_addr; uint8_t link_id; uint8_t state; }; bool bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_get(void) { return false; } void bt_drv_reg_op_ld_sniffer_env_monitored_dev_state_set(bool state) {} void bt_drv_reg_op_ibrt_env_reset(void) { struct ld_device_info *mobile_device_info; BT_DRV_REG_OP_ENTER(); bool status = false; if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { mobile_device_info = (struct ld_device_info *)(sniffer_env_addr + 4); status = true; } if (status) { mobile_device_info->link_id = 3; mobile_device_info->state = 0; } BT_DRV_REG_OP_EXIT(); } int bt_drv_reg_op_currentfreeaclbuf_get(void) { BT_DRV_REG_OP_ENTER(); // ACL packert number of host set - ACL number of controller has been send to // host hci_fc_env.host_set.acl_pkt_nb - hci_fc_env.cntr.acl_pkt_sent if (hci_fc_env_addr != 0) { return (*(volatile uint16_t *)(hci_fc_env_addr + 0x4) - *(volatile uint16_t *)(hci_fc_env_addr + 0xc)); } else { return 0; } BT_DRV_REG_OP_EXIT(); } static uint16_t mobile_sync_info; void bt_drv_reg_op_save_mobile_airpath_info(uint16_t hciHandle) { BT_DRV_REG_OP_ENTER(); uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); if (btdrv_is_link_index_valid(link_id)) { mobile_sync_info = BT_DRIVER_GET_U16_REG_VAL(EM_BT_BTADDR1_ADDR + BT_EM_SIZE * link_id); BT_DRV_TRACE(1, "BT_REG_OP: save xfer mobile sync info 0x%x ", mobile_sync_info); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_block_xfer_with_mobile(uint16_t hciHandle) { BT_DRV_REG_OP_ENTER(); uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); if (btdrv_is_link_index_valid(link_id)) { BT_DRIVER_PUT_U16_REG_VAL((EM_BT_BTADDR1_ADDR + BT_EM_SIZE * link_id), mobile_sync_info ^ 0x8000); BT_DRV_TRACE(2, "BT_REG_OP: block xfer with mobile, save hci handle 0x%x sync " "info as 0x%x", hciHandle, mobile_sync_info ^ 0x8000); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_resume_xfer_with_mobile(uint16_t hciHandle) { BT_DRV_REG_OP_ENTER(); uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); if (btdrv_is_link_index_valid(link_id)) { BT_DRIVER_PUT_U16_REG_VAL((EM_BT_BTADDR1_ADDR + BT_EM_SIZE * link_id), mobile_sync_info); BT_DRV_TRACE(2, "BT_REG_OP:resume xfer with mobile, hci handle 0x%x as 0x%x", hciHandle, mobile_sync_info); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_block_fast_ack_with_mobile(void) { /* * ibrt master set its fast ack sync bit wrong,let itself NACK mobile link * always */ BT_DRV_REG_OP_ENTER(); bt_drv_set_fa_invert_enable(BT_FA_INVERT_DISABLE); BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_resume_fast_ack_with_mobile(void) { /* * old master recovery its fast ack sync bit right */ BT_DRV_REG_OP_ENTER(); bt_drv_set_fa_invert_enable(BT_FA_INVERT_EN); BT_DRV_REG_OP_EXIT(); } int bt_drv_reg_op_packet_type_checker(uint16_t hciHandle) { return 0; } void bt_drv_reg_op_max_slot_setting_checker(uint16_t hciHandle) {} void bt_drv_reg_op_force_task_dbg_idle(void) {} void bt_drv_reg_op_afh_follow_mobile_mobileidx_set(uint16_t hciHandle) {} void bt_drv_reg_op_afh_follow_mobile_twsidx_set(uint16_t hciHandle) {} void bt_drv_reg_op_afh_bak_reset(void) {} void bt_drv_reg_op_afh_bak_save(uint8_t role, uint16_t mobileHciHandle) {} void bt_drv_reg_op_connection_checker(void) {} void bt_drv_reg_op_sco_status_store(void) {} void bt_drv_reg_op_sco_status_restore(void) {} void bt_drv_reg_op_afh_set_default(void) {} void bt_drv_reg_op_ld_sniffer_master_addr_set(uint8_t *addr) {} void bt_drv_reg_op_lsto_hack(uint16_t hciHandle, uint16_t lsto) { uint32_t acl_par_ptr = 0; // ld_acl_env if (ld_acl_env_addr) { acl_par_ptr = *(uint32_t *)(ld_acl_env_addr + (hciHandle - 0x80) * 4); } if (acl_par_ptr) { BT_DRV_TRACE(3, "BT_REG_OP:Set the lsto for hciHandle=0x%x, from:0x%x to 0x%x", hciHandle, *(uint16_t *)(acl_par_ptr + 154), lsto); *(uint16_t *)(acl_par_ptr + 154) = lsto; } else { BT_DRV_TRACE(0, "BT_REG_OP:ERROR,acl par address error"); } } uint16_t bt_drv_reg_op_get_lsto(uint16_t hciHandle) { uint32_t acl_par_ptr = 0; uint16_t lsto = 0; // ld_acl_env if (ld_acl_env_addr) { acl_par_ptr = *(uint32_t *)(ld_acl_env_addr + (hciHandle - 0x80) * 4); } if (acl_par_ptr) { lsto = *(uint16_t *)(acl_par_ptr + 154); BT_DRV_TRACE(2, "BT_REG_OP:lsto=0x%x for hciHandle=0x%x", lsto, hciHandle); } else { lsto = 0xffff; BT_DRV_TRACE(0, "BT_REG_OP:ERROR,acl par null ptr"); } return lsto; } uint8_t bt_drv_reg_opmsbc_find_tx_sync(uint8_t *buff) { BT_DRV_REG_OP_ENTER(); uint8_t i; for (i = 0; i < 60; i++) { if (buff[i] == 0x1 && buff[(i + 2) % 60] == 0xad) { // BT_DRV_TRACE(1,"MSBC tx sync find =%d",i); return i; } } BT_DRV_TRACE(0, "BT_REG_OP:TX No pACKET"); BT_DRV_REG_OP_EXIT(); return 0; } bool bt_drv_reg_op_sco_tx_buf_restore(uint8_t *trigger_test) { uint8_t offset; bool nRet = false; BT_DRV_REG_OP_ENTER(); offset = bt_drv_reg_opmsbc_find_tx_sync((uint8_t *)EM_BT_AUDIOBUF_OFF); if (offset != 0) { #ifndef APB_PCM *trigger_test = (((BTDIGITAL_REG(0xd022045c) & 0x3f)) + (60 - offset)) % 64; #endif BT_DRV_TRACE(2, "BT_REG_OP:TX BUF ERROR trigger_test=%p,offset=%x", trigger_test, offset); DUMP8("%02x ", (uint8_t *)EM_BT_AUDIOBUF_OFF, 10); // BT_DRV_TRACE(2,"pcm reg=%x %x",*(uint32_t *)0xd0220468,*(uint32_t // *)0x400000f0); nRet = true; } BT_DRV_REG_OP_EXIT(); return nRet; } int bt_drv_reg_op_acl_chnmap(uint16_t hciHandle, uint8_t *chnmap, uint8_t chnmap_len) { uint32_t acl_evt_ptr = 0; uint8_t *chnmap_ptr = 0; uint8_t link_id = btdrv_conhdl_to_linkid(hciHandle); if (!btdrv_is_link_index_valid(link_id)) { memset(chnmap, 0, chnmap_len); return -1; } if (chnmap_len < 10) { memset(chnmap, 0, chnmap_len); return -1; } if (ld_acl_env_addr) { acl_evt_ptr = *(volatile uint32_t *)(ld_acl_env_addr + link_id * 4); } if (acl_evt_ptr != 0) { chnmap_ptr = (uint8_t *)(acl_evt_ptr + 0x34); } if (!chnmap_ptr) { memset(chnmap, 0, chnmap_len); return -1; } else { memcpy(chnmap, chnmap_ptr, chnmap_len); } return 0; } extern "C" uint32_t hci_current_left_tx_packets_left(void); extern "C" uint32_t hci_current_left_rx_packets_left(void); extern "C" uint32_t hci_current_rx_packet_complete(void); extern "C" uint8_t hci_current_rx_aclfreelist_cnt(void); void bt_drv_reg_op_bt_info_checker(void) { #ifdef __CLK_GATE_DISABLE__ uint32_t *rx_buf_ptr = NULL; uint32_t *tx_buf_ptr = NULL; uint8_t rx_free_buf_count = 0, i = 0; uint8_t tx_free_buf_count = 0; uint16_t em_buf; BT_DRV_REG_OP_ENTER(); if (bt_util_buf_env_addr) { rx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr + 0x14); // bt_util_buf_env.acl_rx_free tx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr + 0x28); // bt_util_buf_env.acl_tx_free } while (rx_buf_ptr && *rx_buf_ptr) { rx_free_buf_count++; rx_buf_ptr = (uint32_t *)(*rx_buf_ptr); } uint8_t em_buf_count = 0; for (i = 0; i < 4; i++) { em_buf = BT_DRIVER_GET_U16_REG_VAL(EM_BT_RXACLBUFPTR_ADDR + i * REG_EM_BT_RXDESC_SIZE); if (em_buf != 0) em_buf_count++; } BT_DRV_TRACE( 4, "BT_REG_OP: rxbuff = %x,embuff =%x , host rx buff in controller = %x,%x", rx_free_buf_count, em_buf_count, hci_current_left_rx_packets_left(), bt_drv_reg_op_currentfreeaclbuf_get()); // check tx buff while (tx_buf_ptr && *tx_buf_ptr) { tx_free_buf_count++; tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); } BT_DRV_TRACE(2, "BT_REG_OP:txbuff = %x,acl tx host in controller = %x ", tx_free_buf_count, hci_current_left_tx_packets_left()); bt_drv_reg_op_controller_state_checker(); BT_DRV_REG_OP_EXIT(); #endif } #if 0 uint32_t *rxbuff; uint16_t *send_count; uint16_t *free_count; uint16_t *bt_send_count; #endif void bt_drv_reg_op_ble_buffer_cleanup(void) {} struct ke_timer { /// next ke timer struct ke_timer *next; /// message identifier uint16_t id; /// task identifier uint16_t task; /// time value uint32_t time; }; struct co_list_hdr { /// Pointer to next co_list_hdr struct co_list_hdr *next; }; /// structure of a list struct co_list_con { /// pointer to first element of the list struct co_list_hdr *first; /// pointer to the last element struct co_list_hdr *last; /// number of element in the list uint32_t cnt; /// max number of element in the list uint32_t maxcnt; /// min number of element in the list uint32_t mincnt; }; struct mblock_free { /// Next free block pointer struct mblock_free *next; /// Previous free block pointer struct mblock_free *previous; /// Size of the current free block (including delimiter) uint16_t free_size; /// Used to check if memory block has been corrupted or not uint16_t corrupt_check; }; bool bt_drv_reg_op_get_dbg_state(void) { // dbg_state if (dbg_state_addr) { return (*(uint8_t *)dbg_state_addr); } else { return false; } } uint8_t bt_drv_reg_op_get_controller_tx_free_buffer(void) { uint32_t *tx_buf_ptr = NULL; uint8_t tx_free_buf_count = 0; if (bt_util_buf_env_addr) { tx_buf_ptr = (uint32_t *)(bt_util_buf_env_addr + 0x28); // bt_util_buf_env.acl_tx_free } else { BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); return 0; } // check tx buff while (tx_buf_ptr && *tx_buf_ptr) { tx_free_buf_count++; tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); } return tx_free_buf_count; } uint8_t bt_drv_reg_op_get_controller_ble_tx_free_buffer(void) { uint32_t *tx_buf_ptr = NULL; uint8_t tx_free_buf_count = 0; if (em_buf_env_addr) { tx_buf_ptr = (uint32_t *)(em_buf_env_addr + 0x14); // em_buf_env.tx_buff_free } else { BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); return 0; } // check tx buff while (tx_buf_ptr && *tx_buf_ptr) { tx_free_buf_count++; tx_buf_ptr = (uint32_t *)(*tx_buf_ptr); } return tx_free_buf_count; } void bt_drv_reg_op_controller_state_checker(void) { BT_DRV_REG_OP_ENTER(); if (lc_state_addr != 0) { BT_DRV_TRACE(1, "BT_REG_OP: LC_STATE=0x%x", *(uint32_t *)lc_state_addr); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_tx_flow_checker(void) { BT_DRV_REG_OP_ENTER(); uint8_t link_id = 0; uint32_t acl_par_ptr = 0; for (link_id = 0; link_id < 3; link_id++) { if (ld_acl_env_addr) { acl_par_ptr = *(volatile uint32_t *)(ld_acl_env_addr + link_id * 4); } if (acl_par_ptr) { BT_DRV_TRACE(2, "linkid =%d, tx flow=%d", link_id, *(uint8_t *)(acl_par_ptr + 0xc0)); } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_controller_ble_flow_checker(void) { uint8_t link_id = 0; uint32_t llc_env_tag_ptr = 0; uint32_t ea_elt_tag_ptr = 0; uint32_t *tx_acl_rdy_ptr = NULL; uint32_t *tx_acl_tofree_ptr = NULL; uint32_t tx_acl_rdy_count = 0; uint32_t tx_acl_tofree_count = 0; if (!llc_env_addr) { BT_DRV_TRACE(1, "REG_OP: please fix %s", __func__); return; } for (link_id = 0; link_id < 3; link_id += 1) { llc_env_tag_ptr = *(volatile uint32_t *)(llc_env_addr + link_id * 4); if (!llc_env_tag_ptr) { continue; } ea_elt_tag_ptr = *(volatile uint32_t *)(((uint32_t)llc_env_tag_ptr) + 16); if (!ea_elt_tag_ptr) { continue; } tx_acl_rdy_ptr = (uint32_t *)(((uint32_t)ea_elt_tag_ptr) + 48); tx_acl_rdy_count = 0; while (tx_acl_rdy_ptr && *tx_acl_rdy_ptr) { tx_acl_rdy_count++; tx_acl_rdy_ptr = (uint32_t *)(*tx_acl_rdy_ptr); } tx_acl_tofree_ptr = (uint32_t *)(((uint32_t)ea_elt_tag_ptr) + 68); tx_acl_tofree_count = 0; while (tx_acl_tofree_ptr && *tx_acl_tofree_ptr) { tx_acl_tofree_count++; tx_acl_tofree_ptr = (uint32_t *)(*tx_acl_tofree_ptr); } BT_DRV_TRACE(3, "linkid =%d, ble tx alloc=%d tofree=%d", link_id, tx_acl_rdy_count, tx_acl_tofree_count); } } uint8_t bt_drv_reg_op_force_get_lc_state(uint16_t conhdl) { if (lc_state_addr != 0) { // BT_DRV_TRACE(1,"BT_REG_OP: read LC_STATE=0x%x",*(uint32_t // *)lc_state_addr); uint8_t idx = btdrv_conhdl_to_linkid(conhdl); if (btdrv_is_link_index_valid(idx)) { uint8_t *lc_state = (uint8_t *)lc_state_addr; return lc_state[idx]; } } return 0; } void bt_drv_reg_op_force_set_lc_state(uint16_t conhdl, uint8_t state) { // lc_state if (lc_state_addr != 0) { BT_DRV_TRACE(1, "BT_REG_OP: read LC_STATE=0x%x", *(uint32_t *)lc_state_addr); uint8_t idx = btdrv_conhdl_to_linkid(conhdl); if (btdrv_is_link_index_valid(idx)) { uint8_t *lc_state = (uint8_t *)lc_state_addr; lc_state[idx] = state; } } } void bt_drv_reg_op_crash_dump(void) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { uint8_t *bt_dump_mem_start = (uint8_t *)bt_ram_start_addr; uint32_t bt_dump_len_max = 0x8000; // uint8_t *mcu_dump_mem_start = (uint8_t*)0x20000000; // uint32_t mcu_dump_len_max = RAM_SIZE; // uint8_t *em_dump_area_1_start = (uint8_t*)0xd0220000; // uint32_t em_area_1_len_max = 0x04A8; uint8_t *em_dump_area_2_start = (uint8_t *)0xd0210000; uint32_t em_area_2_len_max = 0x8000; BT_DRV_TRACE(1, "BT_REG_OP:BT 2300p: metal id=%d", hal_get_chip_metal_id()); // first move R3 to R9, lost R9 BT_DRV_TRACE(1, "BT controller BusFault_Handler:\nREG:[LR] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE)); BT_DRV_TRACE(1, "REG:[R0] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 120)); BT_DRV_TRACE(1, "REG:[R1] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 124)); BT_DRV_TRACE(1, "REG:[R2] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 128)); BT_DRV_TRACE(1, "REG:[R3] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 132)); BT_DRV_TRACE(1, "REG:[R4] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 4)); BT_DRV_TRACE(1, "REG:[R5] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 8)); BT_DRV_TRACE(1, "REG:[R6] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 12)); BT_DRV_TRACE(1, "REG:[R7] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 16)); BT_DRV_TRACE(1, "REG:[R8] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 20)); hal_sys_timer_delay(MS_TO_TICKS(100)); // BT_DRV_TRACE(1,"REG:[R9] = 0x%08x", // BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE +24)); BT_DRV_TRACE(1, "REG:[sl] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 28)); BT_DRV_TRACE(1, "REG:[fp] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 32)); BT_DRV_TRACE(1, "REG:[ip] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 36)); BT_DRV_TRACE(1, "REG:[SP,#0] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 40)); BT_DRV_TRACE(1, "REG:[SP,#4] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 44)); BT_DRV_TRACE(1, "REG:[SP,#8] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 48)); BT_DRV_TRACE(1, "REG:[SP,#12] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 52)); BT_DRV_TRACE(1, "REG:[SP,#16] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 56)); BT_DRV_TRACE(1, "REG:[SP,#20] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 60)); BT_DRV_TRACE(1, "REG:[SP,#24] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 64)); BT_DRV_TRACE(1, "REG:[SP,#28] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 68)); hal_sys_timer_delay(MS_TO_TICKS(100)); BT_DRV_TRACE(1, "REG:[SP,#32] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 72)); BT_DRV_TRACE(1, "REG:[SP,#36] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 76)); BT_DRV_TRACE(1, "REG:[SP,#40] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 80)); BT_DRV_TRACE(1, "REG:[SP,#44] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 84)); BT_DRV_TRACE(1, "REG:[SP,#48] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 88)); BT_DRV_TRACE(1, "REG:[SP,#52] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 92)); BT_DRV_TRACE(1, "REG:[SP,#56] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 96)); BT_DRV_TRACE(1, "REG:[SP,#60] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 100)); BT_DRV_TRACE(1, "REG:[SP,#64] = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 104)); BT_DRV_TRACE(1, "REG:SP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 108)); BT_DRV_TRACE(1, "REG:MSP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 112)); BT_DRV_TRACE(1, "REG:PSP = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 116)); BT_DRV_TRACE(1, "REG:CFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 120)); BT_DRV_TRACE(1, "REG:BFAR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 124)); BT_DRV_TRACE(1, "REG:HFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 128)); BT_DRV_TRACE(1, "REG:ICSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 132)); BT_DRV_TRACE(1, "REG:AIRCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 136)); BT_DRV_TRACE(1, "REG:SCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 140)); BT_DRV_TRACE(1, "REG:CCR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 144)); BT_DRV_TRACE(1, "REG:SHCSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 148)); BT_DRV_TRACE(1, "REG:AFSR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 152)); BT_DRV_TRACE(1, "REG:MMFAR = 0x%08x", BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 156)); hal_sys_timer_delay(MS_TO_TICKS(100)); // task_message_buffer uint32_t buff_addr = 0; if (task_message_buffer_addr) { buff_addr = task_message_buffer_addr; } BT_DRV_TRACE(2, "0xd0330050: 0x%x, 54:0x%x", *(uint32_t *)0xd0330050, *(uint32_t *)0xd0330054); BT_DRV_TRACE(2, "0x400000a0: 0x%x, a4:0x%x", *(uint32_t *)0x400000a0, *(uint32_t *)0x400000a4); if (g_mem_dump_ctrl_addr) { BT_DRV_TRACE(1, "LMP addr=0x%x", *(uint32_t *)(g_mem_dump_ctrl_addr + 4)); BT_DRV_TRACE(1, "STA addr=0x%x", *(uint32_t *)(g_mem_dump_ctrl_addr + 0x10)); BT_DRV_TRACE(1, "MSG addr=0x%x", *(uint32_t *)(g_mem_dump_ctrl_addr + 0x1c)); BT_DRV_TRACE(1, "SCH addr=0x%x", *(uint32_t *)(g_mem_dump_ctrl_addr + 0x28)); BT_DRV_TRACE(1, "ISR addr=0x%x", *(uint32_t *)(g_mem_dump_ctrl_addr + 0x34)); } BT_DRV_TRACE(0, "task msg buff:"); if (buff_addr != 0) { for (uint8_t j = 0; j < 5; j++) { DUMP8("%02x ", (uint8_t *)(buff_addr + j * 20), 20); } } hal_sys_timer_delay(MS_TO_TICKS(100)); BT_DRV_TRACE(0, " "); BT_DRV_TRACE(0, "lmp buff:"); // lmp_message_buffer if (lmp_message_buffer_addr) { buff_addr = lmp_message_buffer_addr; } if (buff_addr != 0) { for (uint8_t j = 0; j < 10; j++) { DUMP8("%02x ", (uint8_t *)(buff_addr + j * 20), 20); } } hal_sys_timer_delay(MS_TO_TICKS(100)); uint8_t link_id = 0; uint32_t evt_ptr = 0; uint32_t acl_par_ptr = 0; for (link_id = 0; link_id < 3; link_id++) { BT_DRV_TRACE(1, "acl_par: link id %d", link_id); if (ld_acl_env_addr) { evt_ptr = *(uint32_t *)(ld_acl_env_addr + link_id * 4); } if (evt_ptr) { acl_par_ptr = evt_ptr; BT_DRV_TRACE(5, "acl_par: acl_par_ptr 0x%x, clk off 0x%x, bit off 0x%x, " "last sync clk off 0x%x, last sync bit off 0x%x", acl_par_ptr, *(uint32_t *)(acl_par_ptr + 140), *(uint16_t *)(acl_par_ptr + 150), *(uint32_t *)(acl_par_ptr + 136), ((*(uint32_t *)(acl_par_ptr + 150)) & 0xFFFF0000) >> 16); } } hal_sys_timer_delay(MS_TO_TICKS(100)); // ld_sco_env evt_ptr = 0; if (ld_sco_env_addr) { evt_ptr = *(uint32_t *)ld_sco_env_addr; } if (evt_ptr != 0) { BT_DRV_TRACE(1, "esco linkid :%d", *(uint8_t *)(evt_ptr + 70)); for (link_id = 0; link_id < 3; link_id++) { BT_DRV_TRACE(2, "bt_linkcntl_linklbl 0x%x: link id %d", *(uint16_t *)(EM_BT_LINKCNTL_ADDR + link_id * BT_EM_SIZE), link_id); BT_DRV_TRACE( 1, "rxcount :%x", *(uint16_t *)(EM_BT_RXDESCCNT_ADDR + link_id * BT_EM_SIZE)); } } btdrv_dump_mem(bt_dump_mem_start, bt_dump_len_max, BT_SUB_SYS_TYPE); // btdrv_dump_mem(em_dump_area_1_start, em_area_1_len_max, // BT_EM_AREA_1_TYPE); btdrv_dump_mem(em_dump_area_2_start, em_area_2_len_max, BT_EM_AREA_2_TYPE); // btdrv_dump_mem(mcu_dump_mem_start, mcu_dump_len_max, MCU_SYS_TYPE); } } uint8_t bt_drv_reg_op_get_tx_pwr(uint16_t connHandle) { uint8_t idx; uint16_t localVal; uint8_t tx_pwr = 0; idx = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(idx)) { localVal = BT_DRIVER_GET_U16_REG_VAL(EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE); tx_pwr = ((localVal & ((uint16_t)0x000000FF)) >> 0); } return tx_pwr; } void bt_drv_reg_op_set_tx_pwr(uint16_t connHandle, uint8_t txpwr) { BT_DRV_REG_OP_ENTER(); uint8_t idx = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(idx)) { BT_DRIVER_PUT_U16_REG_VAL( EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE, (BT_DRIVER_GET_U16_REG_VAL(EM_BT_PWRCNTL_ADDR + idx * BT_EM_SIZE) & ~((uint16_t)0x000000FF)) | ((uint16_t)txpwr << 0)); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_fix_tx_pwr(uint16_t connHandle) { BT_DRV_REG_OP_ENTER(); bt_drv_reg_op_set_tx_pwr(connHandle, LBRT_TX_PWR_FIX); BT_DRV_REG_OP_EXIT(); } //#define __ACCESS_MODE_ADJUST_GAIN__ //#define __SWAGC_MODE_ADJUST_GAIN__ #define __REBOOT_PAIRING_MODE_ADJUST_GAIN__ void bt_drv_reg_op_set_accessible_mode(uint8_t mode) {} void bt_drv_reg_op_set_swagc_mode(uint8_t mode) {} void bt_drv_reg_op_set_reboot_pairing_mode(uint8_t mode) {} void bt_drv_reg_op_force_sco_retrans(bool enable) { #ifdef __FORCE_SCO_MAX_RETX__ BT_DRV_REG_OP_ENTER(); if (enable) { BTDIGITAL_REG_SET_FIELD(0xd0220468, 3, 24, 3); } else { BTDIGITAL_REG_SET_FIELD(0xd0220468, 3, 24, 0); } BT_DRV_REG_OP_EXIT(); #endif } void bt_drv_reg_op_enable_pcm_tx_hw_cal(void) { BT_DRV_REG_OP_ENTER(); *(volatile uint32_t *)0xd0220468 |= 1 << 22; *(volatile uint32_t *)0x400000f0 |= 1; BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_monitor_clk(void) { BT_DRV_REG_OP_ENTER(); uint32_t env0 = 0; uint32_t env1 = 0; uint32_t env2 = 0; if (ld_acl_env_addr) { env0 = *(uint32_t *)ld_acl_env_addr; env1 = *(uint32_t *)(ld_acl_env_addr + 4); env1 = *(uint32_t *)(ld_acl_env_addr + 8); } if (env0 & bt_ram_start_addr) { env0 += 0x8c; BT_DRV_TRACE(2, "BT_REG_OP:env0 clk off=%x %x", *(uint32_t *)env0, *(uint16_t *)EM_BT_CLKOFF0_ADDR | (*(uint16_t *)EM_BT_CLKOFF1_ADDR << 16)); } if (env1 & bt_ram_start_addr) { env1 += 0x8c; BT_DRV_TRACE(2, "BT_REG_OP:env1 clk off=%x %x", *(uint32_t *)env1, *(uint16_t *)(EM_BT_CLKOFF0_ADDR + BT_EM_SIZE) | (*(uint16_t *)(EM_BT_CLKOFF1_ADDR + BT_EM_SIZE) << 16)); } if (env2 & bt_ram_start_addr) { env2 += 0x8c; BT_DRV_TRACE( 2, "BT_REG_OP:env2 clk off=%x %x", *(uint32_t *)env2, *(uint16_t *)(EM_BT_CLKOFF0_ADDR + BT_EM_SIZE * 2) | (*(uint16_t *)(EM_BT_CLKOFF1_ADDR + BT_EM_SIZE * 2) << 16)); } BT_DRV_REG_OP_EXIT(); } bool bt_drv_reg_op_read_rssi_in_dbm(uint16_t connHandle, rx_agc_t *rx_val) { #ifdef BT_RSSI_MONITOR BT_DRV_REG_OP_ENTER(); if (connHandle == 0xFFFF) return false; if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { uint8_t idx = btdrv_conhdl_to_linkid(connHandle); /// Accumulated RSSI (to compute an average value) int16_t rssi_acc = 0; /// Counter of received packets used in RSSI average uint8_t rssi_avg_cnt = 1; rx_agc_t *rx_monitor_env = NULL; if (!btdrv_is_link_index_valid(idx)) { return false; } // rx_monitor if (rx_monitor_addr) { rx_monitor_env = (rx_agc_t *)rx_monitor_addr; } if (rx_monitor_env != NULL) { for (int i = 0; i < rssi_avg_cnt; i++) { rssi_acc += rx_monitor_env[idx].rssi; } rx_val->rssi = rssi_acc / rssi_avg_cnt; rx_val->rxgain = rx_monitor_env[idx].rxgain; } } BT_DRV_REG_OP_EXIT(); return true; #else return false; #endif } bool bt_drv_reg_op_read_ble_rssi_in_dbm(uint16_t connHandle, rx_agc_t *rx_val) { #ifdef BT_RSSI_MONITOR BT_DRV_REG_OP_ENTER(); if (connHandle == 0xFFFF) return false; if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { uint8_t idx = connHandle; /// Accumulated RSSI (to compute an average value) int16_t rssi_acc = 0; /// Counter of received packets used in RSSI average uint8_t rssi_avg_cnt = 1; rx_agc_t *rx_monitor_env = NULL; if (idx > 2) return false; // invalid idx // rx_monitor if (ble_rx_monitor_addr) { rx_monitor_env = (rx_agc_t *)ble_rx_monitor_addr; } if (rx_monitor_env != NULL) { for (int i = 0; i < rssi_avg_cnt; i++) { rssi_acc += rx_monitor_env[idx].rssi; } rx_val->rssi = rssi_acc / rssi_avg_cnt; rx_val->rxgain = rx_monitor_env[idx].rxgain; } } BT_DRV_REG_OP_EXIT(); return true; #else return false; #endif } void bt_drv_reg_op_acl_silence(uint16_t connHandle, uint8_t silence) { BT_DRV_REG_OP_ENTER(); uint8_t idx = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(idx)) { BT_DRIVER_PUT_U16_REG_VAL( EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE, (BT_DRIVER_GET_U16_REG_VAL(EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE) & ~((uint16_t)0x00008000)) | ((uint16_t)silence << 15)); } BT_DRV_REG_OP_EXIT(); } /// sniffer connect information environment structure struct ld_sniffer_connect_env { /// uint16_t bitoff; /// uint32_t clk_offset; /// uint8_t map[10]; /// uint32_t afh_instant; /// uint8_t afh_mode; /// uint8_t enc_mode; /// uint8_t ltk[16]; /// uint8_t role; }; void bt_drv_reg_op_call_monitor(uint16_t connHandle, uint8_t tws_role) {} void bt_drv_reg_op_lock_sniffer_sco_resync(void) {} void bt_drv_reg_op_unlock_sniffer_sco_resync(void) {} void bt_drv_reg_op_ibrt_retx_att_nb_set(uint8_t retx_nb) { BT_DRV_REG_OP_ENTER(); int ret = -1; uint32_t sco_evt_ptr = 0x0; // TODO: [ld_sco_env address] based on CHIP id if (ld_sco_env_addr) { sco_evt_ptr = *(volatile uint32_t *)ld_sco_env_addr; ret = 0; } if (ret == 0) { uint32_t retx_ptr = 0x0; if (sco_evt_ptr != 0) { // offsetof(struct ea_elt_tag, env) + sizeof(struct ld_sco_evt_params) retx_ptr = sco_evt_ptr + 0x44; } else { BT_DRV_TRACE(0, "BT_REG_OP:Error, ld_sco_env[0].evt ==NULL"); ret = -2; } if (ret == 0) { *(volatile uint8_t *)retx_ptr = retx_nb; } } BT_DRV_TRACE(3, "BT_REG_OP:%s,ret=%d,retx nb=%d", __func__, ret, retx_nb); BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_acl_tx_type_set(uint16_t hciHandle, uint8_t slot_sel) { uint32_t lc_ptr = 0; uint32_t acl_par_ptr = 0; uint32_t packet_type_addr = 0; // lc_env and ld_acl_env if (lc_env_addr) { lc_ptr = *(uint32_t *)(lc_env_addr + (hciHandle - 0x80) * 4); } if (ld_acl_env_addr) { acl_par_ptr = *(uint32_t *)(ld_acl_env_addr + (hciHandle - 0x80) * 4); } // sanity check if (lc_ptr == 0) { return; } else { packet_type_addr = (uint32_t)(acl_par_ptr + 176); BT_DRV_TRACE(3, "BT_REG_OP:%s hdl=0x%x packet_types=0x%x", __func__, hciHandle, *(uint16_t *)(packet_type_addr)); BT_DRV_TRACE(2, "BT_REG_OP:lc_ptr 0x%x, acl_par_ptr 0x%x", lc_ptr, acl_par_ptr); uint16_t edr_type = 0; if (slot_sel == USE_1_SLOT_PACKET) { #if defined(__3M_PACK__) edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX); #else edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX); #endif } else if (slot_sel == USE_3_SLOT_PACKET) { #if defined(__3M_PACK__) edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX) | (1 << DH3_2_IDX) | (1 << DH3_3_IDX); #else edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH3_2_IDX); #endif } else if (slot_sel == USE_5_SLOT_PACKET) { #if defined(__3M_PACK__) edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH1_3_IDX) | (1 << DH3_2_IDX) | (1 << DH3_3_IDX) | (1 << DH5_2_IDX) | (1 << DH5_3_IDX); #else edr_type = (1 << DM1_IDX) | (1 << DH1_2_IDX) | (1 << DH3_2_IDX) | (1 << DH5_2_IDX); #endif } *(uint16_t *)(packet_type_addr) = ((edr_type << 8) | (*(uint16_t *)(packet_type_addr)&0xff)); BT_DRV_TRACE(1, "BT_REG_OP:After op,packet_types 0x%x", *(uint16_t *)(packet_type_addr)); } } void bt_drv_reg_op_acl_tx_type_trace(uint16_t hciHandle) { uint32_t acl_par_ptr = 0; uint32_t packet_type_addr = 0; // ld_acl_env if (ld_acl_env_addr) { acl_par_ptr = *(uint32_t *)(ld_acl_env_addr + (hciHandle - 0x80) * 4); } // sanity check if (acl_par_ptr == 0) { return; } else { packet_type_addr = (uint32_t)(acl_par_ptr + 176); BT_DRV_TRACE(1, "BT_REG_OP:tx packet_types=0x%x", *(uint16_t *)(packet_type_addr)); } } uint8_t bt_drv_reg_op_acl_tx_type_get(uint16_t hciHandle, uint8_t *br_type, uint8_t *edr_type) { uint8_t status = 0xff; uint32_t lc_ptr = 0; uint32_t acl_par_ptr = 0; uint32_t packet_type_addr = 0; if (lc_env_addr) { lc_ptr = *(uint32_t *)(lc_env_addr + (hciHandle - 0x80) * 4); } if (ld_acl_env_addr) { acl_par_ptr = *(uint32_t *)(ld_acl_env_addr + (hciHandle - 0x80) * 4); } // sanity check if (lc_ptr == 0) { BT_DRV_TRACE(2, "BT_REG_OP:%s hdl=0x%x,lc_env_ptr = NULL", __func__, hciHandle); } else { packet_type_addr = (uint32_t)(acl_par_ptr + 176); uint16_t packet_type = *(uint16_t *)(packet_type_addr); if (br_type) { *br_type = packet_type & 0xff; } if (edr_type) { *br_type = (packet_type >> 8) & 0xff; } status = 0; BT_DRV_TRACE(3, "BT_REG_OP:%s hdl=0x%x packet_types=0x%x", __func__, hciHandle, packet_type); } return status; } uint16_t em_bt_bitoff_getf(int elt_idx) { uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_BITOFF_ADDR + elt_idx * BT_EM_SIZE); ASSERT_ERR((localVal & ~((uint16_t)0x000003FF)) == 0); return (localVal >> 0); } void em_bt_bitoff_setf(int elt_idx, uint16_t bitoff) { ASSERT_ERR((((uint16_t)bitoff << 0) & ~((uint16_t)0x000003FF)) == 0); BTDIGITAL_EM_BT_WR(EM_BT_BITOFF_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)bitoff << 0); } void em_bt_clkoff0_setf(int elt_idx, uint16_t clkoff0) { ASSERT_ERR((((uint16_t)clkoff0 << 0) & ~((uint16_t)0x0000FFFF)) == 0); BTDIGITAL_EM_BT_WR(EM_BT_CLKOFF0_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)clkoff0 << 0); } uint16_t em_bt_clkoff0_getf(int elt_idx) { uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_CLKOFF0_ADDR + elt_idx * BT_EM_SIZE); ASSERT_ERR((localVal & ~((uint16_t)0x0000FFFF)) == 0); return (localVal >> 0); } void em_bt_clkoff1_setf(int elt_idx, uint16_t clkoff1) { ASSERT_ERR((((uint16_t)clkoff1 << 0) & ~((uint16_t)0x000007FF)) == 0); BTDIGITAL_EM_BT_WR(EM_BT_CLKOFF1_ADDR + elt_idx * BT_EM_SIZE, (uint16_t)clkoff1 << 0); } uint16_t em_bt_clkoff1_getf(int elt_idx) { uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_CLKOFF1_ADDR + elt_idx * BT_EM_SIZE); ASSERT_ERR((localVal & ~((uint16_t)0x000007FF)) == 0); return (localVal >> 0); } void em_bt_wincntl_pack(int elt_idx, uint8_t rxwide, uint16_t rxwinsz) { ASSERT_ERR((((uint16_t)rxwide << 15) & ~((uint16_t)0x00008000)) == 0); ASSERT_ERR((((uint16_t)rxwinsz << 0) & ~((uint16_t)0x00000FFF)) == 0); BTDIGITAL_EM_BT_WR(EM_BT_WINCNTL_ADDR + elt_idx * BT_EM_SIZE, ((uint16_t)rxwide << 15) | ((uint16_t)rxwinsz << 0)); } void bt_drv_reg_op_update_sniffer_bitoffset(uint16_t mobile_conhdl, uint16_t master_conhdl) {} void bt_drv_reg_op_modify_bitoff_timer(uint16_t time_out) {} void bt_drv_reg_op_cs_monitor(void) { uint32_t addr; addr = BT_EM_ADDR_BASE + 0x1e; BT_DRV_TRACE(0, "BT_REG_OP:AFH 0:"); DUMP8("%02x ", (uint8_t *)addr, 10); addr = BT_EM_ADDR_BASE + 0x1e + 110; BT_DRV_TRACE(0, "AFH 1:"); DUMP8("%02x ", (uint8_t *)addr, 10); addr = BT_EM_ADDR_BASE + 0x1e + 220; BT_DRV_TRACE(0, "AFH 2:"); DUMP8("%02x ", (uint8_t *)addr, 10); uint32_t tmp1, tmp2, tmp3; tmp1 = BT_EM_ADDR_BASE + 0x8; tmp2 = BT_EM_ADDR_BASE + 0x8 + 110; tmp3 = BT_EM_ADDR_BASE + 0x8 + 220; BT_DRV_TRACE(3, "AFH EN:%x %x %x ", *(uint16_t *)tmp1, *(uint16_t *)tmp2, *(uint16_t *)tmp3); tmp1 = BT_EM_ADDR_BASE + 0x28; tmp2 = BT_EM_ADDR_BASE + 0x28 + 110; tmp3 = BT_EM_ADDR_BASE + 0x28 + 220; BT_DRV_TRACE(3, "AFH ch num:%x %x %x ", *(uint16_t *)tmp1, *(uint16_t *)tmp2, *(uint16_t *)tmp3); tmp1 = BT_EM_ADDR_BASE + 0x4; tmp2 = BT_EM_ADDR_BASE + 0x4 + 110; tmp3 = BT_EM_ADDR_BASE + 0x4 + 220; BT_DRV_TRACE(3, "clk off:%x %x %x ", *(uint32_t *)tmp1, *(uint32_t *)tmp2, *(uint32_t *)tmp3); tmp1 = BT_EM_ADDR_BASE + 0x2; tmp2 = BT_EM_ADDR_BASE + 0x2 + 110; tmp3 = BT_EM_ADDR_BASE + 0x2 + 220; BT_DRV_TRACE(3, "bitoff:%x %x %x ", *(uint16_t *)tmp1, *(uint16_t *)tmp2, *(uint16_t *)tmp3); } void bt_drv_reg_op_ble_llm_substate_hacker(void) {} bool bt_drv_reg_op_check_esco_acl_sniff_conflict(uint16_t hciHandle) { return false; } void bt_drv_reg_op_esco_acl_sniff_delay_cal(uint16_t hciHandle, bool enable) {} uint8_t bt_drv_reg_op_get_role(uint8_t linkid) { uint32_t lc_evt_ptr = 0; uint32_t role_ptr = 0; if (lc_env_addr) { lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + linkid * 4); // lc_env } if (lc_evt_ptr != 0) { role_ptr = lc_evt_ptr + 0x40; } else { BT_DRV_TRACE(1, "BT_REG_OP:ERROR LINKID =%x", linkid); return 0xFF; } return *(uint8_t *)role_ptr; } void bt_drv_reg_op_set_tpoll(uint8_t linkid, uint16_t poll_interval) { uint32_t acl_evt_ptr = 0x0; uint32_t poll_addr; if (ld_acl_env_addr) { acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr + linkid * 4); } if (acl_evt_ptr != 0) { poll_addr = acl_evt_ptr + 0xb8; *(uint16_t *)poll_addr = poll_interval; } else { BT_DRV_TRACE(1, "BT_REG_OP:ERROR LINK ID FOR TPOLL %x", linkid); } } int8_t bt_drv_reg_op_rssi_correction(int8_t rssi) { #ifdef __HW_AGC__ if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { // the rssi is already corrected return rssi; } #endif return rssi; } void bt_drv_reg_op_set_music_link(uint8_t link_id) { // dbg_bt_setting.music_playing_link if (dbg_bt_setting_addr) { *(uint8_t *)(dbg_bt_setting_addr + 0x10) = link_id; } } void bt_drv_reg_op_set_music_link_duration_extra(uint8_t slot) { if (dbg_bt_setting_addr) { *(uint32_t *)(dbg_bt_setting_addr + 0x14) = slot * 625; } } void bt_drv_reg_op_set_hwagc_read_en(uint8_t en) {} uint32_t bt_drv_reg_op_get_reconnecting_flag() { uint32_t ret = 0; if (reconnecting_flag_addr) { ret = *(uint32_t *)reconnecting_flag_addr; } return ret; } void bt_drv_reg_op_set_reconnecting_flag() { if (reconnecting_flag_addr) { *(uint32_t *)reconnecting_flag_addr = 1; } } void bt_drv_reg_op_clear_reconnecting_flag() { if (reconnecting_flag_addr) { *(uint32_t *)reconnecting_flag_addr = 0; } } void bt_drv_reg_op_music_link_config(uint16_t active_link, uint8_t active_role, uint16_t inactive_link, uint8_t inactive_role) { BT_DRV_TRACE(4, "BT_REG_OP:bt_drv_reg_op_music_link_config %x %d %x %d", active_link, active_role, inactive_link, inactive_role); if (active_role == 0) // MASTER { bt_drv_reg_op_set_tpoll(active_link - 0x80, 0x10); if (inactive_role == 0) { bt_drv_reg_op_set_tpoll(inactive_link - 0x80, 0x40); } } else { bt_drv_reg_op_set_music_link(active_link - 0x80); bt_drv_reg_op_set_music_link_duration_extra(11); if (inactive_role == 0) { bt_drv_reg_op_set_tpoll(inactive_link - 0x80, 0x40); } } } bool bt_drv_reg_op_check_bt_controller_state(void) { bool ret = true; BT_DRV_REG_OP_ENTER(); if (hal_sysfreq_get() <= HAL_CMU_FREQ_32K) return ret; if ((BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 0) == 0x00) && (BTDIGITAL_REG(BT_CONTROLLER_CRASH_DUMP_ADDR_BASE + 8) == MIC_BUFF_addr)) ret = true; else ret = false; if (false == ret) { BT_DRV_TRACE(0, "controller dead!!!"); btdrv_trigger_coredump(); } BT_DRV_REG_OP_EXIT(); return ret; } void bt_drv_reg_op_piconet_clk_offset_get(uint16_t connHandle, int32_t *clock_offset, uint16_t *bit_offset) { uint8_t index = 0; uint32_t clock_offset_raw = 0; BT_DRV_REG_OP_ENTER(); if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_0) { if (connHandle) { index = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(index)) { *bit_offset = em_bt_bitoff_getf(index); clock_offset_raw = (em_bt_clkoff1_getf(index) << 16) | em_bt_clkoff0_getf(index); *clock_offset = clock_offset_raw; *clock_offset = (*clock_offset << 5) >> 5; } else { *bit_offset = 0; *clock_offset = 0; } } else { *bit_offset = 0; *clock_offset = 0; } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_afh_env_reset(void) { BT_DRV_REG_OP_ENTER(); int ret = -1; uint32_t ld_afh_env_addr = 0x0; if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { ld_afh_env_addr = ld_env_addr + 0x198; ret = 0; if (ret == 0) { struct ld_afh_env *ld_afh_env = (struct ld_afh_env *)ld_afh_env_addr; if (ld_afh_env) { BT_DRV_TRACE(0, "BT_REG_OP:reset ld_afh_env"); ld_afh_env->rf_rssi_interf_thr = BT_AFH_RSSI_INTERF_THR; ld_afh_env->afh_update_period = BT_AFH_UPDATE_PERIOD; ld_afh_env->afh_access_valid_to = BT_AFH_ASSESS_VALID_TO; ld_afh_env->afh_reaccess_to = BT_AFH_REASSESS_TO; ld_afh_env->afh_access_count_max = BT_AFH_ASSESS_COUNT_MAX; ld_afh_env->afh_access_count_thr_good = BT_AFH_ASSESS_COUNT_THR_GOOD; ld_afh_env->afh_access_count_thr_bad = BT_AFH_ASSESS_COUNT_THR_BAD; ld_afh_env->afh_access_count_min = BT_AFH_ASSESS_COUNT_MIN; } } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_dma_tc_clkcnt_get(uint32_t *btclk, uint16_t *btcnt) { BT_DRV_REG_OP_ENTER(); *btclk = *((volatile uint32_t *)0xd02201fc); *btcnt = *((volatile uint32_t *)0xd02201f8); BT_DRV_REG_OP_EXIT(); } void em_bt_bt_ext1_tx_silence_setf(int elt_idx, uint8_t txsilence) { ASSERT_ERR((((uint16_t)txsilence << 15) & ~((uint16_t)0x00008000)) == 0); BTDIGITAL_EM_BT_WR( EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00008000)) | ((uint16_t)txsilence << 15)); } void em_bt_bt_ext1_bw_2m_setf(int elt_idx, uint8_t bw2m) { ASSERT_ERR((((uint16_t)bw2m << 11) & ~((uint16_t)0x00000800)) == 0); BTDIGITAL_EM_BT_WR( EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00000800)) | ((uint16_t)bw2m << 11)); } void em_bt_bt_ext1_sco_tx_silence_setf(int elt_idx, uint8_t scotxsilence) { ASSERT_ERR((((uint16_t)scotxsilence << 13) & ~((uint16_t)0x00002000)) == 0); BTDIGITAL_EM_BT_WR( EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE, (BTDIGITAL_BT_EM(EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE) & ~((uint16_t)0x00002000)) | ((uint16_t)scotxsilence << 13)); } void bt_drv_reg_op_acl_tx_silence(uint16_t connHandle, uint8_t on) { return; BT_DRV_REG_OP_ENTER(); uint8_t idx = btdrv_conhdl_to_linkid(connHandle); BT_DRV_TRACE(2, "BT_REG_OP:BT ACL tx silence idx=%d,on=%d\n", idx, on); if (btdrv_is_link_index_valid(idx)) { if (TX_SILENCE_ON == on) { // config ACL silence cs em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_ON); if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { // config SCO silence cs em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_ON); // select ACL silence BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 2, 2); } } else if (TX_SILENCE_OFF == on) { // config ACL silence cs em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_OFF); if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { // config SCO silence cs em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_OFF); // select ACL silence BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 2, 3); } } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_acl_tx_silence_clear(uint16_t connHandle) { uint8_t idx = btdrv_conhdl_to_linkid(connHandle); BT_DRV_TRACE(1, "BT_REG_OP:ACL tx silence clear idx=%d\n", idx); if (btdrv_is_link_index_valid(idx)) { em_bt_bt_ext1_tx_silence_setf(idx, TX_SILENCE_OFF); if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { // config SCO silence cs em_bt_bt_ext1_sco_tx_silence_setf(idx, TX_SILENCE_OFF); // select ACL silence BTDIGITAL_REG_SET_FIELD(0xd02204a8, 3, 2, 3); } } bt_drv_reg_op_resume_fast_ack_with_mobile(); } void bt_drv_reg_op_sw_seq_filter(uint16_t connHandle) {} void bt_drv_reg_op_pcm_set(uint8_t en) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { if (en) *(volatile unsigned int *)(0xd02204a8) &= 0xffffffdf; else *(volatile unsigned int *)(0xd02204a8) |= 1 << 5; } } uint8_t bt_drv_reg_op_pcm_get() { uint8_t ret = 1; if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { ret = (*(volatile unsigned int *)(0xd02204a8) & 0x00000020) >> 5; } return ~ret; } void bt_drv_reg_op_clear_skip_flag() {} void bt_drv_reg_op_clean_flags_of_ble_and_sco(void) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_0) { // 0xc0006a18,////sco_find_sync_flag // 0xc000699c,///ble_sco_need_move_flag // 0xc000693c,///prev_conflict_type_record // 0xc000099f,///anchor_resume_flag ASSERT(*(uint32_t *)0xc0006a14 == 0xc0006a18, "ERROR 2300pt1 sco_find_sync_flag!"); ASSERT(*(uint32_t *)0xc0006998 == 0xc000699c, "ERROR 2300pt1 ble_sco_need_move_flag!"); ASSERT(*(uint32_t *)0xc0006938 == 0xc000693c, "ERROR 2300pt1 prev_conflict_type_record!"); // BT_DRV_TRACE(4,"0xc0006a18=%x,0xc000699c=%x,0xc000693c=%x,0xc000099f=%x\n",*(volatile // uint32_t *)0xc0006a18,*(volatile uint32_t *)0xc000699c,*(volatile // uint32_t // *)0xc000693c,*(volatile uint32_t *)0xc000099f); *(volatile uint32_t *)0xc0006a18 = 0; *(volatile uint32_t *)0xc0006a88 = 0; *(volatile uint32_t *)0xc000693c = 0; *(volatile uint32_t *)0xc000099f = 0; } } const uint8_t msbc_mute_patten[] = { 0x01, 0x38, 0xad, 0x0, 0x0, 0xc5, 0x0, 0x0, 0x0, 0x0, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c, 0x00}; #define SCO_TX_FIFO_BASE (0xd0210000) #if defined(CVSD_BYPASS) #define SCO_TX_MUTE_PATTERN (0x5555) #else #define SCO_TX_MUTE_PATTERN (0x0000) #endif void bt_drv_reg_op_sco_txfifo_reset(uint16_t codec_id) { uint32_t reg_val = BTDIGITAL_REG(0xd0220148); uint32_t reg_offset0, reg_offset1; uint16_t *patten_p = (uint16_t *)msbc_mute_patten; reg_offset0 = (reg_val & 0xffff); reg_offset1 = (reg_val >> 16) & 0xffff; if (codec_id == 2) { for (uint8_t i = 0; i < 60; i += 2) { BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE + reg_offset0 + i) = *patten_p; BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE + reg_offset1 + i) = *patten_p; patten_p++; } } else { for (uint8_t i = 0; i < 120; i += 2) { BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE + reg_offset0 + i) = SCO_TX_MUTE_PATTERN; BTDIGITAL_BT_EM(SCO_TX_FIFO_BASE + reg_offset1 + i) = SCO_TX_MUTE_PATTERN; } } } /***************************************************************************** Prototype : btdrv_set_tws_acl_poll_interval Description : in ibrt mode, set tws acl poll interval Input : uint16_t poll_interval Output : None Return Value : Calls : Called By : History : Date : 2019/4/19 Author : bestechnic Modification : Created function *****************************************************************************/ void btdrv_reg_op_set_private_tws_poll_interval(uint16_t poll_interval, uint16_t poll_interval_in_sco) { BT_DRV_TRACE( 2, "BT_REG_OP:Set private tws interval,acl interv=%d,acl interv insco =%d", poll_interval, poll_interval_in_sco); if (dbg_bt_setting_addr) { *(volatile uint16_t *)(dbg_bt_setting_addr + 0x40) = poll_interval; *(volatile uint16_t *)(dbg_bt_setting_addr + 0x42) = poll_interval_in_sco; } } void btdrv_reg_op_set_tws_link_duration(uint8_t slot_num) { BT_DRV_REG_OP_ENTER(); // dbg_setting address uint32_t op_addr = 0; if (dbg_bt_setting_addr) { op_addr = dbg_bt_setting_addr; } if (op_addr != 0) { // uint16_t acl_slot = dbg_setting->acl_slot_in_snoop_mode; uint16_t val = *(volatile uint16_t *)(op_addr + 0x44); val &= 0xff00; val |= slot_num; *(volatile uint16_t *)(op_addr + 0x44) = val; BT_DRV_TRACE(1, "BT_REG_OP:Set private tws link duration,val=%d", *((volatile uint16_t *)(op_addr + 0x44)) & 0xff); } BT_DRV_REG_OP_EXIT(); } void btdrv_reg_op_enable_private_tws_schedule(bool enable) { BT_DRV_REG_OP_ENTER(); // sniffer_env uint32_t op_addr = 0; if (sniffer_env_addr) { op_addr = sniffer_env_addr; } if (op_addr != 0) { // sniffer_env.acl_switch_flag.in_process uint16_t val = *((volatile uint16_t *)(op_addr + 0x7e)); val &= 0xff; if (enable) { val |= 1 << 8; } *((volatile uint16_t *)(op_addr + 0x7e)) = val; BT_DRV_TRACE(1, "BT_REG_OP:Enable private tws function,flag=%d", (*((volatile uint16_t *)(op_addr + 0x7e))) >> 8); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_decrease_tx_pwr_when_reconnect(bool enable) { if (enable) { BT_DRV_TRACE(0, "BT_REG_OP:Decrese tx pwr"); // drease defualt TX pwr BTDIGITAL_REG(0xd0350300) = 0x33; } else { BT_DRV_TRACE(0, "BT_REG_OP:Increase tx pwr"); // resume defualt TX pwr BTDIGITAL_REG(0xd0350300) = 0x11; } } /* rwip_heap_env from addr=0xc00027b8 left_length=6K rwip_heap_non_ret from addr=0xc00052b8 left_length=1.5K */ void bt_drv_reg_op_controller_mem_log_config(void) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { uint32_t each_log_length = 0x200; // 512Byte uint32_t lmp_mem_addr = 0xc00027b8 + 0x64; // lmp:each_log_length uint32_t msg_mem_addr = lmp_mem_addr + each_log_length + 0x64; // msg:each_log_length uint32_t sta_mem_addr = msg_mem_addr + each_log_length + 0x64; // sta:each_log_length uint32_t sch_mem_addr = sta_mem_addr + each_log_length + 0x64; // sch:each_log_length uint32_t isr_mem_addr = sch_mem_addr + each_log_length + 0x64; // isr:each_log_length // LMP_DUMP_TRACE *(uint32_t *)g_mem_dump_ctrl_addr = each_log_length; // g_mem_dump_ctrl[0].len_max default:1024 *(uint32_t *)(g_mem_dump_ctrl_addr + 4) = lmp_mem_addr; // g_mem_dump_ctrl[0].start_addr *(uint8_t *)(g_mem_dump_ctrl_addr + 8) = 0x01; // g_mem_dump_ctrl[0].trace_enable // MSG_DUMP_TRACE *(uint32_t *)(g_mem_dump_ctrl_addr + 0xc) = each_log_length; // g_mem_dump_ctrl[1].len_max default:1024 *(uint32_t *)(g_mem_dump_ctrl_addr + 0x10) = msg_mem_addr; // g_mem_dump_ctrl[1].start_addr *(uint8_t *)(g_mem_dump_ctrl_addr + 0x14) = 0x01; // g_mem_dump_ctrl[1].trace_enable // STA_DUMP_TRACE *(uint32_t *)(g_mem_dump_ctrl_addr + 0x18) = each_log_length; // g_mem_dump_ctrl[2].len_max default:1024 *(uint32_t *)(g_mem_dump_ctrl_addr + 0x1c) = sta_mem_addr; // g_mem_dump_ctrl[2].start_addr *(uint8_t *)(g_mem_dump_ctrl_addr + 0x20) = 0x01; // g_mem_dump_ctrl[2].trace_enable // SCH_DUMP_TRACE *(uint32_t *)(g_mem_dump_ctrl_addr + 0x24) = each_log_length; // g_mem_dump_ctrl[3].len_max default:1024 *(uint32_t *)(g_mem_dump_ctrl_addr + 0x28) = sch_mem_addr; // g_mem_dump_ctrl[3].start_addr *(uint8_t *)(g_mem_dump_ctrl_addr + 0x2c) = 0x01; // g_mem_dump_ctrl[3].trace_enable // ISR_DUMP_TRACE *(uint32_t *)(g_mem_dump_ctrl_addr + 0x30) = each_log_length; // g_mem_dump_ctrl[4].len_max default:1024 *(uint32_t *)(g_mem_dump_ctrl_addr + 0x34) = isr_mem_addr; // g_mem_dump_ctrl[4].start_addr *(uint8_t *)(g_mem_dump_ctrl_addr + 0x38) = 0x01; // g_mem_dump_ctrl[4].trace_enable } } void bt_drv_reg_op_lm_nb_sync_hacker(uint8_t sco_status) { BT_DRV_REG_OP_ENTER(); // lm_nb_sync_active uint32_t op_addr = 0; if (lm_nb_sync_active_addr) { op_addr = lm_nb_sync_active_addr; } if (op_addr != 0) { uint8_t org_val = *(volatile uint8_t *)(op_addr); // sanity check if (org_val > 0xf0) org_val = 0; if ((sco_status == SNIFFER_SCO_STOP || sco_status == SNIFFER_SCO_START || sco_status == SNIFFER_ACL_DISCONNECT_STOP_SCO) && (org_val >= 0 && org_val <= 2)) { if (sco_status == SNIFFER_SCO_STOP || sco_status == SNIFFER_ACL_DISCONNECT_STOP_SCO) { if (org_val > 0) { *(volatile uint8_t *)(op_addr) = org_val - 1; } } else if (sco_status == SNIFFER_SCO_START) { *(volatile uint8_t *)(op_addr) = org_val + 1; } BT_DRV_TRACE( 3, "BT_REG_OP:modify lm_nb_sync org val=%d, modify val=%d, status=%d", org_val, *(volatile uint8_t *)(op_addr), sco_status); } else { BT_DRV_TRACE(2, "BT_REG_OP:do not need modify lm_nb_sync val=%d, status=%d", org_val, sco_status); } } BT_DRV_REG_OP_EXIT(); } #define BT_FASTACK_ADDR 0xD0220468 #define BT_SCO_TRIGGER_BYPASS_ADDR 0xD022046C void bt_drv_reg_op_fastack_status_checker(uint16_t conhdl) { BT_DRV_REG_OP_ENTER(); uint8_t elt_idx = btdrv_conhdl_to_linkid(conhdl); if (btdrv_is_link_index_valid(elt_idx)) { uint32_t fast_cs_addr = EM_BT_BT_EXT1_ADDR + elt_idx * BT_EM_SIZE; BT_DRV_TRACE( 3, "BT_DRV_REG: fastack cs=0x%x,fast ack reg=0x%x,Seq filter by pass=0x%x", *(volatile uint16_t *)(fast_cs_addr), // fa rx bit10,tx bit9 *(volatile uint32_t *)(BT_FASTACK_ADDR), // fast ack reg bit22 *(volatile uint32_t *)(BT_SCO_TRIGGER_BYPASS_ADDR)); // seq bypass reg bit 18 } bt_drv_reg_op_bt_info_checker(); BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_clear_ibrt_snoop_status(void) { BT_DRV_REG_OP_ENTER(); // sniffer_env.snoop_status uint32_t op_addr = 0; if (sniffer_env_addr) { op_addr = sniffer_env_addr + 0x84; } if (op_addr != 0) { BT_DRV_TRACE(0, "BT_REG_OP:clear snoop_status"); *(volatile uint8_t *)(op_addr) = 0; } // close fastack register bt_drv_reg_op_fa_set(0); // clear fastack cs for (uint8_t idx = 0; idx < 3; idx++) { // fastack cs: rx bit10,tx bit9 uint32_t fast_cs_addr = EM_BT_BT_EXT1_ADDR + idx * BT_EM_SIZE; *(volatile uint16_t *)(fast_cs_addr) &= ~0x600; } BT_DRV_REG_OP_EXIT(); } uint8_t bt_drv_reg_op_linkcntl_aclltaddr_getf(uint16_t conhdl) { uint8_t elt_idx = btdrv_conhdl_to_linkid(conhdl); if (btdrv_is_link_index_valid(elt_idx)) { uint16_t localVal = BTDIGITAL_BT_EM(EM_BT_LINKCNTL_ADDR + elt_idx * BT_EM_SIZE); return ((localVal & ((uint16_t)0x00000700)) >> 8); } else { return 0; } } uint8_t bt_drv_reg_op_sync_bt_param(uint8_t *param, uint16_t len) { uint8_t status = 0xff; BT_DRV_REG_OP_ENTER(); // link_connect_bak uint32_t op_addr = 0; if (link_connect_bak_addr) { op_addr = link_connect_bak_addr; } if (op_addr != 0) { BT_DRV_TRACE(1, "BT_REG_OP:sync bt param len=%d", len); memcpy((uint8_t *)(op_addr), param, len); status = 0; } BT_DRV_REG_OP_EXIT(); return status; } uint32_t bt_drv_reg_op_get_lc_env_ptr(uint16_t conhdl, uint8_t type) { uint32_t lc_ptr = 0; uint32_t op_ptr = 0; BT_DRV_REG_OP_ENTER(); if (lc_env_addr) { lc_ptr = *(uint32_t *)(lc_env_addr + (conhdl - 0x80) * 4); } BT_DRV_TRACE(3, "BT_REG_OP:lc_env_ptr =0x%x, conhdl=0x%x,type=%d", lc_ptr, conhdl, type); if (lc_ptr == 0) return 0; switch (type) { case LC_LINK_TAG: // link tag len=108 op_ptr = lc_ptr; break; case LC_INFO_TAG: op_ptr = lc_ptr + 0x6c; break; case LC_ENC_TAG: // enc tag len=166 op_ptr = lc_ptr + 0x196; break; case LC_AFH_TAG: op_ptr = lc_ptr + 0x26c; break; case LC_SP_TAG: // link tag len=108 op_ptr = lc_ptr + 0x28c; break; case LC_EPR_TAG: op_ptr = lc_ptr + 0x2f8; break; case LC_EPC_TAG: op_ptr = lc_ptr + 0x2fc; break; default: break; } BT_DRV_REG_OP_EXIT(); return op_ptr; } #ifdef __BT_ONE_BRING_TWO__ void bt_drv_reg_op_set_music_ongong_flag() {} void bt_drv_reg_op_clear_music_ongong_flag() {} #endif uint16_t bt_drv_reg_op_get_ble_conn_latency(uint16_t ble_conhdl) { uint16_t curr_conn_latency = 0xffff; return curr_conn_latency; } bool bt_drv_reg_op_set_ble_conn_latency(uint16_t ble_conhdl, uint16_t conn_latency) { return false; } void bt_drv_reg_op_write_private_public_key(uint8_t *private_key, uint8_t *public_key) { uint8_t *lm_env_ptr = 0; uint8_t *lm_private_key_ptr = 0; uint8_t *lm_public_key_ptr = 0; // lm_env if (lm_env_addr) { lm_env_ptr = (uint8_t *)lm_env_addr; } else { return; } lm_private_key_ptr = lm_env_ptr + 0x6c; lm_public_key_ptr = lm_private_key_ptr + 0x18; memcpy(lm_private_key_ptr, private_key, 24); memcpy(lm_public_key_ptr, public_key, 48); BT_DRV_TRACE(0, "private key"); DUMP8("%02x", lm_private_key_ptr, 24); BT_DRV_TRACE(0, "public key"); DUMP8("%02x", lm_public_key_ptr, 48); } void bt_drv_reg_op_for_test_mode_disable(void) { if (dbg_bt_setting_addr) { *(volatile uint32_t *)(dbg_bt_setting_addr + 0x64) &= ~(1 << 8); ////sw_seq_filter_en set 0 *(volatile uint32_t *)(dbg_bt_setting_addr + 0x64) &= ~(1 << 0); ////ecc_enable set 0 *(volatile uint32_t *)(dbg_bt_setting_addr + 0x1c) &= 0x00ffffff; ////dbg_trace_level set 0 } } uint16_t bt_drv_reg_op_get_ibrt_sco_hdl(uint16_t acl_hdl) { // FIXME return acl_hdl | 0x100; } void bt_drv_reg_op_get_ibrt_address(uint8_t *addr) { struct ld_device_info *mobile_device_info = 0; BT_DRV_REG_OP_ENTER(); if (sniffer_env_addr) { mobile_device_info = (struct ld_device_info *)(sniffer_env_addr + 4); } if (mobile_device_info) { if (addr != NULL) { memcpy(addr, (uint8_t *)mobile_device_info->bd_addr.addr, 6); BT_DRV_TRACE(0, "BT_REG_OP:get mobile address"); DUMP8("%02x ", addr, 6); } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_set_tws_link_id(uint8_t link_id) { // ASSERT(); BT_DRV_TRACE(1, "set tws link id =%x", link_id); ASSERT(link_id < 3 || link_id == 0xff, "error tws link id set"); if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { ASSERT(*(uint32_t *)0xc0006e28 == 0xc0006e2c, "PATCH ERROR!!"); *(uint32_t *)0xc0006e2c = link_id; } else if (tws_link_id_addr) { if (link_id == 0xff) { link_id = 3; } *(uint8_t *)tws_link_id_addr = link_id; } } void bt_drv_reg_op_hack_max_slot(uint8_t link_id, uint8_t slot) { uint32_t acl_evt_ptr = 0x0; uint32_t slot_addr; uint32_t stop_lantency_addr = 0; BT_DRV_TRACE(2, "hack slot id=%d,slot=%d", link_id, slot); if (link_id >= 3) return; if (ld_acl_env_addr) { acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr + link_id * 4); } if (acl_evt_ptr) { slot_addr = acl_evt_ptr + 0xc4; stop_lantency_addr = acl_evt_ptr + 0x18; *(uint8_t *)slot_addr = slot; *(uint8_t *)stop_lantency_addr = slot + 3 + (*(uint16_t *)(acl_evt_ptr + 150) > 128 ? 1 : 0); } } void bt_drv_reg_op_rx_slot_stop_lantency_checker(void) { uint32_t acl_evt_ptr = 0x0; uint32_t slot_addr; uint32_t stop_addr; for (uint8_t i = 0; i < 3; i++) { if (ld_acl_env_addr) { acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr + i * 4); } if (acl_evt_ptr) { slot_addr = acl_evt_ptr + 0xc4; stop_addr = acl_evt_ptr + 0x18; BT_DRV_TRACE( 5, "id=%d,rx slot=%d stop=%d,acl_par: clk off 0x%x, bit off 0x%x", i, *(uint8_t *)slot_addr, *(uint8_t *)stop_addr, *(uint32_t *)(acl_evt_ptr + 140), *(uint16_t *)(acl_evt_ptr + 150)); } } } void bt_drv_reg_op_fa_set(uint8_t en) { if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) { if (en) { *(uint32_t *)0xd0220468 |= 0x00400000; BT_DRV_TRACE(1, "%s", __func__); } else { *(uint32_t *)0xd0220468 &= ~0x00400000; } } } //////return true means controller had received a data packet bool bt_drv_reg_op_check_seq_pending_status(void) { if (pending_seq_error_link_addr) { return (*(uint8_t *)pending_seq_error_link_addr == 3); } else { return TRUE; } } /// if the flag is not clear when disconnect happened call this function void bt_drv_reg_op_clear_seq_pending_status(void) { if (pending_seq_error_link_addr) { *(uint8_t *)pending_seq_error_link_addr = 3; } } void bt_drv_reg_op_rssi_checker(void) { // BT_DRV_TRACE(1,"rssi thd=%x",*(uint32_t *)0xc00041e4); uint32_t acl_evt_ptr = 0x0; uint32_t rssi_acc_addr; uint32_t rssi_count_addr; for (uint8_t i = 0; i < 3; i++) { if (ld_acl_env_addr) { acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr + i * 4); } if (acl_evt_ptr) { rssi_acc_addr = acl_evt_ptr + 0xac; rssi_count_addr = acl_evt_ptr + 0xae; BT_DRV_TRACE(3, "id=%d,rssi acc=%d count=%d", i, *(int16_t *)rssi_acc_addr, *(uint8_t *)rssi_count_addr); } } uint32_t lc_evt_ptr = 0x0; uint32_t recv_addr; for (uint8_t i = 0; i < 3; i++) { if (lc_env_addr) { lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + i * 4); // lc_env } if (lc_evt_ptr) { recv_addr = lc_evt_ptr + 0x60; BT_DRV_TRACE(2, "id=%d,recv=%x", i, *(uint32_t *)recv_addr); } } } void bt_drv_reg_op_set_link_policy(uint8_t linkid, uint8_t policy) { BT_DRV_REG_OP_ENTER(); uint32_t lc_evt_ptr = 0x0; uint32_t policy_addr; if (linkid >= 0x3) return; BT_DRV_TRACE(2, "REG_OP: set link=%d, policy=%d", linkid, policy); if (lc_env_addr) { lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + linkid * 4); // lc_env } if (lc_evt_ptr) { policy_addr = lc_evt_ptr + 0x2c; *(uint8_t *)policy_addr = policy; } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_voice_settings_set(uint16_t voice_settings) { uint32_t voice_settings_addr = 0; if (hci_env_addr) { voice_settings_addr = hci_env_addr + 90; } if (voice_settings_addr != 0) { BT_DRV_TRACE(2, "Fast_bt_init1:%s %d", __func__, voice_settings); *(uint16_t *)voice_settings_addr = voice_settings; } } uint8_t bt_drv_reg_op_lmp_sco_hdl_get(uint16_t sco_handle) { if (sco_handle == 0xffff) { return 0; } if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { // uint32_t lc_sco_env_addr = 0xc000079c; uint16_t sco_link_id = ((sco_handle >> 8) - 1); uint32_t link_params_addr = *((uint32_t *)(lc_sco_env_addr + sco_link_id * 8)); uint8_t sync_hdl = 0; if (sco_link_id > 2 || link_params_addr == 0) { return 0; } sync_hdl = *((uint8_t *)(link_params_addr + 4)); return sync_hdl; } else { BT_DRV_TRACE(0, "BT_DRV:no need to get sco hdl\n"); } return 0; } bool bt_drv_reg_op_lmp_sco_hdl_set(uint16_t sco_handle, uint8_t lmp_hdl) { if (sco_handle == 0xffff || lmp_hdl == 0x00) { return false; } if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { // uint32_t lc_sco_env_addr = 0xc000079c; uint16_t sco_link_id = ((sco_handle >> 8) - 1); uint32_t link_params_addr = *((uint32_t *)(lc_sco_env_addr + sco_link_id * 8)); uint8_t *p_sync_hdl = 0; if (sco_link_id > 2 || link_params_addr == 0) { return false; } p_sync_hdl = (uint8_t *)(link_params_addr + 4); *p_sync_hdl = lmp_hdl; return true; } else { BT_DRV_TRACE(0, "BT_DRV:no need to set sco hdl\n"); } return false; } void bt_drv_reg_op_host_buff_and_flow_ctl_set(uint16_t acl_pkt_len, uint16_t acl_pkt_num, uint16_t sync_pkt_len, uint16_t sync_pkt_num, bool flow_ctl_en) { uint32_t acl_pkt_len_addr = 0; uint32_t acl_pkt_num_addr = 0; uint32_t sync_pkt_len_addr = 0; uint32_t sync_pkt_num_addr = 0; uint32_t flow_ctl_addr = 0; if (hci_fc_env_addr) { flow_ctl_addr = hci_fc_env_addr; } if (flow_ctl_addr != 0) { // hci_fc_env.host_set.acl_pkt_len acl_pkt_len_addr = flow_ctl_addr + 2; // hci_fc_env.host_set.acl_pkt_num acl_pkt_num_addr = flow_ctl_addr + 4; // hci_fc_env.host_set.sync_pkt_len; sync_pkt_len_addr = flow_ctl_addr + 9; // hci_fc_env.host_set.sync_pkt_nb; sync_pkt_num_addr = flow_ctl_addr + 10; BT_DRV_TRACE(6, "Fast_bt_init2:%s,acl len=%x,acl num=%x,sync len=%x sync " "num=%x,fl_ctl=%d", __func__, acl_pkt_len, acl_pkt_num, sync_pkt_len, sync_pkt_num, flow_ctl_en); *(uint8_t *)flow_ctl_addr = flow_ctl_en; *(uint16_t *)acl_pkt_len_addr = acl_pkt_len; *(uint16_t *)acl_pkt_num_addr = acl_pkt_num; *(uint8_t *)sync_pkt_len_addr = sync_pkt_len; *(uint16_t *)sync_pkt_num_addr = sync_pkt_num; } } void bt_drv_reg_op_page_to_set(uint16_t page_to) { BT_DRV_REG_OP_ENTER(); uint32_t page_to_addr = 0; if (lm_env_addr) { page_to_addr = lm_env_addr + 20; } if (page_to_addr != 0) { BT_DRV_TRACE(2, "Fast_bt_init3:%s,to=%x", __func__, page_to); *(uint16_t *)page_to_addr = page_to; } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_btdm_address_set(uint8_t *bt_addr, uint8_t *ble_addr) { BT_DRV_REG_OP_ENTER(); uint32_t btaddr_addr = 0; uint32_t bleaddr_addr = 0; uint32_t bch_addr = 0; if (llm_le_env_addr) { bleaddr_addr = llm_le_env_addr + 0x8f; } if (ld_env_addr) { btaddr_addr = ld_env_addr; bch_addr = btaddr_addr + 451; } if (bleaddr_addr != 0) { BT_DRV_TRACE(1, "Fast_bt_init4:%s", __func__); DUMP8("%02x ", bt_addr, 6); DUMP8("%02x ", ble_addr, 6); for (uint8_t i = 0; i < 6; i++) { *(uint8_t *)(bleaddr_addr + i) = ble_addr[i]; } for (uint8_t i = 0; i < 6; i++) { *(uint8_t *)(btaddr_addr + i) = bt_addr[i]; } ld_util_bch_create(bt_addr, (uint8_t *)bch_addr); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_evtmask_set(uint8_t ble_en) { BT_DRV_REG_OP_ENTER(); uint32_t bt_evtmsk_addr = 0; uint32_t ble_evtmask_addr = 0; if (llm_le_env_addr) { ble_evtmask_addr = llm_le_env_addr + 0x64; } if (hci_env_addr) { bt_evtmsk_addr = hci_env_addr; } if (bt_evtmsk_addr != 0) { BT_DRV_TRACE(2, "Fast_bt_init5:%s,ble enable=%x", __func__, ble_en); uint8_t bt_mask[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f}; if (ble_en) { bt_mask[7] = 0x3f; } memcpy((uint8_t *)bt_evtmsk_addr, bt_mask, 8); uint8_t ble_mask[8] = {0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; memcpy((uint8_t *)ble_evtmask_addr, ble_mask, 8); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_simplepair_mode_set(uint8_t en) { BT_DRV_REG_OP_ENTER(); if (lm_env_addr) { *(uint8_t *)(lm_env_addr + 44) = en; } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_class_of_dev_set(uint8_t *class_of_dev, uint8_t len) { BT_DRV_REG_OP_ENTER(); uint32_t class_of_dev_addr = 0; if (ld_env_addr) { // ld_env.class_of_dev.A class_of_dev_addr = ld_env_addr + 6; } if (class_of_dev_addr != 0) { BT_DRV_TRACE(1, "Fast_bt_init7:%s", __func__); DUMP8("%02x ", class_of_dev, 3); memcpy((uint8_t *)class_of_dev_addr, class_of_dev, 3); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_sleep_set(bool en) { BT_DRV_REG_OP_ENTER(); uint32_t sleep_addr = 0; if (rwip_env_addr) { sleep_addr = rwip_env_addr + 12; } if (sleep_addr != 0) { BT_DRV_TRACE(2, "Fast_bt_init:%s en=%d", __func__, en); *(uint8_t *)(sleep_addr) = en; } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_sco_fifo_reset(void) { uint16_t sco_ptr0 = 0, sco_ptr1 = 0; uint8_t *em_area_base = (uint8_t *)0xd0210000; BT_DRV_REG_OP_ENTER(); BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 0, sco_ptr0); BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 16, sco_ptr1); BT_DRV_TRACE(3, "bt_drv_reg_op_sco_fifo_reset %d/%d %08x", sco_ptr0, sco_ptr1, BTDIGITAL_REG(0xd02201cc)); memset(em_area_base + sco_ptr0, 0x55, 60); memset(em_area_base + sco_ptr1, 0x55, 60); BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_sco_fifo_dump(void) { uint16_t sco_ptr0 = 0, sco_ptr1 = 0; uint8_t *em_area_base = (uint8_t *)0xd0210000; BT_DRV_REG_OP_ENTER(); BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 0, sco_ptr0); BTDIGITAL_REG_GET_FIELD(0xd02201cc, 0xffff, 16, sco_ptr1); BT_DRV_TRACE(3, "bt_drv_reg_op_sco_fifo_reset %d/%d %08x", sco_ptr0, sco_ptr1, BTDIGITAL_REG(0xd02201cc)); DUMP8("%02x ", em_area_base + sco_ptr0, 10); DUMP8("%02x ", em_area_base + sco_ptr1, 10); BT_DRV_REG_OP_EXIT(); } uint8_t bt_drv_reg_op_get_sync_id_op(uint8_t op, uint8_t sync_id) { uint8_t sync_link_id = 0xff; BT_DRV_REG_OP_ENTER(); uint32_t sync_id_addr = 0; // only 2300P chip id =1 need this hack if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { sync_id_addr = (sniffer_env_addr + 0x3c); } if (sync_id_addr != 0) { if (READ_OP == op) { sync_link_id = *(uint8_t *)(sync_id_addr); } else if (WRITE_OP == op) { *(uint8_t *)(sync_id_addr) = sync_id; } } BT_DRV_REG_OP_EXIT(); return sync_link_id; } void bt_drv_reg_op_disable_reporting_en(uint16_t conhdl) { BT_DRV_REG_OP_ENTER(); uint32_t lc_evt_ptr = 0x0; uint32_t report_en_addr; uint8_t linkid = btdrv_conhdl_to_linkid(conhdl); if (btdrv_is_link_index_valid(linkid)) { if (lc_env_addr) { lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + linkid * 4); // lc_env report_en_addr = lc_evt_ptr + 0x28a; *(uint8_t *)report_en_addr = 0; BT_DRV_TRACE(0, "REG_OP:disable afh report"); } } BT_DRV_REG_OP_EXIT(); } uint8_t bt_drv_reg_opcheck_controller_ld_lc_layer_mismatch(void) { uint8_t cnt = 0; BT_DRV_REG_OP_ENTER(); if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { for (uint8_t link_id = 0; link_id < 3; link_id++) { uint32_t ld_acl_evt_ptr = 0; uint32_t lc_evt_ptr = 0; ld_acl_evt_ptr = *(uint32_t *)(ld_acl_env_addr + link_id * 4); lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + link_id * 4); if ((ld_acl_evt_ptr && !lc_evt_ptr) || (!ld_acl_evt_ptr && lc_evt_ptr)) { cnt++; } } } BT_DRV_REG_OP_EXIT(); return cnt; } void bt_drv_reg_op_ble_sup_timeout_set(uint16_t ble_conhdl, uint16_t sup_to) { uint32_t llc_env_ptr = 0; if (llc_env_addr) { uint32_t llc_env_address = llc_env_addr + ble_conhdl * 4; llc_env_ptr = *(volatile uint32_t *)llc_env_address; } if (llc_env_ptr != 0) { uint32_t llc_env_sup_to_address = llc_env_ptr + 0x54; *(volatile uint16_t *)llc_env_sup_to_address = sup_to; BT_DRV_TRACE(1, "BT_DRV:set ble sup_timeout to %d", sup_to); } } void bt_drv_reg_op_disable_swagc_nosync_count(void) { if (dbg_bt_setting_ext1_addr) { *(uint16_t *)(dbg_bt_setting_ext1_addr + 0x14) = 0xa604; } } void bt_drv_reg_op_hw_sw_agc_select(uint8_t agc_mode) { uint32_t hw_agc_select_addr = 0; BT_DRV_REG_OP_ENTER(); if (rwip_rf_addr) { hw_agc_select_addr = rwip_rf_addr + 0x37; } if (hw_agc_select_addr != 0) { *(volatile uint8_t *)hw_agc_select_addr = agc_mode; } BT_DRV_REG_OP_EXIT(); } void ble_maxevtime_set(int elt_idx, uint16_t value) { BTDIGITAL_EM_BT_WR(BLE_MAXEVTIME_ADDR + elt_idx * BLE_EM_CS_SIZE, value); } uint16_t ble_maxevtime_get(int elt_idx) { return BTDIGITAL_BT_EM(BLE_MAXEVTIME_ADDR + elt_idx * BLE_EM_CS_SIZE); } void bt_drv_reg_op_afh_follow_en(bool enable, uint8_t be_followed_link_id, uint8_t follow_link_id) { #if BT_AFH_FOLLOW if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { *(uint8_t *)(lm_env_addr + 0x168) = be_followed_link_id; // be follow follow link id *(uint8_t *)(lm_env_addr + 0x169) = follow_link_id; // follow link id *(uint8_t *)(lm_env_addr + 0x167) = enable; // afh follow enable } #endif } void bt_drv_reg_op_set_agc_thd(bool isMaster, bool isSco) { BT_DRV_REG_OP_ENTER(); if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { ASSERT(*(uint32_t *)0xc00072ec == 0xc0007310, "patch ERROR 2300p t2 bt_drv_reg_op_set_agc_thd!"); BT_DRV_TRACE(1, "isMaster: %d, isSco: %d ", isMaster, isSco); if (isMaster) { if (isSco) { BTDIGITAL_REG(0xc0007310) = 0x00000020; // link_agc_thd_mobile_time£¬ reg address£º0xc0007310 BTDIGITAL_REG(0xc0007300) = 0x00000020; // link_agc_thd_tws_time£¬ reg address£º0xc0007300 } else { BTDIGITAL_REG(0xc0007310) = 0x00000038; // link_agc_thd_mobile_time£¬ reg address£º0xc0007310 BTDIGITAL_REG(0xc0007300) = 0x00000038; // link_agc_thd_tws_time£¬ reg address£º0xc0007300 } } else { if (isSco) { BTDIGITAL_REG(0xc0007310) = 0x00000020; // link_agc_thd_mobile_time£¬ reg address£º0xc0007310 BTDIGITAL_REG(0xc0007300) = 0x00000020; // link_agc_thd_tws_time£¬ reg address£º0xc0007300 } else { BTDIGITAL_REG(0xc0007310) = 0x00000038; // link_agc_thd_mobile_time£¬ reg address£º0xc0007310 BTDIGITAL_REG(0xc0007300) = 0x00000038; // link_agc_thd_tws_time£¬ reg address£º0xc0007300 } } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_force_set_sniff_att(uint16_t conhdle) { BT_DRV_REG_OP_ENTER(); uint8_t linkid = btdrv_conhdl_to_linkid(conhdle); uint32_t acl_evt_ptr = 0x0; if (btdrv_is_link_index_valid(linkid)) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { acl_evt_ptr = *(volatile uint32_t *)(0xc0000998 + linkid * 4); // ld_acl_env } else if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { acl_evt_ptr = *(volatile uint32_t *)(0xc00009d4 + linkid * 4); // ld_acl_env } if (acl_evt_ptr != 0) { uint32_t sniff_att_addr = acl_evt_ptr + 0xe2; if (BT_DRIVER_GET_U16_REG_VAL(sniff_att_addr) < 3) { BT_DRIVER_PUT_U16_REG_VAL(sniff_att_addr, 3); } // set sniff timeout to 0 BT_DRIVER_PUT_U16_REG_VAL(sniff_att_addr + 4, 0); BT_DRV_TRACE(0, "BT_REG_OP:force set sniff att"); } } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_fa_gain_direct_set(uint8_t gain_idx) { BTDIGITAL_REG(0xd0220484) = (BTDIGITAL_REG(0xd0220484) & (~0xffff)) | 0x9401 | (gain_idx << 1); // lxd 20191105 fixed ecc receive gain } uint8_t bt_drv_reg_op_fa_gain_direct_get(void) { uint32_t raw_reg = BTDIGITAL_REG(0xd0220484); return (raw_reg >> 1) & 0x07; } struct rx_gain_fixed_t { uint8_t enable; // enable or disable uint8_t bt_or_ble; // 0:bt 1:ble uint8_t cs_id; // link id uint8_t gain_idx; // gain index }; void bt_drv_reg_op_dgb_link_gain_ctrl_set(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable) { if (hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) { TRACE(1, "%s to all link", __func__); uint16_t raw_reg = *((volatile uint16_t *)0xc00041ec); if (bt_ble_mode) { raw_reg = raw_reg & (~0xff << 8); raw_reg = raw_reg | (gain_idx << 8); } else { raw_reg = raw_reg & ~0xff; raw_reg = raw_reg | gain_idx; } *((volatile uint16_t *)0xc00041ec) = raw_reg; } struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; uint8_t cs_id = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(cs_id)) { for (uint8_t i = 0; i < 3; i++) { if ((rx_gain_fixed_p->cs_id == cs_id) && (rx_gain_fixed_p->bt_or_ble == bt_ble_mode)) { rx_gain_fixed_p->enable = enable; rx_gain_fixed_p->bt_or_ble = bt_ble_mode; rx_gain_fixed_p->gain_idx = gain_idx; BT_DRV_TRACE(5, "%s hdl:%x/%x mode:%d idx:%d", __func__, connHandle, cs_id, rx_gain_fixed_p->bt_or_ble, gain_idx); } rx_gain_fixed_p++; } } } void bt_drv_reg_op_dgb_link_gain_ctrl_clear(uint16_t connHandle, uint8_t bt_ble_mode) { if (hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) { BT_DRV_TRACE(1, "%s REG_OP: not support", __func__); } struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; uint8_t cs_id = btdrv_conhdl_to_linkid(connHandle); if (btdrv_is_link_index_valid(cs_id)) { for (uint8_t i = 0; i < 3; i++) { if ((rx_gain_fixed_p->cs_id == cs_id) && (rx_gain_fixed_p->bt_or_ble == bt_ble_mode)) { rx_gain_fixed_p->enable = 0; rx_gain_fixed_p->bt_or_ble = bt_ble_mode; rx_gain_fixed_p->gain_idx = 0; } rx_gain_fixed_p++; } } } void bt_drv_reg_op_dgb_link_gain_ctrl_init(void) { if (hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) { BT_DRV_TRACE(1, "%s REG_OP: not support", __func__); } struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; for (uint8_t i = 0; i < 3; i++) { rx_gain_fixed_p->cs_id = i; rx_gain_fixed_p++; } } void bt_drv_reg_op_rx_gain_fix(uint16_t connHandle, uint8_t bt_ble_mode, uint8_t gain_idx, uint8_t enable, uint8_t table_idx) { if (hal_get_chip_metal_id() <= HAL_CHIP_METAL_ID_1) { BT_DRV_TRACE(1, "%s REG_OP: not support", __func__); } struct rx_gain_fixed_t *rx_gain_fixed_p = (struct rx_gain_fixed_t *)0xc00004dc; uint8_t cs_id; if (bt_ble_mode == 0) // bt { cs_id = btdrv_conhdl_to_linkid(connHandle); } else if (bt_ble_mode == 1) // ble { cs_id = connHandle; } else { BT_DRV_TRACE(1, "%s:fix gain fail", __func__); return; } if (table_idx < 3) { rx_gain_fixed_p[table_idx].enable = enable; rx_gain_fixed_p[table_idx].bt_or_ble = bt_ble_mode; rx_gain_fixed_p[table_idx].cs_id = cs_id; rx_gain_fixed_p[table_idx].gain_idx = gain_idx; } } void bt_drv_reg_op_set_ibrt_auto_accept_sco(bool en) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { ASSERT(*(uint32_t *)0xc0007344 == 0xc0007348, "ibrt_auto_accept_sco PATCH ERROR!!"); if (en) { BTDIGITAL_REG(0xc0007348) = 1; BT_DRV_TRACE(0, "BT_REG_OP:enable ibrt_auto_accept_sco"); } else { BTDIGITAL_REG(0xc0007348) = 0; } } } void bt_drv_reg_op_update_dbg_state(void) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { ASSERT(*(uint32_t *)0xc00076a0 == 0xc00076a4, "update_dbg_state PATCH ERROR!!"); BTDIGITAL_REG(0xc00076a4) = 1; BT_DRV_TRACE(0, "BT_REG_OP:update_dbg_state"); } } void bt_drv_reg_op_set_ibrt_reject_sniff_req(bool en) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { ASSERT(*(uint32_t *)0xc0006e6c == 0xbb5ef615, "ibrt_reject_sniff_req PATCH ERROR!!"); BTDIGITAL_REG(0xc0006e70) = en ? 1 : 0; // BT_DRV_TRACE(1,"BT_REG_OP:ibrt reject sniff %d", en); } } uint8_t bt_drv_reg_op_get_esco_nego_airmode(uint8_t sco_link_id) { BT_DRV_REG_OP_ENTER(); if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { // uint32_t lc_sco_env_addr = 0xc000079c; uint32_t p_nego_params_addr = *((uint32_t *)(lc_sco_env_addr + 4 + sco_link_id * 8)); uint8_t airmode = 0; if (sco_link_id > 2 || p_nego_params_addr == 0) { return 0xff; } airmode = *((uint8_t *)(p_nego_params_addr + 0x5e)); BT_DRV_TRACE(1, "BT_REG_OP:Get nego esco airmode=%d", airmode); return airmode; } BT_DRV_REG_OP_EXIT(); return 0; } void bt_drv_reg_op_set_max_pwr_rcv(uint16_t connHandle) { BT_DRV_REG_OP_ENTER(); uint32_t lc_evt_ptr = 0x0; uint32_t max_power_rcv_addr; uint8_t linkid = btdrv_conhdl_to_linkid(connHandle); if (lc_env_addr) { lc_evt_ptr = *(volatile uint32_t *)(lc_env_addr + linkid * 4); // lc_env } if (lc_evt_ptr) { // lc_env_ptr->link.MaxPowerRcv max_power_rcv_addr = lc_evt_ptr + 0x61; *(bool *)max_power_rcv_addr = true; BT_DRV_TRACE(1, "BT_REG_OP:conhdl=%x, max pwr recieve", connHandle); } BT_DRV_REG_OP_EXIT(); } void bt_drv_reg_op_set_rand_seed(uint32_t seed) { if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_1) { *(volatile uint32_t *)(0xc0006890) = seed; } else if (hal_get_chip_metal_id() == HAL_CHIP_METAL_ID_2) { *(volatile uint32_t *)(0xc0006998) = seed; } } uint32_t bt_drv_reg_op_get_host_ref_clk(void) { return 0; } void bt_drv_reg_op_hci_vender_ibrt_ll_monitor(uint8_t *ptr, uint16_t *p_sum_err, uint16_t *p_rx_total) { const char *monitor_str[29] = { "TX DM1", "TX DH1", "TX DM3", "TX DH3", "TX DM5", "TX DH5", "TX 2DH1", "TX 3DH1", "TX 2DH3", "TX 3DH3", "TX 2DH5", "TX 3DH5", "RX DM1", "RX DH1", "RX DM3", "RX DH3", "RX DM5", "RX DH5", "RX 2DH1", "RX 3DH1", "RX 2DH3", "RX 3DH3", "RX 2DH5", "RX 3DH5", "hec error", "crc error", "fec error", "gard error", "ecc count", }; uint32_t *p = (uint32_t *)ptr; uint32_t sum_err = 0; uint32_t rx_data_sum = 0; uint32_t val; TRACE(0, "ibrt_ui_log:ll_monitor"); for (uint8_t i = 0; i < 29; i++) { val = co_read32p(p); if (val) { if (i >= 12 && i <= 23) { rx_data_sum += val; } if (i > 23) { sum_err += val; } TRACE(2, "%s %d", monitor_str[i], val); } p += 4; } *p_sum_err = sum_err; *p_rx_total = rx_data_sum; } uint8_t bt_drv_reg_op_bt_sync_swagc_en_get(void) { return 0; } void bt_drv_reg_op_ecc_softbit_process(uint16_t *p_conn_handle1, uint16_t *p_conn_handle2, uint16_t length, uint8_t *data) {} #if defined(PCM_FAST_MODE) && defined(PCM_PRIVATE_DATA_FLAG) void bt_drv_reg_op_set_pcm_flag() {} #endif void bt_drv_reg_op_key_gen_after_reset(bool enable) {}