1/****************************************************************************** 2 * 3 * Copyright (C) 2012-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * Vendor-specific handler for DM events 22 * 23 ******************************************************************************/ 24#include <string.h> 25#include "nfc_hal_int.h" 26#include "nfc_hal_post_reset.h" 27#include "upio.h" 28#include "userial.h" 29 30/***************************************************************************** 31** Constants and types 32*****************************************************************************/ 33 34#define NFC_HAL_I93_RW_CFG_LEN (5) 35#define NFC_HAL_I93_RW_CFG_PARAM_LEN (3) 36#define NFC_HAL_I93_AFI (0) 37#define NFC_HAL_I93_ENABLE_SMART_POLL (1) 38 39static uint8_t nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] = { 40 NCI_PARAM_ID_I93_DATARATE, NFC_HAL_I93_RW_CFG_PARAM_LEN, 41 NFC_HAL_I93_FLAG_DATA_RATE, /* Bit0:Sub carrier, Bit1:Data rate, 42 Bit4:Enable/Disable AFI */ 43 NFC_HAL_I93_AFI, /* AFI if Bit 4 is set in the flag byte */ 44 NFC_HAL_I93_ENABLE_SMART_POLL /* Bit0:Enable/Disable smart poll */ 45}; 46 47static uint8_t nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] = { 48 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_SET_FWFSM, 0x01, 0x00, 49}; 50#define NCI_SET_FWFSM_OFFSET_ENABLE 3 51 52/* length of parameters in XTAL_INDEX CMD */ 53#define NCI_PROP_PARAM_SIZE_XTAL_INDEX 3 54#ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 55#define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 20 56#endif 57 58const uint8_t nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] = { 59 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_GET_BUILD_INFO, 0x00}; 60#define NCI_BUILD_INFO_OFFSET_HWID 25 /* HW ID offset in build info RSP */ 61 62const uint8_t nfc_hal_dm_get_patch_version_cmd[NCI_MSG_HDR_SIZE] = { 63 NCI_MTS_CMD | NCI_GID_PROP, NCI_MSG_GET_PATCH_VERSION, 0x00}; 64/* Length of patch version string in PATCH_INFO */ 65#define NCI_PATCH_INFO_VERSION_LEN 16 66 67/***************************************************************************** 68** Extern function prototypes 69*****************************************************************************/ 70extern uint8_t* p_nfc_hal_dm_lptd_cfg; 71extern uint8_t* p_nfc_hal_dm_pll_325_cfg; 72extern uint8_t* p_nfc_hal_dm_start_up_cfg; 73extern uint8_t* p_nfc_hal_dm_start_up_vsc_cfg; 74extern tNFC_HAL_CFG* p_nfc_hal_cfg; 75extern tNFC_HAL_DM_PRE_SET_MEM* p_nfc_hal_dm_pre_set_mem; 76 77/***************************************************************************** 78** Local function prototypes 79*****************************************************************************/ 80 81/******************************************************************************* 82** 83** Function nfc_hal_dm_set_config 84** 85** Description Send NCI config items to NFCC 86** 87** Returns tHAL_NFC_STATUS 88** 89*******************************************************************************/ 90tHAL_NFC_STATUS nfc_hal_dm_set_config(uint8_t tlv_size, uint8_t* p_param_tlvs, 91 tNFC_HAL_NCI_CBACK* p_cback) { 92 uint8_t *p_buff, *p; 93 uint8_t num_param = 0, param_len, rem_len, *p_tlv; 94 uint16_t cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1; 95 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED; 96 97 if ((tlv_size == 0) || (p_param_tlvs == NULL)) { 98 return status; 99 } 100 101 p_buff = (uint8_t*)GKI_getbuf((uint16_t)(NCI_MSG_HDR_SIZE + tlv_size)); 102 if (p_buff != NULL) { 103 p = p_buff; 104 105 NCI_MSG_BLD_HDR0(p, NCI_MT_CMD, NCI_GID_CORE); 106 NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_SET_CONFIG); 107 UINT8_TO_STREAM(p, (uint8_t)(tlv_size + 1)); 108 109 rem_len = tlv_size; 110 p_tlv = p_param_tlvs; 111 while (rem_len > 1) { 112 num_param++; /* number of params */ 113 114 p_tlv++; /* param type */ 115 param_len = *p_tlv++; /* param length */ 116 117 rem_len -= 2; /* param type and length */ 118 if (rem_len >= param_len) { 119 rem_len -= param_len; 120 p_tlv += param_len; /* next param_type */ 121 122 if (rem_len == 0) { 123 status = HAL_NFC_STATUS_OK; 124 break; 125 } 126 } else { 127 /* error found */ 128 break; 129 } 130 } 131 132 if (status == HAL_NFC_STATUS_OK) { 133 UINT8_TO_STREAM(p, num_param); 134 ARRAY_TO_STREAM(p, p_param_tlvs, tlv_size); 135 136 nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, p_cback); 137 } else { 138 HAL_TRACE_ERROR0("nfc_hal_dm_set_config ():Bad TLV"); 139 } 140 141 GKI_freebuf(p_buff); 142 } 143 144 return status; 145} 146 147/******************************************************************************* 148** 149** Function nfc_hal_dm_set_fw_fsm 150** 151** Description Enable or disable FW FSM 152** 153** Returns void 154** 155*******************************************************************************/ 156void nfc_hal_dm_set_fw_fsm(bool enable, tNFC_HAL_NCI_CBACK* p_cback) { 157 if (enable) 158 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 159 0x01; /* Enable, default is disabled */ 160 else 161 nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */ 162 163 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, 164 p_cback); 165} 166 167/******************************************************************************* 168** 169** Function nfc_hal_dm_config_nfcc_cback 170** 171** Description Callback for NCI vendor specific command complete 172** 173** Returns void 174** 175*******************************************************************************/ 176void nfc_hal_dm_config_nfcc_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len, 177 uint8_t* p_data) { 178 if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE) { 179 nfc_hal_hci_enable(); 180 } else { 181 nfc_hal_dm_config_nfcc(); 182 } 183} 184 185/******************************************************************************* 186** 187** Function nfc_hal_dm_send_startup_vsc 188** 189** Description Send VS command before NFA start-up 190** 191** Returns None 192** 193*******************************************************************************/ 194void nfc_hal_dm_send_startup_vsc(void) { 195 uint8_t *p, *p_end; 196 uint16_t len; 197 198 HAL_TRACE_DEBUG0("nfc_hal_dm_send_startup_vsc ()"); 199 200 /* VSC must have NCI header at least */ 201 if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= 202 *p_nfc_hal_dm_start_up_vsc_cfg) { 203 p = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc; 204 len = *(p + 2); 205 p_end = p + NCI_MSG_HDR_SIZE - 1 + len; 206 207 if (p_end <= 208 p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) { 209 /* move to next VSC */ 210 nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len; 211 212 /* if this is last VSC */ 213 if (p_end == 214 p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg) 215 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 216 217 nfc_hal_dm_send_nci_cmd(p, (uint16_t)(NCI_MSG_HDR_SIZE + len), 218 nfc_hal_dm_config_nfcc_cback); 219 return; 220 } 221 } 222 223 HAL_TRACE_ERROR0("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC"); 224 225 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 226 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED); 227} 228 229/******************************************************************************* 230** 231** Function nfc_hal_dm_config_nfcc 232** 233** Description Send VS config before NFA start-up 234** 235** Returns void 236** 237*******************************************************************************/ 238void nfc_hal_dm_config_nfcc(void) { 239 HAL_TRACE_DEBUG1("nfc_hal_dm_config_nfcc (): next_dm_config = %d", 240 nfc_hal_cb.dev_cb.next_dm_config); 241 242 if ((p_nfc_hal_dm_lptd_cfg[0]) && 243 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD)) { 244 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325; 245 246 if (nfc_hal_dm_set_config( 247 p_nfc_hal_dm_lptd_cfg[0], &p_nfc_hal_dm_lptd_cfg[1], 248 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) { 249 return; 250 } else { 251 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 252 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, 253 HAL_NFC_STATUS_FAILED); 254 return; 255 } 256 } 257 258 if ((p_nfc_hal_dm_pll_325_cfg) && 259 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325)) { 260 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP; 261 262 if (nfc_hal_dm_set_config( 263 NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN, p_nfc_hal_dm_pll_325_cfg, 264 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) { 265 return; 266 } else { 267 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 268 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, 269 HAL_NFC_STATUS_FAILED); 270 return; 271 } 272 } 273 274 if ((p_nfc_hal_dm_start_up_cfg[0]) && 275 (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP)) { 276 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE; 277 if (nfc_hal_dm_set_config( 278 p_nfc_hal_dm_start_up_cfg[0], &p_nfc_hal_dm_start_up_cfg[1], 279 nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK) { 280 return; 281 } else { 282 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 283 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, 284 HAL_NFC_STATUS_FAILED); 285 return; 286 } 287 } 288 289#if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH) 290 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_I93_DATA_RATE) { 291 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM; 292 if (nfc_hal_dm_set_config(NFC_HAL_I93_RW_CFG_LEN, nfc_hal_dm_i93_rw_cfg, 293 nfc_hal_dm_config_nfcc_cback) == 294 HAL_NFC_STATUS_OK) { 295 return; 296 } else { 297 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 298 nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, 299 HAL_NFC_STATUS_FAILED); 300 return; 301 } 302 } 303#endif 304 305 /* FW FSM is disabled as default in NFCC */ 306 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM) { 307 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC; 308 nfc_hal_dm_set_fw_fsm(NFC_HAL_DM_MULTI_TECH_RESP, 309 nfc_hal_dm_config_nfcc_cback); 310 return; 311 } 312 313 if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC) { 314 if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg) { 315 nfc_hal_dm_send_startup_vsc(); 316 return; 317 } 318 } 319 320 /* nothing to config */ 321 nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE; 322 nfc_hal_dm_config_nfcc_cback(0, 0, NULL); 323} 324 325/******************************************************************************* 326** 327** Function: nfc_hal_dm_get_xtal_index 328** 329** Description: Return Xtal index and frequency 330** 331** Returns: tNFC_HAL_XTAL_INDEX 332** 333*******************************************************************************/ 334tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index(uint32_t brcm_hw_id, 335 uint16_t* p_xtal_freq) { 336 uint8_t xx; 337 338 HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id); 339 340 for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++) { 341 if ((brcm_hw_id & BRCM_NFC_GEN_MASK) == 342 nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id) { 343 *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq; 344 return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index); 345 } 346 } 347 348 /* if not found */ 349 *p_xtal_freq = 0; 350 return (NFC_HAL_XTAL_INDEX_MAX); 351} 352 353/******************************************************************************* 354** 355** Function nfc_hal_dm_set_xtal_freq_index 356** 357** Description Set crystal frequency index 358** 359** Returns void 360** 361*******************************************************************************/ 362void nfc_hal_dm_set_xtal_freq_index(void) { 363 uint8_t nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + 364 NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX]; 365 uint8_t* p; 366 tNFC_HAL_XTAL_INDEX xtal_index; 367 uint16_t xtal_freq; 368 uint8_t cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX; 369 extern uint8_t* p_nfc_hal_dm_xtal_params_cfg; 370 371 HAL_TRACE_DEBUG1("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x", 372 nfc_hal_cb.dev_cb.brcm_hw_id); 373 374 xtal_index = 375 nfc_hal_dm_get_xtal_index(nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq); 376 if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) && 377 (p_nfc_hal_dm_xtal_params_cfg)) { 378 cmd_len += 379 p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */ 380 } 381 382 p = nci_brcm_xtal_index_cmd; 383 UINT8_TO_STREAM(p, (NCI_MTS_CMD | NCI_GID_PROP)); 384 UINT8_TO_STREAM(p, NCI_MSG_GET_XTAL_INDEX_FROM_DH); 385 UINT8_TO_STREAM(p, cmd_len); 386 UINT8_TO_STREAM(p, xtal_index); 387 UINT16_TO_STREAM(p, xtal_freq); 388 if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX) { 389 memcpy(p, &p_nfc_hal_dm_xtal_params_cfg[1], 390 p_nfc_hal_dm_xtal_params_cfg[0]); 391 } 392 393 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_XTAL_SET); 394 395 nfc_hal_dm_send_nci_cmd(nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + cmd_len, 396 NULL); 397} 398 399/******************************************************************************* 400** 401** Function nfc_hal_dm_set_power_level_zero 402** 403** Description set power level to 0 404** 405** Returns None 406** 407*******************************************************************************/ 408void nfc_hal_dm_set_power_level_zero(void) { 409 uint8_t 410 nci_brcm_set_pwr_level_cmd[NCI_MSG_HDR_SIZE + NCI_PARAM_LEN_POWER_LEVEL]; 411 uint8_t* p; 412 uint8_t cmd_len = NCI_PARAM_LEN_POWER_LEVEL; 413 414 p = nci_brcm_set_pwr_level_cmd; 415 UINT8_TO_STREAM(p, (NCI_MTS_CMD | NCI_GID_PROP)); 416 UINT8_TO_STREAM(p, NCI_MSG_POWER_LEVEL); 417 UINT8_TO_STREAM(p, NCI_PARAM_LEN_POWER_LEVEL); 418 memset(p, 0, NCI_PARAM_LEN_POWER_LEVEL); 419 420 nfc_hal_dm_send_nci_cmd(nci_brcm_set_pwr_level_cmd, 421 NCI_MSG_HDR_SIZE + cmd_len, 422 nfc_hal_main_exit_op_done); 423} 424 425/******************************************************************************* 426** 427** Function nfc_hal_dm_send_get_build_info_cmd 428** 429** Description Send NCI_MSG_GET_BUILD_INFO CMD 430** 431** Returns void 432** 433*******************************************************************************/ 434void nfc_hal_dm_send_get_build_info_cmd(void) { 435 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_BUILD_INFO); 436 437 /* get build information to find out HW */ 438 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, 439 NULL); 440} 441/******************************************************************************* 442** 443** Function: nfc_hal_dm_adjust_hw_id 444** 445** Description: The hw_id of certain chips are shifted by 8 bits. 446** Adjust the hw_id before processing. 447** 448** Returns: Nothing 449** 450*******************************************************************************/ 451static uint32_t nfc_hal_dm_adjust_hw_id(uint32_t hw_id) { 452 if ((hw_id & 0xF0000000) == 0) 453 hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */ 454 return hw_id; 455} 456 457/******************************************************************************* 458** 459** Function nfc_hal_dm_check_xtal 460** 461** Description check if need to send xtal command. 462** If not, proceed to next step get_patch_version. 463** 464** Returns void 465** 466*******************************************************************************/ 467static void nfc_hal_dm_check_xtal(void) { 468 uint16_t xtal_freq; 469 tNFC_HAL_XTAL_INDEX xtal_index; 470 471 /* if NFCC needs to set Xtal frequency before getting patch version */ 472 xtal_index = 473 nfc_hal_dm_get_xtal_index(nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq); 474 if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) || 475 (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL)) { 476 { 477 /* set Xtal index before getting patch version */ 478 nfc_hal_dm_set_xtal_freq_index(); 479 return; 480 } 481 } 482 483 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PATCH_INFO); 484 485 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, 486 NULL); 487} 488 489/******************************************************************************* 490** 491** Function nfc_hal_dm_pre_set_mem_cback 492** 493** Description This is pre-set mem complete callback. 494** 495** Returns void 496** 497*******************************************************************************/ 498static void nfc_hal_dm_pre_set_mem_cback(tNFC_HAL_BTVSC_CPLT* pData) { 499 uint8_t status = pData->p_param_buf[0]; 500 501 HAL_TRACE_DEBUG1("nfc_hal_dm_pre_set_mem_cback: %d", status); 502 /* if it is completed */ 503 if (status == HCI_SUCCESS) { 504 if (!nfc_hal_dm_check_pre_set_mem()) { 505 return; 506 } 507 } 508 nfc_hal_dm_check_xtal(); 509} 510 511/******************************************************************************* 512** 513** Function nfc_hal_dm_check_pre_set_mem 514** 515** Description Check if need to send the command. 516** 517** Returns TRUE if done. 518** 519*******************************************************************************/ 520bool nfc_hal_dm_check_pre_set_mem(void) { 521 uint8_t cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH]; 522 uint8_t* p; 523 uint32_t addr = 0; 524 525 if (p_nfc_hal_dm_pre_set_mem) 526 addr = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr; 527 HAL_TRACE_DEBUG2("nfc_hal_dm_check_pre_set_mem: %d/0x%x", 528 nfc_hal_cb.pre_set_mem_idx, addr); 529 if (addr == 0) { 530 return true; 531 } 532 p = cmd; 533 534 /* Add the command */ 535 UINT16_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM); 536 UINT8_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM_LENGTH); 537 538 UINT8_TO_STREAM(p, HCI_BRCM_PRE_SET_MEM_TYPE); 539 UINT32_TO_STREAM(p, addr); 540 UINT8_TO_STREAM(p, 0); 541 UINT32_TO_STREAM(p, 542 p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data); 543 nfc_hal_cb.pre_set_mem_idx++; 544 545 nfc_hal_dm_send_bt_cmd( 546 cmd, NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH, 547 nfc_hal_dm_pre_set_mem_cback); 548 return false; 549} 550 551/******************************************************************************* 552** 553** Function nfc_hal_dm_got_vs_rsp 554** 555** Description Received VS RSP. Clean up control block to allow next NCI 556*cmd 557** 558** Returns void 559** 560*******************************************************************************/ 561tNFC_HAL_NCI_CBACK* nfc_hal_dm_got_vs_rsp(void) { 562 tNFC_HAL_NCI_CBACK* p_cback = NULL; 563 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 564 p_cback = (tNFC_HAL_NCI_CBACK*)nfc_hal_cb.ncit_cb.p_vsc_cback; 565 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 566 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 567 return p_cback; 568} 569 570/******************************************************************************* 571** 572** Function nfc_hal_dm_proc_msg_during_init 573** 574** Description Process NCI message while initializing NFCC 575** 576** Returns void 577** 578*******************************************************************************/ 579void nfc_hal_dm_proc_msg_during_init(NFC_HDR* p_msg) { 580 uint8_t* p; 581 uint8_t reset_reason, reset_type; 582 uint8_t mt, pbf, gid, op_code; 583 uint8_t *p_old, old_gid, old_oid, old_mt; 584 uint8_t u8; 585 tNFC_HAL_NCI_CBACK* p_cback = NULL; 586 uint8_t chipverlen; 587 uint8_t chipverstr[NCI_SPD_HEADER_CHIPVER_LEN]; 588 uint32_t hw_id = 0; 589 590 HAL_TRACE_DEBUG1("nfc_hal_dm_proc_msg_during_init(): init state:%d", 591 nfc_hal_cb.dev_cb.initializing_state); 592 593 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 594 595 NCI_MSG_PRS_HDR0(p, mt, pbf, gid); 596 NCI_MSG_PRS_HDR1(p, op_code); 597 598 /* check if waiting for this response */ 599 if ((nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) || 600 (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)) { 601 if (mt == NCI_MT_RSP) { 602 p_old = nfc_hal_cb.ncit_cb.last_hdr; 603 NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid); 604 old_oid = ((*p_old) & NCI_OID_MASK); 605 /* make sure this is the RSP we are waiting for before updating the 606 * command window */ 607 if ((old_gid == gid) && (old_oid == op_code)) { 608 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 609 p_cback = (tNFC_HAL_NCI_CBACK*)nfc_hal_cb.ncit_cb.p_vsc_cback; 610 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; 611 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 612 } 613 } 614 } 615 616 if (gid == NCI_GID_CORE) { 617 if (op_code == NCI_MSG_CORE_RESET) { 618 if (mt == NCI_MT_NTF) { 619 if ((nfc_hal_cb.dev_cb.initializing_state == 620 NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) || 621 (nfc_hal_cb.dev_cb.initializing_state == 622 NFC_HAL_INIT_STATE_POST_XTAL_SET)) { 623 /* 624 ** Core reset ntf in the following cases; 625 ** 1) after power up (raising REG_PU) 626 ** 2) after setting xtal index 627 ** Start pre-initializing NFCC 628 */ 629 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.timer); 630 nfc_hal_dm_pre_init_nfcc(); 631 } else { 632 /* Core reset ntf after post-patch download, Call reset notification 633 * callback */ 634 p++; /* Skip over param len */ 635 STREAM_TO_UINT8(reset_reason, p); 636 STREAM_TO_UINT8(reset_type, p); 637 nfc_hal_prm_spd_reset_ntf(reset_reason, reset_type); 638 } 639 } 640 } else if (p_cback) { 641 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len, 642 (uint8_t*)(p_msg + 1) + p_msg->offset); 643 } 644 } else if (gid == NCI_GID_PROP) /* this is for download patch */ 645 { 646 if (mt == NCI_MT_NTF) 647 op_code |= NCI_NTF_BIT; 648 else 649 op_code |= NCI_RSP_BIT; 650 651 if (nfc_hal_cb.dev_cb.initializing_state == 652 NFC_HAL_INIT_STATE_W4_XTAL_SET) { 653 if (op_code == (NCI_RSP_BIT | NCI_MSG_GET_XTAL_INDEX_FROM_DH)) { 654 /* start timer in case that NFCC doesn't send RESET NTF after loading 655 * patch from NVM */ 656 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_POST_XTAL_SET); 657 658 nfc_hal_main_start_quick_timer( 659 &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE, 660 ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout) * 661 QUICK_TIMER_TICKS_PER_SEC) / 662 1000); 663 } 664 } else if ((op_code == NFC_VS_GET_BUILD_INFO_EVT) && 665 (nfc_hal_cb.dev_cb.initializing_state == 666 NFC_HAL_INIT_STATE_W4_BUILD_INFO)) { 667 p += NCI_BUILD_INFO_OFFSET_HWID; 668 669 STREAM_TO_UINT32(hw_id, p); 670 nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id(hw_id); 671 HAL_TRACE_DEBUG2("brcm_hw_id: 0x%x -> 0x%x", hw_id, 672 nfc_hal_cb.dev_cb.brcm_hw_id); 673 674 STREAM_TO_UINT8(chipverlen, p); 675 memset(chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN); 676 677 STREAM_TO_ARRAY(chipverstr, p, chipverlen); 678 679 /* If chip is not 20791 and 43341, set flag to send the "Disable" VSC */ 680 if (((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) != 681 BRCM_NFC_20791_GEN) && 682 ((nfc_hal_cb.dev_cb.brcm_hw_id & BRCM_NFC_GEN_MASK) != 683 BRCM_NFC_43341_GEN)) { 684 nfc_hal_cb.hal_flags |= NFC_HAL_FLAGS_NEED_DISABLE_VSC; 685 } 686 687 nfc_hal_hci_handle_build_info(chipverlen, chipverstr); 688 nfc_hal_cb.pre_set_mem_idx = 0; 689 if (!nfc_hal_dm_check_pre_set_mem()) { 690 /* pre-set mem started */ 691 return; 692 } 693 nfc_hal_dm_check_xtal(); 694 } else if ((op_code == NFC_VS_GET_PATCH_VERSION_EVT) && 695 (nfc_hal_cb.dev_cb.initializing_state == 696 NFC_HAL_INIT_STATE_W4_PATCH_INFO)) { 697 /* Store NVM info to control block */ 698 699 /* Skip over rsp len */ 700 p++; 701 702 /* Get project id */ 703 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.project_id, p); 704 705 /* RFU */ 706 p++; 707 708 /* Get chip version string */ 709 STREAM_TO_UINT8(u8, p); 710 if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN) u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN; 711 memcpy(nfc_hal_cb.nvm_cb.chip_ver, p, u8); 712 p += NCI_PATCH_INFO_VERSION_LEN; 713 714 /* Get major/minor version */ 715 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.ver_major, p); 716 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.ver_minor, p); 717 718 /* Skip over max_size and patch_max_size */ 719 p += 4; 720 721 /* Get current lpm patch size */ 722 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.lpm_size, p); 723 STREAM_TO_UINT16(nfc_hal_cb.nvm_cb.fpm_size, p); 724 725 /* clear all flags which may be set during previous initialization */ 726 nfc_hal_cb.nvm_cb.flags = 0; 727 728 /* Set patch present flag */ 729 if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size)) 730 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT; 731 732 /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is 733 * present in nvm) */ 734 STREAM_TO_UINT8(u8, p); 735 if (u8) { 736 /* LPM patch in NVM fails CRC check */ 737 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD; 738 } 739 740 /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is 741 * present in nvm) */ 742 STREAM_TO_UINT8(u8, p); 743 if (u8) { 744 /* FPM patch in NVM fails CRC check */ 745 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD; 746 } 747 748 /* Check if downloading patch to RAM only (no NVM) */ 749 STREAM_TO_UINT8(nfc_hal_cb.nvm_cb.nvm_type, p); 750 if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE) { 751 nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM; 752 } 753 754 /* let platform update baudrate or download patch */ 755 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_APP_COMPLETE); 756 nfc_hal_post_reset_init(nfc_hal_cb.dev_cb.brcm_hw_id, 757 nfc_hal_cb.nvm_cb.nvm_type); 758 } else if (p_cback) { 759 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len, 760 (uint8_t*)(p_msg + 1) + p_msg->offset); 761 } else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT) { 762 HAL_TRACE_DEBUG0("signature!!"); 763 nfc_hal_prm_nci_command_complete_cback( 764 (tNFC_HAL_NCI_EVT)(op_code), p_msg->len, 765 (uint8_t*)(p_msg + 1) + p_msg->offset); 766 } 767 } 768} 769 770/******************************************************************************* 771** 772** Function nfc_hal_dm_proc_msg_during_exit 773** 774** Description Process NCI message while shutting down NFCC 775** 776** Returns void 777** 778*******************************************************************************/ 779void nfc_hal_dm_proc_msg_during_exit(NFC_HDR* p_msg) { 780 uint8_t* p; 781 uint8_t mt, pbf, gid, op_code; 782 uint8_t *p_old, old_gid, old_oid, old_mt; 783 uint8_t u8; 784 tNFC_HAL_NCI_CBACK* p_cback = NULL; 785 786 HAL_TRACE_DEBUG1("nfc_hal_dm_proc_msg_during_exit(): state:%d", 787 nfc_hal_cb.dev_cb.initializing_state); 788 789 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 790 791 NCI_MSG_PRS_HDR0(p, mt, pbf, gid); 792 NCI_MSG_PRS_HDR1(p, op_code); 793 u8 = *p; 794 795 /* check if waiting for this response */ 796 if ((nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) || 797 (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)) { 798 if (mt == NCI_MT_RSP) { 799 p_old = nfc_hal_cb.ncit_cb.last_hdr; 800 NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid); 801 old_oid = ((*p_old) & NCI_OID_MASK); 802 /* make sure this is the RSP we are waiting for before updating the 803 * command window */ 804 if ((old_gid == gid) && (old_oid == op_code)) { 805 p_cback = nfc_hal_dm_got_vs_rsp(); 806 if (p_cback) { 807 if (gid == NCI_GID_PROP) { 808 if (mt == NCI_MT_NTF) 809 op_code |= NCI_NTF_BIT; 810 else 811 op_code |= NCI_RSP_BIT; 812 813 if (op_code == NFC_VS_POWER_LEVEL_RSP) { 814 (*p_cback)((tNFC_HAL_NCI_EVT)(op_code), p_msg->len, 815 (uint8_t*)(p_msg + 1) + p_msg->offset); 816 } 817 } 818 } 819 } 820 } 821 } 822} 823 824/******************************************************************************* 825** 826** Function nfc_hal_dm_send_nci_cmd 827** 828** Description Send NCI command to NFCC while initializing BRCM NFCC 829** 830** Returns void 831** 832*******************************************************************************/ 833void nfc_hal_dm_send_nci_cmd(const uint8_t* p_data, uint16_t len, 834 tNFC_HAL_NCI_CBACK* p_cback) { 835 NFC_HDR* p_buf; 836 uint8_t* ps; 837 838 HAL_TRACE_DEBUG1("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", 839 nfc_hal_cb.ncit_cb.nci_wait_rsp); 840 841 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) { 842 HAL_TRACE_ERROR0("nfc_hal_dm_send_nci_cmd(): no command window"); 843 return; 844 } 845 846 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID); 847 if (p_buf != NULL) { 848 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC; 849 850 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 851 p_buf->event = NFC_HAL_EVT_TO_NFC_NCI; 852 p_buf->len = len; 853 854 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, len); 855 856 /* Keep a copy of the command and send to NCI transport */ 857 858 /* save the message header to double check the response */ 859 ps = (uint8_t*)(p_buf + 1) + p_buf->offset; 860 memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE); 861 memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, 862 NFC_HAL_SAVED_CMD_SIZE); 863 864 /* save the callback for NCI VSCs */ 865 nfc_hal_cb.ncit_cb.p_vsc_cback = (void*)p_cback; 866 867 nfc_hal_nci_send_cmd(p_buf); 868 869 /* start NFC command-timeout timer */ 870 nfc_hal_main_start_quick_timer( 871 &nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, 872 (uint16_t)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 873 ((uint32_t)NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 874 } 875} 876 877/******************************************************************************* 878** 879** Function nfc_hal_dm_send_pend_cmd 880** 881** Description Send a command to NFCC 882** 883** Returns void 884** 885*******************************************************************************/ 886void nfc_hal_dm_send_pend_cmd(void) { 887 NFC_HDR* p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd; 888 uint8_t* p; 889 890 if (p_buf == NULL) return; 891 892 /* check low power mode state */ 893 if (!nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TX_DATA_EVT)) { 894 return; 895 } 896 897 if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP) { 898#if (NFC_HAL_TRACE_PROTOCOL == TRUE) 899 DispHciCmd(p_buf); 900#endif 901 902 /* save the message header to double check the response */ 903 p = (uint8_t*)(p_buf + 1) + p_buf->offset; 904 memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE); 905 906 /* add packet type for BT message */ 907 p_buf->offset--; 908 p_buf->len++; 909 910 p = (uint8_t*)(p_buf + 1) + p_buf->offset; 911 *p = HCIT_TYPE_COMMAND; 912 913 USERIAL_Write(USERIAL_NFC_PORT, p, p_buf->len); 914 915 GKI_freebuf(p_buf); 916 nfc_hal_cb.ncit_cb.p_pend_cmd = NULL; 917 918 /* start NFC command-timeout timer */ 919 nfc_hal_main_start_quick_timer( 920 &nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, 921 (uint16_t)(NFC_HAL_TTYPE_NCI_WAIT_RSP), 922 ((uint32_t)NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000); 923 } 924} 925 926/******************************************************************************* 927** 928** Function nfc_hal_dm_send_bt_cmd 929** 930** Description Send BT message to NFCC while initializing BRCM NFCC 931** 932** Returns void 933** 934*******************************************************************************/ 935void nfc_hal_dm_send_bt_cmd(const uint8_t* p_data, uint16_t len, 936 tNFC_HAL_BTVSC_CPLT_CBACK* p_cback) { 937 NFC_HDR* p_buf; 938 char buff[300]; 939 char tmp[4]; 940 buff[0] = 0; 941 int i; 942 943 HAL_TRACE_DEBUG1("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", 944 nfc_hal_cb.ncit_cb.nci_wait_rsp); 945 946 for (i = 0; i < len; i++) { 947 sprintf(tmp, "%02x ", p_data[i]); 948 strcat(buff, tmp); 949 } 950 HAL_TRACE_DEBUG2("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, 951 buff); 952 953 if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) { 954 HAL_TRACE_ERROR0("nfc_hal_dm_send_bt_cmd(): no command window"); 955 return; 956 } 957 958 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID); 959 if (p_buf != NULL) { 960 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP; 961 962 p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE; 963 p_buf->len = len; 964 965 memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, len); 966 967 /* save the callback for NCI VSCs) */ 968 nfc_hal_cb.ncit_cb.p_vsc_cback = (void*)p_cback; 969 970 nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf; 971 if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE) { 972 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE); 973 nfc_hal_cb.p_stack_cback(HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK); 974 return; 975 } 976 977 nfc_hal_dm_send_pend_cmd(); 978 } 979} 980 981/******************************************************************************* 982** 983** Function nfc_hal_dm_set_nfc_wake 984** 985** Description Set NFC_WAKE line 986** 987** Returns void 988** 989*******************************************************************************/ 990void nfc_hal_dm_set_nfc_wake(uint8_t cmd) { 991 HAL_TRACE_DEBUG1("nfc_hal_dm_set_nfc_wake () %s", 992 (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT")); 993 994 /* 995 ** nfc_wake_active_mode cmd result of voltage on 996 *NFC_WAKE 997 ** 998 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_ASSERT_NFC_WAKE (0) pull down 999 *NFC_WAKE (GND) 1000 ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_DEASSERT_NFC_WAKE (1) pull up 1001 *NFC_WAKE (VCC) 1002 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_ASSERT_NFC_WAKE (0) pull up 1003 *NFC_WAKE (VCC) 1004 ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_DEASSERT_NFC_WAKE (1) pull down 1005 *NFC_WAKE (GND) 1006 */ 1007 1008 if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode) 1009 UPIO_Set(UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, 1010 UPIO_OFF); /* pull down NFC_WAKE */ 1011 else 1012 UPIO_Set(UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, 1013 UPIO_ON); /* pull up NFC_WAKE */ 1014} 1015 1016/******************************************************************************* 1017** 1018** Function nfc_hal_dm_power_mode_execute 1019** 1020** Description If snooze mode is enabled in full power mode, 1021** Assert NFC_WAKE before sending data 1022** Deassert NFC_WAKE when idle timer expires 1023** 1024** Returns TRUE if DH can send data to NFCC 1025** 1026*******************************************************************************/ 1027bool nfc_hal_dm_power_mode_execute(tNFC_HAL_LP_EVT event) { 1028 bool send_to_nfcc = false; 1029 1030 HAL_TRACE_DEBUG1("nfc_hal_dm_power_mode_execute () event = %d", event); 1031 1032 if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) { 1033 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) { 1034 /* if any transport activity */ 1035 if ((event == NFC_HAL_LP_TX_DATA_EVT) || 1036 (event == NFC_HAL_LP_RX_DATA_EVT)) { 1037 /* if idle timer is not running */ 1038 if (nfc_hal_cb.dev_cb.lp_timer.in_use == false) { 1039 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE); 1040 } 1041 1042 /* start or extend idle timer */ 1043 nfc_hal_main_start_quick_timer(&nfc_hal_cb.dev_cb.lp_timer, 0x00, 1044 ((uint32_t)NFC_HAL_LP_IDLE_TIMEOUT) * 1045 QUICK_TIMER_TICKS_PER_SEC / 1000); 1046 } else if (event == NFC_HAL_LP_TIMEOUT_EVT) { 1047 /* let NFCC go to snooze mode */ 1048 nfc_hal_dm_set_nfc_wake(NFC_HAL_DEASSERT_NFC_WAKE); 1049 } 1050 } 1051 1052 send_to_nfcc = true; 1053 } 1054 1055 return (send_to_nfcc); 1056} 1057 1058/******************************************************************************* 1059** 1060** Function nci_brcm_lp_timeout_cback 1061** 1062** Description callback function for low power timeout 1063** 1064** Returns void 1065** 1066*******************************************************************************/ 1067static void nci_brcm_lp_timeout_cback(void* p_tle) { 1068 HAL_TRACE_DEBUG0("nci_brcm_lp_timeout_cback ()"); 1069 1070 nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TIMEOUT_EVT); 1071} 1072 1073/******************************************************************************* 1074** 1075** Function nfc_hal_dm_pre_init_nfcc 1076** 1077** Description This function initializes Broadcom specific control blocks 1078*for 1079** NCI transport 1080** 1081** Returns void 1082** 1083*******************************************************************************/ 1084void nfc_hal_dm_pre_init_nfcc(void) { 1085 HAL_TRACE_DEBUG0("nfc_hal_dm_pre_init_nfcc ()"); 1086 1087 /* if it was waiting for core reset notification after raising REG_PU */ 1088 if (nfc_hal_cb.dev_cb.initializing_state == 1089 NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) { 1090 nfc_hal_dm_send_get_build_info_cmd(); 1091 } 1092 /* if it was waiting for core reset notification after setting Xtal */ 1093 else if (nfc_hal_cb.dev_cb.initializing_state == 1094 NFC_HAL_INIT_STATE_POST_XTAL_SET) { 1095 { 1096 /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM 1097 */ 1098 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PATCH_INFO); 1099 1100 nfc_hal_dm_send_nci_cmd(nfc_hal_dm_get_patch_version_cmd, 1101 NCI_MSG_HDR_SIZE, NULL); 1102 } 1103 } 1104} 1105 1106/******************************************************************************* 1107** 1108** Function nfc_hal_dm_shutting_down_nfcc 1109** 1110** Description This function initializes Broadcom specific control blocks 1111*for 1112** NCI transport 1113** 1114** Returns void 1115** 1116*******************************************************************************/ 1117void nfc_hal_dm_shutting_down_nfcc(void) { 1118 HAL_TRACE_DEBUG0("nfc_hal_dm_shutting_down_nfcc ()"); 1119 1120 nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING; 1121 1122 /* reset low power mode variables */ 1123 if ((nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL) && 1124 (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)) { 1125 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE); 1126 } 1127 1128 nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; 1129 1130 nfc_hal_cb.dev_cb.power_mode = NFC_HAL_POWER_MODE_FULL; 1131 nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE; 1132 1133 /* Stop all timers */ 1134 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); 1135 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.dev_cb.lp_timer); 1136 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.prm.timer); 1137#if (NFC_HAL_HCI_INCLUDED == TRUE) 1138 nfc_hal_cb.hci_cb.hcp_conn_id = 0; 1139 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.hci_cb.hci_timer); 1140#endif 1141 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.timer); 1142} 1143 1144/******************************************************************************* 1145** 1146** Function nfc_hal_dm_init 1147** 1148** Description This function initializes Broadcom specific control blocks 1149*for 1150** NCI transport 1151** 1152** Returns void 1153** 1154*******************************************************************************/ 1155void nfc_hal_dm_init(void) { 1156 HAL_TRACE_DEBUG0("nfc_hal_dm_init ()"); 1157 1158 nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback; 1159 1160 nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback; 1161 1162#if (NFC_HAL_HCI_INCLUDED == TRUE) 1163 nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback; 1164#endif 1165 1166 nfc_hal_cb.pre_discover_done = false; 1167 1168 nfc_post_reset_cb.spd_nvm_detection_cur_count = 0; 1169 nfc_post_reset_cb.spd_skip_on_power_cycle = false; 1170} 1171 1172/******************************************************************************* 1173** 1174** Function HAL_NfcDevInitDone 1175** 1176** Description Notify that pre-initialization of NFCC is complete 1177** 1178** Returns void 1179** 1180*******************************************************************************/ 1181void HAL_NfcPreInitDone(tHAL_NFC_STATUS status) { 1182 HAL_TRACE_DEBUG1("HAL_NfcPreInitDone () status=%d", status); 1183 1184 if (nfc_hal_cb.dev_cb.initializing_state == 1185 NFC_HAL_INIT_STATE_W4_APP_COMPLETE) { 1186 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE); 1187 1188 nfc_hal_main_pre_init_done(status); 1189 } 1190} 1191 1192/******************************************************************************* 1193** 1194** Function HAL_NfcReInit 1195** 1196** Description This function is called to restart initialization after 1197*REG_PU 1198** toggled because of failure to detect NVM type or download 1199*patchram. 1200** 1201** Note This function should be called only during the HAL init 1202*process 1203** 1204** Returns HAL_NFC_STATUS_OK if successfully initiated 1205** HAL_NFC_STATUS_FAILED otherwise 1206** 1207*******************************************************************************/ 1208tHAL_NFC_STATUS HAL_NfcReInit(void) { 1209 tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED; 1210 1211 HAL_TRACE_DEBUG1("HAL_NfcReInit () init st=0x%x", 1212 nfc_hal_cb.dev_cb.initializing_state); 1213 if (nfc_hal_cb.dev_cb.initializing_state == 1214 NFC_HAL_INIT_STATE_W4_APP_COMPLETE) { 1215 { 1216 /* Wait for NFCC to enable - Core reset notification */ 1217 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_NFCC_ENABLE); 1218 1219 /* NFCC Enable timeout */ 1220 nfc_hal_main_start_quick_timer( 1221 &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE, 1222 ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout) * 1223 QUICK_TIMER_TICKS_PER_SEC) / 1224 1000); 1225 } 1226 1227 status = HAL_NFC_STATUS_OK; 1228 } 1229 return status; 1230} 1231 1232/******************************************************************************* 1233** 1234** Function nfc_hal_dm_set_snooze_mode_cback 1235** 1236** Description This is snooze update complete callback. 1237** 1238** Returns void 1239** 1240*******************************************************************************/ 1241static void nfc_hal_dm_set_snooze_mode_cback(tNFC_HAL_BTVSC_CPLT* pData) { 1242 uint8_t status = pData->p_param_buf[0]; 1243 tHAL_NFC_STATUS hal_status; 1244 tHAL_NFC_STATUS_CBACK* p_cback; 1245 1246 /* if it is completed */ 1247 if (status == HCI_SUCCESS) { 1248 /* update snooze mode */ 1249 nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode; 1250 1251 nfc_hal_dm_set_nfc_wake(NFC_HAL_ASSERT_NFC_WAKE); 1252 1253 if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) { 1254 /* start idle timer */ 1255 nfc_hal_main_start_quick_timer(&nfc_hal_cb.dev_cb.lp_timer, 0x00, 1256 ((uint32_t)NFC_HAL_LP_IDLE_TIMEOUT) * 1257 QUICK_TIMER_TICKS_PER_SEC / 1000); 1258 } else { 1259 nfc_hal_main_stop_quick_timer(&nfc_hal_cb.dev_cb.lp_timer); 1260 } 1261 hal_status = HAL_NFC_STATUS_OK; 1262 } else { 1263 hal_status = HAL_NFC_STATUS_FAILED; 1264 } 1265 1266 if (nfc_hal_cb.dev_cb.p_prop_cback) { 1267 p_cback = nfc_hal_cb.dev_cb.p_prop_cback; 1268 nfc_hal_cb.dev_cb.p_prop_cback = NULL; 1269 (*p_cback)(hal_status); 1270 } 1271} 1272 1273/******************************************************************************* 1274** 1275** Function HAL_NfcSetSnoozeMode 1276** 1277** Description Set snooze mode 1278** snooze_mode 1279** NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled 1280** NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART 1281** NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C 1282** 1283** idle_threshold_dh/idle_threshold_nfcc 1284** Idle Threshold Host in 100ms unit 1285** 1286** nfc_wake_active_mode/dh_wake_active_mode 1287** NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting 1288** NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is 1289*asserting 1290** 1291** p_snooze_cback 1292** Notify status of operation 1293** 1294** Returns tHAL_NFC_STATUS 1295** 1296*******************************************************************************/ 1297tHAL_NFC_STATUS HAL_NfcSetSnoozeMode(uint8_t snooze_mode, 1298 uint8_t idle_threshold_dh, 1299 uint8_t idle_threshold_nfcc, 1300 uint8_t nfc_wake_active_mode, 1301 uint8_t dh_wake_active_mode, 1302 tHAL_NFC_STATUS_CBACK* p_snooze_cback) { 1303 uint8_t cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH]; 1304 uint8_t* p; 1305 1306 HAL_TRACE_API1("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode); 1307 1308 nfc_hal_cb.dev_cb.new_snooze_mode = snooze_mode; 1309 nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode; 1310 nfc_hal_cb.dev_cb.p_prop_cback = p_snooze_cback; 1311 1312 p = cmd; 1313 1314 /* Add the HCI command */ 1315 UINT16_TO_STREAM(p, HCI_BRCM_WRITE_SLEEP_MODE); 1316 UINT8_TO_STREAM(p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 1317 1318 memset(p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH); 1319 1320 UINT8_TO_STREAM(p, snooze_mode); /* Sleep Mode */ 1321 1322 UINT8_TO_STREAM(p, idle_threshold_dh); /* Idle Threshold Host */ 1323 UINT8_TO_STREAM(p, idle_threshold_nfcc); /* Idle Threshold HC */ 1324 UINT8_TO_STREAM(p, nfc_wake_active_mode); /* BT Wake Active Mode */ 1325 UINT8_TO_STREAM(p, dh_wake_active_mode); /* Host Wake Active Mode */ 1326 1327 nfc_hal_dm_send_bt_cmd( 1328 cmd, NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH, 1329 nfc_hal_dm_set_snooze_mode_cback); 1330 return (NCI_STATUS_OK); 1331} 1332