#include "aic_txrxif.h" #include "aicwf_usb.h" #include "aicbluetooth.h" #include "aic_compat_8800d80.h" #include "aicwf_debug.h" extern int ble_scan_wakeup_reboot_time; extern uint32_t ad_data_filter_mask; extern uint32_t gpio_num;//default select gpiob2 for fw_wakeup_host extern uint32_t gpio_dft_lvl;//0:defalut pull down, 1:default pull up int rwnx_plat_bin_fw_upload_2(struct aic_usb_dev *usbdev, u32 fw_addr, char *filename); int rwnx_request_firmware_common(struct aic_usb_dev *usbdev, u32** buffer, const char *filename); void rwnx_plat_userconfig_parsing(char *buffer, int size); void rwnx_release_firmware_common(u32** buffer); extern int testmode; extern u8 chip_id; extern u8 chip_mcu_id; typedef u32 (*array2_tbl_t)[2]; #define AIC_PATCH_MAGIG_NUM 0x48435450 // "PTCH" #define AIC_PATCH_MAGIG_NUM_2 0x50544348 // "HCTP" #define AIC_PATCH_BLOCK_MAX 4 typedef struct { uint32_t magic_num; uint32_t pair_start; uint32_t magic_num_2; uint32_t pair_count; uint32_t block_dst[AIC_PATCH_BLOCK_MAX]; uint32_t block_src[AIC_PATCH_BLOCK_MAX]; uint32_t block_size[AIC_PATCH_BLOCK_MAX]; // word count } aic_patch_t; #define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem) #define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem))) #define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) #define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) #define USER_TX_USE_ANA_F_FLAG (0x01U << 2) #define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) #define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) #define CFG_PWROFST_COVER_CALIB 1 #ifdef CONFIG_POWER_LIMIT #define CFG_USER_CHAN_MAX_TXPWR_EN 1 #else #define CFG_USER_CHAN_MAX_TXPWR_EN 0 #endif #define CFG_USER_TX_USE_ANA_F 0 #ifdef CONFIG_BAND_STEERING #define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1 #else #define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 #endif #define CFG_USER_EXT_FLAGS_EN (CFG_PWROFST_COVER_CALIB || CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F|| CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE) u32 patch_tbl_d80[][2] = { #ifdef USE_5G {0x00b4, 0xf3010001}, #else {0x00b4, 0xf3010000}, #endif #ifdef CONFIG_PLATFORM_HI {0x0170, 0x00010001},//rx aggr counter #else {0x0170, 0x0001000A},//rx aggr counter #endif #if CFG_USER_EXT_FLAGS_EN {0x0188, 0x00000000 #if CFG_PWROFST_COVER_CALIB | USER_PWROFST_COVER_CALIB_FLAG #endif #if CFG_USER_CHAN_MAX_TXPWR_EN | USER_CHAN_MAX_TXPWR_EN_FLAG #endif #if CFG_USER_TX_USE_ANA_F | USER_TX_USE_ANA_F_FLAG #endif #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE | USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG #endif }, // user_ext_flags #endif #ifdef CONFIG_RADAR_OR_IR_DETECT {0x0019c,0x00000B00}, #endif }; //adap test u32 adaptivity_patch_tbl_d80[][2] = { {0x000C, 0x0000320A}, //linkloss_thd {0x009C, 0x00000000}, //ac_param_conf {0x0168, 0x00010000}, //tx_adaptivity_en }; u32 syscfg_tbl_masked_8800d80[][3] = { }; u32 syscfg_tbl_8800d80[][2] = { #ifdef CONFIG_PMIC_SETTING {0x70001408, 0x00000000}, // stop wdg #endif /* CONFIG_PMIC_SETTING */ }; extern int adap_test; #define NEW_PATCH_BUFFER_MAP 1 int aicwf_patch_config_8800d80(struct aic_usb_dev *usb_dev) { u32 rd_patch_addr; u32 aic_patch_addr; u32 config_base, aic_patch_str_base; #if (NEW_PATCH_BUFFER_MAP) u32 patch_buff_addr, patch_buff_base, rd_version_addr, rd_version_val; #endif uint32_t start_addr = 0x001D7000; u32 patch_addr = start_addr; u32 patch_cnt = sizeof(patch_tbl_d80) / 4 / 2; struct dbg_mem_read_cfm rd_patch_addr_cfm; int ret = 0; int cnt = 0; //adap test int adap_patch_cnt = 0; if (adap_test) { AICWFDBG(LOGINFO, "%s adap test \r\n", __func__); adap_patch_cnt = sizeof(adaptivity_patch_tbl_d80)/sizeof(u32)/2; } if (chip_id == CHIP_REV_U01) { rd_patch_addr = RAM_FMAC_FW_ADDR_8800D80 + 0x0198; } else { rd_patch_addr = RAM_FMAC_FW_ADDR_8800D80_U02 + 0x0198; } aic_patch_addr = rd_patch_addr + 8; AICWFDBG(LOGERROR, "Read FW mem: %08x\n", rd_patch_addr); if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_patch_addr, &rd_patch_addr_cfm))) { AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", rd_patch_addr, ret); return ret; } AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); config_base = rd_patch_addr_cfm.memdata; if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, aic_patch_addr, &rd_patch_addr_cfm))) { AICWFDBG(LOGERROR, "patch_str_base[0x%x] rd fail: %d\n", aic_patch_addr, ret); return ret; } AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); aic_patch_str_base = rd_patch_addr_cfm.memdata; #if (NEW_PATCH_BUFFER_MAP) if (chip_id == CHIP_REV_U01) { rd_version_addr = RAM_FMAC_FW_ADDR_8800D80 + 0x01C; } else { rd_version_addr = RAM_FMAC_FW_ADDR_8800D80_U02 + 0x01C; } if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_version_addr, &rd_patch_addr_cfm))) { AICWFDBG(LOGERROR, "version val[0x%x] rd fail: %d\n", rd_version_addr, ret); return ret; } rd_version_val = rd_patch_addr_cfm.memdata; AICWFDBG(LOGINFO, "rd_version_val=%08X\n", rd_version_val); usb_dev->fw_version_uint = rd_version_val; if (rd_version_val > 0x06090100) { patch_buff_addr = rd_patch_addr + 12; ret = rwnx_send_dbg_mem_read_req(usb_dev, patch_buff_addr, &rd_patch_addr_cfm); if (ret) { AICWFDBG(LOGERROR, "patch buf rd fail\n"); return ret; } AICWFDBG(LOGINFO, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); patch_buff_base = rd_patch_addr_cfm.memdata; patch_addr = start_addr = patch_buff_base; } #endif if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) { AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num_2), AIC_PATCH_MAGIG_NUM_2))) { AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num_2), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(pair_start), patch_addr))) { AICWFDBG(LOGERROR, "pair_start[0x%x] write fail: %d\n", AIC_PATCH_ADDR(pair_start), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(pair_count), patch_cnt + adap_patch_cnt))) { AICWFDBG(LOGERROR, "pair_count[0x%x] write fail: %d\n", AIC_PATCH_ADDR(pair_count), ret); return ret; } for (cnt = 0; cnt < patch_cnt; cnt++) { if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt, patch_tbl_d80[cnt][0]+config_base))) { AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt+4, patch_tbl_d80[cnt][1]))) { AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt+4); return ret; } } if (adap_test){ int tmp_cnt = patch_cnt + adap_patch_cnt; for (cnt = patch_cnt; cnt < tmp_cnt; cnt++) { int tbl_idx = cnt - patch_cnt; if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt, adaptivity_patch_tbl_d80[tbl_idx][0]+config_base))) { AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt+4, adaptivity_patch_tbl_d80[tbl_idx][1]))) { AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt+4); return ret; } } } /* * Patch block 0 ~ 3, that is void by default, can be set as: * * const u32 patch_block_0[3] = {0x11223344, 0x55667788, 0xaabbccdd}; * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_dst[0]), 0x160000))) { * printk("block_dst [0x%x] write fail: %d\n", (u32)(&aic_patch->block_dst[0]), ret); * } * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_src[0]), 0x307000))) { * printk("block_src [0x%x] write fail: %d\n", (u32)(&aic_patch->block_src[0]), ret); * } * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_size[0]), sizeof(patch_block_0) / sizeof(u32)))) { * printk("block_size[0x%x] write fail: %d\n", (u32)(&aic_patch->block_size[0]), ret); * } * if ((ret = rwnx_send_dbg_mem_block_write_req(usb_dev, 0x307000, sizeof(patch_block_0), patch_block_0))) { * printk("blk set fail: %d\n", ret); * } */ if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[0]), 0))) { AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[0]), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[1]), 0))) { AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[1]), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[2]), 0))) { AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[2]), ret); return ret; } if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[3]), 0))) { AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[3]), ret); return ret; } return 0; } #if 0 extern char aic_fw_path[200]; int rwnx_plat_userconfig_load_8800d80(struct aic_usb_dev *usb_dev){ int size; u32 *dst=NULL; char *filename = FW_USERCONFIG_NAME_8800D80; AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); /* load file */ size = rwnx_request_firmware_common(usb_dev, &dst, filename); if (size <= 0) { AICWFDBG(LOGERROR, "wrong size of firmware file\n"); dst = NULL; return 0; } /* Copy the file on the Embedded side */ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); rwnx_plat_userconfig_parsing((char *)dst, size); rwnx_release_firmware_common(&dst); AICWFDBG(LOGINFO, "userconfig download complete\n\n"); return 0; } #endif int system_config_8800d80(struct aic_usb_dev *usb_dev){ int syscfg_num; int ret, cnt; const u32 mem_addr = 0x40500000; const u32 cache_mem_addr = 0x40100020; struct dbg_mem_read_cfm rd_mem_addr_cfm; ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); if (ret) { printk("%x rd fail: %d\n", mem_addr, ret); return ret; } if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL) { chip_mcu_id = 1; } chip_id = (u8)(rd_mem_addr_cfm.memdata >> 16); printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); if (chip_mcu_id) { ret = rwnx_send_dbg_mem_read_req(usb_dev, cache_mem_addr, &rd_mem_addr_cfm); if (ret) { printk("%x rd fail: %d\n", mem_addr, ret); return ret; } rd_mem_addr_cfm.memdata |= 0x01; ret = rwnx_send_dbg_mem_write_req(usb_dev, cache_mem_addr, rd_mem_addr_cfm.memdata); if (ret) { printk("%x write fail: %d\n", cache_mem_addr, ret); return ret; } } #if 1 syscfg_num = sizeof(syscfg_tbl_8800d80) / sizeof(u32) / 2; for (cnt = 0; cnt < syscfg_num; cnt++) { ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80[cnt][0], syscfg_tbl_8800d80[cnt][1]); if (ret) { printk("%x write fail: %d\n", syscfg_tbl_8800d80[cnt][0], ret); return ret; } } syscfg_num = sizeof(syscfg_tbl_masked_8800d80) / sizeof(u32) / 3; for (cnt = 0; cnt < syscfg_num; cnt++) { ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, syscfg_tbl_masked_8800d80[cnt][0], syscfg_tbl_masked_8800d80[cnt][1], syscfg_tbl_masked_8800d80[cnt][2]); if (ret) { printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80[cnt][0], ret); return ret; } } #endif return 0; } static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) { int ret = 0; uint32_t ext_patch_nb = patch_info->ext_patch_nb; char ext_patch_file_name[50]; int index = 0; uint32_t id = 0; uint32_t addr = 0; if (ext_patch_nb > 0){ for (index = 0; index < patch_info->ext_patch_nb; index++){ id = *(patch_info->ext_patch_param + (index * 2)); addr = *(patch_info->ext_patch_param + (index * 2) + 1); memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); sprintf(ext_patch_file_name,"%s%d.bin", FW_PATCH_BASE_NAME_8800D80_U02_EXT, id); AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", __func__,ext_patch_file_name, id, addr); if (rwnx_plat_bin_fw_upload_android(usb_dev, addr, ext_patch_file_name)) { ret = -1; break; } } } return ret; } int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) { struct aicbt_patch_table *head = NULL; struct aicbt_patch_info_t patch_info = { .info_len = 0, .adid_addrinf = 0, .addr_adid = 0, .patch_addrinf = 0, .addr_patch = 0, .reset_addr = 0, .reset_val = 0, .adid_flag_addr = 0, .adid_flag = 0, }; int i = 0; if (chip_id == CHIP_REV_U01) { head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80); } else { head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80_U02); } if (head == NULL){ printk("aicbt_patch_table_alloc fail\n"); return -1; } if(head == NULL){ return -1; } if (chip_id == CHIP_REV_U01) { patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80; patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80; } else if (chip_id == CHIP_REV_U02 || chip_id == CHIP_REV_U03) { patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80_U02; patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80_U02; } aicbt_patch_info_unpack(&patch_info, head); if(patch_info.info_len == 0) { printk("%s, aicbt_patch_info_unpack fail\n", __func__); return -1; } printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch); if(testmode == FW_NORMAL_MODE){ if (chip_id != CHIP_REV_U01){ if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) { return -1; } if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80_U02)) { return -1; } if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { return -1; } if (aicbt_patch_table_load(usb_dev, head)) { return -1; } if (IS_CHIP_ID_H()){ if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02)) return -1; } else { if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_U02)) return -1; } #if 0 if(rwnx_plat_bin_fw_upload_android(usb_dev, FW_RAM_CALIBMODE_ADDR_8800D80_U02, FW_CALIBMODE_NAME_8800D80_U02)) { return -1; } if (rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, 0x1e0000)) return -1; #endif if (aicwf_patch_config_8800d80(usb_dev)) { return -1; } if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, HOST_START_APP_AUTO)) { return -1; } }else { if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80)) { return -1; } if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80)) { return -1; } #if 0 if (rwnx_plat_bin_fw_patch_table_upload_android(usb_dev, FW_PATCH_TABLE_NAME_8800D80)) { return -1; } #else if (aicbt_patch_table_load(usb_dev, head)) { return -1; } #endif if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80, FW_BASE_NAME_8800D80)) { return -1; } if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_FW_ADDR_8800D80, HOST_START_APP_AUTO)) { return -1; } } }else if(testmode == FW_TEST_MODE){ if (chip_id != CHIP_REV_U01){ if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) { return -1; } if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80_U02)) { return -1; } if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { return -1; } if (aicbt_patch_table_load(usb_dev, head)) { return -1; } if (chip_mcu_id) { int ret = 0; ret = rwnx_plat_flash_bin_upload_android(usb_dev, FLASH_BIN_ADDR_8800M80, FLASH_BIN_8800M80); if (ret && ret!= ENOENT) { AICWFDBG(LOGERROR,"%s flash bin download fail \r\n", __func__); return -1; } } if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) { AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); return -1; } if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, HOST_START_APP_AUTO)) { return -1; } } else { if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80, FW_RF_BASE_NAME_8800D80)) { AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); return -1; } if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80, HOST_START_APP_AUTO)) { return -1; } } }else if(testmode == FW_BLE_SCAN_AD_FILTER_MODE){ /* data and ad_data_filter_mask instructions for use ex. data[18] = {0x46,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0xff,0xff,0x43,0x52,0x45,0x4c,0x42}; mask = 1100 0000 0111 1111 1100 0000 0000 0000 = 0xc07fc000 data = 0x46,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0xff,0xff,0x43,0x52,0x45,0x4c,0x42 mask = 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0...... fill 0 data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42" using data & mask value condition to wakeup host_wake_bt gpio */ struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); uint32_t *write_blocks = (uint32_t *)wakeup_param; printk("%s ble scan wakeup \r\n", __func__); memset(wakeup_param, 0, sizeof(struct ble_wakeup_param_t)); rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, FW_BLE_SCAN_AD_FILTER_NAME); wakeup_param->magic_num = 0x53454C42;//magic_num wakeup_param->delay_scan_to = 1000;//delay start scan time(ms) wakeup_param->reboot_to = ble_scan_wakeup_reboot_time;//reboot time /******************************************************************/ ///gpio_trigger_idx : 0 if wakeup_param->gpio_dft_lvl[0]=0xfe,this idx will be invalid. wakeup_param->gpio_num[0] = gpio_num;////default select gpiob2 for fw_wakeup_host wakeup_param->gpio_dft_lvl[0] = gpio_dft_lvl;////0:defalut pull down, 1:default pull up ///gpio_trigger_idx : 1 if wakeup_param->gpio_dft_lvl[1]=0xfe,this idx will be invalid. wakeup_param->gpio_num[1] = 3;////default select gpiob2 for fw_wakeup_host wakeup_param->gpio_dft_lvl[1] = 1;////0:defalut pull down, 1:default pull up /********************************************************************/ /********************************************************************/ //MAX_AD_FILTER_NUM=5 :num 0 { const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; wakeup_param->ad_filter[0].ad_len = 12; wakeup_param->ad_filter[0].ad_type = 0x09; memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] /********************************************************************/ /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter wl_addr have value xx: only remote addr in white_list_addr will use ad filter ********************************************************************/ wakeup_param->ad_filter[0].wl_addr.addr[0] = 0; wakeup_param->ad_filter[0].wl_addr.addr[1] = 0; wakeup_param->ad_filter[0].wl_addr.addr[2] = 0; wakeup_param->ad_filter[0].wl_addr.addr[3] = 0; wakeup_param->ad_filter[0].wl_addr.addr[4] = 0; wakeup_param->ad_filter[0].wl_addr.addr[5] = 0; } /********************************************************************/ //MAX_AD_FILTER_NUM=5 :num 1 { const uint8_t data[2] = {0x12,0x18}; wakeup_param->ad_filter[1].ad_len = 3; wakeup_param->ad_filter[1].ad_type = 0x3; memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] /********************************************************************/ /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter wl_addr have value xx: only remote addr in white_list_addr will use ad filter ********************************************************************/ wakeup_param->ad_filter[1].wl_addr.addr[0] = 0; wakeup_param->ad_filter[1].wl_addr.addr[1] = 0; wakeup_param->ad_filter[1].wl_addr.addr[2] = 0; wakeup_param->ad_filter[1].wl_addr.addr[3] = 0; wakeup_param->ad_filter[1].wl_addr.addr[4] = 0; wakeup_param->ad_filter[1].wl_addr.addr[5] = 0; } /********************************************************************/ //MAX_AD_FILTER_NUM=5 :num 2 { //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; wakeup_param->ad_filter[2].ad_len = 0; wakeup_param->ad_filter[2].ad_type = 0; //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 wakeup_param->ad_filter[2].ad_data_mask = 0; wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] /********************************************************************/ /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter wl_addr have value xx: only remote addr in white_list_addr will use ad filter ********************************************************************/ wakeup_param->ad_filter[2].wl_addr.addr[0] = 0; wakeup_param->ad_filter[2].wl_addr.addr[1] = 0; wakeup_param->ad_filter[2].wl_addr.addr[2] = 0; wakeup_param->ad_filter[2].wl_addr.addr[3] = 0; wakeup_param->ad_filter[2].wl_addr.addr[4] = 0; wakeup_param->ad_filter[2].wl_addr.addr[5] = 0; } /********************************************************************/ //MAX_AD_FILTER_NUM=5 :num 3 { //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; wakeup_param->ad_filter[3].ad_len = 0; wakeup_param->ad_filter[3].ad_type = 0; //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 wakeup_param->ad_filter[3].ad_data_mask = 0; wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] /********************************************************************/ /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter wl_addr have value xx: only remote addr in white_list_addr will use ad filter ********************************************************************/ wakeup_param->ad_filter[3].wl_addr.addr[0] = 0; wakeup_param->ad_filter[3].wl_addr.addr[1] = 0; wakeup_param->ad_filter[3].wl_addr.addr[2] = 0; wakeup_param->ad_filter[3].wl_addr.addr[3] = 0; wakeup_param->ad_filter[3].wl_addr.addr[4] = 0; wakeup_param->ad_filter[3].wl_addr.addr[5] = 0; } /********************************************************************/ //MAX_AD_FILTER_NUM=5 :num 4 { //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; wakeup_param->ad_filter[4].ad_len = 0; wakeup_param->ad_filter[4].ad_type = 0x09; //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] /********************************************************************/ /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter wl_addr have value xx: only remote addr in white_list_addr will use ad filter ********************************************************************/ wakeup_param->ad_filter[4].wl_addr.addr[0] = 0; wakeup_param->ad_filter[4].wl_addr.addr[1] = 0; wakeup_param->ad_filter[4].wl_addr.addr[2] = 0; wakeup_param->ad_filter[4].wl_addr.addr[3] = 0; wakeup_param->ad_filter[4].wl_addr.addr[4] = 0; wakeup_param->ad_filter[4].wl_addr.addr[5] = 0; } for(i = 0; i < (sizeof(struct ble_wakeup_param_t)/4 +1); i++){ printk("write_blocks[%d]:0x%08X \r\n", i, write_blocks[i]); rwnx_send_dbg_mem_write_req(usb_dev, 0x15FE00 + (4 * i), write_blocks[i]); } rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO); kfree(wakeup_param); return -1; } return 0; }